diff options
author | Mathias Agopian <mathias@google.com> | 2010-05-21 17:24:35 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2010-05-24 18:26:01 -0700 |
commit | a138f89c5e78b7e8994823e97d6e860869762837 (patch) | |
tree | 9d11e5f9ee406798070a5cb335390147ae1dffa5 /libs/surfaceflinger/Layer.cpp | |
parent | a0b3f1d2eb796eb90a7576c13890ab8df8516d9d (diff) | |
download | frameworks_native-a138f89c5e78b7e8994823e97d6e860869762837.zip frameworks_native-a138f89c5e78b7e8994823e97d6e860869762837.tar.gz frameworks_native-a138f89c5e78b7e8994823e97d6e860869762837.tar.bz2 |
added the notion of fixed-size buffers
the new native_window_set_buffers_geometry allows
to specify a size and format for all buffers to be
dequeued. the buffer will be scalled to the window's
size.
Change-Id: I2c378b85c88d29cdd827a5f319d5c704d79ba381
Diffstat (limited to 'libs/surfaceflinger/Layer.cpp')
-rw-r--r-- | libs/surfaceflinger/Layer.cpp | 113 |
1 files changed, 70 insertions, 43 deletions
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 621b7e3..84584aa 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -55,7 +55,8 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, mNeedsBlending(true), mNeedsDithering(false), mTextureManager(mFlags), - mBufferManager(mTextureManager) + mBufferManager(mTextureManager), + mWidth(0), mHeight(0), mFixedSize(false) { // no OpenGL operation is possible here, since we might not be // in the OpenGL thread. @@ -227,10 +228,18 @@ status_t Layer::setBufferCount(int bufferCount) return err; } -sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) +sp<GraphicBuffer> Layer::requestBuffer(int index, + uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, + uint32_t usage) { sp<GraphicBuffer> buffer; + if ((reqWidth | reqHeight | reqFormat) < 0) + return buffer; + + if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) + return buffer; + // this ensures our client doesn't go away while we're accessing // the shared area. sp<Client> ourClient(client.promote()); @@ -256,23 +265,33 @@ sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) return buffer; } - uint32_t w, h; + uint32_t w, h, f; { // scope for the lock Mutex::Autolock _l(mLock); - w = mWidth; - h = mHeight; + const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight); + const bool formatChanged = mReqFormat != reqFormat; + mReqWidth = reqWidth; + mReqHeight = reqHeight; + mReqFormat = reqFormat; + mFixedSize = reqWidth && reqHeight; + w = reqWidth ? reqWidth : mWidth; + h = reqHeight ? reqHeight : mHeight; + f = reqFormat ? reqFormat : mFormat; buffer = mBufferManager.detachBuffer(index); + if (fixedSizeChanged || formatChanged) { + lcblk->reallocateAllExcept(index); + } } const uint32_t effectiveUsage = getEffectiveUsage(usage); if (buffer!=0 && buffer->getStrongCount() == 1) { - err = buffer->reallocate(w, h, mFormat, effectiveUsage); + err = buffer->reallocate(w, h, f, effectiveUsage); } else { // here we have to reallocate a new buffer because we could have a // client in our process with a reference to it (eg: status bar), // and we can't release the handle under its feet. buffer.clear(); - buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage); + buffer = new GraphicBuffer(w, h, f, effectiveUsage); err = buffer->initCheck(); } @@ -288,12 +307,7 @@ sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) if (err == NO_ERROR && buffer->handle != 0) { Mutex::Autolock _l(mLock); - if (mWidth && mHeight) { - mBufferManager.attachBuffer(index, buffer); - } else { - // oops we got killed while we were allocating the buffer - buffer.clear(); - } + mBufferManager.attachBuffer(index, buffer); } return buffer; } @@ -330,39 +344,46 @@ uint32_t Layer::doTransaction(uint32_t flags) const Layer::State& front(drawingState()); const Layer::State& temp(currentState()); - if ((front.requested_w != temp.requested_w) || - (front.requested_h != temp.requested_h)) { + const bool sizeChanged = (front.requested_w != temp.requested_w) || + (front.requested_h != temp.requested_h); + + if (sizeChanged) { // the size changed, we need to ask our client to request a new buffer LOGD_IF(DEBUG_RESIZE, - "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", - this, - int(temp.requested_w), int(temp.requested_h), - int(front.requested_w), int(front.requested_h)); - - // we're being resized and there is a freeze display request, - // acquire a freeze lock, so that the screen stays put - // until we've redrawn at the new size; this is to avoid - // glitches upon orientation changes. - if (mFlinger->hasFreezeRequest()) { - // if the surface is hidden, don't try to acquire the - // freeze lock, since hidden surfaces may never redraw - if (!(front.flags & ISurfaceComposer::eLayerHidden)) { - mFreezeLock = mFlinger->getFreezeLock(); + "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", + this, + int(temp.requested_w), int(temp.requested_h), + int(front.requested_w), int(front.requested_h)); + + if (!isFixedSize()) { + // we're being resized and there is a freeze display request, + // acquire a freeze lock, so that the screen stays put + // until we've redrawn at the new size; this is to avoid + // glitches upon orientation changes. + if (mFlinger->hasFreezeRequest()) { + // if the surface is hidden, don't try to acquire the + // freeze lock, since hidden surfaces may never redraw + if (!(front.flags & ISurfaceComposer::eLayerHidden)) { + mFreezeLock = mFlinger->getFreezeLock(); + } } - } - // this will make sure LayerBase::doTransaction doesn't update - // the drawing state's size - Layer::State& editDraw(mDrawingState); - editDraw.requested_w = temp.requested_w; - editDraw.requested_h = temp.requested_h; + // this will make sure LayerBase::doTransaction doesn't update + // the drawing state's size + Layer::State& editDraw(mDrawingState); + editDraw.requested_w = temp.requested_w; + editDraw.requested_h = temp.requested_h; - // record the new size, form this point on, when the client request a - // buffer, it'll get the new size. - setDrawingSize(temp.requested_w, temp.requested_h); + // record the new size, form this point on, when the client request + // a buffer, it'll get the new size. + setBufferSize(temp.requested_w, temp.requested_h); - // all buffers need reallocation - lcblk->reallocate(); + // all buffers need reallocation + lcblk->reallocateAll(); + } else { + // record the new size + setBufferSize(temp.requested_w, temp.requested_h); + } } if (temp.sequence != front.sequence) { @@ -376,12 +397,17 @@ uint32_t Layer::doTransaction(uint32_t flags) return LayerBase::doTransaction(flags); } -void Layer::setDrawingSize(uint32_t w, uint32_t h) { +void Layer::setBufferSize(uint32_t w, uint32_t h) { Mutex::Autolock _l(mLock); mWidth = w; mHeight = h; } +bool Layer::isFixedSize() const { + Mutex::Autolock _l(mLock); + return mFixedSize; +} + // ---------------------------------------------------------------------------- // pageflip handling... // ---------------------------------------------------------------------------- @@ -677,7 +703,8 @@ Layer::SurfaceLayer::~SurfaceLayer() { } -sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) +sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, + uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { sp<GraphicBuffer> buffer; sp<Layer> owner(getOwner()); @@ -687,7 +714,7 @@ sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) * as it could cause a dead-lock, since it may have to wait * on conditions updated my the main thread. */ - buffer = owner->requestBuffer(index, usage); + buffer = owner->requestBuffer(index, w, h, format, usage); } return buffer; } |