diff options
-rw-r--r-- | gyp/tests.gyp | 1 | ||||
-rw-r--r-- | include/gpu/GrRenderTarget.h | 9 | ||||
-rw-r--r-- | include/gpu/GrSurface.h | 16 | ||||
-rw-r--r-- | include/gpu/GrTexture.h | 19 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 3 | ||||
-rw-r--r-- | src/gpu/GrTexture.cpp | 20 | ||||
-rw-r--r-- | tests/GrSurfaceTest.cpp | 68 |
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 |