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/context_group.h"
15 #include "gpu/command_buffer/service/gl_utils.h"
16 #include "gpu/gpu_export.h"
21 class FramebufferCompletenessCache
;
22 class FramebufferManager
;
24 class RenderbufferManager
;
29 // Info about a particular Framebuffer.
30 class GPU_EXPORT Framebuffer
: public base::RefCounted
<Framebuffer
> {
32 class Attachment
: public base::RefCounted
<Attachment
> {
34 virtual GLsizei
width() const = 0;
35 virtual GLsizei
height() const = 0;
36 virtual GLenum
internal_format() const = 0;
37 virtual GLenum
texture_type() const = 0;
38 virtual GLsizei
samples() const = 0;
39 virtual GLuint
object_name() const = 0;
40 virtual bool cleared() const = 0;
41 virtual void SetCleared(
42 RenderbufferManager
* renderbuffer_manager
,
43 TextureManager
* texture_manager
,
45 virtual bool IsTexture(TextureRef
* texture
) const = 0;
46 virtual bool IsRenderbuffer(
47 Renderbuffer
* renderbuffer
) const = 0;
48 virtual bool CanRenderTo() const = 0;
49 virtual void DetachFromFramebuffer(Framebuffer
* framebuffer
) const = 0;
50 virtual bool ValidForAttachmentType(
51 GLenum attachment_type
, uint32 max_color_attachments
) = 0;
52 virtual size_t GetSignatureSize(TextureManager
* texture_manager
) const = 0;
53 virtual void AddToSignature(
54 TextureManager
* texture_manager
, std::string
* signature
) const = 0;
55 virtual void OnWillRenderTo() const = 0;
56 virtual void OnDidRenderTo() const = 0;
57 virtual bool FormsFeedbackLoop(TextureRef
* texture
, GLint level
) const = 0;
60 friend class base::RefCounted
<Attachment
>;
61 virtual ~Attachment() {}
64 Framebuffer(FramebufferManager
* manager
, GLuint service_id
);
66 GLuint
service_id() const {
70 bool HasUnclearedAttachment(GLenum attachment
) const;
71 bool HasUnclearedColorAttachments() const;
73 void MarkAttachmentAsCleared(
74 RenderbufferManager
* renderbuffer_manager
,
75 TextureManager
* texture_manager
,
79 // Unbinds all attachments from this framebuffer for workaround
80 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
81 // bound when calling this.
82 void DoUnbindGLAttachmentsForWorkaround(GLenum target
);
84 // Attaches a renderbuffer to a particlar attachment.
85 // Pass null to detach.
86 void AttachRenderbuffer(
87 GLenum attachment
, Renderbuffer
* renderbuffer
);
89 // Attaches a texture to a particlar attachment. Pass null to detach.
91 GLenum attachment
, TextureRef
* texture_ref
, GLenum target
,
92 GLint level
, GLsizei samples
);
94 // Unbinds the given renderbuffer if it is bound.
95 void UnbindRenderbuffer(
96 GLenum target
, Renderbuffer
* renderbuffer
);
98 // Unbinds the given texture if it is bound.
100 GLenum target
, TextureRef
* texture_ref
);
102 const Attachment
* GetAttachment(GLenum attachment
) const;
104 const Attachment
* GetReadBufferAttachment() const;
106 bool IsDeleted() const {
111 has_been_bound_
= true;
114 bool IsValid() const {
115 return has_been_bound_
&& !IsDeleted();
118 bool HasDepthAttachment() const;
119 bool HasStencilAttachment() const;
120 GLenum
GetDrawBufferInternalFormat() const;
121 GLenum
GetReadBufferInternalFormat() const;
122 // If the color attachment is a texture, returns its type; otherwise,
124 GLenum
GetReadBufferTextureType() const;
126 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
127 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
128 // use this combination of attachments. Otherwise returns the value
129 // that glCheckFramebufferStatus should return for this set of attachments.
130 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
131 // not mean the real OpenGL will consider it framebuffer complete. It just
132 // means it passed our tests.
133 GLenum
IsPossiblyComplete() const;
135 // Implements optimized glGetFramebufferStatus.
136 GLenum
GetStatus(TextureManager
* texture_manager
, GLenum target
) const;
138 // Check all attachments are cleared
139 bool IsCleared() const;
141 GLenum
GetDrawBuffer(GLenum draw_buffer
) const;
143 void SetDrawBuffers(GLsizei n
, const GLenum
* bufs
);
145 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
146 // draw buffer for glClear().
147 void PrepareDrawBuffersForClear() const;
149 // Restore draw buffers states that have been changed in
150 // PrepareDrawBuffersForClear().
151 void RestoreDrawBuffersAfterClear() const;
153 // Clear all the active INT or UINT type color buffers to (0, 0, 0, 0).
154 void ClearIntegerBuffers();
156 // Return true if any draw buffers has an alpha channel.
157 bool HasAlphaMRT() const;
159 // Return false if any two active color attachments have different internal
161 bool HasSameInternalFormatsMRT() const;
163 void OnTextureRefDetached(TextureRef
* texture
);
165 // If attachment is 0, apply to all attachments; otherwise, apply only to
166 // the specified attachment.
167 void OnWillRenderTo(GLenum attachment
) const;
168 void OnDidRenderTo(GLenum attachment
) const;
170 void set_read_buffer(GLenum read_buffer
) {
171 read_buffer_
= read_buffer
;
174 GLenum
read_buffer() const {
179 friend class FramebufferManager
;
180 friend class base::RefCounted
<Framebuffer
>;
184 void MarkAsDeleted();
186 void MarkAttachmentsAsCleared(
187 RenderbufferManager
* renderbuffer_manager
,
188 TextureManager
* texture_manager
,
191 void MarkAsComplete(unsigned state_id
) {
192 framebuffer_complete_state_count_id_
= state_id
;
195 unsigned framebuffer_complete_state_count_id() const {
196 return framebuffer_complete_state_count_id_
;
199 // Helper function for PrepareDrawBuffersForClear() and
200 // RestoreDrawBuffersAfterClear().
201 void ChangeDrawBuffersHelper(bool recover
) const;
203 // The managers that owns this.
204 FramebufferManager
* manager_
;
208 // Service side framebuffer id.
211 // Whether this framebuffer has ever been bound.
212 bool has_been_bound_
;
214 // state count when this framebuffer was last checked for completeness.
215 unsigned framebuffer_complete_state_count_id_
;
217 // A map of attachments.
218 typedef base::hash_map
<GLenum
, scoped_refptr
<Attachment
> > AttachmentMap
;
219 AttachmentMap attachments_
;
221 scoped_ptr
<GLenum
[]> draw_buffers_
;
225 DISALLOW_COPY_AND_ASSIGN(Framebuffer
);
228 struct DecoderFramebufferState
{
229 DecoderFramebufferState();
230 ~DecoderFramebufferState();
232 // State saved for clearing so we can clear render buffers and then
233 // restore to these values.
234 bool clear_state_dirty
;
236 // The currently bound framebuffers
237 scoped_refptr
<Framebuffer
> bound_read_framebuffer
;
238 scoped_refptr
<Framebuffer
> bound_draw_framebuffer
;
241 // This class keeps track of the frambebuffers and their attached renderbuffers
242 // so we can correctly clear them.
243 class GPU_EXPORT FramebufferManager
{
245 class GPU_EXPORT TextureDetachObserver
{
247 TextureDetachObserver();
248 virtual ~TextureDetachObserver();
250 virtual void OnTextureRefDetachedFromFramebuffer(TextureRef
* texture
) = 0;
253 DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver
);
256 FramebufferManager(uint32 max_draw_buffers
,
257 uint32 max_color_attachments
,
258 ContextGroup::ContextType context_type
,
259 const scoped_refptr
<FramebufferCompletenessCache
>&
260 framebuffer_combo_complete_cache
);
261 ~FramebufferManager();
263 // Must call before destruction.
264 void Destroy(bool have_context
);
266 // Creates a Framebuffer for the given framebuffer.
267 void CreateFramebuffer(GLuint client_id
, GLuint service_id
);
269 // Gets the framebuffer info for the given framebuffer.
270 Framebuffer
* GetFramebuffer(GLuint client_id
);
272 // Removes a framebuffer info for the given framebuffer.
273 void RemoveFramebuffer(GLuint client_id
);
275 // Gets a client id for a given service id.
276 bool GetClientId(GLuint service_id
, GLuint
* client_id
) const;
278 void MarkAttachmentsAsCleared(
279 Framebuffer
* framebuffer
,
280 RenderbufferManager
* renderbuffer_manager
,
281 TextureManager
* texture_manager
);
283 void MarkAsComplete(Framebuffer
* framebuffer
);
285 bool IsComplete(Framebuffer
* framebuffer
);
287 void IncFramebufferStateChangeCount() {
288 // make sure this is never 0.
289 framebuffer_state_change_count_
=
290 (framebuffer_state_change_count_
+ 1) | 0x80000000U
;
293 void AddObserver(TextureDetachObserver
* observer
) {
294 texture_detach_observers_
.push_back(observer
);
297 void RemoveObserver(TextureDetachObserver
* observer
) {
298 texture_detach_observers_
.erase(
299 std::remove(texture_detach_observers_
.begin(),
300 texture_detach_observers_
.end(),
302 texture_detach_observers_
.end());
305 ContextGroup::ContextType
context_type() const {
306 return context_type_
;
310 friend class Framebuffer
;
312 void StartTracking(Framebuffer
* framebuffer
);
313 void StopTracking(Framebuffer
* framebuffer
);
315 void OnTextureRefDetached(TextureRef
* texture
);
317 FramebufferCompletenessCache
* GetFramebufferComboCompleteCache() {
318 return framebuffer_combo_complete_cache_
.get();
321 // Info for each framebuffer in the system.
322 typedef base::hash_map
<GLuint
, scoped_refptr
<Framebuffer
> >
324 FramebufferMap framebuffers_
;
326 // Incremented anytime anything changes that might effect framebuffer
328 unsigned framebuffer_state_change_count_
;
330 // Counts the number of Framebuffer allocated with 'this' as its manager.
331 // Allows to check no Framebuffer will outlive this.
332 unsigned int framebuffer_count_
;
336 uint32 max_draw_buffers_
;
337 uint32 max_color_attachments_
;
339 ContextGroup::ContextType context_type_
;
341 typedef std::vector
<TextureDetachObserver
*> TextureDetachObserverVector
;
342 TextureDetachObserverVector texture_detach_observers_
;
344 scoped_refptr
<FramebufferCompletenessCache
> framebuffer_combo_complete_cache_
;
346 DISALLOW_COPY_AND_ASSIGN(FramebufferManager
);
352 #endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_