1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
10 #include "base/basictypes.h"
11 #include "base/containers/hash_tables.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "gpu/command_buffer/service/gl_utils.h"
15 #include "gpu/gpu_export.h"
20 class FramebufferManager
;
22 class RenderbufferManager
;
27 // Info about a particular Framebuffer.
28 class GPU_EXPORT Framebuffer
: public base::RefCounted
<Framebuffer
> {
30 class Attachment
: public base::RefCounted
<Attachment
> {
32 virtual GLsizei
width() const = 0;
33 virtual GLsizei
height() const = 0;
34 virtual GLenum
internal_format() const = 0;
35 virtual GLenum
texture_type() const = 0;
36 virtual GLsizei
samples() const = 0;
37 virtual GLuint
object_name() const = 0;
38 virtual bool cleared() const = 0;
39 virtual void SetCleared(
40 RenderbufferManager
* renderbuffer_manager
,
41 TextureManager
* texture_manager
,
43 virtual bool IsTexture(TextureRef
* texture
) const = 0;
44 virtual bool IsRenderbuffer(
45 Renderbuffer
* renderbuffer
) const = 0;
46 virtual bool CanRenderTo() const = 0;
47 virtual void DetachFromFramebuffer(Framebuffer
* framebuffer
) const = 0;
48 virtual bool ValidForAttachmentType(
49 GLenum attachment_type
, uint32 max_color_attachments
) = 0;
50 virtual size_t GetSignatureSize(TextureManager
* texture_manager
) const = 0;
51 virtual void AddToSignature(
52 TextureManager
* texture_manager
, std::string
* signature
) const = 0;
53 virtual void OnWillRenderTo() const = 0;
54 virtual void OnDidRenderTo() const = 0;
55 virtual bool FormsFeedbackLoop(TextureRef
* texture
, GLint level
) const = 0;
58 friend class base::RefCounted
<Attachment
>;
59 virtual ~Attachment() {}
62 Framebuffer(FramebufferManager
* manager
, GLuint service_id
);
64 GLuint
service_id() const {
68 bool HasUnclearedAttachment(GLenum attachment
) const;
69 bool HasUnclearedColorAttachments() const;
71 void MarkAttachmentAsCleared(
72 RenderbufferManager
* renderbuffer_manager
,
73 TextureManager
* texture_manager
,
77 // Unbinds all attachments from this framebuffer for workaround
78 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
79 // bound when calling this.
80 void DoUnbindGLAttachmentsForWorkaround(GLenum target
);
82 // Attaches a renderbuffer to a particlar attachment.
83 // Pass null to detach.
84 void AttachRenderbuffer(
85 GLenum attachment
, Renderbuffer
* renderbuffer
);
87 // Attaches a texture to a particlar attachment. Pass null to detach.
89 GLenum attachment
, TextureRef
* texture_ref
, GLenum target
,
90 GLint level
, GLsizei samples
);
92 // Unbinds the given renderbuffer if it is bound.
93 void UnbindRenderbuffer(
94 GLenum target
, Renderbuffer
* renderbuffer
);
96 // Unbinds the given texture if it is bound.
98 GLenum target
, TextureRef
* texture_ref
);
100 const Attachment
* GetAttachment(GLenum attachment
) const;
102 bool IsDeleted() const {
107 has_been_bound_
= true;
110 bool IsValid() const {
111 return has_been_bound_
&& !IsDeleted();
114 bool HasDepthAttachment() const;
115 bool HasStencilAttachment() const;
116 GLenum
GetColorAttachmentFormat() const;
117 // If the color attachment is a texture, returns its type; otherwise,
119 GLenum
GetColorAttachmentTextureType() const;
121 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
122 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
123 // use this combination of attachments. Otherwise returns the value
124 // that glCheckFramebufferStatus should return for this set of attachments.
125 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
126 // not mean the real OpenGL will consider it framebuffer complete. It just
127 // means it passed our tests.
128 GLenum
IsPossiblyComplete() const;
130 // Implements optimized glGetFramebufferStatus.
131 GLenum
GetStatus(TextureManager
* texture_manager
, GLenum target
) const;
133 // Check all attachments are cleared
134 bool IsCleared() const;
136 GLenum
GetDrawBuffer(GLenum draw_buffer
) const;
138 void SetDrawBuffers(GLsizei n
, const GLenum
* bufs
);
140 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
141 // draw buffer for glClear().
142 void PrepareDrawBuffersForClear() const;
144 // Restore draw buffers states that have been changed in
145 // PrepareDrawBuffersForClear().
146 void RestoreDrawBuffersAfterClear() const;
148 // Return true if any draw buffers has an alpha channel.
149 bool HasAlphaMRT() const;
151 static void ClearFramebufferCompleteComboMap();
153 static bool AllowFramebufferComboCompleteMapForTesting() {
154 return allow_framebuffer_combo_complete_map_
;
157 void OnTextureRefDetached(TextureRef
* texture
);
158 void OnWillRenderTo() const;
159 void OnDidRenderTo() const;
162 friend class FramebufferManager
;
163 friend class base::RefCounted
<Framebuffer
>;
167 void MarkAsDeleted();
169 void MarkAttachmentsAsCleared(
170 RenderbufferManager
* renderbuffer_manager
,
171 TextureManager
* texture_manager
,
174 void MarkAsComplete(unsigned state_id
) {
175 framebuffer_complete_state_count_id_
= state_id
;
178 unsigned framebuffer_complete_state_count_id() const {
179 return framebuffer_complete_state_count_id_
;
182 // Helper function for PrepareDrawBuffersForClear() and
183 // RestoreDrawBuffersAfterClear().
184 void ChangeDrawBuffersHelper(bool recover
) const;
186 // The managers that owns this.
187 FramebufferManager
* manager_
;
191 // Service side framebuffer id.
194 // Whether this framebuffer has ever been bound.
195 bool has_been_bound_
;
197 // state count when this framebuffer was last checked for completeness.
198 unsigned framebuffer_complete_state_count_id_
;
200 // A map of attachments.
201 typedef base::hash_map
<GLenum
, scoped_refptr
<Attachment
> > AttachmentMap
;
202 AttachmentMap attachments_
;
204 // A map of successful frame buffer combos. If it's in the map
205 // it should be FRAMEBUFFER_COMPLETE.
206 typedef base::hash_map
<std::string
, bool> FramebufferComboCompleteMap
;
207 static FramebufferComboCompleteMap
* framebuffer_combo_complete_map_
;
208 static bool allow_framebuffer_combo_complete_map_
;
210 scoped_ptr
<GLenum
[]> draw_buffers_
;
212 DISALLOW_COPY_AND_ASSIGN(Framebuffer
);
215 struct DecoderFramebufferState
{
216 DecoderFramebufferState();
217 ~DecoderFramebufferState();
219 // State saved for clearing so we can clear render buffers and then
220 // restore to these values.
221 bool clear_state_dirty
;
223 // The currently bound framebuffers
224 scoped_refptr
<Framebuffer
> bound_read_framebuffer
;
225 scoped_refptr
<Framebuffer
> bound_draw_framebuffer
;
228 // This class keeps track of the frambebuffers and their attached renderbuffers
229 // so we can correctly clear them.
230 class GPU_EXPORT FramebufferManager
{
232 class GPU_EXPORT TextureDetachObserver
{
234 TextureDetachObserver();
235 virtual ~TextureDetachObserver();
237 virtual void OnTextureRefDetachedFromFramebuffer(TextureRef
* texture
) = 0;
240 DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver
);
243 FramebufferManager(uint32 max_draw_buffers
, uint32 max_color_attachments
);
244 ~FramebufferManager();
246 // Must call before destruction.
247 void Destroy(bool have_context
);
249 // Creates a Framebuffer for the given framebuffer.
250 void CreateFramebuffer(GLuint client_id
, GLuint service_id
);
252 // Gets the framebuffer info for the given framebuffer.
253 Framebuffer
* GetFramebuffer(GLuint client_id
);
255 // Removes a framebuffer info for the given framebuffer.
256 void RemoveFramebuffer(GLuint client_id
);
258 // Gets a client id for a given service id.
259 bool GetClientId(GLuint service_id
, GLuint
* client_id
) const;
261 void MarkAttachmentsAsCleared(
262 Framebuffer
* framebuffer
,
263 RenderbufferManager
* renderbuffer_manager
,
264 TextureManager
* texture_manager
);
266 void MarkAsComplete(Framebuffer
* framebuffer
);
268 bool IsComplete(Framebuffer
* framebuffer
);
270 void IncFramebufferStateChangeCount() {
271 // make sure this is never 0.
272 framebuffer_state_change_count_
=
273 (framebuffer_state_change_count_
+ 1) | 0x80000000U
;
276 void AddObserver(TextureDetachObserver
* observer
) {
277 texture_detach_observers_
.push_back(observer
);
280 void RemoveObserver(TextureDetachObserver
* observer
) {
281 texture_detach_observers_
.erase(
282 std::remove(texture_detach_observers_
.begin(),
283 texture_detach_observers_
.end(),
285 texture_detach_observers_
.end());
289 friend class Framebuffer
;
291 void StartTracking(Framebuffer
* framebuffer
);
292 void StopTracking(Framebuffer
* framebuffer
);
294 void OnTextureRefDetached(TextureRef
* texture
);
296 // Info for each framebuffer in the system.
297 typedef base::hash_map
<GLuint
, scoped_refptr
<Framebuffer
> >
299 FramebufferMap framebuffers_
;
301 // Incremented anytime anything changes that might effect framebuffer
303 unsigned framebuffer_state_change_count_
;
305 // Counts the number of Framebuffer allocated with 'this' as its manager.
306 // Allows to check no Framebuffer will outlive this.
307 unsigned int framebuffer_count_
;
311 uint32 max_draw_buffers_
;
312 uint32 max_color_attachments_
;
314 typedef std::vector
<TextureDetachObserver
*> TextureDetachObserverVector
;
315 TextureDetachObserverVector texture_detach_observers_
;
317 DISALLOW_COPY_AND_ASSIGN(FramebufferManager
);
323 #endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_