Index: src/gpu/gl/GrGLRenderTarget.h |
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h |
index 7e7349257f054ac44e8a32cd5626c1cf94e1041c..cb7e761054c0ee1f1b322557da9a470497818b99 100644 |
--- a/src/gpu/gl/GrGLRenderTarget.h |
+++ b/src/gpu/gl/GrGLRenderTarget.h |
@@ -15,17 +15,59 @@ |
class GrGLGpu; |
-class GrGLRenderTarget : public GrRenderTarget { |
+class GrGLFBO : public SkRefCnt { |
public: |
- // set fTexFBOID to this value to indicate that it is multisampled but |
- // Gr doesn't know how to resolve it. |
- enum { kUnresolvableFBOID = 0 }; |
+ SK_DECLARE_INST_COUNT(GrGLFBO); |
+ |
+ GrGLFBO() : fGenID(SK_InvalidGenID) {} |
+ |
+ GrGLFBO(GrGLint id) : fID(id), fGenID(NextGenID()) {} |
+ |
+ GrGLFBO(const GrGLInterface* gl) : fGenID(NextGenID()) { |
+ GR_GL_CALL(gl, GenFramebuffers(1, &fID)); |
+ } |
+ |
+ ~GrGLFBO() SK_OVERRIDE { SkASSERT(!this->isValid()); } |
+ |
+ void generateIfInvalid(const GrGLInterface* gl) { |
+ if (!this->isValid()) { |
+ GR_GL_CALL(gl, GenFramebuffers(1, &fID)); |
+ fGenID = NextGenID(); |
+ } |
+ } |
+ |
+ bool isValid() const { return SK_InvalidGenID != fGenID; } |
+ |
+ uint32_t genID() const { return fGenID; } |
+ |
+ GrGLint fboID() const { SkASSERT(this->isValid()); return fID; } |
+ |
+ bool isDefaultFramebuffer() const { SkASSERT(this->isValid()); return 0 == fID; } |
+ |
+ void abandon(GrGLGpu* gpu); |
+ void deleteIfValid(GrGLGpu* gpu); |
+ |
+private: |
+ static uint32_t NextGenID() { |
+ static int32_t gGenID = SK_InvalidGenID + 1; |
+ return static_cast<uint32_t>(sk_atomic_inc(&gGenID)); |
+ } |
+ |
+ GrGLuint fID; |
+ uint32_t fGenID; |
+ |
+ typedef SkRefCnt INHERITED; |
+}; |
+ |
+ |
+class GrGLRenderTarget : public GrRenderTarget { |
+public: |
struct IDDesc { |
- GrGLuint fRTFBOID; |
- GrGLuint fTexFBOID; |
+ SkAutoTUnref<GrGLFBO> fRenderFBO; |
+ SkAutoTUnref<GrGLFBO> fTextureFBO; |
GrGLuint fMSColorRenderbufferID; |
- GrGpuResource::LifeCycle fLifeCycle; |
+ GrGpuResource::LifeCycle fLifeCycle; // Make this an ownership bool? |
}; |
GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&); |
@@ -33,21 +75,32 @@ public: |
void setViewport(const GrGLIRect& rect) { fViewport = rect; } |
const GrGLIRect& getViewport() const { return fViewport; } |
- // The following two functions return the same ID when a |
- // texture/render target 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; } |
+ // For multisampled renderbuffer render targets, these will return different GrGLFBO objects. If |
+ // the render target is not texturable, textureFBO() returns NULL. If the render target auto |
+ // resolves to a texture, the same object is returned. |
+ |
+ // FBO that should be rendered into. Always non-NULL. |
+ const GrGLFBO* renderFBO() const { |
+ SkASSERT(fRenderFBO && fRenderFBO->isValid()); |
+ return fRenderFBO; |
+ } |
+ |
+ // FBO that has the target's texture ID attached. The return value may be: |
+ // * NULL when this render target is not a texture, |
+ // * the same as renderFBO() when this surface is not multisampled or auto-resolves, |
+ // * or different than renderFBO() when it requires explicit resolving via |
+ // glBlitFramebuffer. |
+ const GrGLFBO* textureFBO() const { |
+ SkASSERT(!fTextureFBO || fTextureFBO->isValid()); |
+ return fTextureFBO; |
+ } |
// override of GrRenderTarget |
ResolveType getResolveType() const SK_OVERRIDE { |
- if (!this->isMultisampled() || |
- fRTFBOID == fTexFBOID) { |
+ if (!this->isMultisampled() || this->renderFBO() == this->textureFBO()) { |
// catches FBO 0 and non MSAA case |
return kAutoResolves_ResolveType; |
- } else if (kUnresolvableFBOID == fTexFBOID) { |
+ } else if (!this->textureFBO()) { |
return kCantResolve_ResolveType; |
} else { |
return kCanResolve_ResolveType; |
@@ -73,23 +126,23 @@ protected: |
size_t onGpuMemorySize() const SK_OVERRIDE; |
private: |
- GrGLuint fRTFBOID; |
- GrGLuint fTexFBOID; |
- GrGLuint fMSColorRenderbufferID; |
+ SkAutoTUnref<GrGLFBO> fRenderFBO; |
+ SkAutoTUnref<GrGLFBO> fTextureFBO; |
+ GrGLuint fMSColorRenderbufferID; |
// We track this separately from GrGpuResource because this may be both a texture and a render |
// target, and the texture may be wrapped while the render target is not. |
- bool fIsWrapped; |
+ bool fIsWrapped; |
// when we switch to this render target we want to set the viewport to |
// 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; |
+ GrGLIRect fViewport; |
// onGpuMemorySize() 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; |
+ uint8_t fColorValuesPerPixel; |
typedef GrRenderTarget INHERITED; |
}; |