diff options
| author | Mathias Agopian <mathias@google.com> | 2010-03-15 18:15:20 -0700 |
|---|---|---|
| committer | Mathias Agopian <mathias@google.com> | 2010-03-15 18:15:20 -0700 |
| commit | 9e3d693b1895010f3a2dc1efaf11389da8557cb8 (patch) | |
| tree | 62b6ec1c04856374988fa7697d6b17d8d3fb9284 /libs/surfaceflinger/Layer.cpp | |
| parent | 0167c317eba2f147513d054aaecd7419c3819150 (diff) | |
| download | frameworks_base-9e3d693b1895010f3a2dc1efaf11389da8557cb8.zip frameworks_base-9e3d693b1895010f3a2dc1efaf11389da8557cb8.tar.gz frameworks_base-9e3d693b1895010f3a2dc1efaf11389da8557cb8.tar.bz2 | |
fix [2515291] Native crash and runtime restart while trying to preview captured picture on Sapphire
if a buffer couldn't be allocated because of an OOM, SF could, in some case dereference
a null pointer.
Change-Id: I5321248c38a21e56d5278b6aada2694e64451378
Diffstat (limited to 'libs/surfaceflinger/Layer.cpp')
| -rw-r--r-- | libs/surfaceflinger/Layer.cpp | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 7ca7875..4dc4a15 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -465,44 +465,61 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // for composition later in the loop return; } - + + // ouch, this really should never happen + if (uint32_t(buf)>=NUM_BUFFERS) { + LOGE("retireAndLock() buffer index (%d) out of range", buf); + mPostedDirtyRegion.clear(); + return; + } + // we retired a buffer, which becomes the new front buffer mFrontBufferIndex = buf; // get the dirty region sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); - const Region dirty(lcblk->getDirtyRegion(buf)); - mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); - - const Layer::State& front(drawingState()); - if (newFrontBuffer->getWidth() == front.requested_w && - newFrontBuffer->getHeight() == front.requested_h) - { - if ((front.w != front.requested_w) || - (front.h != front.requested_h)) + if (newFrontBuffer != NULL) { + // compute the posted region + const Region dirty(lcblk->getDirtyRegion(buf)); + mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); + + // update the layer size and release freeze-lock + const Layer::State& front(drawingState()); + if (newFrontBuffer->getWidth() == front.requested_w && + newFrontBuffer->getHeight() == front.requested_h) { - // Here we pretend the transaction happened by updating the - // current and drawing states. Drawing state is only accessed - // in this thread, no need to have it locked - Layer::State& editDraw(mDrawingState); - editDraw.w = editDraw.requested_w; - editDraw.h = editDraw.requested_h; - - // We also need to update the current state so that we don't - // end-up doing too much work during the next transaction. - // NOTE: We actually don't need hold the transaction lock here - // because State::w and State::h are only accessed from - // this thread - Layer::State& editTemp(currentState()); - editTemp.w = editDraw.w; - editTemp.h = editDraw.h; - - // recompute visible region - recomputeVisibleRegions = true; - } + if ((front.w != front.requested_w) || + (front.h != front.requested_h)) + { + // Here we pretend the transaction happened by updating the + // current and drawing states. Drawing state is only accessed + // in this thread, no need to have it locked + Layer::State& editDraw(mDrawingState); + editDraw.w = editDraw.requested_w; + editDraw.h = editDraw.requested_h; + + // We also need to update the current state so that we don't + // end-up doing too much work during the next transaction. + // NOTE: We actually don't need hold the transaction lock here + // because State::w and State::h are only accessed from + // this thread + Layer::State& editTemp(currentState()); + editTemp.w = editDraw.w; + editTemp.h = editDraw.h; + + // recompute visible region + recomputeVisibleRegions = true; + } - // we now have the correct size, unfreeze the screen - mFreezeLock.clear(); + // we now have the correct size, unfreeze the screen + mFreezeLock.clear(); + } + } else { + // this should not happen unless we ran out of memory while + // allocating the buffer. we're hoping that things will get back + // to normal the next time the app tries to draw into this buffer. + // meanwhile, pretend the screen didn't update. + mPostedDirtyRegion.clear(); } if (lcblk->getQueuedCount()) { |
