OSDN Git Service

now able to set the layer stack on a DisplayDevice
[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 static __attribute__((noinline))
63 void checkEGLErrors(const char* token)
64 {
65     struct EGLUtils {
66         static const char *strerror(EGLint err) {
67             switch (err){
68                 case EGL_SUCCESS:           return "EGL_SUCCESS";
69                 case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
70                 case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
71                 case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
72                 case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
73                 case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
74                 case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
75                 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
76                 case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
77                 case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
78                 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
79                 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
80                 case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
81                 case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
82                 case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
83                 default: return "UNKNOWN";
84             }
85         }
86     };
87
88     EGLint error = eglGetError();
89     if (error && error != EGL_SUCCESS) {
90         ALOGE("%s: EGL error 0x%04x (%s)",
91                 token, int(error), EGLUtils::strerror(error));
92     }
93 }
94
95 // ----------------------------------------------------------------------------
96
97 /*
98  * Initialize the display to the specified values.
99  *
100  */
101
102 DisplayDevice::DisplayDevice(
103         const sp<SurfaceFlinger>& flinger,
104         int display,
105         const sp<ANativeWindow>& nativeWindow,
106         const sp<FramebufferSurface>& framebufferSurface,
107         EGLConfig config)
108     : mFlinger(flinger),
109       mId(display),
110       mNativeWindow(nativeWindow),
111       mFramebufferSurface(framebufferSurface),
112       mDisplay(EGL_NO_DISPLAY),
113       mSurface(EGL_NO_SURFACE),
114       mContext(EGL_NO_CONTEXT),
115       mDpiX(), mDpiY(),
116       mDensity(),
117       mDisplayWidth(), mDisplayHeight(), mFormat(),
118       mFlags(),
119       mPageFlipCount(),
120       mSecureLayerVisible(false),
121       mScreenAcquired(false),
122       mOrientation(),
123       mLayerStack(0)
124 {
125     init(config);
126 }
127
128 DisplayDevice::~DisplayDevice() {
129     if (mSurface != EGL_NO_SURFACE) {
130         eglDestroySurface(mDisplay, mSurface);
131         mSurface = EGL_NO_SURFACE;
132     }
133 }
134
135 bool DisplayDevice::isValid() const {
136     return mFlinger != NULL;
137 }
138
139 float DisplayDevice::getDpiX() const {
140     return mDpiX;
141 }
142
143 float DisplayDevice::getDpiY() const {
144     return mDpiY;
145 }
146
147 float DisplayDevice::getDensity() const {
148     return mDensity;
149 }
150
151 int DisplayDevice::getWidth() const {
152     return mDisplayWidth;
153 }
154
155 int DisplayDevice::getHeight() const {
156     return mDisplayHeight;
157 }
158
159 PixelFormat DisplayDevice::getFormat() const {
160     return mFormat;
161 }
162
163 EGLSurface DisplayDevice::getEGLSurface() const {
164     return mSurface;
165 }
166
167 void DisplayDevice::init(EGLConfig config)
168 {
169     ANativeWindow* const window = mNativeWindow.get();
170
171     int format;
172     window->query(window, NATIVE_WINDOW_FORMAT, &format);
173     mDpiX = window->xdpi;
174     mDpiY = window->ydpi;
175
176     // TODO: Not sure if display density should handled by SF any longer
177     class Density {
178         static int getDensityFromProperty(char const* propName) {
179             char property[PROPERTY_VALUE_MAX];
180             int density = 0;
181             if (property_get(propName, property, NULL) > 0) {
182                 density = atoi(property);
183             }
184             return density;
185         }
186     public:
187         static int getEmuDensity() {
188             return getDensityFromProperty("qemu.sf.lcd_density"); }
189         static int getBuildDensity()  {
190             return getDensityFromProperty("ro.sf.lcd_density"); }
191     };
192     // The density of the device is provided by a build property
193     mDensity = Density::getBuildDensity() / 160.0f;
194     if (mDensity == 0) {
195         // the build doesn't provide a density -- this is wrong!
196         // use xdpi instead
197         ALOGE("ro.sf.lcd_density must be defined as a build property");
198         mDensity = mDpiX / 160.0f;
199     }
200     if (Density::getEmuDensity()) {
201         // if "qemu.sf.lcd_density" is specified, it overrides everything
202         mDpiX = mDpiY = mDensity = Density::getEmuDensity();
203         mDensity /= 160.0f;
204     }
205
206     /*
207      * Create our display's surface
208      */
209
210     EGLSurface surface;
211     EGLint w, h;
212     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
213     surface = eglCreateWindowSurface(display, config, window, NULL);
214     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
215     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
216
217     mDisplay = display;
218     mSurface = surface;
219     mFormat  = format;
220     mPageFlipCount = 0;
221
222     // initialize the display orientation transform.
223     DisplayDevice::setOrientation(ISurfaceComposer::eOrientationDefault);
224 }
225
226 uint32_t DisplayDevice::getPageFlipCount() const {
227     return mPageFlipCount;
228 }
229
230 status_t DisplayDevice::compositionComplete() const {
231     if (mFramebufferSurface == NULL) {
232         return NO_ERROR;
233     }
234     return mFramebufferSurface->compositionComplete();
235 }
236
237 void DisplayDevice::flip(const Region& dirty) const
238 {
239     checkGLErrors();
240
241     EGLDisplay dpy = mDisplay;
242     EGLSurface surface = mSurface;
243
244 #ifdef EGL_ANDROID_swap_rectangle    
245     if (mFlags & SWAP_RECTANGLE) {
246         const Region newDirty(dirty.intersect(bounds()));
247         const Rect b(newDirty.getBounds());
248         eglSetSwapRectangleANDROID(dpy, surface,
249                 b.left, b.top, b.width(), b.height());
250     } 
251 #endif
252     
253     mPageFlipCount++;
254 }
255
256 uint32_t DisplayDevice::getFlags() const
257 {
258     return mFlags;
259 }
260
261 void DisplayDevice::dump(String8& res) const
262 {
263     if (mFramebufferSurface != NULL) {
264         mFramebufferSurface->dump(res);
265     }
266 }
267
268 void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) {
269     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
270     if (sur != hw->mSurface) {
271         EGLDisplay dpy = eglGetCurrentDisplay();
272         eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
273     }
274 }
275
276 // ----------------------------------------------------------------------------
277
278 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
279     mVisibleLayersSortedByZ = layers;
280     size_t count = layers.size();
281     for (size_t i=0 ; i<count ; i++) {
282         if (layers[i]->isSecure()) {
283             mSecureLayerVisible = true;
284         }
285     }
286 }
287
288 Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const {
289     return mVisibleLayersSortedByZ;
290 }
291
292 bool DisplayDevice::getSecureLayerVisible() const {
293     return mSecureLayerVisible;
294 }
295
296 // ----------------------------------------------------------------------------
297
298 bool DisplayDevice::canDraw() const {
299     return mScreenAcquired;
300 }
301
302 void DisplayDevice::releaseScreen() const {
303     mScreenAcquired = false;
304 }
305
306 void DisplayDevice::acquireScreen() const {
307     mScreenAcquired = true;
308 }
309
310 bool DisplayDevice::isScreenAcquired() const {
311     return mScreenAcquired;
312 }
313
314 // ----------------------------------------------------------------------------
315
316 void DisplayDevice::setLayerStack(uint32_t stack) {
317     mLayerStack = stack;
318     dirtyRegion.set(bounds());
319 }
320
321 // ----------------------------------------------------------------------------
322
323 status_t DisplayDevice::orientationToTransfrom(
324         int orientation, int w, int h, Transform* tr)
325 {
326     uint32_t flags = 0;
327     switch (orientation) {
328     case ISurfaceComposer::eOrientationDefault:
329         flags = Transform::ROT_0;
330         break;
331     case ISurfaceComposer::eOrientation90:
332         flags = Transform::ROT_90;
333         break;
334     case ISurfaceComposer::eOrientation180:
335         flags = Transform::ROT_180;
336         break;
337     case ISurfaceComposer::eOrientation270:
338         flags = Transform::ROT_270;
339         break;
340     default:
341         return BAD_VALUE;
342     }
343     tr->set(flags, w, h);
344     return NO_ERROR;
345 }
346
347 status_t DisplayDevice::setOrientation(int orientation) {
348     int w = mDisplayWidth;
349     int h = mDisplayHeight;
350
351     DisplayDevice::orientationToTransfrom(
352             orientation, w, h, &mGlobalTransform);
353     if (orientation & ISurfaceComposer::eOrientationSwapMask) {
354         int tmp = w;
355         w = h;
356         h = tmp;
357     }
358     mOrientation = orientation;
359     dirtyRegion.set(bounds());
360     return NO_ERROR;
361 }