| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/framebuffer_manager.h" | 5 #include "gpu/command_buffer/service/framebuffer_manager.h" |
| 6 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 8 | 8 |
| 9 namespace gpu { | 9 namespace gpu { |
| 10 namespace gles2 { | 10 namespace gles2 { |
| 11 | 11 |
| 12 class RenderbufferAttachment | 12 class RenderbufferAttachment |
| 13 : public FramebufferManager::FramebufferInfo::Attachment { | 13 : public FramebufferManager::FramebufferInfo::Attachment { |
| 14 public: | 14 public: |
| 15 explicit RenderbufferAttachment( | 15 explicit RenderbufferAttachment( |
| 16 RenderbufferManager::RenderbufferInfo* render_buffer) | 16 RenderbufferManager::RenderbufferInfo* renderbuffer) |
| 17 : render_buffer_(render_buffer) { | 17 : renderbuffer_(renderbuffer) { |
| 18 } | 18 } |
| 19 | 19 |
| 20 virtual ~RenderbufferAttachment() { } | 20 virtual ~RenderbufferAttachment() { } |
| 21 | 21 |
| 22 virtual GLsizei width() const { | 22 virtual GLsizei width() const { |
| 23 return render_buffer_->width(); | 23 return renderbuffer_->width(); |
| 24 } | 24 } |
| 25 | 25 |
| 26 virtual GLsizei height() const { | 26 virtual GLsizei height() const { |
| 27 return render_buffer_->height(); | 27 return renderbuffer_->height(); |
| 28 } | 28 } |
| 29 | 29 |
| 30 virtual GLenum internal_format() const { | 30 virtual GLenum internal_format() const { |
| 31 return render_buffer_->internal_format(); | 31 return renderbuffer_->internal_format(); |
| 32 } | 32 } |
| 33 | 33 |
| 34 virtual GLsizei samples() const { | 34 virtual GLsizei samples() const { |
| 35 return render_buffer_->samples(); | 35 return renderbuffer_->samples(); |
| 36 } | 36 } |
| 37 | 37 |
| 38 virtual bool cleared() const { | 38 virtual bool cleared() const { |
| 39 return render_buffer_->cleared(); | 39 return renderbuffer_->cleared(); |
| 40 } | 40 } |
| 41 | 41 |
| 42 virtual void set_cleared() { | 42 virtual void SetCleared( |
| 43 render_buffer_->set_cleared(); | 43 RenderbufferManager* renderbuffer_manager, |
| 44 TextureManager* /* texture_manager */) { |
| 45 renderbuffer_manager->SetCleared(renderbuffer_); |
| 44 } | 46 } |
| 45 | 47 |
| 46 virtual bool IsTexture(TextureManager::TextureInfo* /* texture */) const { | 48 virtual bool IsTexture(TextureManager::TextureInfo* /* texture */) const { |
| 47 return false; | 49 return false; |
| 48 } | 50 } |
| 49 | 51 |
| 50 virtual bool CanRenderTo() const { | 52 virtual bool CanRenderTo() const { |
| 51 return true; | 53 return true; |
| 52 } | 54 } |
| 53 | 55 |
| 54 RenderbufferManager::RenderbufferInfo* render_buffer() const { | 56 virtual void DetachFromFramebuffer() { |
| 55 return render_buffer_.get(); | 57 // Nothing to do for renderbuffers. |
| 58 } |
| 59 |
| 60 virtual bool ValidForAttachmentType(GLenum attachment_type) { |
| 61 // TODO(gman): Fill this out. |
| 62 return true; |
| 63 } |
| 64 |
| 65 RenderbufferManager::RenderbufferInfo* renderbuffer() const { |
| 66 return renderbuffer_.get(); |
| 56 } | 67 } |
| 57 | 68 |
| 58 private: | 69 private: |
| 59 RenderbufferManager::RenderbufferInfo::Ref render_buffer_; | 70 RenderbufferManager::RenderbufferInfo::Ref renderbuffer_; |
| 60 | 71 |
| 61 DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment); | 72 DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment); |
| 62 }; | 73 }; |
| 63 | 74 |
| 64 class TextureAttachment | 75 class TextureAttachment |
| 65 : public FramebufferManager::FramebufferInfo::Attachment { | 76 : public FramebufferManager::FramebufferInfo::Attachment { |
| 66 public: | 77 public: |
| 67 TextureAttachment( | 78 TextureAttachment( |
| 68 TextureManager::TextureInfo* texture, GLenum target, GLint level) | 79 TextureManager::TextureInfo* texture, GLenum target, GLint level) |
| 69 : texture_(texture), | 80 : texture_(texture), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 92 GLenum temp_internal_format = 0; | 103 GLenum temp_internal_format = 0; |
| 93 texture_->GetLevelType(target_, level_, &temp_type, &temp_internal_format); | 104 texture_->GetLevelType(target_, level_, &temp_type, &temp_internal_format); |
| 94 return temp_internal_format; | 105 return temp_internal_format; |
| 95 } | 106 } |
| 96 | 107 |
| 97 virtual GLsizei samples() const { | 108 virtual GLsizei samples() const { |
| 98 return 0; | 109 return 0; |
| 99 } | 110 } |
| 100 | 111 |
| 101 virtual bool cleared() const { | 112 virtual bool cleared() const { |
| 102 // Textures are cleared on creation. | 113 return texture_->IsLevelCleared(target_, level_); |
| 103 return true; | |
| 104 } | 114 } |
| 105 | 115 |
| 106 virtual void set_cleared() { | 116 virtual void SetCleared( |
| 107 NOTREACHED(); | 117 RenderbufferManager* /* renderbuffer_manager */, |
| 118 TextureManager* texture_manager) { |
| 119 texture_manager->SetLevelCleared(texture_, target_, level_); |
| 108 } | 120 } |
| 109 | 121 |
| 110 virtual bool IsTexture(TextureManager::TextureInfo* texture) const { | 122 virtual bool IsTexture(TextureManager::TextureInfo* texture) const { |
| 111 return texture == texture_.get(); | 123 return texture == texture_.get(); |
| 112 } | 124 } |
| 113 | 125 |
| 114 TextureManager::TextureInfo* texture() const { | 126 TextureManager::TextureInfo* texture() const { |
| 115 return texture_.get(); | 127 return texture_.get(); |
| 116 } | 128 } |
| 117 | 129 |
| 118 virtual bool CanRenderTo() const { | 130 virtual bool CanRenderTo() const { |
| 119 return texture_->CanRenderTo(); | 131 return texture_->CanRenderTo(); |
| 120 } | 132 } |
| 121 | 133 |
| 134 virtual void DetachFromFramebuffer() { |
| 135 texture_->DetachFromFramebuffer(); |
| 136 } |
| 137 |
| 138 virtual bool ValidForAttachmentType(GLenum attachment_type) { |
| 139 // TODO(gman): Fill this out. |
| 140 return true; |
| 141 } |
| 142 |
| 122 private: | 143 private: |
| 123 TextureManager::TextureInfo::Ref texture_; | 144 TextureManager::TextureInfo::Ref texture_; |
| 124 GLenum target_; | 145 GLenum target_; |
| 125 GLint level_; | 146 GLint level_; |
| 126 | 147 |
| 127 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); | 148 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); |
| 128 }; | 149 }; |
| 129 | 150 |
| 130 FramebufferManager::FramebufferManager() {} | 151 FramebufferManager::FramebufferManager() {} |
| 131 | 152 |
| 132 FramebufferManager::~FramebufferManager() { | 153 FramebufferManager::~FramebufferManager() { |
| 133 DCHECK(framebuffer_infos_.empty()); | 154 DCHECK(framebuffer_infos_.empty()); |
| 134 } | 155 } |
| 135 | 156 |
| 157 void FramebufferManager::FramebufferInfo::MarkAsDeleted() { |
| 158 service_id_ = 0; |
| 159 while (!attachments_.empty()) { |
| 160 Attachment* attachment = attachments_.begin()->second.get(); |
| 161 attachment->DetachFromFramebuffer(); |
| 162 attachments_.erase(attachments_.begin()); |
| 163 } |
| 164 } |
| 165 |
| 136 void FramebufferManager::Destroy(bool have_context) { | 166 void FramebufferManager::Destroy(bool have_context) { |
| 137 while (!framebuffer_infos_.empty()) { | 167 while (!framebuffer_infos_.empty()) { |
| 138 if (have_context) { | 168 FramebufferInfo* info = framebuffer_infos_.begin()->second; |
| 139 FramebufferInfo* info = framebuffer_infos_.begin()->second; | 169 if (!info->IsDeleted()) { |
| 140 if (!info->IsDeleted()) { | 170 if (have_context) { |
| 141 GLuint service_id = info->service_id(); | 171 GLuint service_id = info->service_id(); |
| 142 glDeleteFramebuffersEXT(1, &service_id); | 172 glDeleteFramebuffersEXT(1, &service_id); |
| 143 info->MarkAsDeleted(); | |
| 144 } | 173 } |
| 174 info->MarkAsDeleted(); |
| 145 } | 175 } |
| 146 framebuffer_infos_.erase(framebuffer_infos_.begin()); | 176 framebuffer_infos_.erase(framebuffer_infos_.begin()); |
| 147 } | 177 } |
| 148 } | 178 } |
| 149 | 179 |
| 150 void FramebufferManager::CreateFramebufferInfo( | 180 void FramebufferManager::CreateFramebufferInfo( |
| 151 GLuint client_id, GLuint service_id) { | 181 GLuint client_id, GLuint service_id) { |
| 152 std::pair<FramebufferInfoMap::iterator, bool> result = | 182 std::pair<FramebufferInfoMap::iterator, bool> result = |
| 153 framebuffer_infos_.insert( | 183 framebuffer_infos_.insert( |
| 154 std::make_pair( | 184 std::make_pair( |
| 155 client_id, | 185 client_id, |
| 156 FramebufferInfo::Ref(new FramebufferInfo(service_id)))); | 186 FramebufferInfo::Ref(new FramebufferInfo(service_id)))); |
| 157 DCHECK(result.second); | 187 DCHECK(result.second); |
| 158 } | 188 } |
| 159 | 189 |
| 160 FramebufferManager::FramebufferInfo::FramebufferInfo(GLuint service_id) | 190 FramebufferManager::FramebufferInfo::FramebufferInfo(GLuint service_id) |
| 161 : service_id_(service_id) | 191 : service_id_(service_id), |
| 162 , has_been_bound_(false) { | 192 has_been_bound_(false) { |
| 163 } | 193 } |
| 164 | 194 |
| 165 FramebufferManager::FramebufferInfo::~FramebufferInfo() {} | 195 FramebufferManager::FramebufferInfo::~FramebufferInfo() {} |
| 166 | 196 |
| 167 bool FramebufferManager::FramebufferInfo::HasUnclearedAttachment( | 197 bool FramebufferManager::FramebufferInfo::HasUnclearedAttachment( |
| 168 GLenum attachment) const { | 198 GLenum attachment) const { |
| 169 AttachmentMap::const_iterator it = | 199 AttachmentMap::const_iterator it = |
| 170 attachments_.find(attachment); | 200 attachments_.find(attachment); |
| 171 if (it != attachments_.end()) { | 201 if (it != attachments_.end()) { |
| 172 const Attachment* attachment = it->second; | 202 const Attachment* attachment = it->second; |
| 173 return !attachment->cleared(); | 203 return !attachment->cleared(); |
| 174 } | 204 } |
| 175 return false; | 205 return false; |
| 176 } | 206 } |
| 177 | 207 |
| 178 void FramebufferManager::FramebufferInfo::MarkAttachedRenderbuffersAsCleared() { | 208 void FramebufferManager::FramebufferInfo::MarkAttachmentsAsCleared( |
| 209 RenderbufferManager* renderbuffer_manager, |
| 210 TextureManager* texture_manager) { |
| 179 for (AttachmentMap::iterator it = attachments_.begin(); | 211 for (AttachmentMap::iterator it = attachments_.begin(); |
| 180 it != attachments_.end(); ++it) { | 212 it != attachments_.end(); ++it) { |
| 181 Attachment* attachment = it->second; | 213 Attachment* attachment = it->second; |
| 182 if (!attachment->cleared()) { | 214 if (!attachment->cleared()) { |
| 183 attachment->set_cleared(); | 215 attachment->SetCleared(renderbuffer_manager, texture_manager); |
| 184 } | 216 } |
| 185 } | 217 } |
| 186 } | 218 } |
| 187 | 219 |
| 188 bool FramebufferManager::FramebufferInfo::HasDepthAttachment() const { | 220 bool FramebufferManager::FramebufferInfo::HasDepthAttachment() const { |
| 189 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 221 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || |
| 190 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); | 222 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); |
| 191 } | 223 } |
| 192 | 224 |
| 193 bool FramebufferManager::FramebufferInfo::HasStencilAttachment() const { | 225 bool FramebufferManager::FramebufferInfo::HasStencilAttachment() const { |
| 194 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 226 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || |
| 195 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); | 227 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); |
| 196 } | 228 } |
| 197 | 229 |
| 198 GLenum FramebufferManager::FramebufferInfo::GetColorAttachmentFormat() const { | 230 GLenum FramebufferManager::FramebufferInfo::GetColorAttachmentFormat() const { |
| 199 AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); | 231 AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); |
| 200 if (it == attachments_.end()) { | 232 if (it == attachments_.end()) { |
| 201 return 0; | 233 return 0; |
| 202 } | 234 } |
| 203 const Attachment* attachment = it->second; | 235 const Attachment* attachment = it->second; |
| 204 return attachment->internal_format(); | 236 return attachment->internal_format(); |
| 205 } | 237 } |
| 206 | 238 |
| 207 bool FramebufferManager::FramebufferInfo::IsNotComplete() const { | 239 GLenum FramebufferManager::FramebufferInfo::IsPossiblyComplete() const { |
| 240 if (attachments_.empty()) { |
| 241 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; |
| 242 } |
| 243 |
| 244 GLsizei width = -1; |
| 245 GLsizei height = -1; |
| 246 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 247 it != attachments_.end(); ++it) { |
| 248 GLenum attachment_type = it->first; |
| 249 Attachment* attachment = it->second; |
| 250 if (!attachment->ValidForAttachmentType(attachment_type)) { |
| 251 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
| 252 } |
| 253 if (width < 0) { |
| 254 width = attachment->width(); |
| 255 height = attachment->height(); |
| 256 if (width == 0 || height == 0) { |
| 257 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
| 258 } |
| 259 } else { |
| 260 if (attachment->width() != width || attachment->height() != height) { |
| 261 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT; |
| 262 } |
| 263 } |
| 264 |
| 265 if (!attachment->CanRenderTo()) { |
| 266 return GL_FRAMEBUFFER_UNSUPPORTED; |
| 267 } |
| 268 } |
| 269 |
| 270 // This does not mean the framebuffer is actually complete. It just means our |
| 271 // checks passed. |
| 272 return GL_FRAMEBUFFER_COMPLETE; |
| 273 } |
| 274 |
| 275 bool FramebufferManager::FramebufferInfo::IsCleared() const { |
| 276 // are all the attachments cleaared? |
| 208 for (AttachmentMap::const_iterator it = attachments_.begin(); | 277 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 209 it != attachments_.end(); ++it) { | 278 it != attachments_.end(); ++it) { |
| 210 Attachment* attachment = it->second; | 279 Attachment* attachment = it->second; |
| 211 if (attachment->width() == 0 || attachment->height() == 0) { | 280 if (!attachment->cleared()) { |
| 212 return true; | 281 return false; |
| 213 } | |
| 214 if (!attachment->CanRenderTo()) { | |
| 215 return true; | |
| 216 } | 282 } |
| 217 } | 283 } |
| 218 return false; | 284 return true; |
| 219 } | 285 } |
| 220 | 286 |
| 221 FramebufferManager::FramebufferInfo* FramebufferManager::GetFramebufferInfo( | 287 FramebufferManager::FramebufferInfo* FramebufferManager::GetFramebufferInfo( |
| 222 GLuint client_id) { | 288 GLuint client_id) { |
| 223 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); | 289 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); |
| 224 return it != framebuffer_infos_.end() ? it->second : NULL; | 290 return it != framebuffer_infos_.end() ? it->second : NULL; |
| 225 } | 291 } |
| 226 | 292 |
| 227 void FramebufferManager::RemoveFramebufferInfo(GLuint client_id) { | 293 void FramebufferManager::RemoveFramebufferInfo(GLuint client_id) { |
| 228 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); | 294 FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 return true; | 352 return true; |
| 287 } | 353 } |
| 288 } | 354 } |
| 289 return false; | 355 return false; |
| 290 } | 356 } |
| 291 | 357 |
| 292 } // namespace gles2 | 358 } // namespace gles2 |
| 293 } // namespace gpu | 359 } // namespace gpu |
| 294 | 360 |
| 295 | 361 |
| OLD | NEW |