aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/tests.gyp1
-rw-r--r--include/gpu/GrRenderTarget.h9
-rw-r--r--include/gpu/GrSurface.h16
-rw-r--r--include/gpu/GrTexture.h19
-rw-r--r--src/gpu/GrContext.cpp1
-rw-r--r--src/gpu/GrGpu.h3
-rw-r--r--src/gpu/GrTexture.cpp20
-rw-r--r--tests/GrSurfaceTest.cpp68
8 files changed, 93 insertions, 44 deletions
diff --git a/gyp/tests.gyp b/gyp/tests.gyp
index cd9e1b80c7..8914edd165 100644
--- a/gyp/tests.gyp
+++ b/gyp/tests.gyp
@@ -57,6 +57,7 @@
'../tests/GrContextFactoryTest.cpp',
'../tests/GradientTest.cpp',
'../tests/GrMemoryPoolTest.cpp',
+ '../tests/GrSurfaceTest.cpp',
'../tests/HashCacheTest.cpp',
'../tests/InfRectTest.cpp',
'../tests/LListTest.cpp',
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index fcb4c3d3b1..22f42f22dc 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -149,15 +149,6 @@ protected:
}
friend class GrTexture;
- // When a texture unrefs an owned render target this func
- // removes the back pointer. This could be called from
- // texture's destructor but would have to be done in derived
- // classes. By the time of texture base destructor it has already
- // lost its pointer to the rt.
- void onTextureReleaseRenderTarget() {
- GrAssert(NULL != fTexture);
- fTexture = NULL;
- }
// override of GrResource
virtual void onAbandon() SK_OVERRIDE;
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 02fc0d5dea..52a56659ab 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -64,6 +64,22 @@ public:
virtual const GrRenderTarget* asRenderTarget() const = 0;
/**
+ * Checks whether this GrSurface refers to the same GPU object as other. This
+ * catches the case where a GrTexture and GrRenderTarget refer to the same
+ * GPU memory.
+ */
+ bool isSameAs(const GrSurface* other) const {
+ const GrRenderTarget* thisRT = this->asRenderTarget();
+ if (NULL != thisRT) {
+ return thisRT == other->asRenderTarget();
+ } else {
+ const GrTexture* thisTex = this->asTexture();
+ GrAssert(NULL != thisTex); // We must be one or the other
+ return thisTex == other->asTexture();
+ }
+ }
+
+ /**
* Reads a rectangle of pixels from the surface.
* @param left left edge of the rectangle to read (inclusive)
* @param top top edge of the rectangle to read (inclusive)
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 5d8ecaaaf2..52253ed2dd 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -11,8 +11,8 @@
#include "GrSurface.h"
#include "SkPoint.h"
+#include "GrRenderTarget.h"
-class GrRenderTarget;
class GrResourceKey;
class GrTextureParams;
@@ -80,10 +80,10 @@ public:
* render target
*/
virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE {
- return fRenderTarget;
+ return fRenderTarget.get();
}
virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE {
- return fRenderTarget;
+ return fRenderTarget.get();
}
// GrTexture
@@ -101,13 +101,6 @@ public:
}
/**
- * Removes the reference on the associated GrRenderTarget held by this
- * texture. Afterwards asRenderTarget() will return NULL. The
- * GrRenderTarget survives the release if another ref is held on it.
- */
- void releaseRenderTarget();
-
- /**
* Return the native ID or handle to the texture, depending on the
* platform. e.g. on OpenGL, return the texture ID.
*/
@@ -137,9 +130,9 @@ public:
static bool NeedsFiltering(const GrResourceKey& key);
protected:
- GrRenderTarget* fRenderTarget; // texture refs its rt representation
- // base class cons sets to NULL
- // subclass cons can create and set
+ // A texture refs its rt representation but not vice-versa. It is up to
+ // the subclass constructor to initialize this pointer.
+ SkAutoTUnref<GrRenderTarget> fRenderTarget;
GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
: INHERITED(gpu, isWrapped, desc)
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1b62062cc1..071183bc1c 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -373,7 +373,6 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint));
fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
}
- texture->releaseRenderTarget();
} else {
// TODO: Our CPU stretch doesn't filter. But we create separate
// stretched textures when the texture params is either filtered or
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index d4e4e6b2fb..f55c6ada29 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -78,8 +78,7 @@ public:
*
* If kRenderTarget_TextureFlag is specified the GrRenderTarget is
* accessible via GrTexture::asRenderTarget(). The texture will hold a ref
- * on the render target until its releaseRenderTarget() is called or it is
- * destroyed.
+ * on the render target until the texture is destroyed.
*
* @param desc describes the texture to be created.
* @param srcData texel data to load texture. Begins with full-size
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 44a1442b3b..87df1470e9 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -67,33 +67,15 @@ void GrTexture::writePixels(int left, int top, int width, int height,
pixelOpsFlags);
}
-void GrTexture::releaseRenderTarget() {
- if (NULL != fRenderTarget) {
- GrAssert(fRenderTarget->asTexture() == this);
- GrAssert(fDesc.fFlags & kRenderTarget_GrTextureFlagBit);
-
- fRenderTarget->onTextureReleaseRenderTarget();
- fRenderTarget->unref();
- fRenderTarget = NULL;
-
- fDesc.fFlags = fDesc.fFlags &
- ~(kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit);
- fDesc.fSampleCnt = 0;
- }
-}
-
void GrTexture::onRelease() {
GrAssert(!this->isSetFlag((GrTextureFlags) kReturnToCache_FlagBit));
- this->releaseRenderTarget();
-
INHERITED::onRelease();
}
void GrTexture::onAbandon() {
- if (NULL != fRenderTarget) {
+ if (NULL != fRenderTarget.get()) {
fRenderTarget->abandon();
}
-
INHERITED::onAbandon();
}
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
new file mode 100644
index 0000000000..3fe071ca0f
--- /dev/null
+++ b/tests/GrSurfaceTest.cpp
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// This is a GPU-backend specific test.
+
+#include "SkTypes.h"
+
+#if SK_SUPPORT_GPU
+
+#include "Test.h"
+#include "GrContext.h"
+#include "GrContextFactory.h"
+#include "GrRenderTarget.h"
+#include "GrTexture.h"
+
+static void GrSurfaceIsSameTest(skiatest::Reporter* reporter, GrContextFactory* factory) {
+ GrContext* context = factory->get(GrContextFactory::kNull_GLContextType);
+ if (NULL != context) {
+ GrTextureDesc desc;
+ desc.fConfig = kSkia8888_GrPixelConfig;
+ desc.fFlags = kRenderTarget_GrTextureFlagBit;
+ desc.fWidth = 256;
+ desc.fHeight = 256;
+ desc.fSampleCnt = 0;
+ GrSurface* texRT1 = context->createUncachedTexture(desc, NULL, 0);
+ GrSurface* texRT2 = context->createUncachedTexture(desc, NULL, 0);
+ desc.fFlags = kNone_GrTextureFlags;
+ GrSurface* tex1 = context->createUncachedTexture(desc, NULL, 0);
+
+ REPORTER_ASSERT(reporter, texRT1->isSameAs(texRT1));
+ REPORTER_ASSERT(reporter, texRT1->isSameAs(texRT1->asRenderTarget()));
+ REPORTER_ASSERT(reporter, texRT1->asRenderTarget()->isSameAs(texRT1));
+ REPORTER_ASSERT(reporter, !texRT2->isSameAs(texRT1));
+ REPORTER_ASSERT(reporter, !texRT2->asRenderTarget()->isSameAs(texRT1));
+ REPORTER_ASSERT(reporter, !texRT2->isSameAs(texRT1->asRenderTarget()));
+ REPORTER_ASSERT(reporter, !texRT2->isSameAs(tex1));
+ REPORTER_ASSERT(reporter, !texRT2->asRenderTarget()->isSameAs(tex1));
+
+ GrBackendTextureDesc backendDesc;
+ backendDesc.fConfig = kSkia8888_GrPixelConfig;
+ backendDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
+ backendDesc.fWidth = 256;
+ backendDesc.fHeight = 256;
+ backendDesc.fSampleCnt = 0;
+ backendDesc.fTextureHandle = 5;
+ GrSurface* externalTexRT = context->wrapBackendTexture(backendDesc);
+ REPORTER_ASSERT(reporter, externalTexRT->isSameAs(externalTexRT));
+ REPORTER_ASSERT(reporter, externalTexRT->isSameAs(externalTexRT->asRenderTarget()));
+ REPORTER_ASSERT(reporter, externalTexRT->asRenderTarget()->isSameAs(externalTexRT));
+ REPORTER_ASSERT(reporter, !externalTexRT->isSameAs(texRT1));
+ REPORTER_ASSERT(reporter, !externalTexRT->asRenderTarget()->isSameAs(texRT1));
+
+ texRT1->unref();
+ texRT2->unref();
+ tex1->unref();
+ externalTexRT->unref();
+ }
+}
+
+#include "TestClassDef.h"
+DEFINE_GPUTESTCLASS("GrSurfaceIsSame", GrSurfaceIsSameTestClass, GrSurfaceIsSameTest)
+
+#endif