aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2014-11-03 08:47:23 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-03 08:47:23 -0800
commit37dd331b20a92ce79cc26556e065dec98a66cb0b (patch)
treecac1c6927c1f8f9860890e37b9d08cca01de251b /src/gpu/gl
parent89a9ecef9ead1f6093e796173b28b82dca4adcbd (diff)
Add class GrGLTextureRenderTarget for GL texture/rendertarget objects
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLRenderTarget.cpp70
-rw-r--r--src/gpu/gl/GrGLRenderTarget.h41
-rw-r--r--src/gpu/gl/GrGLTexture.cpp46
-rw-r--r--src/gpu/gl/GrGLTexture.h20
-rw-r--r--src/gpu/gl/GrGLTextureRenderTarget.h58
-rw-r--r--src/gpu/gl/GrGpuGL.cpp20
-rw-r--r--src/gpu/gl/GrGpuGL.h1
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"