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 #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 // ----------------------------------------------------------------------------
     44 using namespace android;
     45 // ----------------------------------------------------------------------------
     46 
     47 /*
     48  * Initialize the display to the specified values.
     49  *
     50  */
     51 
     52 DisplayDevice::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 
    136 DisplayDevice::~DisplayDevice() {
    137     if (mSurface != EGL_NO_SURFACE) {
    138         eglDestroySurface(mDisplay, mSurface);
    139         mSurface = EGL_NO_SURFACE;
    140     }
    141 }
    142 
    143 void 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 
    152 bool DisplayDevice::isValid() const {
    153     return mFlinger != NULL;
    154 }
    155 
    156 int DisplayDevice::getWidth() const {
    157     return mDisplayWidth;
    158 }
    159 
    160 int DisplayDevice::getHeight() const {
    161     return mDisplayHeight;
    162 }
    163 
    164 PixelFormat DisplayDevice::getFormat() const {
    165     return mFormat;
    166 }
    167 
    168 EGLSurface DisplayDevice::getEGLSurface() const {
    169     return mSurface;
    170 }
    171 
    172 void DisplayDevice::setDisplayName(const String8& displayName) {
    173     if (!displayName.isEmpty()) {
    174         // never override the name with an empty name
    175         mDisplayName = displayName;
    176     }
    177 }
    178 
    179 uint32_t DisplayDevice::getPageFlipCount() const {
    180     return mPageFlipCount;
    181 }
    182 
    183 status_t DisplayDevice::compositionComplete() const {
    184     return mDisplaySurface->compositionComplete();
    185 }
    186 
    187 void 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 
    208 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
    209     return mDisplaySurface->beginFrame(mustRecompose);
    210 }
    211 
    212 status_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 
    231 void 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 
    262 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
    263     if (hwc.initCheck() == NO_ERROR) {
    264         mDisplaySurface->onFrameCommitted();
    265     }
    266 }
    267 
    268 uint32_t DisplayDevice::getFlags() const
    269 {
    270     return mFlags;
    271 }
    272 
    273 EGLBoolean 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 
    287 void 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,
    292         false, Transform::ROT_0);
    293 }
    294 
    295 // ----------------------------------------------------------------------------
    296 
    297 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
    298     mVisibleLayersSortedByZ = layers;
    299     mSecureLayerVisible = false;
    300     size_t count = layers.size();
    301     for (size_t i=0 ; i<count ; i++) {
    302         const sp<Layer>& layer(layers[i]);
    303         if (layer->isSecure()) {
    304             mSecureLayerVisible = true;
    305         }
    306     }
    307 }
    308 
    309 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
    310     return mVisibleLayersSortedByZ;
    311 }
    312 
    313 bool DisplayDevice::getSecureLayerVisible() const {
    314     return mSecureLayerVisible;
    315 }
    316 
    317 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
    318     Region dirty;
    319     if (repaintEverything) {
    320         dirty.set(getBounds());
    321     } else {
    322         const Transform& planeTransform(mGlobalTransform);
    323         dirty = planeTransform.transform(this->dirtyRegion);
    324         dirty.andSelf(getBounds());
    325     }
    326     return dirty;
    327 }
    328 
    329 // ----------------------------------------------------------------------------
    330 void DisplayDevice::setPowerMode(int mode) {
    331     mPowerMode = mode;
    332 }
    333 
    334 int DisplayDevice::getPowerMode()  const {
    335     return mPowerMode;
    336 }
    337 
    338 bool DisplayDevice::isDisplayOn() const {
    339     return (mPowerMode != HWC_POWER_MODE_OFF);
    340 }
    341 
    342 // ----------------------------------------------------------------------------
    343 void DisplayDevice::setActiveConfig(int mode) {
    344     mActiveConfig = mode;
    345 }
    346 
    347 int DisplayDevice::getActiveConfig()  const {
    348     return mActiveConfig;
    349 }
    350 
    351 // ----------------------------------------------------------------------------
    352 
    353 void DisplayDevice::setLayerStack(uint32_t stack) {
    354     mLayerStack = stack;
    355     dirtyRegion.set(bounds());
    356 }
    357 
    358 // ----------------------------------------------------------------------------
    359 
    360 uint32_t DisplayDevice::getOrientationTransform() const {
    361     uint32_t transform = 0;
    362     switch (mOrientation) {
    363         case DisplayState::eOrientationDefault:
    364             transform = Transform::ROT_0;
    365             break;
    366         case DisplayState::eOrientation90:
    367             transform = Transform::ROT_90;
    368             break;
    369         case DisplayState::eOrientation180:
    370             transform = Transform::ROT_180;
    371             break;
    372         case DisplayState::eOrientation270:
    373             transform = Transform::ROT_270;
    374             break;
    375     }
    376     return transform;
    377 }
    378 
    379 status_t DisplayDevice::orientationToTransfrom(
    380         int orientation, int w, int h, Transform* tr)
    381 {
    382     uint32_t flags = 0;
    383     switch (orientation) {
    384     case DisplayState::eOrientationDefault:
    385         flags = Transform::ROT_0;
    386         break;
    387     case DisplayState::eOrientation90:
    388         flags = Transform::ROT_90;
    389         break;
    390     case DisplayState::eOrientation180:
    391         flags = Transform::ROT_180;
    392         break;
    393     case DisplayState::eOrientation270:
    394         flags = Transform::ROT_270;
    395         break;
    396     default:
    397         return BAD_VALUE;
    398     }
    399     tr->set(flags, w, h);
    400     return NO_ERROR;
    401 }
    402 
    403 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
    404     dirtyRegion.set(getBounds());
    405 
    406     if (mSurface != EGL_NO_SURFACE) {
    407         eglDestroySurface(mDisplay, mSurface);
    408         mSurface = EGL_NO_SURFACE;
    409     }
    410 
    411     mDisplaySurface->resizeBuffers(newWidth, newHeight);
    412 
    413     ANativeWindow* const window = mNativeWindow.get();
    414     mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
    415     eglQuerySurface(mDisplay, mSurface, EGL_WIDTH,  &mDisplayWidth);
    416     eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
    417 
    418     LOG_FATAL_IF(mDisplayWidth != newWidth,
    419                 "Unable to set new width to %d", newWidth);
    420     LOG_FATAL_IF(mDisplayHeight != newHeight,
    421                 "Unable to set new height to %d", newHeight);
    422 }
    423 
    424 void DisplayDevice::setProjection(int orientation,
    425         const Rect& newViewport, const Rect& newFrame) {
    426     Rect viewport(newViewport);
    427     Rect frame(newFrame);
    428 
    429     const int w = mDisplayWidth;
    430     const int h = mDisplayHeight;
    431 
    432     Transform R;
    433     DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
    434 
    435     if (!frame.isValid()) {
    436         // the destination frame can be invalid if it has never been set,
    437         // in that case we assume the whole display frame.
    438         frame = Rect(w, h);
    439     }
    440 
    441     if (viewport.isEmpty()) {
    442         // viewport can be invalid if it has never been set, in that case
    443         // we assume the whole display size.
    444         // it's also invalid to have an empty viewport, so we handle that
    445         // case in the same way.
    446         viewport = Rect(w, h);
    447         if (R.getOrientation() & Transform::ROT_90) {
    448             // viewport is always specified in the logical orientation
    449             // of the display (ie: post-rotation).
    450             swap(viewport.right, viewport.bottom);
    451         }
    452     }
    453 
    454     dirtyRegion.set(getBounds());
    455 
    456     Transform TL, TP, S;
    457     float src_width  = viewport.width();
    458     float src_height = viewport.height();
    459     float dst_width  = frame.width();
    460     float dst_height = frame.height();
    461     if (src_width != dst_width || src_height != dst_height) {
    462         float sx = dst_width  / src_width;
    463         float sy = dst_height / src_height;
    464         S.set(sx, 0, 0, sy);
    465     }
    466 
    467     float src_x = viewport.left;
    468     float src_y = viewport.top;
    469     float dst_x = frame.left;
    470     float dst_y = frame.top;
    471     TL.set(-src_x, -src_y);
    472     TP.set(dst_x, dst_y);
    473 
    474     // The viewport and frame are both in the logical orientation.
    475     // Apply the logical translation, scale to physical size, apply the
    476     // physical translation and finally rotate to the physical orientation.
    477     mGlobalTransform = R * TP * S * TL;
    478 
    479     const uint8_t type = mGlobalTransform.getType();
    480     mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
    481             (type >= Transform::SCALE));
    482 
    483     mScissor = mGlobalTransform.transform(viewport);
    484     if (mScissor.isEmpty()) {
    485         mScissor = getBounds();
    486     }
    487 
    488     mOrientation = orientation;
    489     mViewport = viewport;
    490     mFrame = frame;
    491 }
    492 
    493 void DisplayDevice::dump(String8& result) const {
    494     const Transform& tr(mGlobalTransform);
    495     result.appendFormat(
    496         "+ DisplayDevice: %s\n"
    497         "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
    498         "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
    499         "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
    500         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
    501         mDisplayName.string(), mType, mHwcDisplayId,
    502         mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
    503         mOrientation, tr.getType(), getPageFlipCount(),
    504         mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig,
    505         mVisibleLayersSortedByZ.size(),
    506         mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
    507         mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
    508         mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
    509         tr[0][0], tr[1][0], tr[2][0],
    510         tr[0][1], tr[1][1], tr[2][1],
    511         tr[0][2], tr[1][2], tr[2][2]);
    512 
    513     String8 surfaceDump;
    514     mDisplaySurface->dump(surfaceDump);
    515     result.append(surfaceDump);
    516 }
    517