fix [2037525] Fail to start camera after adb sync new Camera
we ended-up locking a Mutex that had been destroyed.
This happened because we gave an sp<Source> to the outside world,
and were called after LayerBuffer had been destroyed.
Instead we now give a wp<LayerBuffer> to the outside and have it
do the destruction.
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 0945571..bbfc54b9 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -133,6 +133,14 @@
return false;
}
+void LayerBuffer::serverDestroy()
+{
+ sp<Source> source(clearSource());
+ if (source != 0) {
+ source->destroy();
+ }
+}
+
/**
* This creates a "buffer" source for this surface
*/
@@ -413,7 +421,7 @@
status_t err = NO_ERROR;
NativeBuffer src(ourBuffer->getBuffer());
- const Rect& transformedBounds = mLayer.getTransformedBounds();
+ const Rect transformedBounds(mLayer.getTransformedBounds());
copybit_device_t* copybit = mBlitEngine;
if (copybit) {
@@ -493,7 +501,7 @@
}
}
- const Rect& transformedBounds = mLayer.getTransformedBounds();
+ const Rect transformedBounds(mLayer.getTransformedBounds());
const copybit_rect_t& drect =
reinterpret_cast<const copybit_rect_t&>(transformedBounds);
const State& s(mLayer.drawingState());
@@ -583,9 +591,7 @@
mOverlayHandle = overlay->getHandleRef(overlay);
- // NOTE: here it's okay to acquire a reference to "this" as long as
- // the reference is not released before we leave the ctor.
- sp<OverlayChannel> channel = new OverlayChannel(this);
+ sp<OverlayChannel> channel = new OverlayChannel( &layer );
*overlayRef = new OverlayRef(mOverlayHandle, channel,
mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
@@ -625,7 +631,7 @@
if (mVisibilityChanged || !mInitialized) {
mVisibilityChanged = false;
mInitialized = true;
- const Rect& bounds = mLayer.getTransformedBounds();
+ const Rect bounds(mLayer.getTransformedBounds());
int x = bounds.left;
int y = bounds.top;
int w = bounds.width();
@@ -644,17 +650,11 @@
}
}
-void LayerBuffer::OverlaySource::serverDestroy()
-{
- mLayer.clearSource();
- destroyOverlay();
-}
-
-void LayerBuffer::OverlaySource::destroyOverlay()
+void LayerBuffer::OverlaySource::destroy()
{
// we need a lock here to protect "onVisibilityResolved"
Mutex::Autolock _l(mOverlaySourceLock);
- if (mOverlay) {
+ if (mOverlay && mOverlayDevice) {
overlay_control_device_t* overlay_dev = mOverlayDevice;
overlay_dev->destroyOverlay(overlay_dev, mOverlay);
mOverlay = 0;
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 3b09998..0452818 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -49,6 +49,7 @@
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
virtual bool transformed() const;
+ virtual void destroy() { }
protected:
LayerBuffer& mLayer;
};
@@ -81,10 +82,12 @@
sp<Source> getSource() const;
sp<Source> clearSource();
void setNeedsBlending(bool blending);
- const Rect& getTransformedBounds() const {
+ Rect getTransformedBounds() const {
return mTransformedBounds;
}
+ void serverDestroy();
+
private:
struct NativeBuffer {
copybit_image_t img;
@@ -123,6 +126,7 @@
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
virtual bool transformed() const;
+ virtual void destroy() { }
private:
mutable Mutex mBufferSourceLock;
sp<Buffer> mBuffer;
@@ -143,29 +147,21 @@
virtual void onDraw(const Region& clip) const;
virtual void onTransaction(uint32_t flags);
virtual void onVisibilityResolved(const Transform& planeTransform);
+ virtual void destroy();
private:
- void serverDestroy();
- void destroyOverlay();
-
+
class OverlayChannel : public BnOverlay {
- public:
- OverlayChannel(const sp<OverlaySource>& source)
- : mSource(source) {
- }
- private:
+ wp<LayerBuffer> mLayer;
virtual void destroy() {
- sp<OverlaySource> source;
- { // scope for the lock;
- Mutex::Autolock _l(mDestroyLock);
- source = mSource;
- mSource.clear();
- }
- if (source != 0) {
- source->serverDestroy();
+ sp<LayerBuffer> layer(mLayer.promote());
+ if (layer != 0) {
+ layer->serverDestroy();
}
}
- mutable Mutex mDestroyLock;
- sp<OverlaySource> mSource;
+ public:
+ OverlayChannel(const sp<LayerBuffer>& layer)
+ : mLayer(layer) {
+ }
};
friend class OverlayChannel;