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 <math.h>
     20 #include <sys/types.h>
     21 
     22 #include <utils/Errors.h>
     23 #include <utils/Log.h>
     24 #include <utils/StopWatch.h>
     25 
     26 #include <ui/GraphicBuffer.h>
     27 #include <ui/PixelFormat.h>
     28 #include <ui/FramebufferNativeWindow.h>
     29 #include <ui/Rect.h>
     30 #include <ui/Region.h>
     31 
     32 #include <hardware/copybit.h>
     33 
     34 #include "LayerBuffer.h"
     35 #include "SurfaceFlinger.h"
     36 #include "DisplayHardware/DisplayHardware.h"
     37 
     38 namespace android {
     39 
     40 // ---------------------------------------------------------------------------
     41 
     42 gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
     43 
     44 // ---------------------------------------------------------------------------
     45 
     46 LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
     47         const sp<Client>& client)
     48     : LayerBaseClient(flinger, display, client),
     49       mNeedsBlending(false), mBlitEngine(0)
     50 {
     51 }
     52 
     53 LayerBuffer::~LayerBuffer()
     54 {
     55     if (mBlitEngine) {
     56         copybit_close(mBlitEngine);
     57     }
     58 }
     59 
     60 void LayerBuffer::onFirstRef()
     61 {
     62     LayerBaseClient::onFirstRef();
     63     mSurface = new SurfaceLayerBuffer(mFlinger, this);
     64 
     65     hw_module_t const* module = (hw_module_t const*)sGrallocModule;
     66     if (!module) {
     67         // NOTE: technically there is a race here, but it shouldn't
     68         // cause any problem since hw_get_module() always returns
     69         // the same value.
     70         if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
     71             sGrallocModule = (gralloc_module_t const *)module;
     72         }
     73     }
     74 
     75     if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
     76         copybit_open(module, &mBlitEngine);
     77     }
     78 }
     79 
     80 sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
     81 {
     82     return mSurface;
     83 }
     84 
     85 status_t LayerBuffer::ditch()
     86 {
     87     mSurface.clear();
     88     return NO_ERROR;
     89 }
     90 
     91 bool LayerBuffer::needsBlending() const {
     92     return mNeedsBlending;
     93 }
     94 
     95 void LayerBuffer::setNeedsBlending(bool blending) {
     96     mNeedsBlending = blending;
     97 }
     98 
     99 void LayerBuffer::postBuffer(ssize_t offset)
    100 {
    101     sp<Source> source(getSource());
    102     if (source != 0)
    103         source->postBuffer(offset);
    104 }
    105 
    106 void LayerBuffer::unregisterBuffers()
    107 {
    108     sp<Source> source(clearSource());
    109     if (source != 0)
    110         source->unregisterBuffers();
    111 }
    112 
    113 uint32_t LayerBuffer::doTransaction(uint32_t flags)
    114 {
    115     sp<Source> source(getSource());
    116     if (source != 0)
    117         source->onTransaction(flags);
    118     uint32_t res = LayerBase::doTransaction(flags);
    119     // we always want filtering for these surfaces
    120     mNeedsFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG);
    121     return res;
    122 }
    123 
    124 void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
    125         Region& outDirtyRegion)
    126 {
    127     // this code-path must be as tight as possible, it's called each time
    128     // the screen is composited.
    129     sp<Source> source(getSource());
    130     if (source != 0)
    131         source->onVisibilityResolved(planeTransform);
    132     LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
    133 }
    134 
    135 void LayerBuffer::validateVisibility(const Transform& globalTransform)
    136 {
    137     sp<Source> source(getSource());
    138     if (source != 0)
    139         source->onvalidateVisibility(globalTransform);
    140     LayerBase::validateVisibility(globalTransform);
    141 }
    142 
    143 void LayerBuffer::drawForSreenShot() const
    144 {
    145     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    146     clearWithOpenGL( Region(hw.bounds()) );
    147 }
    148 
    149 void LayerBuffer::onDraw(const Region& clip) const
    150 {
    151     sp<Source> source(getSource());
    152     if (LIKELY(source != 0)) {
    153         source->onDraw(clip);
    154     } else {
    155         clearWithOpenGL(clip);
    156     }
    157 }
    158 
    159 void LayerBuffer::serverDestroy()
    160 {
    161     sp<Source> source(clearSource());
    162     if (source != 0) {
    163         source->destroy();
    164     }
    165 }
    166 
    167 /**
    168  * This creates a "buffer" source for this surface
    169  */
    170 status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
    171 {
    172     Mutex::Autolock _l(mLock);
    173     if (mSource != 0)
    174         return INVALID_OPERATION;
    175 
    176     sp<BufferSource> source = new BufferSource(*this, buffers);
    177 
    178     status_t result = source->getStatus();
    179     if (result == NO_ERROR) {
    180         mSource = source;
    181     }
    182     return result;
    183 }
    184 
    185 /**
    186  * This creates an "overlay" source for this surface
    187  */
    188 sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f,
    189         int32_t orientation)
    190 {
    191     sp<OverlayRef> result;
    192     Mutex::Autolock _l(mLock);
    193     if (mSource != 0)
    194         return result;
    195 
    196     sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f, orientation);
    197     if (result != 0) {
    198         mSource = source;
    199     }
    200     return result;
    201 }
    202 
    203 sp<LayerBuffer::Source> LayerBuffer::getSource() const {
    204     Mutex::Autolock _l(mLock);
    205     return mSource;
    206 }
    207 
    208 sp<LayerBuffer::Source> LayerBuffer::clearSource() {
    209     sp<Source> source;
    210     Mutex::Autolock _l(mLock);
    211     source = mSource;
    212     mSource.clear();
    213     return source;
    214 }
    215 
    216 // ============================================================================
    217 // LayerBuffer::SurfaceLayerBuffer
    218 // ============================================================================
    219 
    220 LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(
    221         const sp<SurfaceFlinger>& flinger, const sp<LayerBuffer>& owner)
    222     : LayerBaseClient::Surface(flinger, owner->getIdentity(), owner)
    223 {
    224 }
    225 
    226 LayerBuffer::SurfaceLayerBuffer::~SurfaceLayerBuffer()
    227 {
    228     unregisterBuffers();
    229 }
    230 
    231 status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers(
    232         const ISurface::BufferHeap& buffers)
    233 {
    234     sp<LayerBuffer> owner(getOwner());
    235     if (owner != 0)
    236         return owner->registerBuffers(buffers);
    237     return NO_INIT;
    238 }
    239 
    240 void LayerBuffer::SurfaceLayerBuffer::postBuffer(ssize_t offset)
    241 {
    242     sp<LayerBuffer> owner(getOwner());
    243     if (owner != 0)
    244         owner->postBuffer(offset);
    245 }
    246 
    247 void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers()
    248 {
    249     sp<LayerBuffer> owner(getOwner());
    250     if (owner != 0)
    251         owner->unregisterBuffers();
    252 }
    253 
    254 sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(
    255         uint32_t w, uint32_t h, int32_t format, int32_t orientation) {
    256     sp<OverlayRef> result;
    257     sp<LayerBuffer> owner(getOwner());
    258     if (owner != 0)
    259         result = owner->createOverlay(w, h, format, orientation);
    260     return result;
    261 }
    262 
    263 // ============================================================================
    264 // LayerBuffer::Buffer
    265 // ============================================================================
    266 
    267 LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
    268         ssize_t offset, size_t bufferSize)
    269     : mBufferHeap(buffers), mSupportsCopybit(false)
    270 {
    271     NativeBuffer& src(mNativeBuffer);
    272     src.crop.l = 0;
    273     src.crop.t = 0;
    274     src.crop.r = buffers.w;
    275     src.crop.b = buffers.h;
    276 
    277     src.img.w       = buffers.hor_stride ?: buffers.w;
    278     src.img.h       = buffers.ver_stride ?: buffers.h;
    279     src.img.format  = buffers.format;
    280     src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
    281     src.img.handle  = 0;
    282 
    283     gralloc_module_t const * module = LayerBuffer::getGrallocModule();
    284     if (module && module->perform) {
    285         int err = module->perform(module,
    286                 GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
    287                 buffers.heap->heapID(), bufferSize,
    288                 offset, buffers.heap->base(),
    289                 &src.img.handle);
    290 
    291         // we can fail here is the passed buffer is purely software
    292         mSupportsCopybit = (err == NO_ERROR);
    293     }
    294  }
    295 
    296 LayerBuffer::Buffer::~Buffer()
    297 {
    298     NativeBuffer& src(mNativeBuffer);
    299     if (src.img.handle) {
    300         native_handle_delete(src.img.handle);
    301     }
    302 }
    303 
    304 // ============================================================================
    305 // LayerBuffer::Source
    306 // LayerBuffer::BufferSource
    307 // LayerBuffer::OverlaySource
    308 // ============================================================================
    309 
    310 LayerBuffer::Source::Source(LayerBuffer& layer)
    311     : mLayer(layer)
    312 {
    313 }
    314 LayerBuffer::Source::~Source() {
    315 }
    316 void LayerBuffer::Source::onDraw(const Region& clip) const {
    317 }
    318 void LayerBuffer::Source::onTransaction(uint32_t flags) {
    319 }
    320 void LayerBuffer::Source::onVisibilityResolved(
    321         const Transform& planeTransform) {
    322 }
    323 void LayerBuffer::Source::postBuffer(ssize_t offset) {
    324 }
    325 void LayerBuffer::Source::unregisterBuffers() {
    326 }
    327 
    328 // ---------------------------------------------------------------------------
    329 
    330 LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
    331         const ISurface::BufferHeap& buffers)
    332     : Source(layer), mStatus(NO_ERROR), mBufferSize(0)
    333 {
    334     if (buffers.heap == NULL) {
    335         // this is allowed, but in this case, it is illegal to receive
    336         // postBuffer(). The surface just erases the framebuffer with
    337         // fully transparent pixels.
    338         mBufferHeap = buffers;
    339         mLayer.setNeedsBlending(false);
    340         return;
    341     }
    342 
    343     status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
    344     if (err != NO_ERROR) {
    345         LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
    346         mStatus = err;
    347         return;
    348     }
    349 
    350     PixelFormatInfo info;
    351     err = getPixelFormatInfo(buffers.format, &info);
    352     if (err != NO_ERROR) {
    353         LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
    354                 buffers.format, strerror(err));
    355         mStatus = err;
    356         return;
    357     }
    358 
    359     if (buffers.hor_stride<0 || buffers.ver_stride<0) {
    360         LOGE("LayerBuffer::BufferSource: invalid parameters "
    361              "(w=%d, h=%d, xs=%d, ys=%d)",
    362              buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
    363         mStatus = BAD_VALUE;
    364         return;
    365     }
    366 
    367     mBufferHeap = buffers;
    368     mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
    369     mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
    370     mLayer.forceVisibilityTransaction();
    371 }
    372 
    373 LayerBuffer::BufferSource::~BufferSource()
    374 {
    375     class MessageDestroyTexture : public MessageBase {
    376         SurfaceFlinger* flinger;
    377         GLuint name;
    378     public:
    379         MessageDestroyTexture(
    380                 SurfaceFlinger* flinger, GLuint name)
    381             : flinger(flinger), name(name) { }
    382         virtual bool handler() {
    383             glDeleteTextures(1, &name);
    384             return true;
    385         }
    386     };
    387 
    388     if (mTexture.name != -1U) {
    389         // GL textures can only be destroyed from the GL thread
    390         getFlinger()->mEventQueue.postMessage(
    391                 new MessageDestroyTexture(getFlinger(), mTexture.name) );
    392     }
    393     if (mTexture.image != EGL_NO_IMAGE_KHR) {
    394         EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
    395         eglDestroyImageKHR(dpy, mTexture.image);
    396     }
    397 }
    398 
    399 void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
    400 {
    401     ISurface::BufferHeap buffers;
    402     { // scope for the lock
    403         Mutex::Autolock _l(mBufferSourceLock);
    404         buffers = mBufferHeap;
    405         if (buffers.heap != 0) {
    406             const size_t memorySize = buffers.heap->getSize();
    407             if ((size_t(offset) + mBufferSize) > memorySize) {
    408                 LOGE("LayerBuffer::BufferSource::postBuffer() "
    409                      "invalid buffer (offset=%d, size=%d, heap-size=%d",
    410                      int(offset), int(mBufferSize), int(memorySize));
    411                 return;
    412             }
    413         }
    414     }
    415 
    416     sp<Buffer> buffer;
    417     if (buffers.heap != 0) {
    418         buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
    419         if (buffer->getStatus() != NO_ERROR)
    420             buffer.clear();
    421         setBuffer(buffer);
    422         mLayer.invalidate();
    423     }
    424 }
    425 
    426 void LayerBuffer::BufferSource::unregisterBuffers()
    427 {
    428     Mutex::Autolock _l(mBufferSourceLock);
    429     mBufferHeap.heap.clear();
    430     mBuffer.clear();
    431     mLayer.invalidate();
    432 }
    433 
    434 sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
    435 {
    436     Mutex::Autolock _l(mBufferSourceLock);
    437     return mBuffer;
    438 }
    439 
    440 void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
    441 {
    442     Mutex::Autolock _l(mBufferSourceLock);
    443     mBuffer = buffer;
    444 }
    445 
    446 void LayerBuffer::BufferSource::onDraw(const Region& clip) const
    447 {
    448     sp<Buffer> ourBuffer(getBuffer());
    449     if (UNLIKELY(ourBuffer == 0))  {
    450         // nothing to do, we don't have a buffer
    451         mLayer.clearWithOpenGL(clip);
    452         return;
    453     }
    454 
    455     status_t err = NO_ERROR;
    456     NativeBuffer src(ourBuffer->getBuffer());
    457     const Rect transformedBounds(mLayer.getTransformedBounds());
    458 
    459 #if defined(EGL_ANDROID_image_native_buffer)
    460     if (GLExtensions::getInstance().haveDirectTexture()) {
    461         err = INVALID_OPERATION;
    462         if (ourBuffer->supportsCopybit()) {
    463             copybit_device_t* copybit = mLayer.mBlitEngine;
    464             if (copybit && err != NO_ERROR) {
    465                 // create our EGLImageKHR the first time
    466                 err = initTempBuffer();
    467                 if (err == NO_ERROR) {
    468                     // NOTE: Assume the buffer is allocated with the proper USAGE flags
    469                     const NativeBuffer& dst(mTempBuffer);
    470                     region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b)));
    471                     copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
    472                     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
    473                     copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
    474                     err = copybit->stretch(copybit, &dst.img, &src.img,
    475                             &dst.crop, &src.crop, &clip);
    476                     if (err != NO_ERROR) {
    477                         clearTempBufferImage();
    478                     }
    479                 }
    480             }
    481         }
    482     }
    483 #endif
    484     else {
    485         err = INVALID_OPERATION;
    486     }
    487 
    488     if (err != NO_ERROR) {
    489         // slower fallback
    490         GGLSurface t;
    491         t.version = sizeof(GGLSurface);
    492         t.width  = src.crop.r;
    493         t.height = src.crop.b;
    494         t.stride = src.img.w;
    495         t.vstride= src.img.h;
    496         t.format = src.img.format;
    497         t.data = (GGLubyte*)src.img.base;
    498         const Region dirty(Rect(t.width, t.height));
    499         mTextureManager.loadTexture(&mTexture, dirty, t);
    500     }
    501 
    502     mLayer.setBufferTransform(mBufferHeap.transform);
    503     mLayer.drawWithOpenGL(clip, mTexture);
    504 }
    505 
    506 status_t LayerBuffer::BufferSource::initTempBuffer() const
    507 {
    508     // figure out the size we need now
    509     const ISurface::BufferHeap& buffers(mBufferHeap);
    510     uint32_t w = mLayer.mTransformedBounds.width();
    511     uint32_t h = mLayer.mTransformedBounds.height();
    512     if (buffers.w * h != buffers.h * w) {
    513         int t = w; w = h; h = t;
    514     }
    515 
    516     // we're in the copybit case, so make sure we can handle this blit
    517     // we don't have to keep the aspect ratio here
    518     copybit_device_t* copybit = mLayer.mBlitEngine;
    519     const int down = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
    520     const int up = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
    521     if (buffers.w > w*down)     w = buffers.w / down;
    522     else if (w > buffers.w*up)  w = buffers.w*up;
    523     if (buffers.h > h*down)     h = buffers.h / down;
    524     else if (h > buffers.h*up)  h = buffers.h*up;
    525 
    526     if (mTexture.image != EGL_NO_IMAGE_KHR) {
    527         // we have an EGLImage, make sure the needed size didn't change
    528         if (w!=mTexture.width || h!= mTexture.height) {
    529             // delete the EGLImage and texture
    530             clearTempBufferImage();
    531         } else {
    532             // we're good, we have an EGLImageKHR and it's (still) the
    533             // right size
    534             return NO_ERROR;
    535         }
    536     }
    537 
    538     // figure out if we need linear filtering
    539     if (buffers.w * h == buffers.h * w) {
    540         // same pixel area, don't use filtering
    541         mLayer.mNeedsFiltering = false;
    542     }
    543 
    544     // Allocate a temporary buffer and create the corresponding EGLImageKHR
    545     // once the EGLImage has been created we don't need the
    546     // graphic buffer reference anymore.
    547     sp<GraphicBuffer> buffer = new GraphicBuffer(
    548             w, h, HAL_PIXEL_FORMAT_RGB_565,
    549             GraphicBuffer::USAGE_HW_TEXTURE |
    550             GraphicBuffer::USAGE_HW_2D);
    551 
    552     status_t err = buffer->initCheck();
    553     if (err == NO_ERROR) {
    554         NativeBuffer& dst(mTempBuffer);
    555         dst.img.w = buffer->getStride();
    556         dst.img.h = h;
    557         dst.img.format = buffer->getPixelFormat();
    558         dst.img.handle = (native_handle_t *)buffer->handle;
    559         dst.img.base = 0;
    560         dst.crop.l = 0;
    561         dst.crop.t = 0;
    562         dst.crop.r = w;
    563         dst.crop.b = h;
    564 
    565         EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
    566         err = mTextureManager.initEglImage(&mTexture, dpy, buffer);
    567     }
    568 
    569     return err;
    570 }
    571 
    572 void LayerBuffer::BufferSource::clearTempBufferImage() const
    573 {
    574     // delete the image
    575     EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
    576     eglDestroyImageKHR(dpy, mTexture.image);
    577 
    578     // and the associated texture (recreate a name)
    579     glDeleteTextures(1, &mTexture.name);
    580     Texture defaultTexture;
    581     mTexture = defaultTexture;
    582 }
    583 
    584 // ---------------------------------------------------------------------------
    585 
    586 LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
    587         sp<OverlayRef>* overlayRef,
    588         uint32_t w, uint32_t h, int32_t format, int32_t orientation)
    589     : Source(layer), mVisibilityChanged(false),
    590     mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation)
    591 {
    592     overlay_control_device_t* overlay_dev = getFlinger()->getOverlayEngine();
    593     if (overlay_dev == NULL) {
    594         // overlays not supported
    595         return;
    596     }
    597 
    598     mOverlayDevice = overlay_dev;
    599     overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
    600     if (overlay == NULL) {
    601         // couldn't create the overlay (no memory? no more overlays?)
    602         return;
    603     }
    604 
    605     // enable dithering...
    606     overlay_dev->setParameter(overlay_dev, overlay,
    607             OVERLAY_DITHER, OVERLAY_ENABLE);
    608 
    609     mOverlay = overlay;
    610     mWidth = overlay->w;
    611     mHeight = overlay->h;
    612     mFormat = overlay->format;
    613     mWidthStride = overlay->w_stride;
    614     mHeightStride = overlay->h_stride;
    615     mInitialized = false;
    616 
    617     mOverlayHandle = overlay->getHandleRef(overlay);
    618 
    619     sp<OverlayChannel> channel = new OverlayChannel( &layer );
    620 
    621     *overlayRef = new OverlayRef(mOverlayHandle, channel,
    622             mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
    623     getFlinger()->signalEvent();
    624 }
    625 
    626 LayerBuffer::OverlaySource::~OverlaySource()
    627 {
    628     if (mOverlay && mOverlayDevice) {
    629         overlay_control_device_t* overlay_dev = mOverlayDevice;
    630         overlay_dev->destroyOverlay(overlay_dev, mOverlay);
    631     }
    632 }
    633 
    634 void LayerBuffer::OverlaySource::onDraw(const Region& clip) const
    635 {
    636     // this would be where the color-key would be set, should we need it.
    637     GLclampf red = 0;
    638     GLclampf green = 0;
    639     GLclampf blue = 0;
    640     mLayer.clearWithOpenGL(clip, red, green, blue, 0);
    641 }
    642 
    643 void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
    644 {
    645     const Layer::State& front(mLayer.drawingState());
    646     const Layer::State& temp(mLayer.currentState());
    647     if (temp.sequence != front.sequence) {
    648         mVisibilityChanged = true;
    649     }
    650 }
    651 
    652 void LayerBuffer::OverlaySource::onvalidateVisibility(const Transform&)
    653 {
    654     mVisibilityChanged = true;
    655 }
    656 
    657 void LayerBuffer::OverlaySource::onVisibilityResolved(
    658         const Transform& planeTransform)
    659 {
    660     // this code-path must be as tight as possible, it's called each time
    661     // the screen is composited.
    662     if (UNLIKELY(mOverlay != 0)) {
    663         if (mVisibilityChanged || !mInitialized) {
    664             mVisibilityChanged = false;
    665             mInitialized = true;
    666             const Rect bounds(mLayer.getTransformedBounds());
    667             int x = bounds.left;
    668             int y = bounds.top;
    669             int w = bounds.width();
    670             int h = bounds.height();
    671 
    672             // we need a lock here to protect "destroy"
    673             Mutex::Autolock _l(mOverlaySourceLock);
    674             if (mOverlay) {
    675                 overlay_control_device_t* overlay_dev = mOverlayDevice;
    676                 overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
    677                 // we need to combine the layer orientation and the
    678                 // user-requested orientation.
    679                 Transform finalTransform(Transform(mLayer.getOrientation()) *
    680                         Transform(mOrientation));
    681                 overlay_dev->setParameter(overlay_dev, mOverlay,
    682                         OVERLAY_TRANSFORM, finalTransform.getOrientation());
    683                 overlay_dev->commit(overlay_dev, mOverlay);
    684             }
    685         }
    686     }
    687 }
    688 
    689 void LayerBuffer::OverlaySource::destroy()
    690 {
    691     // we need a lock here to protect "onVisibilityResolved"
    692     Mutex::Autolock _l(mOverlaySourceLock);
    693     if (mOverlay && mOverlayDevice) {
    694         overlay_control_device_t* overlay_dev = mOverlayDevice;
    695         overlay_dev->destroyOverlay(overlay_dev, mOverlay);
    696         mOverlay = 0;
    697     }
    698 }
    699 
    700 // ---------------------------------------------------------------------------
    701 }; // namespace android
    702