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