| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_ |
| #define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_ |
| |
| #include "base/basictypes.h" |
| #include "base/hash_tables.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "gpu/command_buffer/service/gl_utils.h" |
| #include "gpu/command_buffer/service/renderbuffer_manager.h" |
| #include "gpu/command_buffer/service/texture_manager.h" |
| #include "gpu/gpu_export.h" |
| |
| namespace gpu { |
| namespace gles2 { |
| |
| // This class keeps track of the frambebuffers and their attached renderbuffers |
| // so we can correctly clear them. |
| class GPU_EXPORT FramebufferManager { |
| public: |
| // Info about Framebuffers currently in the system. |
| class GPU_EXPORT FramebufferInfo : public base::RefCounted<FramebufferInfo> { |
| public: |
| typedef scoped_refptr<FramebufferInfo> Ref; |
| |
| class Attachment : public base::RefCounted<Attachment> { |
| public: |
| typedef scoped_refptr<Attachment> Ref; |
| |
| virtual GLsizei width() const = 0; |
| virtual GLsizei height() const = 0; |
| virtual GLenum internal_format() const = 0; |
| virtual GLsizei samples() const = 0; |
| virtual bool cleared() const = 0; |
| virtual void SetCleared( |
| RenderbufferManager* renderbuffer_manager, |
| TextureManager* texture_manager) = 0; |
| virtual bool IsTexture(TextureManager::TextureInfo* texture) const = 0; |
| virtual bool IsRenderbuffer( |
| RenderbufferManager::RenderbufferInfo* renderbuffer) const = 0; |
| virtual bool CanRenderTo() const = 0; |
| virtual void DetachFromFramebuffer() = 0; |
| virtual bool ValidForAttachmentType(GLenum attachment_type) = 0; |
| |
| protected: |
| friend class base::RefCounted<Attachment>; |
| virtual ~Attachment() {} |
| }; |
| |
| FramebufferInfo(FramebufferManager* manager, GLuint service_id); |
| |
| GLuint service_id() const { |
| return service_id_; |
| } |
| |
| bool HasUnclearedAttachment(GLenum attachment) const; |
| |
| // Attaches a renderbuffer to a particlar attachment. |
| // Pass null to detach. |
| void AttachRenderbuffer( |
| GLenum attachment, RenderbufferManager::RenderbufferInfo* renderbuffer); |
| |
| // Attaches a texture to a particlar attachment. Pass null to detach. |
| void AttachTexture( |
| GLenum attachment, TextureManager::TextureInfo* texture, GLenum target, |
| GLint level); |
| |
| // Unbinds the given renderbuffer if it is bound. |
| void UnbindRenderbuffer( |
| GLenum target, RenderbufferManager::RenderbufferInfo* renderbuffer); |
| |
| // Unbinds the given texture if it is bound. |
| void UnbindTexture( |
| GLenum target, TextureManager::TextureInfo* texture); |
| |
| const Attachment* GetAttachment(GLenum attachment) const; |
| |
| bool IsDeleted() const { |
| return deleted_; |
| } |
| |
| void MarkAsValid() { |
| has_been_bound_ = true; |
| } |
| |
| bool IsValid() const { |
| return has_been_bound_ && !IsDeleted(); |
| } |
| |
| bool HasDepthAttachment() const; |
| bool HasStencilAttachment() const; |
| GLenum GetColorAttachmentFormat() const; |
| |
| // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed. |
| // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't |
| // use this combination of attachments. Otherwise returns the value |
| // that glCheckFramebufferStatus should return for this set of attachments. |
| // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does |
| // not mean the real OpenGL will consider it framebuffer complete. It just |
| // means it passed our tests. |
| GLenum IsPossiblyComplete() const; |
| |
| // Check all attachments are cleared |
| bool IsCleared() const; |
| |
| private: |
| friend class FramebufferManager; |
| friend class base::RefCounted<FramebufferInfo>; |
| |
| ~FramebufferInfo(); |
| |
| void MarkAsDeleted(); |
| |
| void MarkAttachmentsAsCleared( |
| RenderbufferManager* renderbuffer_manager, |
| TextureManager* texture_manager); |
| |
| void MarkAsComplete(unsigned state_id) { |
| framebuffer_complete_state_count_id_ = state_id; |
| } |
| |
| unsigned framebuffer_complete_state_count_id() const { |
| return framebuffer_complete_state_count_id_; |
| } |
| |
| // The managers that owns this. |
| FramebufferManager* manager_; |
| |
| bool deleted_; |
| |
| // Service side framebuffer id. |
| GLuint service_id_; |
| |
| // Whether this framebuffer has ever been bound. |
| bool has_been_bound_; |
| |
| // state count when this framebuffer was last checked for completeness. |
| unsigned framebuffer_complete_state_count_id_; |
| |
| // A map of attachments. |
| typedef base::hash_map<GLenum, Attachment::Ref> AttachmentMap; |
| AttachmentMap attachments_; |
| |
| DISALLOW_COPY_AND_ASSIGN(FramebufferInfo); |
| }; |
| |
| FramebufferManager(); |
| ~FramebufferManager(); |
| |
| // Must call before destruction. |
| void Destroy(bool have_context); |
| |
| // Creates a FramebufferInfo for the given framebuffer. |
| void CreateFramebufferInfo(GLuint client_id, GLuint service_id); |
| |
| // Gets the framebuffer info for the given framebuffer. |
| FramebufferInfo* GetFramebufferInfo(GLuint client_id); |
| |
| // Removes a framebuffer info for the given framebuffer. |
| void RemoveFramebufferInfo(GLuint client_id); |
| |
| // Gets a client id for a given service id. |
| bool GetClientId(GLuint service_id, GLuint* client_id) const; |
| |
| void MarkAttachmentsAsCleared( |
| FramebufferInfo* framebuffer, |
| RenderbufferManager* renderbuffer_manager, |
| TextureManager* texture_manager); |
| |
| void MarkAsComplete(FramebufferInfo* framebuffer); |
| |
| bool IsComplete(FramebufferInfo* framebuffer); |
| |
| void IncFramebufferStateChangeCount() { |
| // make sure this is never 0. |
| framebuffer_state_change_count_ = |
| (framebuffer_state_change_count_ + 1) | 0x80000000U; |
| } |
| |
| private: |
| void StartTracking(FramebufferInfo* info); |
| void StopTracking(FramebufferInfo* info); |
| |
| // Info for each framebuffer in the system. |
| typedef base::hash_map<GLuint, FramebufferInfo::Ref> FramebufferInfoMap; |
| FramebufferInfoMap framebuffer_infos_; |
| |
| // Incremented anytime anything changes that might effect framebuffer |
| // state. |
| unsigned framebuffer_state_change_count_; |
| |
| // Counts the number of FramebufferInfo allocated with 'this' as its manager. |
| // Allows to check no FramebufferInfo will outlive this. |
| unsigned int framebuffer_info_count_; |
| |
| bool have_context_; |
| |
| DISALLOW_COPY_AND_ASSIGN(FramebufferManager); |
| }; |
| |
| } // namespace gles2 |
| } // namespace gpu |
| |
| #endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_ |