From: bsalomon Date: Mon, 3 Nov 2014 16:47:23 +0000 (-0800) Subject: Add class GrGLTextureRenderTarget for GL texture/rendertarget objects X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~5086 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37dd331b20a92ce79cc26556e065dec98a66cb0b;p=platform%2Fupstream%2FlibSkiaSharp.git Add class GrGLTextureRenderTarget for GL texture/rendertarget objects BUG=skia:2889 Review URL: https://codereview.chromium.org/695813003 --- diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 9db1d7f..e4bd92a 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -247,6 +247,7 @@ '<(skia_src_path)/gpu/gl/GrGLStencilBuffer.h', '<(skia_src_path)/gpu/gl/GrGLTexture.cpp', '<(skia_src_path)/gpu/gl/GrGLTexture.h', + '<(skia_src_path)/gpu/gl/GrGLTextureRenderTarget.h', '<(skia_src_path)/gpu/gl/GrGLUtil.cpp', '<(skia_src_path)/gpu/gl/GrGLUtil.h', '<(skia_src_path)/gpu/gl/GrGLUniformHandle.h', diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h index 9b298dd..4ffe17e 100644 --- a/include/gpu/GrGpuResource.h +++ b/include/gpu/GrGpuResource.h @@ -13,10 +13,10 @@ #include "SkInstCnt.h" #include "SkTInternalLList.h" -class GrResourceCacheEntry; -class GrResourceCache2; -class GrGpu; class GrContext; +class GrGpu; +class GrResourceCache2; +class GrResourceCacheEntry; /** * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h index 0223f18..93298f0 100644 --- a/include/gpu/GrGpuResourceRef.h +++ b/include/gpu/GrGpuResourceRef.h @@ -9,6 +9,8 @@ #define GrGpuResourceRef_DEFINED #include "GrGpuResource.h" +#include "GrRenderTarget.h" +#include "GrTexture.h" #include "SkRefCnt.h" /** @@ -96,7 +98,7 @@ public: /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as pending on the resource when markPendingIO is called. */ - GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) {} + GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) { } T* get() const { return static_cast(this->getResource()); } @@ -108,6 +110,49 @@ private: typedef GrGpuResourceRef INHERITED; }; +// Specializations for GrTexture and GrRenderTarget because they use virtual inheritance. +template<> class GrTGpuResourceRef : public GrGpuResourceRef { +public: + GrTGpuResourceRef() {} + + GrTGpuResourceRef(GrTexture* texture, GrIOType ioType) : INHERITED(texture, ioType) { } + + GrTexture* get() const { + GrSurface* surface = static_cast(this->getResource()); + if (surface) { + return surface->asTexture(); + } else { + return NULL; + } + } + + void set(GrTexture* texture, GrIOType ioType) { this->setResource(texture, ioType); } + +private: + typedef GrGpuResourceRef INHERITED; +}; + +template<> class GrTGpuResourceRef : public GrGpuResourceRef { +public: + GrTGpuResourceRef() {} + + GrTGpuResourceRef(GrRenderTarget* rt, GrIOType ioType) : INHERITED(rt, ioType) { } + + GrRenderTarget* get() const { + GrSurface* surface = static_cast(this->getResource()); + if (surface) { + return surface->asRenderTarget(); + } else { + return NULL; + } + } + + void set(GrRenderTarget* rt, GrIOType ioType) { this->setResource(rt, ioType); } + +private: + typedef GrGpuResourceRef INHERITED; +}; + /** * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a * ref. diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h index b8e30d9..e0f1199 100644 --- a/include/gpu/GrRenderTarget.h +++ b/include/gpu/GrRenderTarget.h @@ -12,36 +12,21 @@ #include "SkRect.h" class GrStencilBuffer; -class GrTexture; /** * GrRenderTarget represents a 2D buffer of pixels that can be rendered to. * A context's render target is set by setRenderTarget(). Render targets are - * created by a createTexture with the kRenderTarget_TextureFlag flag. + * created by a createTexture with the kRenderTarget_SurfaceFlag flag. * Additionally, GrContext provides methods for creating GrRenderTargets * that wrap externally created render targets. */ -class GrRenderTarget : public GrSurface { +class GrRenderTarget : virtual public GrSurface { public: SK_DECLARE_INST_COUNT(GrRenderTarget) - // GrResource overrides - virtual size_t gpuMemorySize() const SK_OVERRIDE; - // GrSurface overrides - /** - * @return the texture associated with the render target, may be NULL. - */ - virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; } - virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; } - - /** - * @return this render target. - */ virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return this; } - virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { - return this; - } + virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { return this; } // GrRenderTarget /** @@ -134,11 +119,9 @@ public: protected: GrRenderTarget(GrGpu* gpu, bool isWrapped, - GrTexture* texture, const GrSurfaceDesc& desc) : INHERITED(gpu, isWrapped, desc) - , fStencilBuffer(NULL) - , fTexture(texture) { + , fStencilBuffer(NULL) { fResolveRect.setLargestInverted(); } @@ -147,15 +130,7 @@ protected: virtual void onRelease() SK_OVERRIDE; private: - friend class GrTexture; - // called by ~GrTexture to remove the non-ref'ed back ptr. - void owningTextureDestroyed() { - SkASSERT(fTexture); - fTexture = NULL; - } - GrStencilBuffer* fStencilBuffer; - GrTexture* fTexture; // not ref'ed SkIRect fResolveRect; diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index 9a76d3a..9d89149 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -24,15 +24,11 @@ public: /** * Retrieves the width of the surface. - * - * @return the width in texels */ int width() const { return fDesc.fWidth; } /** * Retrieves the height of the surface. - * - * @return the height in texels */ int height() const { return fDesc.fHeight; } @@ -63,14 +59,14 @@ public: /** * @return the texture associated with the surface, may be NULL. */ - virtual GrTexture* asTexture() = 0; - virtual const GrTexture* asTexture() const = 0; + virtual GrTexture* asTexture() { return NULL; } + virtual const GrTexture* asTexture() const { return NULL; } /** * @return the render target underlying this surface, may be NULL. */ - virtual GrRenderTarget* asRenderTarget() = 0; - virtual const GrRenderTarget* asRenderTarget() const = 0; + virtual GrRenderTarget* asRenderTarget() { return NULL; } + virtual const GrRenderTarget* asRenderTarget() const { return NULL; } /** * Reads a rectangle of pixels from the surface. diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h index 13d5667..87f0d5a 100644 --- a/include/gpu/GrTexture.h +++ b/include/gpu/GrTexture.h @@ -10,7 +10,6 @@ #define GrTexture_DEFINED #include "GrSurface.h" -#include "GrRenderTarget.h" #include "SkPoint.h" #include "SkRefCnt.h" @@ -18,7 +17,7 @@ class GrResourceKey; class GrTextureParams; class GrTexturePriv; -class GrTexture : public GrSurface { +class GrTexture : virtual public GrSurface { public: /** * Approximate number of bytes used by the texture @@ -27,8 +26,6 @@ public: virtual GrTexture* asTexture() SK_OVERRIDE { return this; } virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; } - virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return fRenderTarget.get(); } - virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { return fRenderTarget.get(); } /** * Return the native ID or handle to the texture, depending on the @@ -54,18 +51,8 @@ public: inline const GrTexturePriv texturePriv() const; protected: - // A texture refs its rt representation but not vice-versa. It is up to - // the subclass constructor to initialize this pointer. - SkAutoTUnref fRenderTarget; - GrTexture(GrGpu* gpu, bool isWrapped, const GrSurfaceDesc& desc); - virtual ~GrTexture(); - - // GrResource overrides - virtual void onRelease() SK_OVERRIDE; - virtual void onAbandon() SK_OVERRIDE; - void validateDesc() const; private: diff --git a/src/effects/SkColorCubeFilter.cpp b/src/effects/SkColorCubeFilter.cpp index 2242598..d9d6841 100644 --- a/src/effects/SkColorCubeFilter.cpp +++ b/src/effects/SkColorCubeFilter.cpp @@ -356,11 +356,12 @@ GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context) desc.fHeight = fCache.cubeDimension() * fCache.cubeDimension(); desc.fConfig = kRGBA_8888_GrPixelConfig; - SkAutoTUnref textureCube( - static_cast(context->findAndRefCachedResource( - GrTexturePriv::ComputeKey(context->getGpu(), NULL, desc, cacheID)))); - - if (!textureCube) { + GrResourceKey rkey = GrTexturePriv::ComputeKey(context->getGpu(), NULL, desc, cacheID); + GrSurface* surface = static_cast(context->findAndRefCachedResource(rkey)); + SkAutoTUnref textureCube; + if (surface) { + textureCube.reset(surface->asTexture()); + } else { textureCube.reset(context->createTexture(NULL, desc, cacheID, fCubeData->data(), 0)); } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 5f0001b..c1fee0a 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -255,8 +255,12 @@ GrTexture* GrContext::findAndRefTexture(const GrSurfaceDesc& desc, const GrTextureParams* params) { GrResourceKey resourceKey = GrTexturePriv::ComputeKey(fGpu, params, desc, cacheID); GrGpuResource* resource = fResourceCache->find(resourceKey); - SkSafeRef(resource); - return static_cast(resource); + if (resource) { + resource->ref(); + return static_cast(resource)->asTexture(); + } else { + return NULL; + } } bool GrContext::isTextureInCache(const GrSurfaceDesc& desc, @@ -471,7 +475,7 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM GrGpuResource* resource = fResourceCache2->findAndRefScratchResource(key, scratchFlags); if (resource) { fResourceCache->makeResourceMRU(resource); - return static_cast(resource); + return static_cast(resource)->asTexture(); } if (kExact_ScratchTexMatch == match) { diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 39c9102..97516e8 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -530,9 +530,7 @@ public: * * @return The currently set render target. */ - GrRenderTarget* getRenderTarget() const { - return static_cast(fRenderTarget.getResource()); - } + GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } /** * Sets the render-target used at the next drawing call diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h index f495b89..c32294b 100644 --- a/src/gpu/GrOptDrawState.h +++ b/src/gpu/GrOptDrawState.h @@ -169,9 +169,7 @@ public: * * @return The currently set render target. */ - GrRenderTarget* getRenderTarget() const { - return static_cast(fRenderTarget.getResource()); - } + GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } /// @} diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp index 7ed70c9..7aeb4ee 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -31,20 +31,6 @@ void GrRenderTarget::discard() { context->discardRenderTarget(this); } -size_t GrRenderTarget::gpuMemorySize() const { - size_t colorBits; - if (kUnknown_GrPixelConfig == fDesc.fConfig) { - colorBits = 32; // don't know, make a guess - } else { - colorBits = GrBytesPerPixel(fDesc.fConfig) * 8; - } - uint64_t size = fDesc.fWidth; - size *= fDesc.fHeight; - size *= colorBits; - size *= SkTMax(1, fDesc.fSampleCnt); - return (size_t)(size / 8); -} - void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) { if (kCanResolve_ResolveType == getResolveType()) { if (rect) { diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index 0431a27..9754d44 100644 --- a/src/gpu/GrResourceCache.cpp +++ b/src/gpu/GrResourceCache.cpp @@ -180,8 +180,7 @@ void GrResourceCache::notifyPurgable(const GrGpuResource* resource) { if (resource->getCacheEntry()->key().getResourceType() == GrTexturePriv::ResourceType() && resource->getCacheEntry()->key().isScratch() && !fCaps->reuseScratchTextures() && - !(static_cast(resource)->desc().fFlags & - kRenderTarget_GrSurfaceFlag)) { + !(static_cast(resource)->desc().fFlags & kRenderTarget_GrSurfaceFlag)) { this->deleteResource(resource->getCacheEntry()); } } diff --git a/src/gpu/GrResourceCache2.h b/src/gpu/GrResourceCache2.h index e10b45a..a365a5a 100644 --- a/src/gpu/GrResourceCache2.h +++ b/src/gpu/GrResourceCache2.h @@ -42,9 +42,7 @@ public: private: #ifdef SK_DEBUG - bool isInCache(const GrGpuResource* r) const { - return fResources.isInList(r); - } + bool isInCache(const GrGpuResource* r) const { return fResources.isInList(r); } #endif class AvailableForScratchUse; diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index 2717b31..2139540 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -6,21 +6,13 @@ * found in the LICENSE file. */ - #include "GrContext.h" #include "GrDrawTargetCaps.h" #include "GrGpu.h" -#include "GrRenderTarget.h" #include "GrResourceCache.h" #include "GrTexture.h" #include "GrTexturePriv.h" -GrTexture::~GrTexture() { - if (fRenderTarget.get()) { - fRenderTarget.get()->owningTextureDestroyed(); - } -} - void GrTexture::dirtyMipMaps(bool mipMapsDirty) { if (mipMapsDirty) { if (kValid_MipMapsStatus == fMipMapsStatus) { @@ -53,18 +45,6 @@ size_t GrTexture::gpuMemorySize() const { return textureSize; } -void GrTexture::onRelease() { - - INHERITED::onRelease(); -} - -void GrTexture::onAbandon() { - if (fRenderTarget.get()) { - fRenderTarget->abandon(); - } - INHERITED::onAbandon(); -} - void GrTexture::validateDesc() const { if (this->asRenderTarget()) { // This texture has a render target @@ -140,7 +120,6 @@ GrSurfaceOrigin resolve_origin(const GrSurfaceDesc& desc) { ////////////////////////////////////////////////////////////////////////////// GrTexture::GrTexture(GrGpu* gpu, bool isWrapped, const GrSurfaceDesc& desc) : INHERITED(gpu, isWrapped, desc) - , fRenderTarget(NULL) , fMipMapsStatus(kNotAllocated_MipMapsStatus) { this->setScratchKey(GrTexturePriv::ComputeScratchKey(desc)); // only make sense if alloc size is pow2 diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 0e8bd05..8482ecd 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -9,47 +9,48 @@ #include "GrGpuGL.h" -#define GPUGL static_cast(getGpu()) - +#define GPUGL static_cast(this->getGpu()) #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X) -void GrGLRenderTarget::init(const GrSurfaceDesc& desc, - const IDDesc& idDesc, - const GrGLIRect& viewport, - GrGLTexID* texID) { - fRTFBOID = idDesc.fRTFBOID; - fTexFBOID = idDesc.fTexFBOID; - fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID; - fViewport = viewport; - fTexIDObj.reset(SkSafeRef(texID)); +// Because this class is virtually derived from GrSurface we must explicitly call its constructor. +GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc) + : GrSurface(gpu, idDesc.fIsWrapped, desc) + , INHERITED(gpu, idDesc.fIsWrapped, desc) { + this->init(desc, idDesc); this->registerWithCache(); } -GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu, - const IDDesc& idDesc, - const GrGLIRect& viewport, - GrGLTexID* texID, - GrGLTexture* texture) - : INHERITED(gpu, idDesc.fIsWrapped, texture, texture->desc()) { - SkASSERT(texID); - SkASSERT(texture); - // FBO 0 can't also be a texture, right? - SkASSERT(0 != idDesc.fRTFBOID); - SkASSERT(0 != idDesc.fTexFBOID); +GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc, + Derived) + : GrSurface(gpu, idDesc.fIsWrapped, desc) + , INHERITED(gpu, idDesc.fIsWrapped, desc) { + this->init(desc, idDesc); +} + +void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) { + fRTFBOID = idDesc.fRTFBOID; + fTexFBOID = idDesc.fTexFBOID; + fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID; - // we assume this is true, TODO: get rid of viewport as a param. - SkASSERT(viewport.fWidth == texture->width()); - SkASSERT(viewport.fHeight == texture->height()); + fViewport.fLeft = 0; + fViewport.fBottom = 0; + fViewport.fWidth = desc.fWidth; + fViewport.fHeight = desc.fHeight; - this->init(texture->desc(), idDesc, viewport, texID); + // We own one color value for each MSAA sample. + fColorValuesPerPixel = SkTMax(1, fDesc.fSampleCnt); + if (fTexFBOID != fRTFBOID) { + // If we own the resolve buffer then that is one more sample per pixel. + fColorValuesPerPixel += 1; + } } -GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu, - const GrSurfaceDesc& desc, - const IDDesc& idDesc, - const GrGLIRect& viewport) - : INHERITED(gpu, idDesc.fIsWrapped, NULL, desc) { - this->init(desc, idDesc, viewport, NULL); +size_t GrGLRenderTarget::gpuMemorySize() const { + SkASSERT(kUnknown_GrPixelConfig != fDesc.fConfig); + SkASSERT(!GrPixelConfigIsCompressed(fDesc.fConfig)); + size_t colorBytes = GrBytesPerPixel(fDesc.fConfig); + SkASSERT(colorBytes > 0); + return fColorValuesPerPixel * fDesc.fWidth * fDesc.fHeight * colorBytes; } void GrGLRenderTarget::onRelease() { @@ -67,7 +68,6 @@ void GrGLRenderTarget::onRelease() { fRTFBOID = 0; fTexFBOID = 0; fMSColorRenderbufferID = 0; - fTexIDObj.reset(NULL); INHERITED::onRelease(); } @@ -75,9 +75,5 @@ void GrGLRenderTarget::onAbandon() { fRTFBOID = 0; fTexFBOID = 0; fMSColorRenderbufferID = 0; - if (fTexIDObj.get()) { - fTexIDObj->abandon(); - fTexIDObj.reset(NULL); - } INHERITED::onAbandon(); } diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h index 116862b..0f04160 100644 --- a/src/gpu/gl/GrGLRenderTarget.h +++ b/src/gpu/gl/GrGLRenderTarget.h @@ -14,11 +14,8 @@ #include "SkScalar.h" class GrGpuGL; -class GrGLTexture; -class GrGLTexID; class GrGLRenderTarget : public GrRenderTarget { - public: // set fTexFBOID to this value to indicate that it is multisampled but // Gr doesn't know how to resolve it. @@ -31,12 +28,7 @@ public: bool fIsWrapped; }; - // creates a GrGLRenderTarget associated with a texture - GrGLRenderTarget(GrGpuGL*, const IDDesc&, const GrGLIRect& viewport, - GrGLTexID*, GrGLTexture*); - - // creates an independent GrGLRenderTarget - GrGLRenderTarget(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&, const GrGLIRect& viewport); + GrGLRenderTarget(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&); virtual ~GrGLRenderTarget() { this->release(); } @@ -52,14 +44,9 @@ public: GrGLuint textureFBOID() const { return fTexFBOID; } // override of GrRenderTarget - virtual GrBackendObject getRenderTargetHandle() const { - return this->renderFBOID(); - } - virtual GrBackendObject getRenderTargetResolvedHandle() const { - return this->textureFBOID(); - } + virtual GrBackendObject getRenderTargetHandle() const { return this->renderFBOID(); } + virtual GrBackendObject getRenderTargetResolvedHandle() const { return this->textureFBOID(); } virtual ResolveType getResolveType() const { - if (!this->isMultisampled() || fRTFBOID == fTexFBOID) { // catches FBO 0 and non MSAA case @@ -71,26 +58,34 @@ public: } } + virtual size_t gpuMemorySize() const SK_OVERRIDE; + protected: - // override of GrResource + // The public constructor registers this object with the cache. However, only the most derived + // class should register with the cache. This constructor does not do the registration and + // rather moves that burden onto the derived class. + enum Derived { kDerived }; + GrGLRenderTarget(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&, Derived); + + void init(const GrSurfaceDesc&, const IDDesc&); + virtual void onAbandon() SK_OVERRIDE; virtual void onRelease() SK_OVERRIDE; private: GrGLuint fRTFBOID; GrGLuint fTexFBOID; - GrGLuint fMSColorRenderbufferID; // when we switch to this render target we want to set the viewport to - // only render to to content area (as opposed to the whole allocation) and + // only render to content area (as opposed to the whole allocation) and // we want the rendering to be at top left (GL has origin in bottom left) GrGLIRect fViewport; - // non-NULL if this RT was created by Gr with an associated GrGLTexture. - SkAutoTUnref fTexIDObj; - - void init(const GrSurfaceDesc&, const IDDesc&, const GrGLIRect& viewport, GrGLTexID*); + // gpuMemorySize() needs to know what how many color values are owned per pixel. However, + // abandon and release zero out the IDs and the cache needs to know the size even after those + // actions. + uint8_t fColorValuesPerPixel; typedef GrRenderTarget INHERITED; }; diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp index 8cf574b..d9db6ea 100644 --- a/src/gpu/gl/GrGLTexture.cpp +++ b/src/gpu/gl/GrGLTexture.cpp @@ -8,46 +8,30 @@ #include "GrGLTexture.h" #include "GrGpuGL.h" -#define GPUGL static_cast(getGpu()) - +#define GPUGL static_cast(this->getGpu()) #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X) -void GrGLTexture::init(GrGpuGL* gpu, - const GrSurfaceDesc& desc, - const IDDesc& idDesc, - const GrGLRenderTarget::IDDesc* rtIDDesc) { +// Because this class is virtually derived from GrSurface we must explicitly call its constructor. +GrGLTexture::GrGLTexture(GrGpuGL* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc) + : GrSurface(gpu, idDesc.fIsWrapped, desc) + , INHERITED(gpu, idDesc.fIsWrapped, desc) { + this->init(desc, idDesc); + this->registerWithCache(); +} + +GrGLTexture::GrGLTexture(GrGpuGL* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc, Derived) + : GrSurface(gpu, idDesc.fIsWrapped, desc) + , INHERITED(gpu, idDesc.fIsWrapped, desc) { + this->init(desc, idDesc); +} +void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) { SkASSERT(0 != idDesc.fTextureID); - fTexParams.invalidate(); fTexParamsTimestamp = GrGpu::kExpiredTimestamp; fTexIDObj.reset(SkNEW_ARGS(GrGLTexID, (GPUGL->glInterface(), idDesc.fTextureID, idDesc.fIsWrapped))); - - if (rtIDDesc) { - GrGLIRect vp; - vp.fLeft = 0; - vp.fWidth = desc.fWidth; - vp.fBottom = 0; - vp.fHeight = desc.fHeight; - - fRenderTarget.reset(SkNEW_ARGS(GrGLRenderTarget, (gpu, *rtIDDesc, vp, fTexIDObj, this))); - } - this->registerWithCache(); -} - -GrGLTexture::GrGLTexture(GrGpuGL* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc) - : INHERITED(gpu, idDesc.fIsWrapped, desc) { - this->init(gpu, desc, idDesc, NULL); -} - -GrGLTexture::GrGLTexture(GrGpuGL* gpu, - const GrSurfaceDesc& desc, - const IDDesc& idDesc, - const GrGLRenderTarget::IDDesc& rtIDDesc) - : INHERITED(gpu, idDesc.fIsWrapped, desc) { - this->init(gpu, desc, idDesc, &rtIDDesc); } void GrGLTexture::onRelease() { diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h index 11d6353..5c64eaf 100644 --- a/src/gpu/gl/GrGLTexture.h +++ b/src/gpu/gl/GrGLTexture.h @@ -10,7 +10,8 @@ #define GrGLTexture_DEFINED #include "GrGpu.h" -#include "GrGLRenderTarget.h" +#include "GrTexture.h" +#include "GrGLUtil.h" /** * A ref counted tex id that deletes the texture in its destructor. @@ -62,11 +63,7 @@ public: bool fIsWrapped; }; - // creates a texture that is also an RT - GrGLTexture(GrGpuGL* gpu, const GrSurfaceDesc&, const IDDesc&, const GrGLRenderTarget::IDDesc&); - - // creates a non-RT texture - GrGLTexture(GrGpuGL* gpu, const GrSurfaceDesc&, const IDDesc&); + GrGLTexture(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&); virtual ~GrGLTexture() { this->release(); } @@ -89,7 +86,14 @@ public: GrGLuint textureID() const { return (fTexIDObj.get()) ? fTexIDObj->id() : 0; } protected: - // overrides of GrTexture + // The public constructor registers this object with the cache. However, only the most derived + // class should register with the cache. This constructor does not do the registration and + // rather moves that burden onto the derived class. + enum Derived { kDerived }; + GrGLTexture(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&, Derived); + + void init(const GrSurfaceDesc&, const IDDesc&); + virtual void onAbandon() SK_OVERRIDE; virtual void onRelease() SK_OVERRIDE; @@ -98,8 +102,6 @@ private: GrGpu::ResetTimestamp fTexParamsTimestamp; SkAutoTUnref fTexIDObj; - void init(GrGpuGL* gpu, const GrSurfaceDesc&, const IDDesc&, const GrGLRenderTarget::IDDesc*); - typedef GrTexture INHERITED; }; diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h new file mode 100644 index 0000000..55da28f --- /dev/null +++ b/src/gpu/gl/GrGLTextureRenderTarget.h @@ -0,0 +1,58 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef GrGLTextureRenderTarget_DEFINED +#define GrGLTextureRenderTarget_DEFINED + +#include "GrGLTexture.h" +#include "GrGLRenderTarget.h" + +class GrGpuGL; + +#ifdef SK_BUILD_FOR_WIN +// Windows gives bogus warnings about inheriting asTexture/asRenderTarget via dominance. +#pragma warning(push) +#pragma warning(disable: 4250) +#endif + +class GrGLTextureRenderTarget : public GrGLTexture, public GrGLRenderTarget { +public: + // We're virtually derived from GrSurface (via both GrGLTexture and GrGLRenderTarget) so its + // constructor must be explicitly called. + GrGLTextureRenderTarget(GrGpuGL* gpu, + const GrSurfaceDesc& desc, + const GrGLTexture::IDDesc& texIDDesc, + const GrGLRenderTarget::IDDesc& rtIDDesc) + : GrSurface(gpu, texIDDesc.fIsWrapped, desc) + , GrGLTexture(gpu, desc, texIDDesc, GrGLTexture::kDerived) + , GrGLRenderTarget(gpu, desc, rtIDDesc, GrGLRenderTarget::kDerived) { + this->registerWithCache(); + } + + virtual ~GrGLTextureRenderTarget() { this->release(); } + + // GrGLRenderTarget accounts for the texture's memory and any MSAA renderbuffer's memory. + virtual size_t gpuMemorySize() const SK_OVERRIDE { return GrGLRenderTarget::gpuMemorySize(); } + +protected: + virtual void onAbandon() SK_OVERRIDE { + GrGLRenderTarget::onAbandon(); + GrGLTexture::onAbandon(); + } + + virtual void onRelease() SK_OVERRIDE { + GrGLRenderTarget::onRelease(); + GrGLTexture::onRelease(); + } +}; + +#ifdef SK_BUILD_FOR_WIN +#pragma warning(pop) +#endif + +#endif diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 9d08f64..6c35e9f 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -8,6 +8,7 @@ #include "GrGpuGL.h" #include "GrGLStencilBuffer.h" +#include "GrGLTextureRenderTarget.h" #include "GrOptDrawState.h" #include "GrSurfacePriv.h" #include "GrTemplates.h" @@ -403,7 +404,7 @@ GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) { if (!this->createRenderTargetObjects(surfDesc, idDesc.fTextureID, &rtIDDesc)) { return NULL; } - texture = SkNEW_ARGS(GrGLTexture, (this, surfDesc, idDesc, rtIDDesc)); + texture = SkNEW_ARGS(GrGLTextureRenderTarget, (this, surfDesc, idDesc, rtIDDesc)); } else { texture = SkNEW_ARGS(GrGLTexture, (this, surfDesc, idDesc)); } @@ -428,13 +429,7 @@ GrRenderTarget* GrGpuGL::onWrapBackendRenderTarget(const GrBackendRenderTargetDe desc.fSampleCnt = wrapDesc.fSampleCnt; desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); - GrGLIRect viewport; - viewport.fLeft = 0; - viewport.fBottom = 0; - viewport.fWidth = desc.fWidth; - viewport.fHeight = desc.fHeight; - - GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, (this, desc, idDesc, viewport)); + GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, (this, desc, idDesc)); if (wrapDesc.fStencilBits) { GrGLStencilBuffer::Format format; format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat; @@ -1022,7 +1017,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrSurfaceDesc& origDesc, GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); return return_null_texture(); } - tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc, rtIDDesc)); + tex = SkNEW_ARGS(GrGLTextureRenderTarget, (this, desc, idDesc, rtIDDesc)); } else { tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); } @@ -1193,7 +1188,7 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, } bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) { - GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt; + GrGLRenderTarget* glrt = static_cast(rt); GrGLuint fbo = glrt->renderFBOID(); @@ -1575,8 +1570,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target, case GrGLRenderTarget::kCantResolve_ResolveType: return false; case GrGLRenderTarget::kAutoResolves_ResolveType: - this->flushRenderTarget(static_cast(target), - &SkIRect::EmptyIRect()); + this->flushRenderTarget(static_cast(target), &SkIRect::EmptyIRect()); break; case GrGLRenderTarget::kCanResolve_ResolveType: this->onResolveRenderTarget(tgt); @@ -1989,7 +1983,7 @@ void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur // If we created a rt/tex and rendered to it without using a texture and now we're texturing // from the rt it will still be the last bound texture, but it needs resolving. So keep this // out of the "last != next" check. - GrGLRenderTarget* texRT = static_cast(texture->asRenderTarget()); + GrGLRenderTarget* texRT = static_cast(texture->asRenderTarget()); if (texRT) { this->onResolveRenderTarget(texRT); } diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 1a03c13..e7266f3 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -14,6 +14,7 @@ #include "GrGLIndexBuffer.h" #include "GrGLPathRendering.h" #include "GrGLProgram.h" +#include "GrGLRenderTarget.h" #include "GrGLStencilBuffer.h" #include "GrGLTexture.h" #include "GrGLVertexArray.h"