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>; 57 virtual ~Attachment() {} 58 }; 59 60 Framebuffer(FramebufferManager* manager, GLuint service_id); 61 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 94 bool IsDeleted() const { 95 return deleted_; 96 } 97 98 void MarkAsValid() { 99 has_been_bound_ = true; 100 } 101 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 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 158 void MarkAsComplete(unsigned state_id) { 159 framebuffer_complete_state_count_id_ = state_id; 160 } 161 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 250 void IncFramebufferStateChangeCount() { 251 // make sure this is never 0. 252 framebuffer_state_change_count_ = 253 (framebuffer_state_change_count_ + 1) | 0x80000000U; 254 } 255 256 void AddObserver(TextureDetachObserver* observer) { 257 texture_detach_observers_.push_back(observer); 258 } 259 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