summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2010-12-13 18:51:59 -0800
committerMathias Agopian <mathias@google.com>2010-12-14 15:53:39 -0800
commitda9584dc295cc5e6d0b49a97c1e45159249d650b (patch)
tree1d41f25ec921bf3d8bf28c4367db27fcfee9f1e5 /services/surfaceflinger
parentfb88981051118e169d6acfe796f7eab9a827b2e0 (diff)
downloadframeworks_native-da9584dc295cc5e6d0b49a97c1e45159249d650b.zip
frameworks_native-da9584dc295cc5e6d0b49a97c1e45159249d650b.tar.gz
frameworks_native-da9584dc295cc5e6d0b49a97c1e45159249d650b.tar.bz2
fix [3223749] media server crashes when switching mode from video capture to still image capture
there was an issue were in some situation SF would call prepare() on hwc with a NULL handle and never call prepare again. in this situation, we onw set the SKIP flag to make sure that hwc won't process this layer and as soon as we receive our first buffer we trigger a recompute of the visible regions which will end-up calling prepare() again. Change-Id: I6b400b2df79712408b9315a9859290c7fcb1609e
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r--services/surfaceflinger/Layer.cpp19
-rw-r--r--services/surfaceflinger/Layer.h2
2 files changed, 18 insertions, 3 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2b2f557..5a0f115 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -246,9 +246,10 @@ void Layer::setGeometry(hwc_layer_t* hwcl)
void Layer::setPerFrameData(hwc_layer_t* hwcl) {
sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
if (buffer == NULL) {
- // this situation can happen if we ran out of memory for instance.
- // not much we can do. continue to use whatever texture was bound
- // to this context.
+ // this can happen if the client never drew into this layer yet,
+ // or if we ran out of memory. In that case, don't let
+ // HWC handle it.
+ hwcl->flags |= HWC_SKIP_LAYER;
hwcl->handle = NULL;
return;
}
@@ -581,12 +582,20 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
}
// we retired a buffer, which becomes the new front buffer
+
+ const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
mPostedDirtyRegion.clear();
return;
}
+ if (noActiveBuffer) {
+ // we didn't have an active buffer, we need to recompute
+ // our visible region
+ recomputeVisibleRegions = true;
+ }
+
sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
if (newFrontBuffer != NULL) {
// get the dirty region
@@ -888,6 +897,10 @@ sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
return result;
}
+bool Layer::BufferManager::hasActiveBuffer() const {
+ return mActiveBuffer >= 0;
+}
+
sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
{
BufferData* const buffers = mBufferData;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 30021d3..c367a8d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -188,6 +188,8 @@ private:
size_t getActiveBufferIndex() const;
// return the active buffer
sp<GraphicBuffer> getActiveBuffer() const;
+ // return wether we have an active buffer
+ bool hasActiveBuffer() const;
// return the active texture (or fail-over)
Texture getActiveTexture() const;
// frees resources associated with all buffers