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