DisplayDevice.cpp revision 1a4d883dcc1725892bfb5c28dec255a233186524
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// ----------------------------------------------------------------------------
47using namespace android;
48// ----------------------------------------------------------------------------
49
50static __attribute__((noinline))
51void 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
62static __attribute__((noinline))
63void 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
102DisplayDevice::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
128DisplayDevice::~DisplayDevice() {
129    if (mSurface != EGL_NO_SURFACE) {
130        eglDestroySurface(mDisplay, mSurface);
131        mSurface = EGL_NO_SURFACE;
132    }
133}
134
135bool DisplayDevice::isValid() const {
136    return mFlinger != NULL;
137}
138
139float DisplayDevice::getDpiX() const {
140    return mDpiX;
141}
142
143float DisplayDevice::getDpiY() const {
144    return mDpiY;
145}
146
147float DisplayDevice::getDensity() const {
148    return mDensity;
149}
150
151int DisplayDevice::getWidth() const {
152    return mDisplayWidth;
153}
154
155int DisplayDevice::getHeight() const {
156    return mDisplayHeight;
157}
158
159PixelFormat DisplayDevice::getFormat() const {
160    return mFormat;
161}
162
163EGLSurface DisplayDevice::getEGLSurface() const {
164    return mSurface;
165}
166
167void 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
226uint32_t DisplayDevice::getPageFlipCount() const {
227    return mPageFlipCount;
228}
229
230status_t DisplayDevice::compositionComplete() const {
231    if (mFramebufferSurface == NULL) {
232        return NO_ERROR;
233    }
234    return mFramebufferSurface->compositionComplete();
235}
236
237void 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
256uint32_t DisplayDevice::getFlags() const
257{
258    return mFlags;
259}
260
261void DisplayDevice::dump(String8& res) const
262{
263    if (mFramebufferSurface != NULL) {
264        mFramebufferSurface->dump(res);
265    }
266}
267
268void 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
278void 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
288Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const {
289    return mVisibleLayersSortedByZ;
290}
291
292bool DisplayDevice::getSecureLayerVisible() const {
293    return mSecureLayerVisible;
294}
295
296// ----------------------------------------------------------------------------
297
298bool DisplayDevice::canDraw() const {
299    return mScreenAcquired;
300}
301
302void DisplayDevice::releaseScreen() const {
303    mScreenAcquired = false;
304}
305
306void DisplayDevice::acquireScreen() const {
307    mScreenAcquired = true;
308}
309
310bool DisplayDevice::isScreenAcquired() const {
311    return mScreenAcquired;
312}
313
314// ----------------------------------------------------------------------------
315
316status_t DisplayDevice::orientationToTransfrom(
317        int orientation, int w, int h, Transform* tr)
318{
319    uint32_t flags = 0;
320    switch (orientation) {
321    case ISurfaceComposer::eOrientationDefault:
322        flags = Transform::ROT_0;
323        break;
324    case ISurfaceComposer::eOrientation90:
325        flags = Transform::ROT_90;
326        break;
327    case ISurfaceComposer::eOrientation180:
328        flags = Transform::ROT_180;
329        break;
330    case ISurfaceComposer::eOrientation270:
331        flags = Transform::ROT_270;
332        break;
333    default:
334        return BAD_VALUE;
335    }
336    tr->set(flags, w, h);
337    return NO_ERROR;
338}
339
340status_t DisplayDevice::setOrientation(int orientation) {
341    int w = mDisplayWidth;
342    int h = mDisplayHeight;
343
344    DisplayDevice::orientationToTransfrom(
345            orientation, w, h, &mGlobalTransform);
346    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
347        int tmp = w;
348        w = h;
349        h = tmp;
350    }
351    mOrientation = orientation;
352    dirtyRegion.set(bounds());
353    return NO_ERROR;
354}
355