diff options
author | 2014-11-03 08:47:23 -0800 | |
---|---|---|
committer | 2014-11-03 08:47:23 -0800 | |
commit | 37dd331b20a92ce79cc26556e065dec98a66cb0b (patch) | |
tree | cac1c6927c1f8f9860890e37b9d08cca01de251b /src/gpu/gl | |
parent | 89a9ecef9ead1f6093e796173b28b82dca4adcbd (diff) |
Add class GrGLTextureRenderTarget for GL texture/rendertarget objects
BUG=skia:2889
Review URL: https://codereview.chromium.org/695813003
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLRenderTarget.cpp | 70 | ||||
-rw-r--r-- | src/gpu/gl/GrGLRenderTarget.h | 41 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTexture.cpp | 46 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTexture.h | 20 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTextureRenderTarget.h | 58 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 20 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 1 |
7 files changed, 143 insertions, 113 deletions
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 0e8bd05bc7..8482ecdc6c 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -9,47 +9,48 @@ #include "GrGpuGL.h" -#define GPUGL static_cast<GrGpuGL*>(getGpu()) - +#define GPUGL static_cast<GrGpuGL*>(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 116862bd0b..0f041600ee 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<GrGLTexID> 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 8cf574ba15..d9db6ea2a2 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<GrGpuGL*>(getGpu()) - +#define GPUGL static_cast<GrGpuGL*>(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 11d63531cf..5c64eafe29 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<GrGLTexID> 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 0000000000..55da28f6b8 --- /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 9d08f641eb..6c35e9f2d3 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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(target), - &SkIRect::EmptyIRect()); + this->flushRenderTarget(static_cast<GrGLRenderTarget*>(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<GrGLRenderTarget*>(texture->asRenderTarget()); + GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget()); if (texRT) { this->onResolveRenderTarget(texRT); } diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 1a03c130c6..e7266f3fa2 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" |