DisplayDevice.cpp revision 3f84483382be2d528918cc1a6fbc6a7d68e0b181
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/Surface.h>
31
32#include <hardware/gralloc.h>
33
34#include "DisplayHardware/DisplaySurface.h"
35#include "DisplayHardware/HWComposer.h"
36#include "RenderEngine/RenderEngine.h"
37
38#include "clz.h"
39#include "DisplayDevice.h"
40#include "SurfaceFlinger.h"
41#include "Layer.h"
42
43// ----------------------------------------------------------------------------
44using namespace android;
45// ----------------------------------------------------------------------------
46
47/*
48 * Initialize the display to the specified values.
49 *
50 */
51
52DisplayDevice::DisplayDevice(
53        const sp<SurfaceFlinger>& flinger,
54        DisplayType type,
55        int32_t hwcId,
56        bool isSecure,
57        const wp<IBinder>& displayToken,
58        const sp<DisplaySurface>& displaySurface,
59        const sp<IGraphicBufferProducer>& producer,
60        EGLConfig config)
61    : mFlinger(flinger),
62      mType(type), mHwcDisplayId(hwcId),
63      mDisplayToken(displayToken),
64      mDisplaySurface(displaySurface),
65      mDisplay(EGL_NO_DISPLAY),
66      mSurface(EGL_NO_SURFACE),
67      mDisplayWidth(), mDisplayHeight(), mFormat(),
68      mFlags(),
69      mPageFlipCount(),
70      mIsSecure(isSecure),
71      mSecureLayerVisible(false),
72      mScreenAcquired(false),
73      mLayerStack(NO_LAYER_STACK),
74      mOrientation()
75{
76    mNativeWindow = new Surface(producer);
77    ANativeWindow* const window = mNativeWindow.get();
78
79    int format;
80    window->query(window, NATIVE_WINDOW_FORMAT, &format);
81
82    // Make sure that composition can never be stalled by a virtual display
83    // consumer that isn't processing buffers fast enough. We have to do this
84    // in two places:
85    // * Here, in case the display is composed entirely by HWC.
86    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
87    //   window's swap interval in eglMakeCurrent, so they'll override the
88    //   interval we set here.
89    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
90        window->setSwapInterval(window, 0);
91
92    /*
93     * Create our display's surface
94     */
95
96    EGLSurface surface;
97    EGLint w, h;
98    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
99    surface = eglCreateWindowSurface(display, config, window, NULL);
100    eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
101    eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
102
103    mDisplay = display;
104    mSurface = surface;
105    mFormat  = format;
106    mPageFlipCount = 0;
107    mViewport.makeInvalid();
108    mFrame.makeInvalid();
109
110    // virtual displays are always considered enabled
111    mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
112
113    // Name the display.  The name will be replaced shortly if the display
114    // was created with createDisplay().
115    switch (mType) {
116        case DISPLAY_PRIMARY:
117            mDisplayName = "Built-in Screen";
118            break;
119        case DISPLAY_EXTERNAL:
120            mDisplayName = "HDMI Screen";
121            break;
122        default:
123            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
124            break;
125    }
126
127    // initialize the display orientation transform.
128    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
129}
130
131DisplayDevice::~DisplayDevice() {
132    if (mSurface != EGL_NO_SURFACE) {
133        eglDestroySurface(mDisplay, mSurface);
134        mSurface = EGL_NO_SURFACE;
135    }
136}
137
138void DisplayDevice::disconnect(HWComposer& hwc) {
139    if (mHwcDisplayId >= 0) {
140        hwc.disconnectDisplay(mHwcDisplayId);
141        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
142            hwc.freeDisplayId(mHwcDisplayId);
143        mHwcDisplayId = -1;
144    }
145}
146
147bool DisplayDevice::isValid() const {
148    return mFlinger != NULL;
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::setDisplayName(const String8& displayName) {
168    if (!displayName.isEmpty()) {
169        // never override the name with an empty name
170        mDisplayName = displayName;
171    }
172}
173
174uint32_t DisplayDevice::getPageFlipCount() const {
175    return mPageFlipCount;
176}
177
178status_t DisplayDevice::compositionComplete() const {
179    return mDisplaySurface->compositionComplete();
180}
181
182void DisplayDevice::flip(const Region& dirty) const
183{
184    mFlinger->getRenderEngine().checkErrors();
185
186    EGLDisplay dpy = mDisplay;
187    EGLSurface surface = mSurface;
188
189#ifdef EGL_ANDROID_swap_rectangle
190    if (mFlags & SWAP_RECTANGLE) {
191        const Region newDirty(dirty.intersect(bounds()));
192        const Rect b(newDirty.getBounds());
193        eglSetSwapRectangleANDROID(dpy, surface,
194                b.left, b.top, b.width(), b.height());
195    }
196#endif
197
198    mPageFlipCount++;
199}
200
201status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
202    DisplaySurface::CompositionType compositionType;
203    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
204    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
205    if (haveGles && haveHwc) {
206        compositionType = DisplaySurface::COMPOSITION_MIXED;
207    } else if (haveGles) {
208        compositionType = DisplaySurface::COMPOSITION_GLES;
209    } else if (haveHwc) {
210        compositionType = DisplaySurface::COMPOSITION_HWC;
211    } else {
212        // Nothing to do -- when turning the screen off we get a frame like
213        // this. Call it a HWC frame since we won't be doing any GLES work but
214        // will do a prepare/set cycle.
215        compositionType = DisplaySurface::COMPOSITION_HWC;
216    }
217    return mDisplaySurface->prepareFrame(compositionType);
218}
219
220void DisplayDevice::swapBuffers(HWComposer& hwc) const {
221    // We need to call eglSwapBuffers() unless:
222    // (a) there was no GLES composition this frame, or
223    // (b) we're using a legacy HWC with no framebuffer target support (in
224    //     which case HWComposer::commit() handles things).
225    if (hwc.initCheck() != NO_ERROR ||
226            (hwc.hasGlesComposition(mHwcDisplayId) &&
227             hwc.supportsFramebufferTarget())) {
228        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
229        if (!success) {
230            EGLint error = eglGetError();
231            if (error == EGL_CONTEXT_LOST ||
232                    mType == DisplayDevice::DISPLAY_PRIMARY) {
233                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
234                        mDisplay, mSurface, error);
235            } else {
236                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
237                        mDisplay, mSurface, error);
238            }
239        }
240    }
241
242    status_t result = mDisplaySurface->advanceFrame();
243    if (result != NO_ERROR) {
244        ALOGE("[%s] failed pushing new frame to HWC: %d",
245                mDisplayName.string(), result);
246    }
247}
248
249void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
250    if (hwc.initCheck() == NO_ERROR) {
251        mDisplaySurface->onFrameCommitted();
252    }
253}
254
255uint32_t DisplayDevice::getFlags() const
256{
257    return mFlags;
258}
259
260EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
261    EGLBoolean result = EGL_TRUE;
262    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
263    if (sur != mSurface) {
264        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
265        if (result == EGL_TRUE) {
266            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
267                eglSwapInterval(dpy, 0);
268            setViewportAndProjection();
269        }
270    }
271    return result;
272}
273
274void DisplayDevice::setViewportAndProjection() const {
275    size_t w = mDisplayWidth;
276    size_t h = mDisplayHeight;
277    mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
278}
279
280// ----------------------------------------------------------------------------
281
282void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
283    mVisibleLayersSortedByZ = layers;
284    mSecureLayerVisible = false;
285    size_t count = layers.size();
286    for (size_t i=0 ; i<count ; i++) {
287        const sp<Layer>& layer(layers[i]);
288        if (layer->isSecure()) {
289            mSecureLayerVisible = true;
290        }
291    }
292}
293
294const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
295    return mVisibleLayersSortedByZ;
296}
297
298bool DisplayDevice::getSecureLayerVisible() const {
299    return mSecureLayerVisible;
300}
301
302Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
303    Region dirty;
304    if (repaintEverything) {
305        dirty.set(getBounds());
306    } else {
307        const Transform& planeTransform(mGlobalTransform);
308        dirty = planeTransform.transform(this->dirtyRegion);
309        dirty.andSelf(getBounds());
310    }
311    return dirty;
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
334void DisplayDevice::setLayerStack(uint32_t stack) {
335    mLayerStack = stack;
336    dirtyRegion.set(bounds());
337}
338
339// ----------------------------------------------------------------------------
340
341status_t DisplayDevice::orientationToTransfrom(
342        int orientation, int w, int h, Transform* tr)
343{
344    uint32_t flags = 0;
345    switch (orientation) {
346    case DisplayState::eOrientationDefault:
347        flags = Transform::ROT_0;
348        break;
349    case DisplayState::eOrientation90:
350        flags = Transform::ROT_90;
351        break;
352    case DisplayState::eOrientation180:
353        flags = Transform::ROT_180;
354        break;
355    case DisplayState::eOrientation270:
356        flags = Transform::ROT_270;
357        break;
358    default:
359        return BAD_VALUE;
360    }
361    tr->set(flags, w, h);
362    return NO_ERROR;
363}
364
365void DisplayDevice::setProjection(int orientation,
366        const Rect& newViewport, const Rect& newFrame) {
367    Rect viewport(newViewport);
368    Rect frame(newFrame);
369
370    const int w = mDisplayWidth;
371    const int h = mDisplayHeight;
372
373    Transform R;
374    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
375
376    if (!frame.isValid()) {
377        // the destination frame can be invalid if it has never been set,
378        // in that case we assume the whole display frame.
379        frame = Rect(w, h);
380    }
381
382    if (viewport.isEmpty()) {
383        // viewport can be invalid if it has never been set, in that case
384        // we assume the whole display size.
385        // it's also invalid to have an empty viewport, so we handle that
386        // case in the same way.
387        viewport = Rect(w, h);
388        if (R.getOrientation() & Transform::ROT_90) {
389            // viewport is always specified in the logical orientation
390            // of the display (ie: post-rotation).
391            swap(viewport.right, viewport.bottom);
392        }
393    }
394
395    dirtyRegion.set(getBounds());
396
397    Transform TL, TP, S;
398    float src_width  = viewport.width();
399    float src_height = viewport.height();
400    float dst_width  = frame.width();
401    float dst_height = frame.height();
402    if (src_width != dst_width || src_height != dst_height) {
403        float sx = dst_width  / src_width;
404        float sy = dst_height / src_height;
405        S.set(sx, 0, 0, sy);
406    }
407
408    float src_x = viewport.left;
409    float src_y = viewport.top;
410    float dst_x = frame.left;
411    float dst_y = frame.top;
412    TL.set(-src_x, -src_y);
413    TP.set(dst_x, dst_y);
414
415    // The viewport and frame are both in the logical orientation.
416    // Apply the logical translation, scale to physical size, apply the
417    // physical translation and finally rotate to the physical orientation.
418    mGlobalTransform = R * TP * S * TL;
419
420    const uint8_t type = mGlobalTransform.getType();
421    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
422            (type >= Transform::SCALE));
423
424    mScissor = mGlobalTransform.transform(viewport);
425    if (mScissor.isEmpty()) {
426        mScissor = getBounds();
427    }
428
429    mOrientation = orientation;
430    mViewport = viewport;
431    mFrame = frame;
432}
433
434void DisplayDevice::dump(String8& result) const {
435    const Transform& tr(mGlobalTransform);
436    result.appendFormat(
437        "+ DisplayDevice: %s\n"
438        "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
439        "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
440        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
441        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
442        mDisplayName.string(), mType, mHwcDisplayId,
443        mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
444        mOrientation, tr.getType(), getPageFlipCount(),
445        mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
446        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
447        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
448        mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
449        tr[0][0], tr[1][0], tr[2][0],
450        tr[0][1], tr[1][1], tr[2][1],
451        tr[0][2], tr[1][2], tr[2][2]);
452
453    String8 surfaceDump;
454    mDisplaySurface->dump(surfaceDump);
455    result.append(surfaceDump);
456}
457