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