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