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