DisplayDevice.cpp revision 19e872912af66c53a4350afcc333bbafaf6a2294
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    // Make sure that composition can never be stalled by a virtual display
81    // consumer that isn't processing buffers fast enough. We have to do this
82    // in two places:
83    // * Here, in case the display is composed entirely by HWC.
84    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
85    //   window's swap interval in eglMakeCurrent, so they'll override the
86    //   interval we set here.
87    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
88        window->setSwapInterval(window, 0);
89
90    /*
91     * Create our display's surface
92     */
93
94    EGLSurface surface;
95    EGLint w, h;
96    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
97    if (config == EGL_NO_CONFIG) {
98        config = RenderEngine::chooseEglConfig(display, format);
99    }
100    surface = eglCreateWindowSurface(display, config, window, NULL);
101    eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
102    eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
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#endif
198
199    mPageFlipCount++;
200}
201
202status_t DisplayDevice::beginFrame() const {
203    return mDisplaySurface->beginFrame();
204}
205
206status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
207    DisplaySurface::CompositionType compositionType;
208    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
209    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
210    if (haveGles && haveHwc) {
211        compositionType = DisplaySurface::COMPOSITION_MIXED;
212    } else if (haveGles) {
213        compositionType = DisplaySurface::COMPOSITION_GLES;
214    } else if (haveHwc) {
215        compositionType = DisplaySurface::COMPOSITION_HWC;
216    } else {
217        // Nothing to do -- when turning the screen off we get a frame like
218        // this. Call it a HWC frame since we won't be doing any GLES work but
219        // will do a prepare/set cycle.
220        compositionType = DisplaySurface::COMPOSITION_HWC;
221    }
222    return mDisplaySurface->prepareFrame(compositionType);
223}
224
225void DisplayDevice::swapBuffers(HWComposer& hwc) const {
226    // We need to call eglSwapBuffers() if:
227    //  (1) we don't have a hardware composer, or
228    //  (2) we did GLES composition this frame, and either
229    //    (a) we have framebuffer target support (not present on legacy
230    //        devices, where HWComposer::commit() handles things); or
231    //    (b) this is a virtual display
232    if (hwc.initCheck() != NO_ERROR ||
233            (hwc.hasGlesComposition(mHwcDisplayId) &&
234             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
235        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
236        if (!success) {
237            EGLint error = eglGetError();
238            if (error == EGL_CONTEXT_LOST ||
239                    mType == DisplayDevice::DISPLAY_PRIMARY) {
240                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
241                        mDisplay, mSurface, error);
242            } else {
243                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
244                        mDisplay, mSurface, error);
245            }
246        }
247    }
248
249    status_t result = mDisplaySurface->advanceFrame();
250    if (result != NO_ERROR) {
251        ALOGE("[%s] failed pushing new frame to HWC: %d",
252                mDisplayName.string(), result);
253    }
254}
255
256void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
257    if (hwc.initCheck() == NO_ERROR) {
258        mDisplaySurface->onFrameCommitted();
259    }
260}
261
262uint32_t DisplayDevice::getFlags() const
263{
264    return mFlags;
265}
266
267EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
268    EGLBoolean result = EGL_TRUE;
269    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
270    if (sur != mSurface) {
271        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
272        if (result == EGL_TRUE) {
273            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
274                eglSwapInterval(dpy, 0);
275        }
276    }
277    setViewportAndProjection();
278    return result;
279}
280
281void DisplayDevice::setViewportAndProjection() const {
282    size_t w = mDisplayWidth;
283    size_t h = mDisplayHeight;
284    mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
285}
286
287// ----------------------------------------------------------------------------
288
289void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
290    mVisibleLayersSortedByZ = layers;
291    mSecureLayerVisible = false;
292    size_t count = layers.size();
293    for (size_t i=0 ; i<count ; i++) {
294        const sp<Layer>& layer(layers[i]);
295        if (layer->isSecure()) {
296            mSecureLayerVisible = true;
297        }
298    }
299}
300
301const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
302    return mVisibleLayersSortedByZ;
303}
304
305bool DisplayDevice::getSecureLayerVisible() const {
306    return mSecureLayerVisible;
307}
308
309Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
310    Region dirty;
311    if (repaintEverything) {
312        dirty.set(getBounds());
313    } else {
314        const Transform& planeTransform(mGlobalTransform);
315        dirty = planeTransform.transform(this->dirtyRegion);
316        dirty.andSelf(getBounds());
317    }
318    return dirty;
319}
320
321// ----------------------------------------------------------------------------
322
323bool DisplayDevice::canDraw() const {
324    return mScreenAcquired;
325}
326
327void DisplayDevice::releaseScreen() const {
328    mScreenAcquired = false;
329}
330
331void DisplayDevice::acquireScreen() const {
332    mScreenAcquired = true;
333}
334
335bool DisplayDevice::isScreenAcquired() const {
336    return mScreenAcquired;
337}
338
339// ----------------------------------------------------------------------------
340
341void DisplayDevice::setLayerStack(uint32_t stack) {
342    mLayerStack = stack;
343    dirtyRegion.set(bounds());
344}
345
346// ----------------------------------------------------------------------------
347
348uint32_t DisplayDevice::getOrientationTransform() const {
349    uint32_t transform = 0;
350    switch (mOrientation) {
351        case DisplayState::eOrientationDefault:
352            transform = Transform::ROT_0;
353            break;
354        case DisplayState::eOrientation90:
355            transform = Transform::ROT_90;
356            break;
357        case DisplayState::eOrientation180:
358            transform = Transform::ROT_180;
359            break;
360        case DisplayState::eOrientation270:
361            transform = Transform::ROT_270;
362            break;
363    }
364    return transform;
365}
366
367status_t DisplayDevice::orientationToTransfrom(
368        int orientation, int w, int h, Transform* tr)
369{
370    uint32_t flags = 0;
371    switch (orientation) {
372    case DisplayState::eOrientationDefault:
373        flags = Transform::ROT_0;
374        break;
375    case DisplayState::eOrientation90:
376        flags = Transform::ROT_90;
377        break;
378    case DisplayState::eOrientation180:
379        flags = Transform::ROT_180;
380        break;
381    case DisplayState::eOrientation270:
382        flags = Transform::ROT_270;
383        break;
384    default:
385        return BAD_VALUE;
386    }
387    tr->set(flags, w, h);
388    return NO_ERROR;
389}
390
391void DisplayDevice::setProjection(int orientation,
392        const Rect& newViewport, const Rect& newFrame) {
393    Rect viewport(newViewport);
394    Rect frame(newFrame);
395
396    const int w = mDisplayWidth;
397    const int h = mDisplayHeight;
398
399    Transform R;
400    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
401
402    if (!frame.isValid()) {
403        // the destination frame can be invalid if it has never been set,
404        // in that case we assume the whole display frame.
405        frame = Rect(w, h);
406    }
407
408    if (viewport.isEmpty()) {
409        // viewport can be invalid if it has never been set, in that case
410        // we assume the whole display size.
411        // it's also invalid to have an empty viewport, so we handle that
412        // case in the same way.
413        viewport = Rect(w, h);
414        if (R.getOrientation() & Transform::ROT_90) {
415            // viewport is always specified in the logical orientation
416            // of the display (ie: post-rotation).
417            swap(viewport.right, viewport.bottom);
418        }
419    }
420
421    dirtyRegion.set(getBounds());
422
423    Transform TL, TP, S;
424    float src_width  = viewport.width();
425    float src_height = viewport.height();
426    float dst_width  = frame.width();
427    float dst_height = frame.height();
428    if (src_width != dst_width || src_height != dst_height) {
429        float sx = dst_width  / src_width;
430        float sy = dst_height / src_height;
431        S.set(sx, 0, 0, sy);
432    }
433
434    float src_x = viewport.left;
435    float src_y = viewport.top;
436    float dst_x = frame.left;
437    float dst_y = frame.top;
438    TL.set(-src_x, -src_y);
439    TP.set(dst_x, dst_y);
440
441    // The viewport and frame are both in the logical orientation.
442    // Apply the logical translation, scale to physical size, apply the
443    // physical translation and finally rotate to the physical orientation.
444    mGlobalTransform = R * TP * S * TL;
445
446    const uint8_t type = mGlobalTransform.getType();
447    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
448            (type >= Transform::SCALE));
449
450    mScissor = mGlobalTransform.transform(viewport);
451    if (mScissor.isEmpty()) {
452        mScissor = getBounds();
453    }
454
455    mOrientation = orientation;
456    mViewport = viewport;
457    mFrame = frame;
458}
459
460void DisplayDevice::dump(String8& result) const {
461    const Transform& tr(mGlobalTransform);
462    result.appendFormat(
463        "+ DisplayDevice: %s\n"
464        "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
465        "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
466        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
467        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
468        mDisplayName.string(), mType, mHwcDisplayId,
469        mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
470        mOrientation, tr.getType(), getPageFlipCount(),
471        mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
472        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
473        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
474        mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
475        tr[0][0], tr[1][0], tr[2][0],
476        tr[0][1], tr[1][1], tr[2][1],
477        tr[0][2], tr[1][2], tr[2][2]);
478
479    String8 surfaceDump;
480    mDisplaySurface->dump(surfaceDump);
481    result.append(surfaceDump);
482}
483