DisplayDevice.cpp revision 144e116f45f196396f0d59d5fc09766ab618f885
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        bool supportHdr)
81    : lastCompositionHadVisibleLayers(false),
82      mFlinger(flinger),
83      mType(type),
84      mHwcDisplayId(hwcId),
85      mDisplayToken(displayToken),
86      mDisplaySurface(displaySurface),
87      mSurface{flinger->getRenderEngine().createSurface()},
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    mDisplayHasHdr = supportHdr;
105
106    /*
107     * Create our display's surface
108     */
109    mSurface->setCritical(mType == DisplayDevice::DISPLAY_PRIMARY);
110    mSurface->setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL);
111    mSurface->setNativeWindow(window);
112    mDisplayWidth = mSurface->queryWidth();
113    mDisplayHeight = mSurface->queryHeight();
114
115    // Make sure that composition can never be stalled by a virtual display
116    // consumer that isn't processing buffers fast enough. We have to do this
117    // in two places:
118    // * Here, in case the display is composed entirely by HWC.
119    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
120    //   window's swap interval in eglMakeCurrent, so they'll override the
121    //   interval we set here.
122    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
123        window->setSwapInterval(window, 0);
124
125    mPageFlipCount = 0;
126    mViewport.makeInvalid();
127    mFrame.makeInvalid();
128
129    // virtual displays are always considered enabled
130    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
131                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
132
133    // initialize the display orientation transform.
134    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
135
136    if (useTripleFramebuffer) {
137        surface->allocateBuffers();
138    }
139}
140
141DisplayDevice::~DisplayDevice() {
142}
143
144void DisplayDevice::disconnect(HWComposer& hwc) {
145    if (mHwcDisplayId >= 0) {
146        hwc.disconnectDisplay(mHwcDisplayId);
147        mHwcDisplayId = -1;
148    }
149}
150
151bool DisplayDevice::isValid() const {
152    return mFlinger != nullptr;
153}
154
155int DisplayDevice::getWidth() const {
156    return mDisplayWidth;
157}
158
159int DisplayDevice::getHeight() const {
160    return mDisplayHeight;
161}
162
163void DisplayDevice::setDisplayName(const String8& displayName) {
164    if (!displayName.isEmpty()) {
165        // never override the name with an empty name
166        mDisplayName = displayName;
167    }
168}
169
170uint32_t DisplayDevice::getPageFlipCount() const {
171    return mPageFlipCount;
172}
173
174void DisplayDevice::flip() const
175{
176    mFlinger->getRenderEngine().checkErrors();
177    mPageFlipCount++;
178}
179
180status_t DisplayDevice::beginFrame(bool mustRecompose) const {
181    return mDisplaySurface->beginFrame(mustRecompose);
182}
183
184status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
185    status_t error = hwc.prepare(*this);
186    if (error != NO_ERROR) {
187        return error;
188    }
189
190    DisplaySurface::CompositionType compositionType;
191    bool hasClient = hwc.hasClientComposition(mHwcDisplayId);
192    bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId);
193    if (hasClient && hasDevice) {
194        compositionType = DisplaySurface::COMPOSITION_MIXED;
195    } else if (hasClient) {
196        compositionType = DisplaySurface::COMPOSITION_GLES;
197    } else if (hasDevice) {
198        compositionType = DisplaySurface::COMPOSITION_HWC;
199    } else {
200        // Nothing to do -- when turning the screen off we get a frame like
201        // this. Call it a HWC frame since we won't be doing any GLES work but
202        // will do a prepare/set cycle.
203        compositionType = DisplaySurface::COMPOSITION_HWC;
204    }
205    return mDisplaySurface->prepareFrame(compositionType);
206}
207
208void DisplayDevice::swapBuffers(HWComposer& hwc) const {
209    if (hwc.hasClientComposition(mHwcDisplayId) || hwc.hasFlipClientTargetRequest(mHwcDisplayId)) {
210        mSurface->swapBuffers();
211    }
212
213    status_t result = mDisplaySurface->advanceFrame();
214    if (result != NO_ERROR) {
215        ALOGE("[%s] failed pushing new frame to HWC: %d",
216                mDisplayName.string(), result);
217    }
218}
219
220void DisplayDevice::onSwapBuffersCompleted() const {
221    mDisplaySurface->onFrameCommitted();
222}
223
224bool DisplayDevice::makeCurrent() const {
225    bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface);
226    setViewportAndProjection();
227    return success;
228}
229
230void DisplayDevice::setViewportAndProjection() const {
231    size_t w = mDisplayWidth;
232    size_t h = mDisplayHeight;
233    Rect sourceCrop(0, 0, w, h);
234    mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
235        false, Transform::ROT_0);
236}
237
238const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
239    return mDisplaySurface->getClientTargetAcquireFence();
240}
241
242// ----------------------------------------------------------------------------
243
244void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
245    mVisibleLayersSortedByZ = layers;
246}
247
248const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
249    return mVisibleLayersSortedByZ;
250}
251
252void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) {
253    mLayersNeedingFences = layers;
254}
255
256const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const {
257    return mLayersNeedingFences;
258}
259
260Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
261    Region dirty;
262    if (repaintEverything) {
263        dirty.set(getBounds());
264    } else {
265        const Transform& planeTransform(mGlobalTransform);
266        dirty = planeTransform.transform(this->dirtyRegion);
267        dirty.andSelf(getBounds());
268    }
269    return dirty;
270}
271
272// ----------------------------------------------------------------------------
273void DisplayDevice::setPowerMode(int mode) {
274    mPowerMode = mode;
275}
276
277int DisplayDevice::getPowerMode()  const {
278    return mPowerMode;
279}
280
281bool DisplayDevice::isDisplayOn() const {
282    return (mPowerMode != HWC_POWER_MODE_OFF);
283}
284
285// ----------------------------------------------------------------------------
286void DisplayDevice::setActiveConfig(int mode) {
287    mActiveConfig = mode;
288}
289
290int DisplayDevice::getActiveConfig()  const {
291    return mActiveConfig;
292}
293
294// ----------------------------------------------------------------------------
295void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
296    mActiveColorMode = mode;
297}
298
299android_color_mode_t DisplayDevice::getActiveColorMode() const {
300    return mActiveColorMode;
301}
302
303void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) {
304    ANativeWindow* const window = mNativeWindow.get();
305    native_window_set_buffers_data_space(window, dataspace);
306}
307
308// ----------------------------------------------------------------------------
309
310void DisplayDevice::setLayerStack(uint32_t stack) {
311    mLayerStack = stack;
312    dirtyRegion.set(bounds());
313}
314
315// ----------------------------------------------------------------------------
316
317uint32_t DisplayDevice::getOrientationTransform() const {
318    uint32_t transform = 0;
319    switch (mOrientation) {
320        case DisplayState::eOrientationDefault:
321            transform = Transform::ROT_0;
322            break;
323        case DisplayState::eOrientation90:
324            transform = Transform::ROT_90;
325            break;
326        case DisplayState::eOrientation180:
327            transform = Transform::ROT_180;
328            break;
329        case DisplayState::eOrientation270:
330            transform = Transform::ROT_270;
331            break;
332    }
333    return transform;
334}
335
336status_t DisplayDevice::orientationToTransfrom(
337        int orientation, int w, int h, Transform* tr)
338{
339    uint32_t flags = 0;
340    switch (orientation) {
341    case DisplayState::eOrientationDefault:
342        flags = Transform::ROT_0;
343        break;
344    case DisplayState::eOrientation90:
345        flags = Transform::ROT_90;
346        break;
347    case DisplayState::eOrientation180:
348        flags = Transform::ROT_180;
349        break;
350    case DisplayState::eOrientation270:
351        flags = Transform::ROT_270;
352        break;
353    default:
354        return BAD_VALUE;
355    }
356    tr->set(flags, w, h);
357    return NO_ERROR;
358}
359
360void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
361    dirtyRegion.set(getBounds());
362
363    mSurface->setNativeWindow(nullptr);
364
365    mDisplaySurface->resizeBuffers(newWidth, newHeight);
366
367    ANativeWindow* const window = mNativeWindow.get();
368    mSurface->setNativeWindow(window);
369    mDisplayWidth = mSurface->queryWidth();
370    mDisplayHeight = mSurface->queryHeight();
371
372    LOG_FATAL_IF(mDisplayWidth != newWidth,
373                "Unable to set new width to %d", newWidth);
374    LOG_FATAL_IF(mDisplayHeight != newHeight,
375                "Unable to set new height to %d", newHeight);
376}
377
378void DisplayDevice::setProjection(int orientation,
379        const Rect& newViewport, const Rect& newFrame) {
380    Rect viewport(newViewport);
381    Rect frame(newFrame);
382
383    const int w = mDisplayWidth;
384    const int h = mDisplayHeight;
385
386    Transform R;
387    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
388
389    if (!frame.isValid()) {
390        // the destination frame can be invalid if it has never been set,
391        // in that case we assume the whole display frame.
392        frame = Rect(w, h);
393    }
394
395    if (viewport.isEmpty()) {
396        // viewport can be invalid if it has never been set, in that case
397        // we assume the whole display size.
398        // it's also invalid to have an empty viewport, so we handle that
399        // case in the same way.
400        viewport = Rect(w, h);
401        if (R.getOrientation() & Transform::ROT_90) {
402            // viewport is always specified in the logical orientation
403            // of the display (ie: post-rotation).
404            swap(viewport.right, viewport.bottom);
405        }
406    }
407
408    dirtyRegion.set(getBounds());
409
410    Transform TL, TP, S;
411    float src_width  = viewport.width();
412    float src_height = viewport.height();
413    float dst_width  = frame.width();
414    float dst_height = frame.height();
415    if (src_width != dst_width || src_height != dst_height) {
416        float sx = dst_width  / src_width;
417        float sy = dst_height / src_height;
418        S.set(sx, 0, 0, sy);
419    }
420
421    float src_x = viewport.left;
422    float src_y = viewport.top;
423    float dst_x = frame.left;
424    float dst_y = frame.top;
425    TL.set(-src_x, -src_y);
426    TP.set(dst_x, dst_y);
427
428    // The viewport and frame are both in the logical orientation.
429    // Apply the logical translation, scale to physical size, apply the
430    // physical translation and finally rotate to the physical orientation.
431    mGlobalTransform = R * TP * S * TL;
432
433    const uint8_t type = mGlobalTransform.getType();
434    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
435            (type >= Transform::SCALE));
436
437    mScissor = mGlobalTransform.transform(viewport);
438    if (mScissor.isEmpty()) {
439        mScissor = getBounds();
440    }
441
442    mOrientation = orientation;
443    if (mType == DisplayType::DISPLAY_PRIMARY) {
444        uint32_t transform = 0;
445        switch (mOrientation) {
446            case DisplayState::eOrientationDefault:
447                transform = Transform::ROT_0;
448                break;
449            case DisplayState::eOrientation90:
450                transform = Transform::ROT_90;
451                break;
452            case DisplayState::eOrientation180:
453                transform = Transform::ROT_180;
454                break;
455            case DisplayState::eOrientation270:
456                transform = Transform::ROT_270;
457                break;
458        }
459        sPrimaryDisplayOrientation = transform;
460    }
461    mViewport = viewport;
462    mFrame = frame;
463}
464
465uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
466    return sPrimaryDisplayOrientation;
467}
468
469void DisplayDevice::dump(String8& result) const {
470    const Transform& tr(mGlobalTransform);
471    ANativeWindow* const window = mNativeWindow.get();
472    result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string());
473    result.appendFormat("   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p "
474                        "(%d:%d:%d:%d), orient=%2d (type=%08x), "
475                        "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
476                        mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window,
477                        mSurface->queryRedSize(), mSurface->queryGreenSize(),
478                        mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation,
479                        tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
480                        mVisibleLayersSortedByZ.size());
481    result.appendFormat("   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
482                        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
483                        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
484                        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left,
485                        mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0],
486                        tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]);
487    auto const surface = static_cast<Surface*>(window);
488    android_dataspace dataspace = surface->getBuffersDataSpace();
489    result.appendFormat("   dataspace: %s (%d)\n", dataspaceDetails(dataspace).c_str(), dataspace);
490
491    String8 surfaceDump;
492    mDisplaySurface->dumpAsString(surfaceDump);
493    result.append(surfaceDump);
494}
495
496std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
497
498DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
499    : type(type),
500      layerStack(DisplayDevice::NO_LAYER_STACK),
501      orientation(0),
502      width(0),
503      height(0),
504      isSecure(isSecure)
505{
506    viewport.makeInvalid();
507    frame.makeInvalid();
508}
509