summaryrefslogtreecommitdiffstats
path: root/libs/surfaceflinger
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2010-03-15 18:15:20 -0700
committerMathias Agopian <mathias@google.com>2010-03-15 18:15:20 -0700
commitd343e3d5e3177806205b9452b0b43907e28afd9a (patch)
treea094c9ea996f2d1ceb872340a192741ea6395635 /libs/surfaceflinger
parent80586f4230f974c2a3fe2b8aa398ffd6764e3a3a (diff)
downloadframeworks_native-d343e3d5e3177806205b9452b0b43907e28afd9a.zip
frameworks_native-d343e3d5e3177806205b9452b0b43907e28afd9a.tar.gz
frameworks_native-d343e3d5e3177806205b9452b0b43907e28afd9a.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')
-rw-r--r--libs/surfaceflinger/Layer.cpp79
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()) {