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