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 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 95 bool IsDeleted() const { 96 return deleted_; 97 } 98 99 void MarkAsValid() { 100 has_been_bound_ = true; 101 } 102 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 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 167 void MarkAsComplete(unsigned state_id) { 168 framebuffer_complete_state_count_id_ = state_id; 169 } 170 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 263 void IncFramebufferStateChangeCount() { 264 // make sure this is never 0. 265 framebuffer_state_change_count_ = 266 (framebuffer_state_change_count_ + 1) | 0x80000000U; 267 } 268 269 void AddObserver(TextureDetachObserver* observer) { 270 texture_detach_observers_.push_back(observer); 271 } 272 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