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 <stdint.h>
     19 #include <sys/types.h>
     20 
     21 #include <cutils/compiler.h>
     22 #include <cutils/native_handle.h>
     23 #include <cutils/properties.h>
     24 
     25 #include <utils/Errors.h>
     26 #include <utils/Log.h>
     27 #include <utils/StopWatch.h>
     28 
     29 #include <ui/GraphicBuffer.h>
     30 #include <ui/PixelFormat.h>
     31 
     32 #include <surfaceflinger/Surface.h>
     33 
     34 #include "clz.h"
     35 #include "DisplayHardware/DisplayHardware.h"
     36 #include "DisplayHardware/HWComposer.h"
     37 #include "GLExtensions.h"
     38 #include "Layer.h"
     39 #include "SurfaceFlinger.h"
     40 #include "SurfaceTextureLayer.h"
     41 
     42 #define DEBUG_RESIZE    0
     43 
     44 
     45 namespace android {
     46 
     47 // ---------------------------------------------------------------------------
     48 
     49 Layer::Layer(SurfaceFlinger* flinger,
     50         DisplayID display, const sp<Client>& client)
     51     :   LayerBaseClient(flinger, display, client),
     52         mTextureName(-1U),
     53         mQueuedFrames(0),
     54         mCurrentTransform(0),
     55         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     56         mCurrentOpacity(true),
     57         mFormat(PIXEL_FORMAT_NONE),
     58         mGLExtensions(GLExtensions::getInstance()),
     59         mOpaqueLayer(true),
     60         mNeedsDithering(false),
     61         mSecure(false),
     62         mProtectedByApp(false)
     63 {
     64     mCurrentCrop.makeInvalid();
     65     glGenTextures(1, &mTextureName);
     66 }
     67 
     68 void Layer::onFirstRef()
     69 {
     70     LayerBaseClient::onFirstRef();
     71 
     72     struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
     73         FrameQueuedListener(Layer* layer) : mLayer(layer) { }
     74     private:
     75         wp<Layer> mLayer;
     76         virtual void onFrameAvailable() {
     77             sp<Layer> that(mLayer.promote());
     78             if (that != 0) {
     79                 that->onFrameQueued();
     80             }
     81         }
     82     };
     83     mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
     84     mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
     85     mSurfaceTexture->setSynchronousMode(true);
     86     mSurfaceTexture->setBufferCountServer(2);
     87 }
     88 
     89 Layer::~Layer()
     90 {
     91     mFlinger->postMessageAsync(
     92             new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
     93 }
     94 
     95 void Layer::onFrameQueued() {
     96     android_atomic_inc(&mQueuedFrames);
     97     mFlinger->signalEvent();
     98 }
     99 
    100 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
    101 // in the purgatory list
    102 void Layer::onRemoved()
    103 {
    104     mSurfaceTexture->abandon();
    105 }
    106 
    107 void Layer::setName(const String8& name) {
    108     LayerBase::setName(name);
    109     mSurfaceTexture->setName(name);
    110 }
    111 
    112 sp<ISurface> Layer::createSurface()
    113 {
    114     class BSurface : public BnSurface, public LayerCleaner {
    115         wp<const Layer> mOwner;
    116         virtual sp<ISurfaceTexture> getSurfaceTexture() const {
    117             sp<ISurfaceTexture> res;
    118             sp<const Layer> that( mOwner.promote() );
    119             if (that != NULL) {
    120                 res = that->mSurfaceTexture;
    121             }
    122             return res;
    123         }
    124     public:
    125         BSurface(const sp<SurfaceFlinger>& flinger,
    126                 const sp<Layer>& layer)
    127             : LayerCleaner(flinger, layer), mOwner(layer) { }
    128     };
    129     sp<ISurface> sur(new BSurface(mFlinger, this));
    130     return sur;
    131 }
    132 
    133 wp<IBinder> Layer::getSurfaceTextureBinder() const
    134 {
    135     return mSurfaceTexture->asBinder();
    136 }
    137 
    138 status_t Layer::setBuffers( uint32_t w, uint32_t h,
    139                             PixelFormat format, uint32_t flags)
    140 {
    141     // this surfaces pixel format
    142     PixelFormatInfo info;
    143     status_t err = getPixelFormatInfo(format, &info);
    144     if (err) return err;
    145 
    146     // the display's pixel format
    147     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    148     uint32_t const maxSurfaceDims = min(
    149             hw.getMaxTextureSize(), hw.getMaxViewportDims());
    150 
    151     // never allow a surface larger than what our underlying GL implementation
    152     // can handle.
    153     if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
    154         return BAD_VALUE;
    155     }
    156 
    157     PixelFormatInfo displayInfo;
    158     getPixelFormatInfo(hw.getFormat(), &displayInfo);
    159     const uint32_t hwFlags = hw.getFlags();
    160 
    161     mFormat = format;
    162 
    163     mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
    164     mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
    165     mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
    166     mCurrentOpacity = getOpacityForFormat(format);
    167 
    168     mSurfaceTexture->setDefaultBufferSize(w, h);
    169     mSurfaceTexture->setDefaultBufferFormat(format);
    170 
    171     // we use the red index
    172     int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
    173     int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
    174     mNeedsDithering = layerRedsize > displayRedSize;
    175 
    176     return NO_ERROR;
    177 }
    178 
    179 void Layer::setGeometry(hwc_layer_t* hwcl)
    180 {
    181     LayerBaseClient::setGeometry(hwcl);
    182 
    183     hwcl->flags &= ~HWC_SKIP_LAYER;
    184 
    185     // we can't do alpha-fade with the hwc HAL
    186     const State& s(drawingState());
    187     if (s.alpha < 0xFF) {
    188         hwcl->flags = HWC_SKIP_LAYER;
    189     }
    190 
    191     /*
    192      * Transformations are applied in this order:
    193      * 1) buffer orientation/flip/mirror
    194      * 2) state transformation (window manager)
    195      * 3) layer orientation (screen orientation)
    196      * mTransform is already the composition of (2) and (3)
    197      * (NOTE: the matrices are multiplied in reverse order)
    198      */
    199 
    200     const Transform bufferOrientation(mCurrentTransform);
    201     const Transform tr(mTransform * bufferOrientation);
    202 
    203     // this gives us only the "orientation" component of the transform
    204     const uint32_t finalTransform = tr.getOrientation();
    205 
    206     // we can only handle simple transformation
    207     if (finalTransform & Transform::ROT_INVALID) {
    208         hwcl->flags = HWC_SKIP_LAYER;
    209     } else {
    210         hwcl->transform = finalTransform;
    211     }
    212 
    213     if (isCropped()) {
    214         hwcl->sourceCrop.left   = mCurrentCrop.left;
    215         hwcl->sourceCrop.top    = mCurrentCrop.top;
    216         hwcl->sourceCrop.right  = mCurrentCrop.right;
    217         hwcl->sourceCrop.bottom = mCurrentCrop.bottom;
    218     } else {
    219         const sp<GraphicBuffer>& buffer(mActiveBuffer);
    220         hwcl->sourceCrop.left   = 0;
    221         hwcl->sourceCrop.top    = 0;
    222         if (buffer != NULL) {
    223             hwcl->sourceCrop.right  = buffer->width;
    224             hwcl->sourceCrop.bottom = buffer->height;
    225         } else {
    226             hwcl->sourceCrop.right  = mTransformedBounds.width();
    227             hwcl->sourceCrop.bottom = mTransformedBounds.height();
    228         }
    229     }
    230 }
    231 
    232 void Layer::setPerFrameData(hwc_layer_t* hwcl) {
    233     const sp<GraphicBuffer>& buffer(mActiveBuffer);
    234     if (buffer == NULL) {
    235         // this can happen if the client never drew into this layer yet,
    236         // or if we ran out of memory. In that case, don't let
    237         // HWC handle it.
    238         hwcl->flags |= HWC_SKIP_LAYER;
    239         hwcl->handle = NULL;
    240     } else {
    241         hwcl->handle = buffer->handle;
    242     }
    243 }
    244 
    245 void Layer::onDraw(const Region& clip) const
    246 {
    247     if (CC_UNLIKELY(mActiveBuffer == 0)) {
    248         // the texture has not been created yet, this Layer has
    249         // in fact never been drawn into. This happens frequently with
    250         // SurfaceView because the WindowManager can't know when the client
    251         // has drawn the first time.
    252 
    253         // If there is nothing under us, we paint the screen in black, otherwise
    254         // we just skip this update.
    255 
    256         // figure out if there is something below us
    257         Region under;
    258         const SurfaceFlinger::LayerVector& drawingLayers(
    259                 mFlinger->mDrawingState.layersSortedByZ);
    260         const size_t count = drawingLayers.size();
    261         for (size_t i=0 ; i<count ; ++i) {
    262             const sp<LayerBase>& layer(drawingLayers[i]);
    263             if (layer.get() == static_cast<LayerBase const*>(this))
    264                 break;
    265             under.orSelf(layer->visibleRegionScreen);
    266         }
    267         // if not everything below us is covered, we plug the holes!
    268         Region holes(clip.subtract(under));
    269         if (!holes.isEmpty()) {
    270             clearWithOpenGL(holes, 0, 0, 0, 1);
    271         }
    272         return;
    273     }
    274 
    275     if (!isProtected()) {
    276         glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
    277         GLenum filter = GL_NEAREST;
    278         if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
    279             // TODO: we could be more subtle with isFixedSize()
    280             filter = GL_LINEAR;
    281         }
    282         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
    283         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
    284         glMatrixMode(GL_TEXTURE);
    285         glLoadMatrixf(mTextureMatrix);
    286         glMatrixMode(GL_MODELVIEW);
    287         glDisable(GL_TEXTURE_2D);
    288         glEnable(GL_TEXTURE_EXTERNAL_OES);
    289     } else {
    290         glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
    291         glMatrixMode(GL_TEXTURE);
    292         glLoadIdentity();
    293         glMatrixMode(GL_MODELVIEW);
    294         glDisable(GL_TEXTURE_EXTERNAL_OES);
    295         glEnable(GL_TEXTURE_2D);
    296     }
    297 
    298     drawWithOpenGL(clip);
    299 
    300     glDisable(GL_TEXTURE_EXTERNAL_OES);
    301     glDisable(GL_TEXTURE_2D);
    302 }
    303 
    304 // As documented in libhardware header, formats in the range
    305 // 0x100 - 0x1FF are specific to the HAL implementation, and
    306 // are known to have no alpha channel
    307 // TODO: move definition for device-specific range into
    308 // hardware.h, instead of using hard-coded values here.
    309 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
    310 
    311 bool Layer::getOpacityForFormat(uint32_t format)
    312 {
    313     if (HARDWARE_IS_DEVICE_FORMAT(format)) {
    314         return true;
    315     }
    316     PixelFormatInfo info;
    317     status_t err = getPixelFormatInfo(PixelFormat(format), &info);
    318     // in case of error (unknown format), we assume no blending
    319     return (err || info.h_alpha <= info.l_alpha);
    320 }
    321 
    322 
    323 bool Layer::isOpaque() const
    324 {
    325     // if we don't have a buffer yet, we're translucent regardless of the
    326     // layer's opaque flag.
    327     if (mActiveBuffer == 0) {
    328         return false;
    329     }
    330 
    331     // if the layer has the opaque flag, then we're always opaque,
    332     // otherwise we use the current buffer's format.
    333     return mOpaqueLayer || mCurrentOpacity;
    334 }
    335 
    336 bool Layer::isProtected() const
    337 {
    338     const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
    339     return (activeBuffer != 0) &&
    340             (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
    341 }
    342 
    343 uint32_t Layer::doTransaction(uint32_t flags)
    344 {
    345     const Layer::State& front(drawingState());
    346     const Layer::State& temp(currentState());
    347 
    348     const bool sizeChanged = (front.requested_w != temp.requested_w) ||
    349             (front.requested_h != temp.requested_h);
    350 
    351     if (sizeChanged) {
    352         // the size changed, we need to ask our client to request a new buffer
    353         LOGD_IF(DEBUG_RESIZE,
    354                 "doTransaction: "
    355                 "resize (layer=%p), requested (%dx%d), drawing (%d,%d), "
    356                 "scalingMode=%d",
    357                 this,
    358                 int(temp.requested_w), int(temp.requested_h),
    359                 int(front.requested_w), int(front.requested_h),
    360                 mCurrentScalingMode);
    361 
    362         if (!isFixedSize()) {
    363             // this will make sure LayerBase::doTransaction doesn't update
    364             // the drawing state's size
    365             Layer::State& editDraw(mDrawingState);
    366             editDraw.requested_w = temp.requested_w;
    367             editDraw.requested_h = temp.requested_h;
    368         }
    369 
    370         // record the new size, form this point on, when the client request
    371         // a buffer, it'll get the new size.
    372         mSurfaceTexture->setDefaultBufferSize(temp.requested_w,
    373                 temp.requested_h);
    374     }
    375 
    376     return LayerBase::doTransaction(flags);
    377 }
    378 
    379 bool Layer::isFixedSize() const {
    380     return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
    381 }
    382 
    383 bool Layer::isCropped() const {
    384     return !mCurrentCrop.isEmpty();
    385 }
    386 
    387 // ----------------------------------------------------------------------------
    388 // pageflip handling...
    389 // ----------------------------------------------------------------------------
    390 
    391 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
    392 {
    393     if (mQueuedFrames > 0) {
    394         // Capture the old state of the layer for comparisons later
    395         const bool oldOpacity = isOpaque();
    396         sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
    397 
    398         // signal another event if we have more frames pending
    399         if (android_atomic_dec(&mQueuedFrames) > 1) {
    400             mFlinger->signalEvent();
    401         }
    402 
    403         if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
    404             // something happened!
    405             recomputeVisibleRegions = true;
    406             return;
    407         }
    408 
    409         // update the active buffer
    410         mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
    411 
    412         const Rect crop(mSurfaceTexture->getCurrentCrop());
    413         const uint32_t transform(mSurfaceTexture->getCurrentTransform());
    414         const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
    415         if ((crop != mCurrentCrop) ||
    416             (transform != mCurrentTransform) ||
    417             (scalingMode != mCurrentScalingMode))
    418         {
    419             mCurrentCrop = crop;
    420             mCurrentTransform = transform;
    421             mCurrentScalingMode = scalingMode;
    422             mFlinger->invalidateHwcGeometry();
    423         }
    424 
    425         GLfloat textureMatrix[16];
    426         mSurfaceTexture->getTransformMatrix(textureMatrix);
    427         if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) {
    428             memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix));
    429             mFlinger->invalidateHwcGeometry();
    430         }
    431 
    432         uint32_t bufWidth  = mActiveBuffer->getWidth();
    433         uint32_t bufHeight = mActiveBuffer->getHeight();
    434         if (oldActiveBuffer != NULL) {
    435             if (bufWidth != uint32_t(oldActiveBuffer->width) ||
    436                 bufHeight != uint32_t(oldActiveBuffer->height)) {
    437                 mFlinger->invalidateHwcGeometry();
    438             }
    439         }
    440 
    441         mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
    442         if (oldOpacity != isOpaque()) {
    443             recomputeVisibleRegions = true;
    444         }
    445 
    446         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    447         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    448 
    449         // update the layer size if needed
    450         const Layer::State& front(drawingState());
    451 
    452         // FIXME: mPostedDirtyRegion = dirty & bounds
    453         mPostedDirtyRegion.set(front.w, front.h);
    454 
    455         if ((front.w != front.requested_w) ||
    456             (front.h != front.requested_h))
    457         {
    458             // check that we received a buffer of the right size
    459             // (Take the buffer's orientation into account)
    460             if (mCurrentTransform & Transform::ROT_90) {
    461                 swap(bufWidth, bufHeight);
    462             }
    463 
    464             if (isFixedSize() ||
    465                     (bufWidth == front.requested_w &&
    466                     bufHeight == front.requested_h))
    467             {
    468                 // Here we pretend the transaction happened by updating the
    469                 // current and drawing states. Drawing state is only accessed
    470                 // in this thread, no need to have it locked
    471                 Layer::State& editDraw(mDrawingState);
    472                 editDraw.w = editDraw.requested_w;
    473                 editDraw.h = editDraw.requested_h;
    474 
    475                 // We also need to update the current state so that we don't
    476                 // end-up doing too much work during the next transaction.
    477                 // NOTE: We actually don't need hold the transaction lock here
    478                 // because State::w and State::h are only accessed from
    479                 // this thread
    480                 Layer::State& editTemp(currentState());
    481                 editTemp.w = editDraw.w;
    482                 editTemp.h = editDraw.h;
    483 
    484                 // recompute visible region
    485                 recomputeVisibleRegions = true;
    486             }
    487 
    488             LOGD_IF(DEBUG_RESIZE,
    489                     "lockPageFlip : "
    490                     "       (layer=%p), buffer (%ux%u, tr=%02x), "
    491                     "requested (%dx%d)",
    492                     this,
    493                     bufWidth, bufHeight, mCurrentTransform,
    494                     front.requested_w, front.requested_h);
    495         }
    496     }
    497 }
    498 
    499 void Layer::unlockPageFlip(
    500         const Transform& planeTransform, Region& outDirtyRegion)
    501 {
    502     Region dirtyRegion(mPostedDirtyRegion);
    503     if (!dirtyRegion.isEmpty()) {
    504         mPostedDirtyRegion.clear();
    505         // The dirty region is given in the layer's coordinate space
    506         // transform the dirty region by the surface's transformation
    507         // and the global transformation.
    508         const Layer::State& s(drawingState());
    509         const Transform tr(planeTransform * s.transform);
    510         dirtyRegion = tr.transform(dirtyRegion);
    511 
    512         // At this point, the dirty region is in screen space.
    513         // Make sure it's constrained by the visible region (which
    514         // is in screen space as well).
    515         dirtyRegion.andSelf(visibleRegionScreen);
    516         outDirtyRegion.orSelf(dirtyRegion);
    517     }
    518 }
    519 
    520 void Layer::dump(String8& result, char* buffer, size_t SIZE) const
    521 {
    522     LayerBaseClient::dump(result, buffer, SIZE);
    523 
    524     sp<const GraphicBuffer> buf0(mActiveBuffer);
    525     uint32_t w0=0, h0=0, s0=0, f0=0;
    526     if (buf0 != 0) {
    527         w0 = buf0->getWidth();
    528         h0 = buf0->getHeight();
    529         s0 = buf0->getStride();
    530         f0 = buf0->format;
    531     }
    532     snprintf(buffer, SIZE,
    533             "      "
    534             "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
    535             " transform-hint=0x%02x, queued-frames=%d\n",
    536             mFormat, w0, h0, s0,f0,
    537             getTransformHint(), mQueuedFrames);
    538 
    539     result.append(buffer);
    540 
    541     if (mSurfaceTexture != 0) {
    542         mSurfaceTexture->dump(result, "            ", buffer, SIZE);
    543     }
    544 }
    545 
    546 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
    547 {
    548     // TODO: should we do something special if mSecure is set?
    549     if (mProtectedByApp) {
    550         // need a hardware-protected path to external video sink
    551         usage |= GraphicBuffer::USAGE_PROTECTED;
    552     }
    553     usage |= GraphicBuffer::USAGE_HW_COMPOSER;
    554     return usage;
    555 }
    556 
    557 uint32_t Layer::getTransformHint() const {
    558     uint32_t orientation = 0;
    559     if (!mFlinger->mDebugDisableTransformHint) {
    560         orientation = getPlaneOrientation();
    561         if (orientation & Transform::ROT_INVALID) {
    562             orientation = 0;
    563         }
    564     }
    565     return orientation;
    566 }
    567 
    568 // ---------------------------------------------------------------------------
    569 
    570 
    571 }; // namespace android
    572