Merge "fix [2515291] Native crash and runtime restart while trying to preview captured picture on Sapphire"
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 @@
// 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() );
+ if (newFrontBuffer != NULL) {
+ // compute the posted region
+ 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))
+ // 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;
+ 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;
+ // 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;
+ // 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()) {