Add APIs and plumbing for external rendertaret-textures w/ and w/out MSAA.
Review URL: http://codereview.appspot.com/4388049/ git-svn-id: http://skia.googlecode.com/svn/trunk@1102 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
afac88855a
commit
5877ffd5ea
@ -158,6 +158,43 @@ public:
|
|||||||
// Render targets
|
// Render targets
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sets the render target.
|
||||||
|
* @param target the render target to set. (should not be NULL.)
|
||||||
|
*/
|
||||||
|
void setRenderTarget(GrRenderTarget* target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current render target.
|
||||||
|
* @return the currently bound render target. Should never be NULL.
|
||||||
|
*/
|
||||||
|
const GrRenderTarget* getRenderTarget() const;
|
||||||
|
GrRenderTarget* getRenderTarget();
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Platform Surfaces
|
||||||
|
|
||||||
|
// GrContext provides an interface for wrapping externally created textures
|
||||||
|
// and rendertargets in their Gr-equivalents.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps an existing 3D API surface in a GrObject. desc.fFlags determines
|
||||||
|
* the type of object returned. If kIsTexture is set the returned object
|
||||||
|
* will be a GrTexture*. Otherwise, it will be a GrRenderTarget*. If both
|
||||||
|
* are set the render target object is accessible by
|
||||||
|
* GrTexture::asRenderTarget().
|
||||||
|
*
|
||||||
|
* GL: if the object is a texture Gr may change its GL texture parameters
|
||||||
|
* when it is drawn.
|
||||||
|
*
|
||||||
|
* @param desc description of the object to create.
|
||||||
|
* @return either a GrTexture* or GrRenderTarget* depending on desc. NULL
|
||||||
|
* on failure.
|
||||||
|
*/
|
||||||
|
GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED, WILL BE REMOVED SOON. USE createPlatformSurface.
|
||||||
|
*
|
||||||
* Wraps an externally-created rendertarget in a GrRenderTarget.
|
* Wraps an externally-created rendertarget in a GrRenderTarget.
|
||||||
* @param platformRenderTarget 3D API-specific render target identifier
|
* @param platformRenderTarget 3D API-specific render target identifier
|
||||||
* e.g. in GL platforamRenderTarget is an FBO
|
* e.g. in GL platforamRenderTarget is an FBO
|
||||||
@ -172,9 +209,18 @@ public:
|
|||||||
GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
|
GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
|
||||||
int stencilBits,
|
int stencilBits,
|
||||||
bool isMultisampled,
|
bool isMultisampled,
|
||||||
int width, int height);
|
int width, int height) {
|
||||||
|
#if GR_DEBUG
|
||||||
|
GrPrintf("Using deprecated createPlatformRenderTarget API.");
|
||||||
|
#endif
|
||||||
|
return fGpu->createPlatformRenderTarget(platformRenderTarget,
|
||||||
|
stencilBits, isMultisampled,
|
||||||
|
width, height);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED, WILL BE REMOVED SOON. USE createPlatformSurface.
|
||||||
|
*
|
||||||
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
|
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
|
||||||
* viewport state from the underlying 3D API and wraps it in a
|
* viewport state from the underlying 3D API and wraps it in a
|
||||||
* GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
|
* GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
|
||||||
@ -184,22 +230,12 @@ public:
|
|||||||
* @return the newly created GrRenderTarget
|
* @return the newly created GrRenderTarget
|
||||||
*/
|
*/
|
||||||
GrRenderTarget* createRenderTargetFrom3DApiState() {
|
GrRenderTarget* createRenderTargetFrom3DApiState() {
|
||||||
|
#if GR_DEBUG
|
||||||
|
GrPrintf("Using deprecated createRenderTargetFrom3DApiState API.");
|
||||||
|
#endif
|
||||||
return fGpu->createRenderTargetFrom3DApiState();
|
return fGpu->createRenderTargetFrom3DApiState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the render target.
|
|
||||||
* @param target the render target to set. (should not be NULL.)
|
|
||||||
*/
|
|
||||||
void setRenderTarget(GrRenderTarget* target);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current render target.
|
|
||||||
* @return the currently bound render target. Should never be NULL.
|
|
||||||
*/
|
|
||||||
const GrRenderTarget* getRenderTarget() const;
|
|
||||||
GrRenderTarget* getRenderTarget();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Matrix state
|
// Matrix state
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef GrGLTexture_DEFINED
|
#ifndef GrGLTexture_DEFINED
|
||||||
#define GrGLTexture_DEFINED
|
#define GrGLTexture_DEFINED
|
||||||
|
|
||||||
@ -31,10 +30,10 @@ class GrGLTexture;
|
|||||||
class GrGLTexID : public GrRefCnt {
|
class GrGLTexID : public GrRefCnt {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GrGLTexID(GrGLuint texID) : fTexID(texID) {}
|
GrGLTexID(GrGLuint texID, bool ownsID) : fTexID(texID), fOwnsID(ownsID) {}
|
||||||
|
|
||||||
virtual ~GrGLTexID() {
|
virtual ~GrGLTexID() {
|
||||||
if (0 != fTexID) {
|
if (0 != fTexID && fOwnsID) {
|
||||||
GR_GL(DeleteTextures(1, &fTexID));
|
GR_GL(DeleteTextures(1, &fTexID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,27 +43,25 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
GrGLuint fTexID;
|
GrGLuint fTexID;
|
||||||
|
bool fOwnsID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class GrGLRenderTarget : public GrRenderTarget {
|
class GrGLRenderTarget : public GrRenderTarget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~GrGLRenderTarget() { this->release(); }
|
// set fTexFBOID to this value to indicate that it is multisampled but
|
||||||
|
// Gr doesn't know how to resolve it.
|
||||||
|
enum { kUnresolvableFBOID = 0 };
|
||||||
|
|
||||||
bool resolveable() const { return fRTFBOID != fTexFBOID; }
|
|
||||||
bool needsResolve() const { return fNeedsResolve; }
|
|
||||||
void setDirty(bool dirty) { fNeedsResolve = resolveable() && dirty; }
|
|
||||||
|
|
||||||
GrGLuint renderFBOID() const { return fRTFBOID; }
|
|
||||||
GrGLuint textureFBOID() const { return fTexFBOID; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
struct GLRenderTargetIDs {
|
struct GLRenderTargetIDs {
|
||||||
GrGLuint fRTFBOID;
|
GrGLuint fRTFBOID;
|
||||||
GrGLuint fTexFBOID;
|
GrGLuint fTexFBOID;
|
||||||
GrGLuint fStencilRenderbufferID;
|
GrGLuint fStencilRenderbufferID;
|
||||||
GrGLuint fMSColorRenderbufferID;
|
GrGLuint fMSColorRenderbufferID;
|
||||||
bool fOwnIDs;
|
bool fOwnIDs;
|
||||||
|
void reset() { memset(this, 0, sizeof(GLRenderTargetIDs)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
GrGLRenderTarget(GrGpuGL* gpu,
|
GrGLRenderTarget(GrGpuGL* gpu,
|
||||||
@ -75,10 +72,33 @@ protected:
|
|||||||
const GrGLIRect& fViewport,
|
const GrGLIRect& fViewport,
|
||||||
GrGLTexture* texture);
|
GrGLTexture* texture);
|
||||||
|
|
||||||
|
virtual ~GrGLRenderTarget() { this->release(); }
|
||||||
|
|
||||||
void setViewport(const GrGLIRect& rect) { fViewport = rect; }
|
void setViewport(const GrGLIRect& rect) { fViewport = rect; }
|
||||||
const GrGLIRect& getViewport() const { return fViewport; }
|
const GrGLIRect& getViewport() const { return fViewport; }
|
||||||
|
|
||||||
// overloads of GrResource
|
// The following two functions return the same ID when a
|
||||||
|
// texture-rendertarget is multisampled, and different IDs when
|
||||||
|
// it is.
|
||||||
|
// FBO ID used to render into
|
||||||
|
GrGLuint renderFBOID() const { return fRTFBOID; }
|
||||||
|
// FBO ID that has texture ID attached.
|
||||||
|
GrGLuint textureFBOID() const { return fTexFBOID; }
|
||||||
|
|
||||||
|
// override of GrRenderTarget
|
||||||
|
virtual ResolveType getResolveType() const {
|
||||||
|
if (fRTFBOID == fTexFBOID) {
|
||||||
|
// catches FBO 0 and non MSAA case
|
||||||
|
return kAutoResolves_ResolveType;
|
||||||
|
} else if (kUnresolvableFBOID == fTexFBOID) {
|
||||||
|
return kCantResolve_ResolveType;
|
||||||
|
} else {
|
||||||
|
return kCanResolve_ResolveType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// override of GrResource
|
||||||
virtual void onAbandon();
|
virtual void onAbandon();
|
||||||
virtual void onRelease();
|
virtual void onRelease();
|
||||||
|
|
||||||
@ -92,10 +112,6 @@ private:
|
|||||||
// else own them.
|
// else own them.
|
||||||
bool fOwnIDs;
|
bool fOwnIDs;
|
||||||
|
|
||||||
// If there separate Texture and RenderTarget FBO IDs then the rendertarget
|
|
||||||
// must be resolved to the texture FBO before it is used as a texture.
|
|
||||||
bool fNeedsResolve;
|
|
||||||
|
|
||||||
// when we switch to this rendertarget we want to set the viewport to
|
// when we switch to this rendertarget we want to set the viewport to
|
||||||
// only render to to content area (as opposed to the whole allocation) and
|
// only render to 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)
|
// we want the rendering to be at top left (GL has origin in bottom left)
|
||||||
@ -104,12 +120,11 @@ private:
|
|||||||
// non-NULL if this RT was created by Gr with an associated GrGLTexture.
|
// non-NULL if this RT was created by Gr with an associated GrGLTexture.
|
||||||
GrGLTexID* fTexIDObj;
|
GrGLTexID* fTexIDObj;
|
||||||
|
|
||||||
friend class GrGpuGL;
|
|
||||||
friend class GrGLTexture;
|
|
||||||
|
|
||||||
typedef GrRenderTarget INHERITED;
|
typedef GrRenderTarget INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class GrGLTexture : public GrTexture {
|
class GrGLTexture : public GrTexture {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -122,8 +137,31 @@ public:
|
|||||||
GrGLenum fFilter;
|
GrGLenum fFilter;
|
||||||
GrGLenum fWrapS;
|
GrGLenum fWrapS;
|
||||||
GrGLenum fWrapT;
|
GrGLenum fWrapT;
|
||||||
|
void invalidate() { memset(this, 0xff, sizeof(TexParams)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GLTextureDesc {
|
||||||
|
uint32_t fContentWidth;
|
||||||
|
uint32_t fContentHeight;
|
||||||
|
uint32_t fAllocWidth;
|
||||||
|
uint32_t fAllocHeight;
|
||||||
|
GrPixelConfig fFormat;
|
||||||
|
GrGLuint fTextureID;
|
||||||
|
bool fOwnsID;
|
||||||
|
GrGLenum fUploadFormat;
|
||||||
|
GrGLenum fUploadByteCount;
|
||||||
|
GrGLenum fUploadType;
|
||||||
|
GrGLuint fStencilBits;
|
||||||
|
Orientation fOrientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
|
||||||
|
|
||||||
|
GrGLTexture(GrGpuGL* gpu,
|
||||||
|
const GLTextureDesc& textureDesc,
|
||||||
|
const GLRenderTargetIDs& rtIDs,
|
||||||
|
const TexParams& initialTexParams);
|
||||||
|
|
||||||
virtual ~GrGLTexture() { this->release(); }
|
virtual ~GrGLTexture() { this->release(); }
|
||||||
|
|
||||||
// overrides of GrTexture
|
// overrides of GrTexture
|
||||||
@ -176,26 +214,9 @@ public:
|
|||||||
// and it is up to the GrGpuGL derivative to handle y-mirroing.
|
// and it is up to the GrGpuGL derivative to handle y-mirroing.
|
||||||
Orientation orientation() const { return fOrientation; }
|
Orientation orientation() const { return fOrientation; }
|
||||||
|
|
||||||
protected:
|
static const GrGLenum* WrapMode2GLWrap();
|
||||||
|
|
||||||
struct GLTextureDesc {
|
protected:
|
||||||
uint32_t fContentWidth;
|
|
||||||
uint32_t fContentHeight;
|
|
||||||
uint32_t fAllocWidth;
|
|
||||||
uint32_t fAllocHeight;
|
|
||||||
GrPixelConfig fFormat;
|
|
||||||
GrGLuint fTextureID;
|
|
||||||
GrGLenum fUploadFormat;
|
|
||||||
GrGLenum fUploadByteCount;
|
|
||||||
GrGLenum fUploadType;
|
|
||||||
GrGLuint fStencilBits;
|
|
||||||
Orientation fOrientation;
|
|
||||||
};
|
|
||||||
typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
|
|
||||||
GrGLTexture(GrGpuGL* gpu,
|
|
||||||
const GLTextureDesc& textureDesc,
|
|
||||||
const GLRenderTargetIDs& rtIDs,
|
|
||||||
const TexParams& initialTexParams);
|
|
||||||
|
|
||||||
// overrides of GrTexture
|
// overrides of GrTexture
|
||||||
virtual void onAbandon();
|
virtual void onAbandon();
|
||||||
@ -215,10 +236,6 @@ private:
|
|||||||
Orientation fOrientation;
|
Orientation fOrientation;
|
||||||
GrGpuGL* fGpuGL;
|
GrGpuGL* fGpuGL;
|
||||||
|
|
||||||
static const GrGLenum* WrapMode2GLWrap();
|
|
||||||
|
|
||||||
friend class GrGpuGL;
|
|
||||||
|
|
||||||
typedef GrTexture INHERITED;
|
typedef GrTexture INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,12 +192,13 @@ public:
|
|||||||
* @param width width of the render target
|
* @param width width of the render target
|
||||||
* @param height height of the render target
|
* @param height height of the render target
|
||||||
*/
|
*/
|
||||||
virtual GrRenderTarget* createPlatformRenderTarget(
|
GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
|
||||||
intptr_t platformRenderTarget,
|
|
||||||
int stencilBits,
|
int stencilBits,
|
||||||
bool isMultisampled,
|
bool isMultisampled,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
|
GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
|
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
|
||||||
* viewport state from the underlying 3D API and wraps it in a
|
* viewport state from the underlying 3D API and wraps it in a
|
||||||
@ -485,6 +486,7 @@ protected:
|
|||||||
virtual GrTexture* createTextureHelper(const TextureDesc& desc,
|
virtual GrTexture* createTextureHelper(const TextureDesc& desc,
|
||||||
const void* srcData,
|
const void* srcData,
|
||||||
size_t rowBytes) = 0;
|
size_t rowBytes) = 0;
|
||||||
|
virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
|
||||||
virtual GrRenderTarget* createPlatformRenderTargetHelper(
|
virtual GrRenderTarget* createPlatformRenderTargetHelper(
|
||||||
intptr_t platformRenderTarget,
|
intptr_t platformRenderTarget,
|
||||||
int stencilBits,
|
int stencilBits,
|
||||||
@ -514,8 +516,9 @@ protected:
|
|||||||
virtual void forceRenderTargetFlushHelper() = 0;
|
virtual void forceRenderTargetFlushHelper() = 0;
|
||||||
|
|
||||||
// overridden by API-specific derived class to perform the read pixels.
|
// overridden by API-specific derived class to perform the read pixels.
|
||||||
virtual bool readPixelsHelper(int left, int top, int width, int height,
|
virtual bool onReadPixels(GrRenderTarget* target,
|
||||||
GrPixelConfig, void* buffer) = 0;
|
int left, int top, int width, int height,
|
||||||
|
GrPixelConfig, void* buffer) = 0;
|
||||||
|
|
||||||
// called to program the vertex data, indexCount will be 0 if drawing non-
|
// called to program the vertex data, indexCount will be 0 if drawing non-
|
||||||
// indexed geometry. The subclass may adjust the startVertex and/or
|
// indexed geometry. The subclass may adjust the startVertex and/or
|
||||||
|
@ -58,6 +58,29 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isMultisampled() { return fIsMultisampled; }
|
bool isMultisampled() { return fIsMultisampled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call to indicate the multisample contents were modified such that the
|
||||||
|
* render target needs to be resolved before it can be used as texture. Gr
|
||||||
|
* tracks this for its own drawing and thus this only needs to be called
|
||||||
|
* when the render target has been modified outside of Gr. Only meaningful
|
||||||
|
* for Gr-created RT/Textures and Platform RT/Textures created with the
|
||||||
|
* kGrCanResolve flag.
|
||||||
|
*/
|
||||||
|
void flagAsNeedingResolve() {
|
||||||
|
fNeedsResolve = kCanResolve_ResolveType == getResolveType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call to indicate that GrRenderTarget was externally resolved. This may
|
||||||
|
* allow Gr to skip a redundant resolve step.
|
||||||
|
*/
|
||||||
|
void flagAsResolved() { fNeedsResolve = false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the GrRenderTarget requires MSAA resolving
|
||||||
|
*/
|
||||||
|
bool needsResolve() { return fNeedsResolve; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a rectangle of pixels from the render target.
|
* Reads a rectangle of pixels from the render target.
|
||||||
* @param left left edge of the rectangle to read (inclusive)
|
* @param left left edge of the rectangle to read (inclusive)
|
||||||
@ -73,6 +96,16 @@ public:
|
|||||||
bool readPixels(int left, int top, int width, int height,
|
bool readPixels(int left, int top, int width, int height,
|
||||||
GrPixelConfig config, void* buffer);
|
GrPixelConfig config, void* buffer);
|
||||||
|
|
||||||
|
// a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
|
||||||
|
// 0 in GL), or be unresolvable because the client didn't give us the
|
||||||
|
// resolve destination.
|
||||||
|
enum ResolveType {
|
||||||
|
kCanResolve_ResolveType,
|
||||||
|
kAutoResolves_ResolveType,
|
||||||
|
kCantResolve_ResolveType,
|
||||||
|
};
|
||||||
|
virtual ResolveType getResolveType() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GrRenderTarget(GrGpu* gpu,
|
GrRenderTarget(GrGpu* gpu,
|
||||||
GrTexture* texture,
|
GrTexture* texture,
|
||||||
@ -86,6 +119,7 @@ protected:
|
|||||||
, fHeight(height)
|
, fHeight(height)
|
||||||
, fStencilBits(stencilBits)
|
, fStencilBits(stencilBits)
|
||||||
, fIsMultisampled(isMultisampled)
|
, fIsMultisampled(isMultisampled)
|
||||||
|
, fNeedsResolve(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
friend class GrTexture;
|
friend class GrTexture;
|
||||||
@ -104,6 +138,7 @@ protected:
|
|||||||
int fHeight;
|
int fHeight;
|
||||||
int fStencilBits;
|
int fStencilBits;
|
||||||
bool fIsMultisampled;
|
bool fIsMultisampled;
|
||||||
|
bool fNeedsResolve;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// GrGpu keeps a cached clip in the render target to avoid redundantly
|
// GrGpu keeps a cached clip in the render target to avoid redundantly
|
||||||
|
@ -154,6 +154,50 @@ template <typename Dst, typename Src> Dst GrTCast(Src src) {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// saves value of T* in and restores in destructor
|
||||||
|
// e.g.:
|
||||||
|
// {
|
||||||
|
// GrAutoTPtrValueRestore<int*> autoCountRestore;
|
||||||
|
// if (useExtra) {
|
||||||
|
// autoCountRestore.save(&fCount);
|
||||||
|
// fCount += fExtraCount;
|
||||||
|
// }
|
||||||
|
// ...
|
||||||
|
// } // fCount is restored
|
||||||
|
//
|
||||||
|
template <typename T>
|
||||||
|
class GrAutoTPtrValueRestore {
|
||||||
|
public:
|
||||||
|
GrAutoTPtrValueRestore() : fPtr(NULL), fVal() {}
|
||||||
|
|
||||||
|
GrAutoTPtrValueRestore(T* ptr) {
|
||||||
|
fPtr = ptr;
|
||||||
|
if (NULL != ptr) {
|
||||||
|
fVal = *ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~GrAutoTPtrValueRestore() {
|
||||||
|
if (NULL != fPtr) {
|
||||||
|
*fPtr = fVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// restores previously saved value (if any) and saves value for passed T*
|
||||||
|
void save(T* ptr) {
|
||||||
|
if (NULL != fPtr) {
|
||||||
|
*fPtr = fVal;
|
||||||
|
}
|
||||||
|
fPtr = ptr;
|
||||||
|
fVal = *ptr;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T* fPtr;
|
||||||
|
T fVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type used to describe format of vertices in arrays
|
* Type used to describe format of vertices in arrays
|
||||||
* Values are defined in GrDrawTarget
|
* Values are defined in GrDrawTarget
|
||||||
@ -388,6 +432,139 @@ enum GrConvexHint {
|
|||||||
// concave
|
// concave
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum GrPlatformSurfaceType {
|
||||||
|
/**
|
||||||
|
* Specifies that the object being created is a render target.
|
||||||
|
*/
|
||||||
|
kRenderTarget_GrPlatformSurfaceType,
|
||||||
|
/**
|
||||||
|
* Specifies that the object being created is a texture.
|
||||||
|
*/
|
||||||
|
kTexture_GrPlatformSurfaceType,
|
||||||
|
/**
|
||||||
|
* Specifies that the object being created is a texture and a render
|
||||||
|
* target.
|
||||||
|
*/
|
||||||
|
kTextureRenderTarget_GrPlatformSurfaceType,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GrPlatformRenderTargetFlags {
|
||||||
|
kNone_GrPlatformRenderTargetFlagBit = 0x0,
|
||||||
|
/**
|
||||||
|
* Specifies that the object being created is multisampled.
|
||||||
|
*/
|
||||||
|
kIsMultisampled_GrPlatformRenderTargetFlagBit = 0x1,
|
||||||
|
/**
|
||||||
|
* Gives permission to Gr to perform the downsample-resolve of a
|
||||||
|
* multisampled render target. If this is not set then read pixel
|
||||||
|
* operations may fail. If the object is both a texture and render target
|
||||||
|
* then this *must* be set. Otherwise, if the client wants do its own
|
||||||
|
* resolves it must create separate GrRenderTarget and GrTexture objects
|
||||||
|
* and insert appropriate flushes and resolves betweeen data hazards.
|
||||||
|
* GrRenderTarget has a flagForResolve()
|
||||||
|
*/
|
||||||
|
kGrCanResolve_GrPlatformRenderTargetFlagBit = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline GrPlatformRenderTargetFlags operator | (GrPlatformRenderTargetFlags a, GrPlatformRenderTargetFlags b) {
|
||||||
|
return (GrPlatformRenderTargetFlags) (+a | +b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GrPlatformRenderTargetFlags operator & (GrPlatformRenderTargetFlags a, GrPlatformRenderTargetFlags b) {
|
||||||
|
return (GrPlatformRenderTargetFlags) (+a & +b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// opaque type for 3D API object handles
|
||||||
|
typedef intptr_t GrPlatform3DObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of platform surface to create. See below for GL example.
|
||||||
|
*/
|
||||||
|
struct GrPlatformSurfaceDesc {
|
||||||
|
GrPlatformSurfaceType fSurfaceType; // type of surface to create
|
||||||
|
/**
|
||||||
|
* Flags for kRenderTarget and kTextureRenderTarget surface types
|
||||||
|
*/
|
||||||
|
GrPlatformRenderTargetFlags fRenderTargetFlags;
|
||||||
|
|
||||||
|
int fWidth; // width in pixels
|
||||||
|
int fHeight; // height in pixels
|
||||||
|
GrPixelConfig fConfig; // color format
|
||||||
|
/**
|
||||||
|
* Number of per sample stencil buffer. Only relevant if kIsRenderTarget is
|
||||||
|
* set in fFlags.
|
||||||
|
*/
|
||||||
|
int fStencilBits;
|
||||||
|
/**
|
||||||
|
* Texture object in 3D API. Only relevant if fSurfaceType is kTexture or
|
||||||
|
* kTextureRenderTarget.
|
||||||
|
* GL: this is a texture object (glGenTextures)
|
||||||
|
*/
|
||||||
|
GrPlatform3DObject fPlatformTexture;
|
||||||
|
/**
|
||||||
|
* Render target object in 3D API. Only relevant if fSurfaceType is
|
||||||
|
* kRenderTarget or kTextureRenderTarget
|
||||||
|
* GL: this is a FBO object (glGenFramebuffers)
|
||||||
|
*/
|
||||||
|
GrPlatform3DObject fPlatformRenderTarget;
|
||||||
|
/**
|
||||||
|
* 3D API object used as destination of resolve. Only relevant if
|
||||||
|
* fSurfaceType is kRenderTarget or kTextureRenderTarget and
|
||||||
|
* kGrCanResolve is set in fRenderTargetFlags.
|
||||||
|
* fFlags.
|
||||||
|
* GL: this is a FBO object (glGenFramebuffers)
|
||||||
|
*/
|
||||||
|
GrPlatform3DObject fPlatformResolveDestination;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(GrPlatformSurfaceDesc)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example of how to wrap render-to-texture-with-MSAA GL objects with a GrPlatformSurace
|
||||||
|
*
|
||||||
|
* GLint colorBufferID;
|
||||||
|
* glGenRenderbuffers(1, &colorID);
|
||||||
|
* glBindRenderbuffer(GL_RENDERBUFFER, colorBufferID);
|
||||||
|
* glRenderbufferStorageMultisample(GL_RENDERBUFFER, S, GL_RGBA, W, H);
|
||||||
|
*
|
||||||
|
* GLint stencilBufferID;
|
||||||
|
* glGenRenderBuffers(1, &stencilBufferID);
|
||||||
|
* glBindRenderbuffer(GL_RENDERBUFFER, stencilBufferID);
|
||||||
|
* glRenderbufferStorageMultisample(GL_RENDERBUFFER, S, GL_STENCIL_INDEX8, W, H);
|
||||||
|
*
|
||||||
|
* GLint drawFBOID;
|
||||||
|
* glGenFramebuffers(1, &drawFBOID);
|
||||||
|
* glBindFramebuffer(GL_FRAMEBUFFER, drawFBOID);
|
||||||
|
* glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBufferID);
|
||||||
|
* glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilBufferID);
|
||||||
|
*
|
||||||
|
* GLint textureID;
|
||||||
|
* glGenTextures(1, &textureID);
|
||||||
|
* glBindTexture(GL_TEXTURE_2D, textureID);
|
||||||
|
* glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, H, ...);
|
||||||
|
*
|
||||||
|
* GLint readFBOID;
|
||||||
|
* glGenFramebuffers(1, &readFBOID);
|
||||||
|
* glBindFramebuffer(GL_FRAMEBUFFER, readFBOID);
|
||||||
|
* glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureID, 0);
|
||||||
|
*
|
||||||
|
* GrPlatformSurfaceDesc renderTargetTextureDesc;
|
||||||
|
* renderTargetTextureDesc.fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType;
|
||||||
|
* renderTargetTextureDesc.fRenderTargetFlags = (kIsMultisampled_GrPlatformRenderTargetFlagBit | kGrCanResolve_GrPlatformRenderTargetFlagBit);
|
||||||
|
* renderTargetTextureDesc.fWidth = W;
|
||||||
|
* renderTargetTextureDesc.fHeight = H;
|
||||||
|
* renderTargetTextureDesc.fConfig = kRGBA_8888_GrPixelConfig
|
||||||
|
* renderTargetTextureDesc.fStencilBits = 8;
|
||||||
|
* renderTargetTextureDesc.fPlatformTexture = textureID;
|
||||||
|
* renderTargetTextureDesc.fPlatformRenderTarget = drawFBOID;
|
||||||
|
* renderTargetTextureDesc.fPlatformResolveDestination = readFBOID;
|
||||||
|
*
|
||||||
|
* GrTexture* texture = static_cast<GrTexture*>(grContext->createPlatrformSurface(renderTargetTextureDesc));
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// this is included only to make it easy to use this debugging facility
|
// this is included only to make it easy to use this debugging facility
|
||||||
|
@ -267,16 +267,26 @@ int GrContext::getMaxTextureDimension() {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
GrRenderTarget* GrContext::createPlatformRenderTarget(
|
GrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
|
||||||
intptr_t platformRenderTarget,
|
// validate flags here so that GrGpu subclasses don't have to check
|
||||||
int stencilBits,
|
if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType &&
|
||||||
bool isMultisampled,
|
0 != desc.fRenderTargetFlags) {
|
||||||
int width, int height) {
|
return NULL;
|
||||||
return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits,
|
}
|
||||||
isMultisampled,
|
if (!(kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) &&
|
||||||
width, height);
|
(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType &&
|
||||||
|
(kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) &&
|
||||||
|
!(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return fGpu->createPlatformSurface(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
|
bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
if (!fGpu->supports8BitPalette()) {
|
if (!fGpu->supports8BitPalette()) {
|
||||||
|
@ -108,7 +108,8 @@ GrGLTexture::GrGLTexture(GrGpuGL* gpu,
|
|||||||
textureDesc.fFormat) {
|
textureDesc.fFormat) {
|
||||||
|
|
||||||
fTexParams = initialTexParams;
|
fTexParams = initialTexParams;
|
||||||
fTexIDObj = new GrGLTexID(textureDesc.fTextureID);
|
fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
|
||||||
|
textureDesc.fOwnsID);
|
||||||
fUploadFormat = textureDesc.fUploadFormat;
|
fUploadFormat = textureDesc.fUploadFormat;
|
||||||
fUploadByteCount = textureDesc.fUploadByteCount;
|
fUploadByteCount = textureDesc.fUploadByteCount;
|
||||||
fUploadType = textureDesc.fUploadType;
|
fUploadType = textureDesc.fUploadType;
|
||||||
|
@ -158,6 +158,11 @@ GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {
|
|||||||
return this->createRenderTargetFrom3DApiStateHelper();
|
return this->createRenderTargetFrom3DApiStateHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrResource* GrGpu::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
|
||||||
|
this->handleDirtyContext();
|
||||||
|
return this->onCreatePlatformSurface(desc);
|
||||||
|
}
|
||||||
|
|
||||||
GrVertexBuffer* GrGpu::createVertexBuffer(uint32_t size, bool dynamic) {
|
GrVertexBuffer* GrGpu::createVertexBuffer(uint32_t size, bool dynamic) {
|
||||||
this->handleDirtyContext();
|
this->handleDirtyContext();
|
||||||
return this->createVertexBufferHelper(size, dynamic);
|
return this->createVertexBufferHelper(size, dynamic);
|
||||||
@ -183,12 +188,7 @@ bool GrGpu::readPixels(GrRenderTarget* target,
|
|||||||
GrPixelConfig config, void* buffer) {
|
GrPixelConfig config, void* buffer) {
|
||||||
|
|
||||||
this->handleDirtyContext();
|
this->handleDirtyContext();
|
||||||
GrRenderTarget* prevTarget = fCurrDrawState.fRenderTarget;
|
return this->onReadPixels(target, left, top, width, height, config, buffer);
|
||||||
if (NULL != target) {
|
|
||||||
fCurrDrawState.fRenderTarget = target;
|
|
||||||
}
|
|
||||||
return this->readPixelsHelper(left, top, width, height, config, buffer);
|
|
||||||
fCurrDrawState.fRenderTarget = prevTarget;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -533,6 +533,73 @@ void GrGpuGL::resetContext() {
|
|||||||
fHWDrawState.fRenderTarget = NULL;
|
fHWDrawState.fRenderTarget = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) {
|
||||||
|
|
||||||
|
bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType ||
|
||||||
|
kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType;
|
||||||
|
bool isRenderTarget = kRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType ||
|
||||||
|
kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType;
|
||||||
|
|
||||||
|
GrGLRenderTarget::GLRenderTargetIDs rtIDs;
|
||||||
|
if (isRenderTarget) {
|
||||||
|
rtIDs.fRTFBOID = desc.fPlatformRenderTarget;
|
||||||
|
if (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) {
|
||||||
|
if (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) {
|
||||||
|
rtIDs.fTexFBOID = desc.fPlatformResolveDestination;
|
||||||
|
} else {
|
||||||
|
GrAssert(!isTexture); // this should have been filtered by GrContext
|
||||||
|
rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rtIDs.fTexFBOID = desc.fPlatformRenderTarget;
|
||||||
|
}
|
||||||
|
// we don't know what the RB ids are without glGets and we don't care
|
||||||
|
// since we aren't responsible for deleting them.
|
||||||
|
rtIDs.fStencilRenderbufferID = 0;
|
||||||
|
rtIDs.fMSColorRenderbufferID = 0;
|
||||||
|
|
||||||
|
rtIDs.fOwnIDs = false;
|
||||||
|
} else {
|
||||||
|
rtIDs.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTexture) {
|
||||||
|
GrGLTexture::GLTextureDesc texDesc;
|
||||||
|
GrGLenum dontCare;
|
||||||
|
if (!canBeTexture(desc.fConfig, &dontCare,
|
||||||
|
&texDesc.fUploadFormat,
|
||||||
|
&texDesc.fUploadType)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrGLTexture::TexParams params;
|
||||||
|
|
||||||
|
texDesc.fAllocWidth = texDesc.fContentWidth = desc.fWidth;
|
||||||
|
texDesc.fAllocHeight = texDesc.fContentHeight = desc.fHeight;
|
||||||
|
|
||||||
|
texDesc.fFormat = texDesc.fFormat;
|
||||||
|
texDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
|
||||||
|
texDesc.fStencilBits = desc.fStencilBits;
|
||||||
|
texDesc.fTextureID = desc.fPlatformTexture;
|
||||||
|
texDesc.fUploadByteCount = GrBytesPerPixel(desc.fConfig);
|
||||||
|
texDesc.fOwnsID = false;
|
||||||
|
|
||||||
|
params.invalidate(); // rather than do glGets.
|
||||||
|
|
||||||
|
return new GrGLTexture(this, texDesc, rtIDs, params);
|
||||||
|
} else {
|
||||||
|
GrGLIRect viewport;
|
||||||
|
viewport.fLeft = 0;
|
||||||
|
viewport.fBottom = 0;
|
||||||
|
viewport.fWidth = desc.fWidth;
|
||||||
|
viewport.fHeight = desc.fHeight;
|
||||||
|
|
||||||
|
return new GrGLRenderTarget(this, rtIDs, NULL, desc.fStencilBits,
|
||||||
|
kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags,
|
||||||
|
viewport, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper(
|
GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper(
|
||||||
intptr_t platformRenderTarget,
|
intptr_t platformRenderTarget,
|
||||||
int stencilBits,
|
int stencilBits,
|
||||||
@ -655,6 +722,7 @@ GrTexture* GrGpuGL::createTextureHelper(const TextureDesc& desc,
|
|||||||
glDesc.fAllocHeight = desc.fHeight;
|
glDesc.fAllocHeight = desc.fHeight;
|
||||||
glDesc.fStencilBits = 0;
|
glDesc.fStencilBits = 0;
|
||||||
glDesc.fFormat = desc.fFormat;
|
glDesc.fFormat = desc.fFormat;
|
||||||
|
glDesc.fOwnsID = true;
|
||||||
|
|
||||||
bool renderTarget = 0 != (desc.fFlags & kRenderTarget_TextureFlag);
|
bool renderTarget = 0 != (desc.fFlags & kRenderTarget_TextureFlag);
|
||||||
if (!canBeTexture(desc.fFormat,
|
if (!canBeTexture(desc.fFormat,
|
||||||
@ -1154,21 +1222,35 @@ void GrGpuGL::forceRenderTargetFlushHelper() {
|
|||||||
flushRenderTarget();
|
flushRenderTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrGpuGL::readPixelsHelper(int left, int top, int width, int height,
|
bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
||||||
GrPixelConfig config, void* buffer) {
|
int left, int top, int width, int height,
|
||||||
|
GrPixelConfig config, void* buffer) {
|
||||||
GrGLenum internalFormat; // we don't use this for glReadPixels
|
GrGLenum internalFormat; // we don't use this for glReadPixels
|
||||||
GrGLenum format;
|
GrGLenum format;
|
||||||
GrGLenum type;
|
GrGLenum type;
|
||||||
if (!this->canBeTexture(config, &internalFormat, &format, &type)) {
|
if (!this->canBeTexture(config, &internalFormat, &format, &type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
|
||||||
if (NULL == fCurrDrawState.fRenderTarget) {
|
GrAutoTPtrValueRestore<GrRenderTarget*> autoTargetRestore;
|
||||||
return false;
|
switch (tgt->getResolveType()) {
|
||||||
|
case GrGLRenderTarget::kCantResolve_ResolveType:
|
||||||
|
return false;
|
||||||
|
case GrGLRenderTarget::kAutoResolves_ResolveType:
|
||||||
|
autoTargetRestore.save(&fCurrDrawState.fRenderTarget);
|
||||||
|
fCurrDrawState.fRenderTarget = target;
|
||||||
|
flushRenderTarget();
|
||||||
|
break;
|
||||||
|
case GrGLRenderTarget::kCanResolve_ResolveType:
|
||||||
|
resolveRenderTarget(tgt);
|
||||||
|
// we don't track the state of the READ FBO ID.
|
||||||
|
GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, tgt->textureFBOID()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GrCrash("Unknown resolve type");
|
||||||
}
|
}
|
||||||
flushRenderTarget();
|
|
||||||
|
|
||||||
const GrGLIRect& glvp = ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport();
|
const GrGLIRect& glvp = tgt->getViewport();
|
||||||
|
|
||||||
// the read rect is viewport-relative
|
// the read rect is viewport-relative
|
||||||
GrGLIRect readRect;
|
GrGLIRect readRect;
|
||||||
@ -1208,7 +1290,7 @@ void GrGpuGL::flushRenderTarget() {
|
|||||||
#if GR_COLLECT_STATS
|
#if GR_COLLECT_STATS
|
||||||
++fStats.fRenderTargetChngCnt;
|
++fStats.fRenderTargetChngCnt;
|
||||||
#endif
|
#endif
|
||||||
rt->setDirty(true);
|
rt->flagAsNeedingResolve();
|
||||||
#if GR_DEBUG
|
#if GR_DEBUG
|
||||||
GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||||
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
|
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
|
||||||
@ -1316,10 +1398,9 @@ void GrGpuGL::drawNonIndexedHelper(GrPrimitiveType type,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) {
|
void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) {
|
||||||
GrGLRenderTarget* rt = (GrGLRenderTarget*) texture->asRenderTarget();
|
|
||||||
|
|
||||||
if (NULL != rt && rt->needsResolve()) {
|
if (rt->needsResolve()) {
|
||||||
GrAssert(kNone_MSFBO != fMSFBOType);
|
GrAssert(kNone_MSFBO != fMSFBOType);
|
||||||
GrAssert(rt->textureFBOID() != rt->renderFBOID());
|
GrAssert(rt->textureFBOID() != rt->renderFBOID());
|
||||||
GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
|
GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
|
||||||
@ -1329,32 +1410,32 @@ void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) {
|
|||||||
#if GR_COLLECT_STATS
|
#if GR_COLLECT_STATS
|
||||||
++fStats.fRenderTargetChngCnt;
|
++fStats.fRenderTargetChngCnt;
|
||||||
#endif
|
#endif
|
||||||
// make sure we go through set render target
|
// make sure we go through flushRenderTarget() since we've modified
|
||||||
|
// the bound DRAW FBO ID.
|
||||||
fHWDrawState.fRenderTarget = NULL;
|
fHWDrawState.fRenderTarget = NULL;
|
||||||
|
const GrGLIRect& vp = rt->getViewport();
|
||||||
|
|
||||||
GrGLint left = 0;
|
|
||||||
GrGLint right = texture->width();
|
|
||||||
// we will have rendered to the top of the FBO.
|
|
||||||
GrGLint top = texture->allocHeight();
|
|
||||||
GrGLint bottom = texture->allocHeight() - texture->height();
|
|
||||||
if (kAppleES_MSFBO == fMSFBOType) {
|
if (kAppleES_MSFBO == fMSFBOType) {
|
||||||
// Apple's extension uses the scissor as the blit bounds.
|
// Apple's extension uses the scissor as the blit bounds.
|
||||||
GR_GL(Enable(GR_GL_SCISSOR_TEST));
|
GR_GL(Enable(GR_GL_SCISSOR_TEST));
|
||||||
GR_GL(Scissor(left, bottom, right-left, top-bottom));
|
GR_GL(Scissor(vp.fLeft, vp.fBottom,
|
||||||
|
vp.fWidth, vp.fHeight));
|
||||||
GR_GL(ResolveMultisampleFramebuffer());
|
GR_GL(ResolveMultisampleFramebuffer());
|
||||||
fHWBounds.fScissorRect.invalidate();
|
fHWBounds.fScissorRect.invalidate();
|
||||||
fHWBounds.fScissorEnabled = true;
|
fHWBounds.fScissorEnabled = true;
|
||||||
} else {
|
} else {
|
||||||
if (kDesktopARB_MSFBO != fMSFBOType) {
|
if (kDesktopARB_MSFBO != fMSFBOType) {
|
||||||
// these respect the scissor during the blit, so disable it.
|
// this respects the scissor during the blit, so disable it.
|
||||||
GrAssert(kDesktopEXT_MSFBO == fMSFBOType);
|
GrAssert(kDesktopEXT_MSFBO == fMSFBOType);
|
||||||
flushScissor(NULL);
|
flushScissor(NULL);
|
||||||
}
|
}
|
||||||
GR_GL(BlitFramebuffer(left, bottom, right, top,
|
int right = vp.fLeft + vp.fWidth;
|
||||||
left, bottom, right, top,
|
int top = vp.fBottom + vp.fHeight;
|
||||||
GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
|
GR_GL(BlitFramebuffer(vp.fLeft, vp.fBottom, right, top,
|
||||||
|
vp.fLeft, vp.fBottom, right, top,
|
||||||
|
GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
|
||||||
}
|
}
|
||||||
rt->setDirty(false);
|
rt->flagAsResolved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1631,7 +1712,11 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
|||||||
// texture and now we're texuring from the rt it will still be
|
// texture and now we're texuring from the rt it will still be
|
||||||
// the last bound texture, but it needs resolving. So keep this
|
// the last bound texture, but it needs resolving. So keep this
|
||||||
// out of the "last != next" check.
|
// out of the "last != next" check.
|
||||||
resolveTextureRenderTarget(nextTexture);
|
GrGLRenderTarget* texRT =
|
||||||
|
static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
|
||||||
|
if (NULL != texRT) {
|
||||||
|
resolveRenderTarget(texRT);
|
||||||
|
}
|
||||||
|
|
||||||
if (fHWDrawState.fTextures[s] != nextTexture) {
|
if (fHWDrawState.fTextures[s] != nextTexture) {
|
||||||
setTextureUnit(s);
|
setTextureUnit(s);
|
||||||
|
@ -79,21 +79,21 @@ protected:
|
|||||||
bool dynamic);
|
bool dynamic);
|
||||||
virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size,
|
virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size,
|
||||||
bool dynamic);
|
bool dynamic);
|
||||||
|
virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc);
|
||||||
virtual GrRenderTarget* createPlatformRenderTargetHelper(
|
virtual GrRenderTarget* createPlatformRenderTargetHelper(
|
||||||
intptr_t platformRenderTarget,
|
intptr_t platformRenderTarget,
|
||||||
int stencilBits,
|
int stencilBits,
|
||||||
bool isMultisampled,
|
bool isMultisampled,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper();
|
virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper();
|
||||||
|
|
||||||
virtual void eraseColorHelper(GrColor color);
|
virtual void eraseColorHelper(GrColor color);
|
||||||
|
|
||||||
virtual void forceRenderTargetFlushHelper();
|
virtual void forceRenderTargetFlushHelper();
|
||||||
|
|
||||||
virtual bool readPixelsHelper(int left, int top, int width, int height,
|
virtual bool onReadPixels(GrRenderTarget* target,
|
||||||
GrPixelConfig, void* buffer);
|
int left, int top, int width, int height,
|
||||||
|
GrPixelConfig, void* buffer);
|
||||||
|
|
||||||
virtual void drawIndexedHelper(GrPrimitiveType type,
|
virtual void drawIndexedHelper(GrPrimitiveType type,
|
||||||
uint32_t startVertex,
|
uint32_t startVertex,
|
||||||
@ -158,7 +158,7 @@ private:
|
|||||||
void flushAAState(GrPrimitiveType type);
|
void flushAAState(GrPrimitiveType type);
|
||||||
void flushBlend(GrPrimitiveType type);
|
void flushBlend(GrPrimitiveType type);
|
||||||
|
|
||||||
void resolveTextureRenderTarget(GrGLTexture* texture);
|
void resolveRenderTarget(GrGLRenderTarget* texture);
|
||||||
|
|
||||||
bool canBeTexture(GrPixelConfig config,
|
bool canBeTexture(GrPixelConfig config,
|
||||||
GrGLenum* internalFormat,
|
GrGLenum* internalFormat,
|
||||||
|
@ -35,6 +35,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
SkGpuDeviceFactory(GrContext*, GrRenderTarget* rootRenderTarget);
|
SkGpuDeviceFactory(GrContext*, GrRenderTarget* rootRenderTarget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the root layer is both a GrRenderTarget and a GrTexture it
|
||||||
|
* is handy to have the factory hang on to a ref to the GrTexture object.
|
||||||
|
* This is because the GrTexture has a ref to the GrRenderTarget but not
|
||||||
|
* vice-versa.
|
||||||
|
*/
|
||||||
|
SkGpuDeviceFactory(GrContext*, GrTexture* rootRenderTargetTexture);
|
||||||
|
|
||||||
virtual ~SkGpuDeviceFactory();
|
virtual ~SkGpuDeviceFactory();
|
||||||
|
|
||||||
virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
|
virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
|
||||||
@ -43,6 +51,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
GrContext* fContext;
|
GrContext* fContext;
|
||||||
GrRenderTarget* fRootRenderTarget;
|
GrRenderTarget* fRootRenderTarget;
|
||||||
|
GrTexture* fRootTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1453,12 +1453,27 @@ SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
|
|||||||
rootRenderTarget->ref();
|
rootRenderTarget->ref();
|
||||||
}
|
}
|
||||||
context->ref();
|
context->ref();
|
||||||
|
fRootTexture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context, GrTexture* rootRenderTargetTexture) {
|
||||||
|
GrAssert(NULL != context);
|
||||||
|
GrAssert(NULL != rootRenderTargetTexture);
|
||||||
|
GrAssert(NULL != rootRenderTargetTexture->asRenderTarget());
|
||||||
|
|
||||||
|
fRootTexture = rootRenderTargetTexture;
|
||||||
|
rootRenderTargetTexture->ref();
|
||||||
|
|
||||||
|
fRootRenderTarget = rootRenderTargetTexture->asRenderTarget();
|
||||||
|
fRootRenderTarget->ref();
|
||||||
|
|
||||||
|
context->ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkGpuDeviceFactory::~SkGpuDeviceFactory() {
|
SkGpuDeviceFactory::~SkGpuDeviceFactory() {
|
||||||
fContext->unref();
|
fContext->unref();
|
||||||
fRootRenderTarget->unref();
|
fRootRenderTarget->unref();
|
||||||
|
GrSafeUnref(fRootTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
|
SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
|
||||||
|
Loading…
Reference in New Issue
Block a user