• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
7 
8 #include <vector>
9 
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"
16 
17 namespace gpu {
18 namespace gles2 {
19 
20 class FramebufferManager;
21 class Renderbuffer;
22 class RenderbufferManager;
23 class Texture;
24 class TextureRef;
25 class TextureManager;
26 
27 // Info about a particular Framebuffer.
28 class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
29  public:
30   class Attachment : public base::RefCounted<Attachment> {
31    public:
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,
42         bool cleared) = 0;
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 void AddToSignature(
51         TextureManager* texture_manager, std::string* signature) const = 0;
52     virtual void OnWillRenderTo() const = 0;
53     virtual void OnDidRenderTo() const = 0;
54 
55    protected:
56     friend class base::RefCounted<Attachment>;
~Attachment()57     virtual ~Attachment() {}
58   };
59 
60   Framebuffer(FramebufferManager* manager, GLuint service_id);
61 
service_id()62   GLuint service_id() const {
63     return service_id_;
64   }
65 
66   bool HasUnclearedAttachment(GLenum attachment) const;
67   bool HasUnclearedColorAttachments() const;
68 
69   void MarkAttachmentAsCleared(
70     RenderbufferManager* renderbuffer_manager,
71     TextureManager* texture_manager,
72     GLenum attachment,
73     bool cleared);
74 
75   // Attaches a renderbuffer to a particlar attachment.
76   // Pass null to detach.
77   void AttachRenderbuffer(
78       GLenum attachment, Renderbuffer* renderbuffer);
79 
80   // Attaches a texture to a particlar attachment. Pass null to detach.
81   void AttachTexture(
82       GLenum attachment, TextureRef* texture_ref, GLenum target,
83       GLint level, GLsizei samples);
84 
85   // Unbinds the given renderbuffer if it is bound.
86   void UnbindRenderbuffer(
87       GLenum target, Renderbuffer* renderbuffer);
88 
89   // Unbinds the given texture if it is bound.
90   void UnbindTexture(
91       GLenum target, TextureRef* texture_ref);
92 
93   const Attachment* GetAttachment(GLenum attachment) const;
94 
IsDeleted()95   bool IsDeleted() const {
96     return deleted_;
97   }
98 
MarkAsValid()99   void MarkAsValid() {
100     has_been_bound_ = true;
101   }
102 
IsValid()103   bool IsValid() const {
104     return has_been_bound_ && !IsDeleted();
105   }
106 
107   bool HasDepthAttachment() const;
108   bool HasStencilAttachment() const;
109   GLenum GetColorAttachmentFormat() const;
110   // If the color attachment is a texture, returns its type; otherwise,
111   // returns 0.
112   GLenum GetColorAttachmentTextureType() const;
113 
114   // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
115   // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
116   // use this combination of attachments. Otherwise returns the value
117   // that glCheckFramebufferStatus should return for this set of attachments.
118   // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
119   // not mean the real OpenGL will consider it framebuffer complete. It just
120   // means it passed our tests.
121   GLenum IsPossiblyComplete() const;
122 
123   // Implements optimized glGetFramebufferStatus.
124   GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
125 
126   // Check all attachments are cleared
127   bool IsCleared() const;
128 
129   GLenum GetDrawBuffer(GLenum draw_buffer) const;
130 
131   void SetDrawBuffers(GLsizei n, const GLenum* bufs);
132 
133   // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
134   // draw buffer for glClear().
135   void PrepareDrawBuffersForClear() const;
136 
137   // Restore draw buffers states that have been changed in
138   // PrepareDrawBuffersForClear().
139   void RestoreDrawBuffersAfterClear() const;
140 
141   // Return true if any draw buffers has an alpha channel.
142   bool HasAlphaMRT() const;
143 
144   static void ClearFramebufferCompleteComboMap();
145 
AllowFramebufferComboCompleteMapForTesting()146   static bool AllowFramebufferComboCompleteMapForTesting() {
147     return allow_framebuffer_combo_complete_map_;
148   }
149 
150   void OnTextureRefDetached(TextureRef* texture);
151   void OnWillRenderTo() const;
152   void OnDidRenderTo() const;
153 
154  private:
155   friend class FramebufferManager;
156   friend class base::RefCounted<Framebuffer>;
157 
158   ~Framebuffer();
159 
160   void MarkAsDeleted();
161 
162   void MarkAttachmentsAsCleared(
163     RenderbufferManager* renderbuffer_manager,
164     TextureManager* texture_manager,
165     bool cleared);
166 
MarkAsComplete(unsigned state_id)167   void MarkAsComplete(unsigned state_id) {
168     framebuffer_complete_state_count_id_ = state_id;
169   }
170 
framebuffer_complete_state_count_id()171   unsigned framebuffer_complete_state_count_id() const {
172     return framebuffer_complete_state_count_id_;
173   }
174 
175   // Helper function for PrepareDrawBuffersForClear() and
176   // RestoreDrawBuffersAfterClear().
177   void ChangeDrawBuffersHelper(bool recover) const;
178 
179   // The managers that owns this.
180   FramebufferManager* manager_;
181 
182   bool deleted_;
183 
184   // Service side framebuffer id.
185   GLuint service_id_;
186 
187   // Whether this framebuffer has ever been bound.
188   bool has_been_bound_;
189 
190   // state count when this framebuffer was last checked for completeness.
191   unsigned framebuffer_complete_state_count_id_;
192 
193   // A map of attachments.
194   typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
195   AttachmentMap attachments_;
196 
197   // A map of successful frame buffer combos. If it's in the map
198   // it should be FRAMEBUFFER_COMPLETE.
199   typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
200   static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
201   static bool allow_framebuffer_combo_complete_map_;
202 
203   scoped_ptr<GLenum[]> draw_buffers_;
204 
205   DISALLOW_COPY_AND_ASSIGN(Framebuffer);
206 };
207 
208 struct DecoderFramebufferState {
209   DecoderFramebufferState();
210   ~DecoderFramebufferState();
211 
212   // State saved for clearing so we can clear render buffers and then
213   // restore to these values.
214   bool clear_state_dirty;
215 
216   // The currently bound framebuffers
217   scoped_refptr<Framebuffer> bound_read_framebuffer;
218   scoped_refptr<Framebuffer> bound_draw_framebuffer;
219 };
220 
221 // This class keeps track of the frambebuffers and their attached renderbuffers
222 // so we can correctly clear them.
223 class GPU_EXPORT FramebufferManager {
224  public:
225   class GPU_EXPORT TextureDetachObserver {
226    public:
227     TextureDetachObserver();
228     virtual ~TextureDetachObserver();
229 
230     virtual void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) = 0;
231 
232    private:
233     DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver);
234   };
235 
236   FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments);
237   ~FramebufferManager();
238 
239   // Must call before destruction.
240   void Destroy(bool have_context);
241 
242   // Creates a Framebuffer for the given framebuffer.
243   void CreateFramebuffer(GLuint client_id, GLuint service_id);
244 
245   // Gets the framebuffer info for the given framebuffer.
246   Framebuffer* GetFramebuffer(GLuint client_id);
247 
248   // Removes a framebuffer info for the given framebuffer.
249   void RemoveFramebuffer(GLuint client_id);
250 
251   // Gets a client id for a given service id.
252   bool GetClientId(GLuint service_id, GLuint* client_id) const;
253 
254   void MarkAttachmentsAsCleared(
255     Framebuffer* framebuffer,
256     RenderbufferManager* renderbuffer_manager,
257     TextureManager* texture_manager);
258 
259   void MarkAsComplete(Framebuffer* framebuffer);
260 
261   bool IsComplete(Framebuffer* framebuffer);
262 
IncFramebufferStateChangeCount()263   void IncFramebufferStateChangeCount() {
264     // make sure this is never 0.
265     framebuffer_state_change_count_ =
266         (framebuffer_state_change_count_ + 1) | 0x80000000U;
267   }
268 
AddObserver(TextureDetachObserver * observer)269   void AddObserver(TextureDetachObserver* observer) {
270     texture_detach_observers_.push_back(observer);
271   }
272 
RemoveObserver(TextureDetachObserver * observer)273   void RemoveObserver(TextureDetachObserver* observer) {
274     texture_detach_observers_.erase(
275         std::remove(texture_detach_observers_.begin(),
276                     texture_detach_observers_.end(),
277                     observer),
278         texture_detach_observers_.end());
279   }
280 
281  private:
282   friend class Framebuffer;
283 
284   void StartTracking(Framebuffer* framebuffer);
285   void StopTracking(Framebuffer* framebuffer);
286 
287   void OnTextureRefDetached(TextureRef* texture);
288 
289   // Info for each framebuffer in the system.
290   typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
291       FramebufferMap;
292   FramebufferMap framebuffers_;
293 
294   // Incremented anytime anything changes that might effect framebuffer
295   // state.
296   unsigned framebuffer_state_change_count_;
297 
298   // Counts the number of Framebuffer allocated with 'this' as its manager.
299   // Allows to check no Framebuffer will outlive this.
300   unsigned int framebuffer_count_;
301 
302   bool have_context_;
303 
304   uint32 max_draw_buffers_;
305   uint32 max_color_attachments_;
306 
307   typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector;
308   TextureDetachObserverVector texture_detach_observers_;
309 
310   DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
311 };
312 
313 }  // namespace gles2
314 }  // namespace gpu
315 
316 #endif  // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
317