GrGLRenderTarget.h revision 0b70b86a7e9fda52ee7ebc1b9897eeaa09b9abef
1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9#ifndef GrGLRenderTarget_DEFINED 10#define GrGLRenderTarget_DEFINED 11 12#include "GrGLIRect.h" 13#include "GrRenderTarget.h" 14#include "SkScalar.h" 15 16class GrGLGpu; 17 18/** Represents a GL FBO object. It has a gen ID which is valid whenever the FBO ID owned by the 19 object is valid. The gen IDs are not recycled after FBOs are freed, unlike FBO IDs, and so 20 can be used to uniquely identity FBO ID instantiations. If this object owns an FBO ID, the ID 21 must be deleted or abandoned before this object is freed. FBO IDs should never be owned by 22 more than one instance. */ 23class GrGLFBO : public SkNVRefCnt<GrGLFBO> { 24public: 25 SK_DECLARE_INST_COUNT(GrGLFBO); 26 27 /** Initializes to an FBO. The FBO should already be valid in the relevant GL context. */ 28 GrGLFBO(GrGLint id) : fID(id), fIsValid(true) {} 29 30 /** Initializes to an FBO ID generated using the interface. */ 31 GrGLFBO(const GrGLInterface* gl) { 32 GR_GL_CALL(gl, GenFramebuffers(1, &fID)); 33 fIsValid = SkToBool(fID); 34 } 35 36 ~GrGLFBO() { SkASSERT(!this->isValid()); } 37 38 /** Has this object been released or abandoned? */ 39 bool isValid() const { return fIsValid; } 40 41 GrGLint fboID() const { SkASSERT(this->isValid()); return fID; } 42 43 bool isDefaultFramebuffer() const { return fIsValid && 0 == fID; } 44 45 /** Give up ownership of the FBO ID owned by this object without deleting it. */ 46 void abandon(); 47 48 /** Delete and give up ownership of the the FBO ID if it is valid. */ 49 void release(const GrGLInterface*); 50 51private: 52 static uint32_t NextGenID() { 53 static int32_t gGenID = SK_InvalidGenID + 1; 54 return static_cast<uint32_t>(sk_atomic_inc(&gGenID)); 55 } 56 57 GrGLuint fID; 58 bool fIsValid; 59 60 typedef SkRefCnt INHERITED; 61}; 62 63////////////////////////////////////////////////////////////////////////////// 64 65/** GL-specific subclass of GrRenderTarget. */ 66class GrGLRenderTarget : public GrRenderTarget { 67public: 68 struct IDDesc { 69 SkAutoTUnref<GrGLFBO> fRenderFBO; 70 SkAutoTUnref<GrGLFBO> fTextureFBO; 71 GrGLuint fMSColorRenderbufferID; 72 GrGpuResource::LifeCycle fLifeCycle; 73 }; 74 75 GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&); 76 77 void setViewport(const GrGLIRect& rect) { fViewport = rect; } 78 const GrGLIRect& getViewport() const { return fViewport; } 79 80 // For multisampled renderbuffer render targets, these will return different GrGLFBO objects. If 81 // the render target is not texturable, textureFBO() returns NULL. If the render target auto 82 // resolves to a texture, the same object is returned. 83 84 // FBO that should be rendered into. Always non-NULL unless this resource is destroyed 85 // (this->wasDestroyed()). 86 const GrGLFBO* renderFBO() const { 87 SkASSERT(fRenderFBO && fRenderFBO->isValid()); 88 return fRenderFBO; 89 } 90 91 // FBO that has the target's texture ID attached. The return value may be: 92 // * NULL when this render target is not a texture, 93 // * the same as renderFBO() when this surface is not multisampled or auto-resolves, 94 // * or different than renderFBO() when it requires explicit resolving via 95 // glBlitFramebuffer. 96 const GrGLFBO* textureFBO() const { 97 SkASSERT(!fTextureFBO || fTextureFBO->isValid()); 98 return fTextureFBO; 99 } 100 101 // override of GrRenderTarget 102 ResolveType getResolveType() const SK_OVERRIDE { 103 if (!this->isMultisampled() || this->renderFBO() == this->textureFBO()) { 104 // catches FBO 0 and non MSAA case 105 return kAutoResolves_ResolveType; 106 } else if (!this->textureFBO()) { 107 return kCantResolve_ResolveType; 108 } else { 109 return kCanResolve_ResolveType; 110 } 111 } 112 113 /** When we don't own the FBO ID we don't attempt to modify its attachments. */ 114 bool canAttemptStencilAttachment() const SK_OVERRIDE { return !fIsWrapped; } 115 116protected: 117 // The public constructor registers this object with the cache. However, only the most derived 118 // class should register with the cache. This constructor does not do the registration and 119 // rather moves that burden onto the derived class. 120 enum Derived { kDerived }; 121 GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived); 122 123 void init(const GrSurfaceDesc&, const IDDesc&); 124 125 void onAbandon() SK_OVERRIDE; 126 void onRelease() SK_OVERRIDE; 127 128 // In protected because subclass GrGLTextureRenderTarget calls this version. 129 size_t onGpuMemorySize() const SK_OVERRIDE; 130 131private: 132 SkAutoTUnref<GrGLFBO> fRenderFBO; 133 SkAutoTUnref<GrGLFBO> fTextureFBO; 134 GrGLuint fMSColorRenderbufferID; 135 136 // We track this separately from GrGpuResource because this may be both a texture and a render 137 // target, and the texture may be wrapped while the render target is not. 138 bool fIsWrapped; 139 140 // when we switch to this render target we want to set the viewport to 141 // only render to content area (as opposed to the whole allocation) and 142 // we want the rendering to be at top left (GL has origin in bottom left) 143 GrGLIRect fViewport; 144 145 // onGpuMemorySize() needs to know what how many color values are owned per pixel. However, 146 // abandon and release zero out the IDs and the cache needs to know the size even after those 147 // actions. 148 uint8_t fColorValuesPerPixel; 149 150 typedef GrRenderTarget INHERITED; 151}; 152 153#endif 154