Index: gpu/command_buffer/service/framebuffer_manager.cc |
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc |
index 909a45182b9cec65da344468745fde47538f18e2..0ce9df075ec63e8553f2281c55cfccc673a153f9 100644 |
--- a/gpu/command_buffer/service/framebuffer_manager.cc |
+++ b/gpu/command_buffer/service/framebuffer_manager.cc |
@@ -13,34 +13,36 @@ class RenderbufferAttachment |
: public FramebufferManager::FramebufferInfo::Attachment { |
public: |
explicit RenderbufferAttachment( |
- RenderbufferManager::RenderbufferInfo* render_buffer) |
- : render_buffer_(render_buffer) { |
+ RenderbufferManager::RenderbufferInfo* renderbuffer) |
+ : renderbuffer_(renderbuffer) { |
} |
virtual ~RenderbufferAttachment() { } |
virtual GLsizei width() const { |
- return render_buffer_->width(); |
+ return renderbuffer_->width(); |
} |
virtual GLsizei height() const { |
- return render_buffer_->height(); |
+ return renderbuffer_->height(); |
} |
virtual GLenum internal_format() const { |
- return render_buffer_->internal_format(); |
+ return renderbuffer_->internal_format(); |
} |
virtual GLsizei samples() const { |
- return render_buffer_->samples(); |
+ return renderbuffer_->samples(); |
} |
virtual bool cleared() const { |
- return render_buffer_->cleared(); |
+ return renderbuffer_->cleared(); |
} |
- virtual void set_cleared() { |
- render_buffer_->set_cleared(); |
+ virtual void SetCleared( |
+ RenderbufferManager* renderbuffer_manager, |
+ TextureManager* /* texture_manager */) { |
+ renderbuffer_manager->SetCleared(renderbuffer_); |
} |
virtual bool IsTexture(TextureManager::TextureInfo* /* texture */) const { |
@@ -51,12 +53,21 @@ class RenderbufferAttachment |
return true; |
} |
- RenderbufferManager::RenderbufferInfo* render_buffer() const { |
- return render_buffer_.get(); |
+ virtual void DetachFromFramebuffer() { |
+ // Nothing to do for renderbuffers. |
+ } |
+ |
+ virtual bool ValidForAttachmentType(GLenum attachment_type) { |
+ // TODO(gman): Fill this out. |
+ return true; |
+ } |
+ |
+ RenderbufferManager::RenderbufferInfo* renderbuffer() const { |
+ return renderbuffer_.get(); |
} |
private: |
- RenderbufferManager::RenderbufferInfo::Ref render_buffer_; |
+ RenderbufferManager::RenderbufferInfo::Ref renderbuffer_; |
DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment); |
}; |
@@ -99,12 +110,13 @@ class TextureAttachment |
} |
virtual bool cleared() const { |
- // Textures are cleared on creation. |
- return true; |
+ return texture_->IsLevelCleared(target_, level_); |
} |
- virtual void set_cleared() { |
- NOTREACHED(); |
+ virtual void SetCleared( |
+ RenderbufferManager* /* renderbuffer_manager */, |
+ TextureManager* texture_manager) { |
+ texture_manager->SetLevelCleared(texture_, target_, level_); |
} |
virtual bool IsTexture(TextureManager::TextureInfo* texture) const { |
@@ -119,6 +131,15 @@ class TextureAttachment |
return texture_->CanRenderTo(); |
} |
+ virtual void DetachFromFramebuffer() { |
+ texture_->DetachFromFramebuffer(); |
+ } |
+ |
+ virtual bool ValidForAttachmentType(GLenum attachment_type) { |
+ // TODO(gman): Fill this out. |
+ return true; |
+ } |
+ |
private: |
TextureManager::TextureInfo::Ref texture_; |
GLenum target_; |
@@ -133,15 +154,24 @@ FramebufferManager::~FramebufferManager() { |
DCHECK(framebuffer_infos_.empty()); |
} |
+void FramebufferManager::FramebufferInfo::MarkAsDeleted() { |
+ service_id_ = 0; |
+ while (!attachments_.empty()) { |
+ Attachment* attachment = attachments_.begin()->second.get(); |
+ attachment->DetachFromFramebuffer(); |
+ attachments_.erase(attachments_.begin()); |
+ } |
+} |
+ |
void FramebufferManager::Destroy(bool have_context) { |
while (!framebuffer_infos_.empty()) { |
- if (have_context) { |
- FramebufferInfo* info = framebuffer_infos_.begin()->second; |
- if (!info->IsDeleted()) { |
+ FramebufferInfo* info = framebuffer_infos_.begin()->second; |
+ if (!info->IsDeleted()) { |
+ if (have_context) { |
GLuint service_id = info->service_id(); |
glDeleteFramebuffersEXT(1, &service_id); |
- info->MarkAsDeleted(); |
} |
+ info->MarkAsDeleted(); |
} |
framebuffer_infos_.erase(framebuffer_infos_.begin()); |
} |
@@ -158,8 +188,8 @@ void FramebufferManager::CreateFramebufferInfo( |
} |
FramebufferManager::FramebufferInfo::FramebufferInfo(GLuint service_id) |
- : service_id_(service_id) |
- , has_been_bound_(false) { |
+ : service_id_(service_id), |
+ has_been_bound_(false) { |
} |
FramebufferManager::FramebufferInfo::~FramebufferInfo() {} |
@@ -175,12 +205,14 @@ bool FramebufferManager::FramebufferInfo::HasUnclearedAttachment( |
return false; |
} |
-void FramebufferManager::FramebufferInfo::MarkAttachedRenderbuffersAsCleared() { |
+void FramebufferManager::FramebufferInfo::MarkAttachmentsAsCleared( |
+ RenderbufferManager* renderbuffer_manager, |
+ TextureManager* texture_manager) { |
for (AttachmentMap::iterator it = attachments_.begin(); |
it != attachments_.end(); ++it) { |
Attachment* attachment = it->second; |
if (!attachment->cleared()) { |
- attachment->set_cleared(); |
+ attachment->SetCleared(renderbuffer_manager, texture_manager); |
} |
} |
} |
@@ -204,18 +236,52 @@ GLenum FramebufferManager::FramebufferInfo::GetColorAttachmentFormat() const { |
return attachment->internal_format(); |
} |
-bool FramebufferManager::FramebufferInfo::IsNotComplete() const { |
+GLenum FramebufferManager::FramebufferInfo::IsPossiblyComplete() const { |
+ if (attachments_.empty()) { |
+ return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; |
+ } |
+ |
+ GLsizei width = -1; |
+ GLsizei height = -1; |
for (AttachmentMap::const_iterator it = attachments_.begin(); |
it != attachments_.end(); ++it) { |
+ GLenum attachment_type = it->first; |
Attachment* attachment = it->second; |
- if (attachment->width() == 0 || attachment->height() == 0) { |
- return true; |
+ if (!attachment->ValidForAttachmentType(attachment_type)) { |
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
+ } |
+ if (width < 0) { |
+ width = attachment->width(); |
+ height = attachment->height(); |
+ if (width == 0 || height == 0) { |
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
+ } |
+ } else { |
+ if (attachment->width() != width || attachment->height() != height) { |
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT; |
+ } |
} |
+ |
if (!attachment->CanRenderTo()) { |
- return true; |
+ return GL_FRAMEBUFFER_UNSUPPORTED; |
} |
} |
- return false; |
+ |
+ // This does not mean the framebuffer is actually complete. It just means our |
+ // checks passed. |
+ return GL_FRAMEBUFFER_COMPLETE; |
+} |
+ |
+bool FramebufferManager::FramebufferInfo::IsCleared() const { |
+ // are all the attachments cleaared? |
+ for (AttachmentMap::const_iterator it = attachments_.begin(); |
+ it != attachments_.end(); ++it) { |
+ Attachment* attachment = it->second; |
+ if (!attachment->cleared()) { |
+ return false; |
+ } |
+ } |
+ return true; |
} |
FramebufferManager::FramebufferInfo* FramebufferManager::GetFramebufferInfo( |