From a280496bd2ce04d6beff4536f2115a9a4d7568e4 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 8 Sep 2009 23:52:08 -0700 Subject: 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 to the outside world, and were called after LayerBuffer had been destroyed. Instead we now give a wp to the outside and have it do the destruction. --- libs/surfaceflinger/LayerBuffer.cpp | 28 ++++++++++++++-------------- libs/surfaceflinger/LayerBuffer.h | 34 +++++++++++++++------------------- 2 files changed, 29 insertions(+), 33 deletions(-) (limited to 'libs') diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 0945571..bbfc54b 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -133,6 +133,14 @@ bool LayerBuffer::transformed() const return false; } +void LayerBuffer::serverDestroy() +{ + sp source(clearSource()); + if (source != 0) { + source->destroy(); + } +} + /** * This creates a "buffer" source for this surface */ @@ -413,7 +421,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const 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 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const } } - const Rect& transformedBounds = mLayer.getTransformedBounds(); + const Rect transformedBounds(mLayer.getTransformedBounds()); const copybit_rect_t& drect = reinterpret_cast(transformedBounds); const State& s(mLayer.drawingState()); @@ -583,9 +591,7 @@ LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer, 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 channel = new OverlayChannel(this); + sp channel = new OverlayChannel( &layer ); *overlayRef = new OverlayRef(mOverlayHandle, channel, mWidth, mHeight, mFormat, mWidthStride, mHeightStride); @@ -625,7 +631,7 @@ void LayerBuffer::OverlaySource::onVisibilityResolved( 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::onVisibilityResolved( } } -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 @@ class LayerBuffer : public LayerBaseClient virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); virtual bool transformed() const; + virtual void destroy() { } protected: LayerBuffer& mLayer; }; @@ -81,10 +82,12 @@ public: sp getSource() const; sp 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 @@ private: virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); virtual bool transformed() const; + virtual void destroy() { } private: mutable Mutex mBufferSourceLock; sp mBuffer; @@ -143,29 +147,21 @@ private: 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& source) - : mSource(source) { - } - private: + wp mLayer; virtual void destroy() { - sp source; - { // scope for the lock; - Mutex::Autolock _l(mDestroyLock); - source = mSource; - mSource.clear(); - } - if (source != 0) { - source->serverDestroy(); + sp layer(mLayer.promote()); + if (layer != 0) { + layer->serverDestroy(); } } - mutable Mutex mDestroyLock; - sp mSource; + public: + OverlayChannel(const sp& layer) + : mLayer(layer) { + } }; friend class OverlayChannel; -- cgit v1.1