OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #ifndef GrGLRenderTarget_DEFINED | 9 #ifndef GrGLRenderTarget_DEFINED |
10 #define GrGLRenderTarget_DEFINED | 10 #define GrGLRenderTarget_DEFINED |
11 | 11 |
12 #include "GrGLIRect.h" | 12 #include "GrGLIRect.h" |
13 #include "GrRenderTarget.h" | 13 #include "GrRenderTarget.h" |
14 #include "SkScalar.h" | 14 #include "SkScalar.h" |
15 | 15 |
16 class GrGLGpu; | 16 class GrGLGpu; |
17 | 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 F
BO 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 nev
er be owned by |
| 22 more than one instance. */ |
| 23 class GrGLFBO : public SkNVRefCnt<GrGLFBO> { |
| 24 public: |
| 25 SK_DECLARE_INST_COUNT(GrGLFBO); |
| 26 |
| 27 /** Initializes to an FBO. The FBO should already be valid in the relevant G
L 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 |
| 51 private: |
| 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. */ |
18 class GrGLRenderTarget : public GrRenderTarget { | 66 class GrGLRenderTarget : public GrRenderTarget { |
19 public: | 67 public: |
20 // set fTexFBOID to this value to indicate that it is multisampled but | |
21 // Gr doesn't know how to resolve it. | |
22 enum { kUnresolvableFBOID = 0 }; | |
23 | |
24 struct IDDesc { | 68 struct IDDesc { |
25 GrGLuint fRTFBOID; | 69 SkAutoTUnref<GrGLFBO> fRenderFBO; |
26 GrGLuint fTexFBOID; | 70 SkAutoTUnref<GrGLFBO> fTextureFBO; |
27 GrGLuint fMSColorRenderbufferID; | 71 GrGLuint fMSColorRenderbufferID; |
28 GrGpuResource::LifeCycle fLifeCycle; | 72 GrGpuResource::LifeCycle fLifeCycle; |
29 }; | 73 }; |
30 | 74 |
31 GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&); | 75 GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&); |
32 | 76 |
33 void setViewport(const GrGLIRect& rect) { fViewport = rect; } | 77 void setViewport(const GrGLIRect& rect) { fViewport = rect; } |
34 const GrGLIRect& getViewport() const { return fViewport; } | 78 const GrGLIRect& getViewport() const { return fViewport; } |
35 | 79 |
36 // The following two functions return the same ID when a | 80 // For multisampled renderbuffer render targets, these will return different
GrGLFBO objects. If |
37 // texture/render target is multisampled, and different IDs when | 81 // the render target is not texturable, textureFBO() returns NULL. If the re
nder target auto |
38 // it is. | 82 // resolves to a texture, the same object is returned. |
39 // FBO ID used to render into | 83 |
40 GrGLuint renderFBOID() const { return fRTFBOID; } | 84 // FBO that should be rendered into. Always non-NULL unless this resource is
destroyed |
41 // FBO ID that has texture ID attached. | 85 // (this->wasDestroyed()). |
42 GrGLuint textureFBOID() const { return fTexFBOID; } | 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 a
uto-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 } |
43 | 100 |
44 // override of GrRenderTarget | 101 // override of GrRenderTarget |
45 ResolveType getResolveType() const SK_OVERRIDE { | 102 ResolveType getResolveType() const SK_OVERRIDE { |
46 if (!this->isMultisampled() || | 103 if (!this->isMultisampled() || this->renderFBO() == this->textureFBO())
{ |
47 fRTFBOID == fTexFBOID) { | |
48 // catches FBO 0 and non MSAA case | 104 // catches FBO 0 and non MSAA case |
49 return kAutoResolves_ResolveType; | 105 return kAutoResolves_ResolveType; |
50 } else if (kUnresolvableFBOID == fTexFBOID) { | 106 } else if (!this->textureFBO()) { |
51 return kCantResolve_ResolveType; | 107 return kCantResolve_ResolveType; |
52 } else { | 108 } else { |
53 return kCanResolve_ResolveType; | 109 return kCanResolve_ResolveType; |
54 } | 110 } |
55 } | 111 } |
56 | 112 |
57 /** When we don't own the FBO ID we don't attempt to modify its attachments.
*/ | 113 /** When we don't own the FBO ID we don't attempt to modify its attachments.
*/ |
58 bool canAttemptStencilAttachment() const SK_OVERRIDE { return !fIsWrapped; } | 114 bool canAttemptStencilAttachment() const SK_OVERRIDE { return !fIsWrapped; } |
59 | 115 |
60 protected: | 116 protected: |
61 // The public constructor registers this object with the cache. However, onl
y the most derived | 117 // The public constructor registers this object with the cache. However, onl
y the most derived |
62 // class should register with the cache. This constructor does not do the re
gistration and | 118 // class should register with the cache. This constructor does not do the re
gistration and |
63 // rather moves that burden onto the derived class. | 119 // rather moves that burden onto the derived class. |
64 enum Derived { kDerived }; | 120 enum Derived { kDerived }; |
65 GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived); | 121 GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived); |
66 | 122 |
67 void init(const GrSurfaceDesc&, const IDDesc&); | 123 void init(const GrSurfaceDesc&, const IDDesc&); |
68 | 124 |
69 void onAbandon() SK_OVERRIDE; | 125 void onAbandon() SK_OVERRIDE; |
70 void onRelease() SK_OVERRIDE; | 126 void onRelease() SK_OVERRIDE; |
71 | 127 |
72 // In protected because subclass GrGLTextureRenderTarget calls this version. | 128 // In protected because subclass GrGLTextureRenderTarget calls this version. |
73 size_t onGpuMemorySize() const SK_OVERRIDE; | 129 size_t onGpuMemorySize() const SK_OVERRIDE; |
74 | 130 |
75 private: | 131 private: |
76 GrGLuint fRTFBOID; | 132 SkAutoTUnref<GrGLFBO> fRenderFBO; |
77 GrGLuint fTexFBOID; | 133 SkAutoTUnref<GrGLFBO> fTextureFBO; |
78 GrGLuint fMSColorRenderbufferID; | 134 GrGLuint fMSColorRenderbufferID; |
79 | 135 |
80 // We track this separately from GrGpuResource because this may be both a te
xture and a render | 136 // We track this separately from GrGpuResource because this may be both a te
xture and a render |
81 // target, and the texture may be wrapped while the render target is not. | 137 // target, and the texture may be wrapped while the render target is not. |
82 bool fIsWrapped; | 138 bool fIsWrapped; |
83 | 139 |
84 // when we switch to this render target we want to set the viewport to | 140 // when we switch to this render target we want to set the viewport to |
85 // only render to content area (as opposed to the whole allocation) and | 141 // only render to content area (as opposed to the whole allocation) and |
86 // we want the rendering to be at top left (GL has origin in bottom left) | 142 // we want the rendering to be at top left (GL has origin in bottom left) |
87 GrGLIRect fViewport; | 143 GrGLIRect fViewport; |
88 | 144 |
89 // onGpuMemorySize() needs to know what how many color values are owned per
pixel. However, | 145 // onGpuMemorySize() needs to know what how many color values are owned per
pixel. However, |
90 // abandon and release zero out the IDs and the cache needs to know the size
even after those | 146 // abandon and release zero out the IDs and the cache needs to know the size
even after those |
91 // actions. | 147 // actions. |
92 uint8_t fColorValuesPerPixel; | 148 uint8_t fColorValuesPerPixel; |
93 | 149 |
94 typedef GrRenderTarget INHERITED; | 150 typedef GrRenderTarget INHERITED; |
95 }; | 151 }; |
96 | 152 |
97 #endif | 153 #endif |
OLD | NEW |