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