Add class GrGLTextureRenderTarget for GL texture/rendertarget objects

BUG=skia:2889

Review URL: https://codereview.chromium.org/695813003
This commit is contained in:
bsalomon 2014-11-03 08:47:23 -08:00 committed by Commit bot
parent 89a9ecef9e
commit 37dd331b20
21 changed files with 221 additions and 224 deletions

View File

@ -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',

View File

@ -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

View File

@ -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<T*>(this->getResource()); }
@ -108,6 +110,49 @@ private:
typedef GrGpuResourceRef INHERITED;
};
// Specializations for GrTexture and GrRenderTarget because they use virtual inheritance.
template<> class GrTGpuResourceRef<GrTexture> : public GrGpuResourceRef {
public:
GrTGpuResourceRef() {}
GrTGpuResourceRef(GrTexture* texture, GrIOType ioType) : INHERITED(texture, ioType) { }
GrTexture* get() const {
GrSurface* surface = static_cast<GrSurface*>(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<GrRenderTarget> : public GrGpuResourceRef {
public:
GrTGpuResourceRef() {}
GrTGpuResourceRef(GrRenderTarget* rt, GrIOType ioType) : INHERITED(rt, ioType) { }
GrRenderTarget* get() const {
GrSurface* surface = static_cast<GrSurface*>(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.

View File

@ -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;

View File

@ -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.

View File

@ -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<GrRenderTarget> 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:

View File

@ -356,11 +356,12 @@ GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context)
desc.fHeight = fCache.cubeDimension() * fCache.cubeDimension();
desc.fConfig = kRGBA_8888_GrPixelConfig;
SkAutoTUnref<GrTexture> textureCube(
static_cast<GrTexture*>(context->findAndRefCachedResource(
GrTexturePriv::ComputeKey(context->getGpu(), NULL, desc, cacheID))));
if (!textureCube) {
GrResourceKey rkey = GrTexturePriv::ComputeKey(context->getGpu(), NULL, desc, cacheID);
GrSurface* surface = static_cast<GrSurface*>(context->findAndRefCachedResource(rkey));
SkAutoTUnref<GrTexture> textureCube;
if (surface) {
textureCube.reset(surface->asTexture());
} else {
textureCube.reset(context->createTexture(NULL, desc, cacheID, fCubeData->data(), 0));
}

View File

@ -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<GrTexture*>(resource);
if (resource) {
resource->ref();
return static_cast<GrSurface*>(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<GrTexture*>(resource);
return static_cast<GrSurface*>(resource)->asTexture();
}
if (kExact_ScratchTexMatch == match) {

View File

@ -530,9 +530,7 @@ public:
*
* @return The currently set render target.
*/
GrRenderTarget* getRenderTarget() const {
return static_cast<GrRenderTarget*>(fRenderTarget.getResource());
}
GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
/**
* Sets the render-target used at the next drawing call

View File

@ -169,9 +169,7 @@ public:
*
* @return The currently set render target.
*/
GrRenderTarget* getRenderTarget() const {
return static_cast<GrRenderTarget*>(fRenderTarget.getResource());
}
GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
/// @}

View File

@ -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) {

View File

@ -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<const GrTexture*>(resource)->desc().fFlags &
kRenderTarget_GrSurfaceFlag)) {
!(static_cast<const GrSurface*>(resource)->desc().fFlags & kRenderTarget_GrSurfaceFlag)) {
this->deleteResource(resource->getCacheEntry());
}
}

View File

@ -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;

View File

@ -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

View File

@ -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);
// we assume this is true, TODO: get rid of viewport as a param.
SkASSERT(viewport.fWidth == texture->width());
SkASSERT(viewport.fHeight == texture->height());
this->init(texture->desc(), idDesc, viewport, texID);
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);
}
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);
void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
fRTFBOID = idDesc.fRTFBOID;
fTexFBOID = idDesc.fTexFBOID;
fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID;
fViewport.fLeft = 0;
fViewport.fBottom = 0;
fViewport.fWidth = desc.fWidth;
fViewport.fHeight = desc.fHeight;
// 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;
}
}
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();
}

View File

@ -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;
};

View File

@ -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() {

View File

@ -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;
};

View File

@ -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

View File

@ -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);
}

View File

@ -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"