| 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(
|
|
|