OSDN Git Service

228944422339c1d48c346060103692d19787e059
[android-x86/frameworks-native.git] / services / surfaceflinger / DisplayDevice.cpp
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <math.h>
21
22 #include <cutils/properties.h>
23
24 #include <utils/RefBase.h>
25 #include <utils/Log.h>
26
27 #include <ui/DisplayInfo.h>
28 #include <ui/PixelFormat.h>
29
30 #include <gui/SurfaceTextureClient.h>
31
32 #include <GLES/gl.h>
33 #include <EGL/egl.h>
34 #include <EGL/eglext.h>
35
36 #include <hardware/gralloc.h>
37
38 #include "DisplayHardware/FramebufferSurface.h"
39 #include "DisplayHardware/HWComposer.h"
40
41 #include "DisplayDevice.h"
42 #include "GLExtensions.h"
43 #include "SurfaceFlinger.h"
44 #include "LayerBase.h"
45
46 // ----------------------------------------------------------------------------
47 using namespace android;
48 // ----------------------------------------------------------------------------
49
50 static __attribute__((noinline))
51 void checkGLErrors()
52 {
53     do {
54         // there could be more than one error flag
55         GLenum error = glGetError();
56         if (error == GL_NO_ERROR)
57             break;
58         ALOGE("GL error 0x%04x", int(error));
59     } while(true);
60 }
61
62 // ----------------------------------------------------------------------------
63
64 /*
65  * Initialize the display to the specified values.
66  *
67  */
68
69 DisplayDevice::DisplayDevice(
70         const sp<SurfaceFlinger>& flinger,
71         int display,
72         const sp<ANativeWindow>& nativeWindow,
73         const sp<FramebufferSurface>& framebufferSurface,
74         EGLConfig config)
75     : mFlinger(flinger),
76       mId(display),
77       mNativeWindow(nativeWindow),
78       mFramebufferSurface(framebufferSurface),
79       mDisplay(EGL_NO_DISPLAY),
80       mSurface(EGL_NO_SURFACE),
81       mContext(EGL_NO_CONTEXT),
82       mDisplayWidth(), mDisplayHeight(), mFormat(),
83       mFlags(),
84       mPageFlipCount(),
85       mSecureLayerVisible(false),
86       mScreenAcquired(false),
87       mOrientation(),
88       mLayerStack(0)
89 {
90     init(config);
91 }
92
93 DisplayDevice::~DisplayDevice() {
94     if (mSurface != EGL_NO_SURFACE) {
95         eglDestroySurface(mDisplay, mSurface);
96         mSurface = EGL_NO_SURFACE;
97     }
98 }
99
100 bool DisplayDevice::isValid() const {
101     return mFlinger != NULL;
102 }
103
104 int DisplayDevice::getWidth() const {
105     return mDisplayWidth;
106 }
107
108 int DisplayDevice::getHeight() const {
109     return mDisplayHeight;
110 }
111
112 PixelFormat DisplayDevice::getFormat() const {
113     return mFormat;
114 }
115
116 EGLSurface DisplayDevice::getEGLSurface() const {
117     return mSurface;
118 }
119
120 void DisplayDevice::init(EGLConfig config)
121 {
122     ANativeWindow* const window = mNativeWindow.get();
123
124     int format;
125     window->query(window, NATIVE_WINDOW_FORMAT, &format);
126
127     /*
128      * Create our display's surface
129      */
130
131     EGLSurface surface;
132     EGLint w, h;
133     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
134     surface = eglCreateWindowSurface(display, config, window, NULL);
135     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
136     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
137
138     mDisplay = display;
139     mSurface = surface;
140     mFormat  = format;
141     mPageFlipCount = 0;
142
143     // external displays are always considered enabled
144     mScreenAcquired = mId >= DisplayDevice::DISPLAY_ID_COUNT;
145
146     // initialize the display orientation transform.
147     DisplayDevice::setOrientation(DisplayState::eOrientationDefault);
148 }
149
150 uint32_t DisplayDevice::getPageFlipCount() const {
151     return mPageFlipCount;
152 }
153
154 status_t DisplayDevice::compositionComplete() const {
155     if (mFramebufferSurface == NULL) {
156         return NO_ERROR;
157     }
158     return mFramebufferSurface->compositionComplete();
159 }
160
161 void DisplayDevice::flip(const Region& dirty) const
162 {
163     checkGLErrors();
164
165     EGLDisplay dpy = mDisplay;
166     EGLSurface surface = mSurface;
167
168 #ifdef EGL_ANDROID_swap_rectangle    
169     if (mFlags & SWAP_RECTANGLE) {
170         const Region newDirty(dirty.intersect(bounds()));
171         const Rect b(newDirty.getBounds());
172         eglSetSwapRectangleANDROID(dpy, surface,
173                 b.left, b.top, b.width(), b.height());
174     } 
175 #endif
176     
177     mPageFlipCount++;
178 }
179
180 uint32_t DisplayDevice::getFlags() const
181 {
182     return mFlags;
183 }
184
185 void DisplayDevice::dump(String8& res) const
186 {
187     if (mFramebufferSurface != NULL) {
188         mFramebufferSurface->dump(res);
189     }
190 }
191
192 void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) {
193     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
194     if (sur != hw->mSurface) {
195         EGLDisplay dpy = eglGetCurrentDisplay();
196         eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
197     }
198 }
199
200 // ----------------------------------------------------------------------------
201
202 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
203     mVisibleLayersSortedByZ = layers;
204     mSecureLayerVisible = false;
205     size_t count = layers.size();
206     for (size_t i=0 ; i<count ; i++) {
207         if (layers[i]->isSecure()) {
208             mSecureLayerVisible = true;
209         }
210     }
211 }
212
213 Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const {
214     return mVisibleLayersSortedByZ;
215 }
216
217 bool DisplayDevice::getSecureLayerVisible() const {
218     return mSecureLayerVisible;
219 }
220
221 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
222     Region dirty;
223     const Transform& planeTransform(mGlobalTransform);
224     if (repaintEverything) {
225         dirty.set(getBounds());
226     } else {
227         dirty = planeTransform.transform(this->dirtyRegion);
228         dirty.andSelf(getBounds());
229     }
230     return dirty;
231 }
232
233 // ----------------------------------------------------------------------------
234
235 bool DisplayDevice::canDraw() const {
236     return mScreenAcquired;
237 }
238
239 void DisplayDevice::releaseScreen() const {
240     mScreenAcquired = false;
241 }
242
243 void DisplayDevice::acquireScreen() const {
244     mScreenAcquired = true;
245 }
246
247 bool DisplayDevice::isScreenAcquired() const {
248     return mScreenAcquired;
249 }
250
251 // ----------------------------------------------------------------------------
252
253 void DisplayDevice::setLayerStack(uint32_t stack) {
254     mLayerStack = stack;
255     dirtyRegion.set(bounds());
256 }
257
258 // ----------------------------------------------------------------------------
259
260 status_t DisplayDevice::orientationToTransfrom(
261         int orientation, int w, int h, Transform* tr)
262 {
263     uint32_t flags = 0;
264     switch (orientation) {
265     case DisplayState::eOrientationDefault:
266         flags = Transform::ROT_0;
267         break;
268     case DisplayState::eOrientation90:
269         flags = Transform::ROT_90;
270         break;
271     case DisplayState::eOrientation180:
272         flags = Transform::ROT_180;
273         break;
274     case DisplayState::eOrientation270:
275         flags = Transform::ROT_270;
276         break;
277     default:
278         return BAD_VALUE;
279     }
280     tr->set(flags, w, h);
281     return NO_ERROR;
282 }
283
284 status_t DisplayDevice::setOrientation(int orientation) {
285     int w = mDisplayWidth;
286     int h = mDisplayHeight;
287
288     DisplayDevice::orientationToTransfrom(
289             orientation, w, h, &mGlobalTransform);
290     if (orientation & DisplayState::eOrientationSwapMask) {
291         int tmp = w;
292         w = h;
293         h = tmp;
294     }
295     mOrientation = orientation;
296     dirtyRegion.set(bounds());
297     return NO_ERROR;
298 }