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         bool isSecure,
     57         const wp<IBinder>& displayToken,
     58         const sp<DisplaySurface>& displaySurface,
     59         const sp<IGraphicBufferProducer>& producer,
     60         EGLConfig config)
     61     : mFlinger(flinger),
     62       mType(type), mHwcDisplayId(hwcId),
     63       mDisplayToken(displayToken),
     64       mDisplaySurface(displaySurface),
     65       mDisplay(EGL_NO_DISPLAY),
     66       mSurface(EGL_NO_SURFACE),
     67       mDisplayWidth(), mDisplayHeight(), mFormat(),
     68       mFlags(),
     69       mPageFlipCount(),
     70       mIsSecure(isSecure),
     71       mSecureLayerVisible(false),
     72       mScreenAcquired(false),
     73       mLayerStack(NO_LAYER_STACK),
     74       mOrientation()
     75 {
     76     mNativeWindow = new Surface(producer, false);
     77     ANativeWindow* const window = mNativeWindow.get();
     78 
     79     int format;
     80     window->query(window, NATIVE_WINDOW_FORMAT, &format);
     81 
     82     // Make sure that composition can never be stalled by a virtual display
     83     // consumer that isn't processing buffers fast enough. We have to do this
     84     // in two places:
     85     // * Here, in case the display is composed entirely by HWC.
     86     // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
     87     //   window's swap interval in eglMakeCurrent, so they'll override the
     88     //   interval we set here.
     89     if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
     90         window->setSwapInterval(window, 0);
     91 
     92     /*
     93      * Create our display's surface
     94      */
     95 
     96     EGLSurface surface;
     97     EGLint w, h;
     98     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     99     surface = eglCreateWindowSurface(display, config, window, NULL);
    100     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
    101     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
    102 
    103     mDisplay = display;
    104     mSurface = surface;
    105     mFormat  = format;
    106     mPageFlipCount = 0;
    107     mViewport.makeInvalid();
    108     mFrame.makeInvalid();
    109 
    110     // virtual displays are always considered enabled
    111     mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
    112 
    113     // Name the display.  The name will be replaced shortly if the display
    114     // was created with createDisplay().
    115     switch (mType) {
    116         case DISPLAY_PRIMARY:
    117             mDisplayName = "Built-in Screen";
    118             break;
    119         case DISPLAY_EXTERNAL:
    120             mDisplayName = "HDMI Screen";
    121             break;
    122         default:
    123             mDisplayName = "Virtual Screen";    // e.g. Overlay #n
    124             break;
    125     }
    126 
    127     // initialize the display orientation transform.
    128     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
    129 }
    130 
    131 DisplayDevice::~DisplayDevice() {
    132     if (mSurface != EGL_NO_SURFACE) {
    133         eglDestroySurface(mDisplay, mSurface);
    134         mSurface = EGL_NO_SURFACE;
    135     }
    136 }
    137 
    138 void DisplayDevice::disconnect(HWComposer& hwc) {
    139     if (mHwcDisplayId >= 0) {
    140         hwc.disconnectDisplay(mHwcDisplayId);
    141         if (mHwcDisplayId >= DISPLAY_VIRTUAL)
    142             hwc.freeDisplayId(mHwcDisplayId);
    143         mHwcDisplayId = -1;
    144     }
    145 }
    146 
    147 bool DisplayDevice::isValid() const {
    148     return mFlinger != NULL;
    149 }
    150 
    151 int DisplayDevice::getWidth() const {
    152     return mDisplayWidth;
    153 }
    154 
    155 int DisplayDevice::getHeight() const {
    156     return mDisplayHeight;
    157 }
    158 
    159 PixelFormat DisplayDevice::getFormat() const {
    160     return mFormat;
    161 }
    162 
    163 EGLSurface DisplayDevice::getEGLSurface() const {
    164     return mSurface;
    165 }
    166 
    167 void DisplayDevice::setDisplayName(const String8& displayName) {
    168     if (!displayName.isEmpty()) {
    169         // never override the name with an empty name
    170         mDisplayName = displayName;
    171     }
    172 }
    173 
    174 uint32_t DisplayDevice::getPageFlipCount() const {
    175     return mPageFlipCount;
    176 }
    177 
    178 status_t DisplayDevice::compositionComplete() const {
    179     return mDisplaySurface->compositionComplete();
    180 }
    181 
    182 void DisplayDevice::flip(const Region& dirty) const
    183 {
    184     mFlinger->getRenderEngine().checkErrors();
    185 
    186     EGLDisplay dpy = mDisplay;
    187     EGLSurface surface = mSurface;
    188 
    189 #ifdef EGL_ANDROID_swap_rectangle
    190     if (mFlags & SWAP_RECTANGLE) {
    191         const Region newDirty(dirty.intersect(bounds()));
    192         const Rect b(newDirty.getBounds());
    193         eglSetSwapRectangleANDROID(dpy, surface,
    194                 b.left, b.top, b.width(), b.height());
    195     }
    196 #endif
    197 
    198     mPageFlipCount++;
    199 }
    200 
    201 status_t DisplayDevice::beginFrame() const {
    202     return mDisplaySurface->beginFrame();
    203 }
    204 
    205 status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
    206     DisplaySurface::CompositionType compositionType;
    207     bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
    208     bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
    209     if (haveGles && haveHwc) {
    210         compositionType = DisplaySurface::COMPOSITION_MIXED;
    211     } else if (haveGles) {
    212         compositionType = DisplaySurface::COMPOSITION_GLES;
    213     } else if (haveHwc) {
    214         compositionType = DisplaySurface::COMPOSITION_HWC;
    215     } else {
    216         // Nothing to do -- when turning the screen off we get a frame like
    217         // this. Call it a HWC frame since we won't be doing any GLES work but
    218         // will do a prepare/set cycle.
    219         compositionType = DisplaySurface::COMPOSITION_HWC;
    220     }
    221     return mDisplaySurface->prepareFrame(compositionType);
    222 }
    223 
    224 void DisplayDevice::swapBuffers(HWComposer& hwc) const {
    225     // We need to call eglSwapBuffers() if:
    226     //  (1) we don't have a hardware composer, or
    227     //  (2) we did GLES composition this frame, and either
    228     //    (a) we have framebuffer target support (not present on legacy
    229     //        devices, where HWComposer::commit() handles things); or
    230     //    (b) this is a virtual display
    231     if (hwc.initCheck() != NO_ERROR ||
    232             (hwc.hasGlesComposition(mHwcDisplayId) &&
    233              (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
    234         EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
    235         if (!success) {
    236             EGLint error = eglGetError();
    237             if (error == EGL_CONTEXT_LOST ||
    238                     mType == DisplayDevice::DISPLAY_PRIMARY) {
    239                 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
    240                         mDisplay, mSurface, error);
    241             } else {
    242                 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
    243                         mDisplay, mSurface, error);
    244             }
    245         }
    246     }
    247 
    248     status_t result = mDisplaySurface->advanceFrame();
    249     if (result != NO_ERROR) {
    250         ALOGE("[%s] failed pushing new frame to HWC: %d",
    251                 mDisplayName.string(), result);
    252     }
    253 }
    254 
    255 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
    256     if (hwc.initCheck() == NO_ERROR) {
    257         mDisplaySurface->onFrameCommitted();
    258     }
    259 }
    260 
    261 uint32_t DisplayDevice::getFlags() const
    262 {
    263     return mFlags;
    264 }
    265 
    266 EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
    267     EGLBoolean result = EGL_TRUE;
    268     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
    269     if (sur != mSurface) {
    270         result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
    271         if (result == EGL_TRUE) {
    272             if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
    273                 eglSwapInterval(dpy, 0);
    274         }
    275     }
    276     setViewportAndProjection();
    277     return result;
    278 }
    279 
    280 void DisplayDevice::setViewportAndProjection() const {
    281     size_t w = mDisplayWidth;
    282     size_t h = mDisplayHeight;
    283     mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
    284 }
    285 
    286 // ----------------------------------------------------------------------------
    287 
    288 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
    289     mVisibleLayersSortedByZ = layers;
    290     mSecureLayerVisible = false;
    291     size_t count = layers.size();
    292     for (size_t i=0 ; i<count ; i++) {
    293         const sp<Layer>& layer(layers[i]);
    294         if (layer->isSecure()) {
    295             mSecureLayerVisible = true;
    296         }
    297     }
    298 }
    299 
    300 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
    301     return mVisibleLayersSortedByZ;
    302 }
    303 
    304 bool DisplayDevice::getSecureLayerVisible() const {
    305     return mSecureLayerVisible;
    306 }
    307 
    308 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
    309     Region dirty;
    310     if (repaintEverything) {
    311         dirty.set(getBounds());
    312     } else {
    313         const Transform& planeTransform(mGlobalTransform);
    314         dirty = planeTransform.transform(this->dirtyRegion);
    315         dirty.andSelf(getBounds());
    316     }
    317     return dirty;
    318 }
    319 
    320 // ----------------------------------------------------------------------------
    321 
    322 bool DisplayDevice::canDraw() const {
    323     return mScreenAcquired;
    324 }
    325 
    326 void DisplayDevice::releaseScreen() const {
    327     mScreenAcquired = false;
    328 }
    329 
    330 void DisplayDevice::acquireScreen() const {
    331     mScreenAcquired = true;
    332 }
    333 
    334 bool DisplayDevice::isScreenAcquired() const {
    335     return mScreenAcquired;
    336 }
    337 
    338 // ----------------------------------------------------------------------------
    339 
    340 void DisplayDevice::setLayerStack(uint32_t stack) {
    341     mLayerStack = stack;
    342     dirtyRegion.set(bounds());
    343 }
    344 
    345 // ----------------------------------------------------------------------------
    346 
    347 uint32_t DisplayDevice::getOrientationTransform() const {
    348     uint32_t transform = 0;
    349     switch (mOrientation) {
    350         case DisplayState::eOrientationDefault:
    351             transform = Transform::ROT_0;
    352             break;
    353         case DisplayState::eOrientation90:
    354             transform = Transform::ROT_90;
    355             break;
    356         case DisplayState::eOrientation180:
    357             transform = Transform::ROT_180;
    358             break;
    359         case DisplayState::eOrientation270:
    360             transform = Transform::ROT_270;
    361             break;
    362     }
    363     return transform;
    364 }
    365 
    366 status_t DisplayDevice::orientationToTransfrom(
    367         int orientation, int w, int h, Transform* tr)
    368 {
    369     uint32_t flags = 0;
    370     switch (orientation) {
    371     case DisplayState::eOrientationDefault:
    372         flags = Transform::ROT_0;
    373         break;
    374     case DisplayState::eOrientation90:
    375         flags = Transform::ROT_90;
    376         break;
    377     case DisplayState::eOrientation180:
    378         flags = Transform::ROT_180;
    379         break;
    380     case DisplayState::eOrientation270:
    381         flags = Transform::ROT_270;
    382         break;
    383     default:
    384         return BAD_VALUE;
    385     }
    386     tr->set(flags, w, h);
    387     return NO_ERROR;
    388 }
    389 
    390 void DisplayDevice::setProjection(int orientation,
    391         const Rect& newViewport, const Rect& newFrame) {
    392     Rect viewport(newViewport);
    393     Rect frame(newFrame);
    394 
    395     const int w = mDisplayWidth;
    396     const int h = mDisplayHeight;
    397 
    398     Transform R;
    399     DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
    400 
    401     if (!frame.isValid()) {
    402         // the destination frame can be invalid if it has never been set,
    403         // in that case we assume the whole display frame.
    404         frame = Rect(w, h);
    405     }
    406 
    407     if (viewport.isEmpty()) {
    408         // viewport can be invalid if it has never been set, in that case
    409         // we assume the whole display size.
    410         // it's also invalid to have an empty viewport, so we handle that
    411         // case in the same way.
    412         viewport = Rect(w, h);
    413         if (R.getOrientation() & Transform::ROT_90) {
    414             // viewport is always specified in the logical orientation
    415             // of the display (ie: post-rotation).
    416             swap(viewport.right, viewport.bottom);
    417         }
    418     }
    419 
    420     dirtyRegion.set(getBounds());
    421 
    422     Transform TL, TP, S;
    423     float src_width  = viewport.width();
    424     float src_height = viewport.height();
    425     float dst_width  = frame.width();
    426     float dst_height = frame.height();
    427     if (src_width != dst_width || src_height != dst_height) {
    428         float sx = dst_width  / src_width;
    429         float sy = dst_height / src_height;
    430         S.set(sx, 0, 0, sy);
    431     }
    432 
    433     float src_x = viewport.left;
    434     float src_y = viewport.top;
    435     float dst_x = frame.left;
    436     float dst_y = frame.top;
    437     TL.set(-src_x, -src_y);
    438     TP.set(dst_x, dst_y);
    439 
    440     // The viewport and frame are both in the logical orientation.
    441     // Apply the logical translation, scale to physical size, apply the
    442     // physical translation and finally rotate to the physical orientation.
    443     mGlobalTransform = R * TP * S * TL;
    444 
    445     const uint8_t type = mGlobalTransform.getType();
    446     mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
    447             (type >= Transform::SCALE));
    448 
    449     mScissor = mGlobalTransform.transform(viewport);
    450     if (mScissor.isEmpty()) {
    451         mScissor = getBounds();
    452     }
    453 
    454     mOrientation = orientation;
    455     mViewport = viewport;
    456     mFrame = frame;
    457 }
    458 
    459 void DisplayDevice::dump(String8& result) const {
    460     const Transform& tr(mGlobalTransform);
    461     result.appendFormat(
    462         "+ DisplayDevice: %s\n"
    463         "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
    464         "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
    465         "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
    466         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
    467         mDisplayName.string(), mType, mHwcDisplayId,
    468         mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
    469         mOrientation, tr.getType(), getPageFlipCount(),
    470         mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
    471         mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
    472         mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
    473         mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
    474         tr[0][0], tr[1][0], tr[2][0],
    475         tr[0][1], tr[1][1], tr[2][1],
    476         tr[0][2], tr[1][2], tr[2][2]);
    477 
    478     String8 surfaceDump;
    479     mDisplaySurface->dump(surfaceDump);
    480     result.append(surfaceDump);
    481 }
    482