DisplayDevice.cpp revision b02087dbd6a25e9d077fde16039050da8012b413
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// #define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "DisplayDevice"
20
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <math.h>
25
26#include <cutils/properties.h>
27
28#include <utils/RefBase.h>
29#include <utils/Log.h>
30
31#include <ui/DebugUtils.h>
32#include <ui/DisplayInfo.h>
33#include <ui/PixelFormat.h>
34
35#include <gui/Surface.h>
36
37#include <hardware/gralloc.h>
38
39#include "DisplayHardware/DisplaySurface.h"
40#include "DisplayHardware/HWComposer.h"
41#include "DisplayHardware/HWC2.h"
42#include "RenderEngine/RenderEngine.h"
43
44#include "clz.h"
45#include "DisplayDevice.h"
46#include "SurfaceFlinger.h"
47#include "Layer.h"
48
49#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
50#include <configstore/Utils.h>
51
52// ----------------------------------------------------------------------------
53using namespace android;
54// ----------------------------------------------------------------------------
55
56// retrieve triple buffer setting from configstore
57using namespace android::hardware::configstore;
58using namespace android::hardware::configstore::V1_0;
59
60static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs,
61        &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) >= 3;
62
63/*
64 * Initialize the display to the specified values.
65 *
66 */
67
68uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
69
70// clang-format off
71DisplayDevice::DisplayDevice(
72        const sp<SurfaceFlinger>& flinger,
73        DisplayType type,
74        int32_t hwcId,
75        bool isSecure,
76        const wp<IBinder>& displayToken,
77        const sp<DisplaySurface>& displaySurface,
78        const sp<IGraphicBufferProducer>& producer,
79        bool supportWideColor)
80    : lastCompositionHadVisibleLayers(false),
81      mFlinger(flinger),
82      mType(type),
83      mHwcDisplayId(hwcId),
84      mDisplayToken(displayToken),
85      mDisplaySurface(displaySurface),
86      mDisplay(EGL_NO_DISPLAY),
87      mSurface(EGL_NO_SURFACE),
88      mDisplayWidth(),
89      mDisplayHeight(),
90      mPageFlipCount(),
91      mIsSecure(isSecure),
92      mLayerStack(NO_LAYER_STACK),
93      mOrientation(),
94      mPowerMode(HWC_POWER_MODE_OFF),
95      mActiveConfig(0)
96{
97    // clang-format on
98    Surface* surface;
99    mNativeWindow = surface = new Surface(producer, false);
100    ANativeWindow* const window = mNativeWindow.get();
101
102    mActiveColorMode = HAL_COLOR_MODE_NATIVE;
103    mDisplayHasWideColor = supportWideColor;
104    /*
105     * Create our display's surface
106     */
107
108    EGLSurface eglSurface;
109    EGLDisplay display = mFlinger->getRenderEngine().getEGLDisplay();
110    EGLConfig config = mFlinger->getRenderEngine().getEGLConfig();
111
112    if (config == EGL_NO_CONFIG) {
113        config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888,
114                                               /*logConfig*/ false);
115    }
116    eglSurface = eglCreateWindowSurface(display, config, window, NULL);
117    eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);
118    eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
119
120    // Make sure that composition can never be stalled by a virtual display
121    // consumer that isn't processing buffers fast enough. We have to do this
122    // in two places:
123    // * Here, in case the display is composed entirely by HWC.
124    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
125    //   window's swap interval in eglMakeCurrent, so they'll override the
126    //   interval we set here.
127    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
128        window->setSwapInterval(window, 0);
129
130    mConfig = config;
131    mDisplay = display;
132    mSurface = eglSurface;
133    mPageFlipCount = 0;
134    mViewport.makeInvalid();
135    mFrame.makeInvalid();
136
137    // virtual displays are always considered enabled
138    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
139                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
140
141    // Name the display.  The name will be replaced shortly if the display
142    // was created with createDisplay().
143    switch (mType) {
144        case DISPLAY_PRIMARY:
145            mDisplayName = "Built-in Screen";
146            break;
147        case DISPLAY_EXTERNAL:
148            mDisplayName = "HDMI Screen";
149            break;
150        default:
151            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
152            break;
153    }
154
155    // initialize the display orientation transform.
156    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
157
158    if (useTripleFramebuffer) {
159        surface->allocateBuffers();
160    }
161}
162
163DisplayDevice::~DisplayDevice() {
164    if (mSurface != EGL_NO_SURFACE) {
165        eglDestroySurface(mDisplay, mSurface);
166        mSurface = EGL_NO_SURFACE;
167    }
168}
169
170void DisplayDevice::disconnect(HWComposer& hwc) {
171    if (mHwcDisplayId >= 0) {
172        hwc.disconnectDisplay(mHwcDisplayId);
173        mHwcDisplayId = -1;
174    }
175}
176
177bool DisplayDevice::isValid() const {
178    return mFlinger != NULL;
179}
180
181int DisplayDevice::getWidth() const {
182    return mDisplayWidth;
183}
184
185int DisplayDevice::getHeight() const {
186    return mDisplayHeight;
187}
188
189EGLSurface DisplayDevice::getEGLSurface() const {
190    return mSurface;
191}
192
193void DisplayDevice::setDisplayName(const String8& displayName) {
194    if (!displayName.isEmpty()) {
195        // never override the name with an empty name
196        mDisplayName = displayName;
197    }
198}
199
200uint32_t DisplayDevice::getPageFlipCount() const {
201    return mPageFlipCount;
202}
203
204void DisplayDevice::flip() const
205{
206    mFlinger->getRenderEngine().checkErrors();
207    mPageFlipCount++;
208}
209
210status_t DisplayDevice::beginFrame(bool mustRecompose) const {
211    return mDisplaySurface->beginFrame(mustRecompose);
212}
213
214status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
215    status_t error = hwc.prepare(*this);
216    if (error != NO_ERROR) {
217        return error;
218    }
219
220    DisplaySurface::CompositionType compositionType;
221    bool hasClient = hwc.hasClientComposition(mHwcDisplayId);
222    bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId);
223    if (hasClient && hasDevice) {
224        compositionType = DisplaySurface::COMPOSITION_MIXED;
225    } else if (hasClient) {
226        compositionType = DisplaySurface::COMPOSITION_GLES;
227    } else if (hasDevice) {
228        compositionType = DisplaySurface::COMPOSITION_HWC;
229    } else {
230        // Nothing to do -- when turning the screen off we get a frame like
231        // this. Call it a HWC frame since we won't be doing any GLES work but
232        // will do a prepare/set cycle.
233        compositionType = DisplaySurface::COMPOSITION_HWC;
234    }
235    return mDisplaySurface->prepareFrame(compositionType);
236}
237
238void DisplayDevice::swapBuffers(HWComposer& hwc) const {
239    if (hwc.hasClientComposition(mHwcDisplayId)) {
240        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
241        if (!success) {
242            EGLint error = eglGetError();
243            if (error == EGL_CONTEXT_LOST ||
244                    mType == DisplayDevice::DISPLAY_PRIMARY) {
245                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
246                        mDisplay, mSurface, error);
247            } else {
248                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
249                        mDisplay, mSurface, error);
250            }
251        }
252    }
253
254    status_t result = mDisplaySurface->advanceFrame();
255    if (result != NO_ERROR) {
256        ALOGE("[%s] failed pushing new frame to HWC: %d",
257                mDisplayName.string(), result);
258    }
259}
260
261void DisplayDevice::onSwapBuffersCompleted() const {
262    mDisplaySurface->onFrameCommitted();
263}
264
265EGLBoolean DisplayDevice::makeCurrent() const {
266    EGLBoolean result = EGL_TRUE;
267    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
268    if (sur != mSurface) {
269        result = mFlinger->getRenderEngine().setCurrentSurface(mSurface);
270        if (result == EGL_TRUE) {
271            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
272                eglSwapInterval(mDisplay, 0);
273        }
274    }
275    setViewportAndProjection();
276    return result;
277}
278
279void DisplayDevice::setViewportAndProjection() const {
280    size_t w = mDisplayWidth;
281    size_t h = mDisplayHeight;
282    Rect sourceCrop(0, 0, w, h);
283    mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
284        false, Transform::ROT_0);
285}
286
287const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
288    return mDisplaySurface->getClientTargetAcquireFence();
289}
290
291// ----------------------------------------------------------------------------
292
293void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
294    mVisibleLayersSortedByZ = layers;
295}
296
297const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
298    return mVisibleLayersSortedByZ;
299}
300
301void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) {
302    mLayersNeedingFences = layers;
303}
304
305const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const {
306    return mLayersNeedingFences;
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// ----------------------------------------------------------------------------
322void DisplayDevice::setPowerMode(int mode) {
323    mPowerMode = mode;
324}
325
326int DisplayDevice::getPowerMode()  const {
327    return mPowerMode;
328}
329
330bool DisplayDevice::isDisplayOn() const {
331    return (mPowerMode != HWC_POWER_MODE_OFF);
332}
333
334// ----------------------------------------------------------------------------
335void DisplayDevice::setActiveConfig(int mode) {
336    mActiveConfig = mode;
337}
338
339int DisplayDevice::getActiveConfig()  const {
340    return mActiveConfig;
341}
342
343// ----------------------------------------------------------------------------
344void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
345    mActiveColorMode = mode;
346}
347
348android_color_mode_t DisplayDevice::getActiveColorMode() const {
349    return mActiveColorMode;
350}
351
352void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) {
353    ANativeWindow* const window = mNativeWindow.get();
354    native_window_set_buffers_data_space(window, dataspace);
355}
356
357// ----------------------------------------------------------------------------
358
359void DisplayDevice::setLayerStack(uint32_t stack) {
360    mLayerStack = stack;
361    dirtyRegion.set(bounds());
362}
363
364// ----------------------------------------------------------------------------
365
366uint32_t DisplayDevice::getOrientationTransform() const {
367    uint32_t transform = 0;
368    switch (mOrientation) {
369        case DisplayState::eOrientationDefault:
370            transform = Transform::ROT_0;
371            break;
372        case DisplayState::eOrientation90:
373            transform = Transform::ROT_90;
374            break;
375        case DisplayState::eOrientation180:
376            transform = Transform::ROT_180;
377            break;
378        case DisplayState::eOrientation270:
379            transform = Transform::ROT_270;
380            break;
381    }
382    return transform;
383}
384
385status_t DisplayDevice::orientationToTransfrom(
386        int orientation, int w, int h, Transform* tr)
387{
388    uint32_t flags = 0;
389    switch (orientation) {
390    case DisplayState::eOrientationDefault:
391        flags = Transform::ROT_0;
392        break;
393    case DisplayState::eOrientation90:
394        flags = Transform::ROT_90;
395        break;
396    case DisplayState::eOrientation180:
397        flags = Transform::ROT_180;
398        break;
399    case DisplayState::eOrientation270:
400        flags = Transform::ROT_270;
401        break;
402    default:
403        return BAD_VALUE;
404    }
405    tr->set(flags, w, h);
406    return NO_ERROR;
407}
408
409void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
410    dirtyRegion.set(getBounds());
411
412    if (mSurface != EGL_NO_SURFACE) {
413        eglDestroySurface(mDisplay, mSurface);
414        mSurface = EGL_NO_SURFACE;
415    }
416
417    mDisplaySurface->resizeBuffers(newWidth, newHeight);
418
419    ANativeWindow* const window = mNativeWindow.get();
420    mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
421    eglQuerySurface(mDisplay, mSurface, EGL_WIDTH,  &mDisplayWidth);
422    eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
423
424    LOG_FATAL_IF(mDisplayWidth != newWidth,
425                "Unable to set new width to %d", newWidth);
426    LOG_FATAL_IF(mDisplayHeight != newHeight,
427                "Unable to set new height to %d", newHeight);
428}
429
430void DisplayDevice::setProjection(int orientation,
431        const Rect& newViewport, const Rect& newFrame) {
432    Rect viewport(newViewport);
433    Rect frame(newFrame);
434
435    const int w = mDisplayWidth;
436    const int h = mDisplayHeight;
437
438    Transform R;
439    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
440
441    if (!frame.isValid()) {
442        // the destination frame can be invalid if it has never been set,
443        // in that case we assume the whole display frame.
444        frame = Rect(w, h);
445    }
446
447    if (viewport.isEmpty()) {
448        // viewport can be invalid if it has never been set, in that case
449        // we assume the whole display size.
450        // it's also invalid to have an empty viewport, so we handle that
451        // case in the same way.
452        viewport = Rect(w, h);
453        if (R.getOrientation() & Transform::ROT_90) {
454            // viewport is always specified in the logical orientation
455            // of the display (ie: post-rotation).
456            swap(viewport.right, viewport.bottom);
457        }
458    }
459
460    dirtyRegion.set(getBounds());
461
462    Transform TL, TP, S;
463    float src_width  = viewport.width();
464    float src_height = viewport.height();
465    float dst_width  = frame.width();
466    float dst_height = frame.height();
467    if (src_width != dst_width || src_height != dst_height) {
468        float sx = dst_width  / src_width;
469        float sy = dst_height / src_height;
470        S.set(sx, 0, 0, sy);
471    }
472
473    float src_x = viewport.left;
474    float src_y = viewport.top;
475    float dst_x = frame.left;
476    float dst_y = frame.top;
477    TL.set(-src_x, -src_y);
478    TP.set(dst_x, dst_y);
479
480    // The viewport and frame are both in the logical orientation.
481    // Apply the logical translation, scale to physical size, apply the
482    // physical translation and finally rotate to the physical orientation.
483    mGlobalTransform = R * TP * S * TL;
484
485    const uint8_t type = mGlobalTransform.getType();
486    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
487            (type >= Transform::SCALE));
488
489    mScissor = mGlobalTransform.transform(viewport);
490    if (mScissor.isEmpty()) {
491        mScissor = getBounds();
492    }
493
494    mOrientation = orientation;
495    if (mType == DisplayType::DISPLAY_PRIMARY) {
496        uint32_t transform = 0;
497        switch (mOrientation) {
498            case DisplayState::eOrientationDefault:
499                transform = Transform::ROT_0;
500                break;
501            case DisplayState::eOrientation90:
502                transform = Transform::ROT_90;
503                break;
504            case DisplayState::eOrientation180:
505                transform = Transform::ROT_180;
506                break;
507            case DisplayState::eOrientation270:
508                transform = Transform::ROT_270;
509                break;
510        }
511        sPrimaryDisplayOrientation = transform;
512    }
513    mViewport = viewport;
514    mFrame = frame;
515}
516
517uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
518    return sPrimaryDisplayOrientation;
519}
520
521void DisplayDevice::dump(String8& result) const {
522    const Transform& tr(mGlobalTransform);
523    ANativeWindow* const window = mNativeWindow.get();
524    EGLint redSize, greenSize, blueSize, alphaSize;
525    eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &redSize);
526    eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &greenSize);
527    eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &blueSize);
528    eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &alphaSize);
529    result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string());
530    result.appendFormat("   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p "
531                        "(%d:%d:%d:%d), orient=%2d (type=%08x), "
532                        "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
533                        mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window,
534                        redSize, greenSize, blueSize, alphaSize, mOrientation, tr.getType(),
535                        getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
536                        mVisibleLayersSortedByZ.size());
537    result.appendFormat("   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
538                        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
539                        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
540                        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left,
541                        mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0],
542                        tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]);
543    auto const surface = static_cast<Surface*>(window);
544    android_dataspace dataspace = surface->getBuffersDataSpace();
545    result.appendFormat("   dataspace: %s (%d)\n", dataspaceDetails(dataspace).c_str(), dataspace);
546
547    String8 surfaceDump;
548    mDisplaySurface->dumpAsString(surfaceDump);
549    result.append(surfaceDump);
550}
551
552std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
553
554DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
555    : type(type),
556      layerStack(DisplayDevice::NO_LAYER_STACK),
557      orientation(0),
558      width(0),
559      height(0),
560      isSecure(isSecure)
561{
562    viewport.makeInvalid();
563    frame.makeInvalid();
564}
565