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