Make the SkGrPixelRef be responsible for unlocking device's scratch texture in the...
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 28 Aug 2012 15:07:11 +0000 (15:07 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 28 Aug 2012 15:07:11 +0000 (15:07 +0000)
Review URL: https://codereview.appspot.com/6498046/

git-svn-id: http://skia.googlecode.com/svn/trunk@5313 2bbb7eff-a529-9590-31e7-b0007b416f81

include/gpu/SkGpuDevice.h
include/gpu/SkGrPixelRef.h
src/gpu/SkGpuDevice.cpp
src/gpu/SkGrPixelRef.cpp

index f04be62..49eea26 100644 (file)
@@ -132,14 +132,12 @@ private:
     GrClipData      fClipData;
 
     // state for our offscreen render-target
-    // TODO: remove 'fCached' and automatically return to the cache
-    bool                fCached;        // is fRenderTarget->asTexture() in the cache
     GrRenderTarget*     fRenderTarget;
     bool                fNeedClear;
     bool                fNeedPrepareRenderTarget;
 
     // called from rt and tex cons
-    void initFromRenderTarget(GrContext*, GrRenderTarget*);
+    void initFromRenderTarget(GrContext*, GrRenderTarget*, bool cached);
 
     // used by createCompatibleDevice
     SkGpuDevice(GrContext*, GrTexture* texture, bool needClear);
index b7eaf0d..4476a84 100644 (file)
@@ -42,7 +42,12 @@ private:
  */
 class SK_API SkGrPixelRef : public SkROLockPixelsPixelRef {
 public:
-    SkGrPixelRef(GrSurface* surface);
+    /**
+     * Constructs a pixel ref around a GrSurface. If the caller has locked the GrSurface in the
+     * cache and would like the pixel ref to unlock it in its destructor then transferCacheLock
+     * should be set to true.
+     */
+    SkGrPixelRef(GrSurface* surface, bool transferCacheLock = false);
     virtual ~SkGrPixelRef();
 
     // override from SkPixelRef
@@ -57,6 +62,8 @@ protected:
 
 private:
     GrSurface*  fSurface;
+    bool        fUnlock;   // if true the pixel ref owns a texture cache lock on fSurface
+
     typedef SkROLockPixelsPixelRef INHERITED;
 };
 
index 8d43f70..fa0f60e 100644 (file)
@@ -172,23 +172,23 @@ static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
 
 SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
 : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
-    this->initFromRenderTarget(context, texture->asRenderTarget());
+    this->initFromRenderTarget(context, texture->asRenderTarget(), false);
 }
 
 SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
 : SkDevice(make_bitmap(context, renderTarget)) {
-    this->initFromRenderTarget(context, renderTarget);
+    this->initFromRenderTarget(context, renderTarget, false);
 }
 
 void SkGpuDevice::initFromRenderTarget(GrContext* context,
-                                       GrRenderTarget* renderTarget) {
+                                       GrRenderTarget* renderTarget,
+                                       bool cached) {
     fNeedPrepareRenderTarget = false;
     fDrawProcs = NULL;
 
     fContext = context;
     fContext->ref();
 
-    fCached = false;
     fRenderTarget = NULL;
     fNeedClear = false;
 
@@ -204,7 +204,7 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
     if (NULL == surface) {
         surface = fRenderTarget;
     }
-    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (surface));
+    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (surface, cached));
 
     this->setPixelRef(pr, 0)->unref();
 }
@@ -221,7 +221,6 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
     fContext = context;
     fContext->ref();
 
-    fCached = false;
     fRenderTarget = NULL;
     fNeedClear = false;
 
@@ -264,10 +263,6 @@ SkGpuDevice::~SkGpuDevice() {
     // This call gives the context a chance to relinquish it
     fContext->setRenderTarget(NULL);
 
-    GrTexture* texture = fRenderTarget->asTexture();
-    if (NULL != texture && fCached) {
-        fContext->unlockTexture(texture);
-    }
     SkSafeUnref(fRenderTarget);
     fContext->unref();
 }
@@ -1964,7 +1959,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
     : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
 
     GrAssert(texture && texture->asRenderTarget());
-    this->initFromRenderTarget(context, texture->asRenderTarget());
-    fCached = true;
+    // This constructor is called from onCreateCompatibleDevice. It has locked the RT in the texture
+    // cache. We pass true for the third argument so that it will get unlocked.
+    this->initFromRenderTarget(context, texture->asRenderTarget(), true);
     fNeedClear = needClear;
 }
index 05c3f02..b7a0765 100644 (file)
@@ -88,7 +88,7 @@ static SkGrPixelRef* copyToTexturePixelRef(GrTexture* texture,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkGrPixelRef::SkGrPixelRef(GrSurface* surface) {
+SkGrPixelRef::SkGrPixelRef(GrSurface* surface, bool transferCacheLock) {
     // TODO: figure out if this is responsible for Chrome canvas errors
 #if 0
     // The GrTexture has a ref to the GrRenderTarget but not vice versa.
@@ -101,11 +101,18 @@ SkGrPixelRef::SkGrPixelRef(GrSurface* surface) {
     if (NULL == fSurface) {
         fSurface = surface;
     }
-
+    fUnlock = transferCacheLock;
     GrSafeRef(surface);
 }
 
 SkGrPixelRef::~SkGrPixelRef() {
+    if (fUnlock) {
+        GrContext* context = fSurface->getContext();
+        GrTexture* texture= fSurface->asTexture();
+        if (NULL != context && NULL != texture) {
+            context->unlockTexture(texture);
+        }
+    }
     GrSafeUnref(fSurface);
 }