OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/stringprintf.h" | 7 #include "base/stringprintf.h" |
8 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 8 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
9 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 9 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
10 #include "gpu/command_buffer/service/texture_manager.h" | 10 #include "gpu/command_buffer/service/texture_manager.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 } | 68 } |
69 | 69 |
70 virtual bool CanRenderTo() const OVERRIDE { | 70 virtual bool CanRenderTo() const OVERRIDE { |
71 return true; | 71 return true; |
72 } | 72 } |
73 | 73 |
74 virtual void DetachFromFramebuffer() const OVERRIDE { | 74 virtual void DetachFromFramebuffer() const OVERRIDE { |
75 // Nothing to do for renderbuffers. | 75 // Nothing to do for renderbuffers. |
76 } | 76 } |
77 | 77 |
78 virtual bool ValidForAttachmentType(GLenum attachment_type) OVERRIDE { | 78 virtual bool ValidForAttachmentType( |
| 79 GLenum attachment_type, uint32 max_color_attachments) OVERRIDE { |
79 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType( | 80 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType( |
80 attachment_type); | 81 attachment_type, max_color_attachments); |
81 uint32 have = GLES2Util::GetChannelsForFormat(internal_format()); | 82 uint32 have = GLES2Util::GetChannelsForFormat(internal_format()); |
82 return (need & have) != 0; | 83 return (need & have) != 0; |
83 } | 84 } |
84 | 85 |
85 Renderbuffer* renderbuffer() const { | 86 Renderbuffer* renderbuffer() const { |
86 return renderbuffer_.get(); | 87 return renderbuffer_.get(); |
87 } | 88 } |
88 | 89 |
89 virtual void AddToSignature( | 90 virtual void AddToSignature( |
90 TextureManager* texture_manager, std::string* signature) const OVERRIDE { | 91 TextureManager* texture_manager, std::string* signature) const OVERRIDE { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 163 } |
163 | 164 |
164 virtual bool CanRenderTo() const OVERRIDE { | 165 virtual bool CanRenderTo() const OVERRIDE { |
165 return texture_->CanRenderTo(); | 166 return texture_->CanRenderTo(); |
166 } | 167 } |
167 | 168 |
168 virtual void DetachFromFramebuffer() const OVERRIDE { | 169 virtual void DetachFromFramebuffer() const OVERRIDE { |
169 texture_->DetachFromFramebuffer(); | 170 texture_->DetachFromFramebuffer(); |
170 } | 171 } |
171 | 172 |
172 virtual bool ValidForAttachmentType(GLenum attachment_type) OVERRIDE { | 173 virtual bool ValidForAttachmentType( |
| 174 GLenum attachment_type, uint32 max_color_attachments) OVERRIDE { |
173 GLenum type = 0; | 175 GLenum type = 0; |
174 GLenum internal_format = 0; | 176 GLenum internal_format = 0; |
175 if (!texture_->GetLevelType(target_, level_, &type, &internal_format)) { | 177 if (!texture_->GetLevelType(target_, level_, &type, &internal_format)) { |
176 return false; | 178 return false; |
177 } | 179 } |
178 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType( | 180 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType( |
179 attachment_type); | 181 attachment_type, max_color_attachments); |
180 uint32 have = GLES2Util::GetChannelsForFormat(internal_format); | 182 uint32 have = GLES2Util::GetChannelsForFormat(internal_format); |
181 return (need & have) != 0; | 183 return (need & have) != 0; |
182 } | 184 } |
183 | 185 |
184 virtual void AddToSignature( | 186 virtual void AddToSignature( |
185 TextureManager* texture_manager, std::string* signature) const OVERRIDE { | 187 TextureManager* texture_manager, std::string* signature) const OVERRIDE { |
186 DCHECK(signature); | 188 DCHECK(signature); |
187 texture_manager->AddToSignature(texture_, target_, level_, signature); | 189 texture_manager->AddToSignature(texture_, target_, level_, signature); |
188 } | 190 } |
189 | 191 |
190 protected: | 192 protected: |
191 virtual ~TextureAttachment() {} | 193 virtual ~TextureAttachment() {} |
192 | 194 |
193 private: | 195 private: |
194 scoped_refptr<Texture> texture_; | 196 scoped_refptr<Texture> texture_; |
195 GLenum target_; | 197 GLenum target_; |
196 GLint level_; | 198 GLint level_; |
197 | 199 |
198 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); | 200 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); |
199 }; | 201 }; |
200 | 202 |
201 FramebufferManager::FramebufferManager() | 203 FramebufferManager::FramebufferManager( |
| 204 uint32 max_draw_buffers, uint32 max_color_attachments) |
202 : framebuffer_state_change_count_(1), | 205 : framebuffer_state_change_count_(1), |
203 framebuffer_count_(0), | 206 framebuffer_count_(0), |
204 have_context_(true) { | 207 have_context_(true), |
| 208 max_draw_buffers_(max_draw_buffers), |
| 209 max_color_attachments_(max_color_attachments) { |
| 210 DCHECK_GT(max_draw_buffers_, 0u); |
| 211 DCHECK_GT(max_color_attachments_, 0u); |
205 } | 212 } |
206 | 213 |
207 FramebufferManager::~FramebufferManager() { | 214 FramebufferManager::~FramebufferManager() { |
208 DCHECK(framebuffers_.empty()); | 215 DCHECK(framebuffers_.empty()); |
209 // If this triggers, that means something is keeping a reference to a | 216 // If this triggers, that means something is keeping a reference to a |
210 // Framebuffer belonging to this. | 217 // Framebuffer belonging to this. |
211 CHECK_EQ(framebuffer_count_, 0u); | 218 CHECK_EQ(framebuffer_count_, 0u); |
212 } | 219 } |
213 | 220 |
214 void Framebuffer::MarkAsDeleted() { | 221 void Framebuffer::MarkAsDeleted() { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 } | 254 } |
248 | 255 |
249 Framebuffer::Framebuffer( | 256 Framebuffer::Framebuffer( |
250 FramebufferManager* manager, GLuint service_id) | 257 FramebufferManager* manager, GLuint service_id) |
251 : manager_(manager), | 258 : manager_(manager), |
252 deleted_(false), | 259 deleted_(false), |
253 service_id_(service_id), | 260 service_id_(service_id), |
254 has_been_bound_(false), | 261 has_been_bound_(false), |
255 framebuffer_complete_state_count_id_(0) { | 262 framebuffer_complete_state_count_id_(0) { |
256 manager->StartTracking(this); | 263 manager->StartTracking(this); |
| 264 DCHECK_GT(manager->max_draw_buffers_, 0u); |
| 265 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); |
| 266 draw_buffers_[0] = GL_COLOR_ATTACHMENT0; |
| 267 for (uint32 i = 1; i < manager->max_draw_buffers_; ++i) |
| 268 draw_buffers_[i] = GL_NONE; |
257 } | 269 } |
258 | 270 |
259 Framebuffer::~Framebuffer() { | 271 Framebuffer::~Framebuffer() { |
260 if (manager_) { | 272 if (manager_) { |
261 if (manager_->have_context_) { | 273 if (manager_->have_context_) { |
262 GLuint id = service_id(); | 274 GLuint id = service_id(); |
263 glDeleteFramebuffersEXT(1, &id); | 275 glDeleteFramebuffersEXT(1, &id); |
264 } | 276 } |
265 manager_->StopTracking(this); | 277 manager_->StopTracking(this); |
266 manager_ = NULL; | 278 manager_ = NULL; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 if (attachments_.empty()) { | 342 if (attachments_.empty()) { |
331 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; | 343 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; |
332 } | 344 } |
333 | 345 |
334 GLsizei width = -1; | 346 GLsizei width = -1; |
335 GLsizei height = -1; | 347 GLsizei height = -1; |
336 for (AttachmentMap::const_iterator it = attachments_.begin(); | 348 for (AttachmentMap::const_iterator it = attachments_.begin(); |
337 it != attachments_.end(); ++it) { | 349 it != attachments_.end(); ++it) { |
338 GLenum attachment_type = it->first; | 350 GLenum attachment_type = it->first; |
339 Attachment* attachment = it->second; | 351 Attachment* attachment = it->second; |
340 if (!attachment->ValidForAttachmentType(attachment_type)) { | 352 if (!attachment->ValidForAttachmentType( |
| 353 attachment_type, manager_->max_color_attachments_)) { |
341 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | 354 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
342 } | 355 } |
343 if (width < 0) { | 356 if (width < 0) { |
344 width = attachment->width(); | 357 width = attachment->width(); |
345 height = attachment->height(); | 358 height = attachment->height(); |
346 if (width == 0 || height == 0) { | 359 if (width == 0 || height == 0) { |
347 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | 360 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
348 } | 361 } |
349 } else { | 362 } else { |
350 if (attachment->width() != width || attachment->height() != height) { | 363 if (attachment->width() != width || attachment->height() != height) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 for (AttachmentMap::const_iterator it = attachments_.begin(); | 408 for (AttachmentMap::const_iterator it = attachments_.begin(); |
396 it != attachments_.end(); ++it) { | 409 it != attachments_.end(); ++it) { |
397 Attachment* attachment = it->second; | 410 Attachment* attachment = it->second; |
398 if (!attachment->cleared()) { | 411 if (!attachment->cleared()) { |
399 return false; | 412 return false; |
400 } | 413 } |
401 } | 414 } |
402 return true; | 415 return true; |
403 } | 416 } |
404 | 417 |
| 418 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { |
| 419 GLsizei index = static_cast<GLsizei>( |
| 420 draw_buffer - GL_DRAW_BUFFER0_ARB); |
| 421 CHECK(index >= 0 && |
| 422 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); |
| 423 return draw_buffers_[index]; |
| 424 } |
| 425 |
| 426 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { |
| 427 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); |
| 428 for (GLsizei i = 0; i < n; ++i) |
| 429 draw_buffers_[i] = bufs[i]; |
| 430 } |
| 431 |
405 void Framebuffer::UnbindRenderbuffer( | 432 void Framebuffer::UnbindRenderbuffer( |
406 GLenum target, Renderbuffer* renderbuffer) { | 433 GLenum target, Renderbuffer* renderbuffer) { |
407 bool done; | 434 bool done; |
408 do { | 435 do { |
409 done = true; | 436 done = true; |
410 for (AttachmentMap::const_iterator it = attachments_.begin(); | 437 for (AttachmentMap::const_iterator it = attachments_.begin(); |
411 it != attachments_.end(); ++it) { | 438 it != attachments_.end(); ++it) { |
412 Attachment* attachment = it->second; | 439 Attachment* attachment = it->second; |
413 if (attachment->IsRenderbuffer(renderbuffer)) { | 440 if (attachment->IsRenderbuffer(renderbuffer)) { |
414 // TODO(gman): manually detach renderbuffer. | 441 // TODO(gman): manually detach renderbuffer. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { | 476 void FramebufferManager::RemoveFramebuffer(GLuint client_id) { |
450 FramebufferMap::iterator it = framebuffers_.find(client_id); | 477 FramebufferMap::iterator it = framebuffers_.find(client_id); |
451 if (it != framebuffers_.end()) { | 478 if (it != framebuffers_.end()) { |
452 it->second->MarkAsDeleted(); | 479 it->second->MarkAsDeleted(); |
453 framebuffers_.erase(it); | 480 framebuffers_.erase(it); |
454 } | 481 } |
455 } | 482 } |
456 | 483 |
457 void Framebuffer::AttachRenderbuffer( | 484 void Framebuffer::AttachRenderbuffer( |
458 GLenum attachment, Renderbuffer* renderbuffer) { | 485 GLenum attachment, Renderbuffer* renderbuffer) { |
459 DCHECK(attachment == GL_COLOR_ATTACHMENT0 || | |
460 attachment == GL_DEPTH_ATTACHMENT || | |
461 attachment == GL_STENCIL_ATTACHMENT || | |
462 attachment == GL_DEPTH_STENCIL_ATTACHMENT); | |
463 const Attachment* a = GetAttachment(attachment); | 486 const Attachment* a = GetAttachment(attachment); |
464 if (a) | 487 if (a) |
465 a->DetachFromFramebuffer(); | 488 a->DetachFromFramebuffer(); |
466 if (renderbuffer) { | 489 if (renderbuffer) { |
467 attachments_[attachment] = scoped_refptr<Attachment>( | 490 attachments_[attachment] = scoped_refptr<Attachment>( |
468 new RenderbufferAttachment(renderbuffer)); | 491 new RenderbufferAttachment(renderbuffer)); |
469 } else { | 492 } else { |
470 attachments_.erase(attachment); | 493 attachments_.erase(attachment); |
471 } | 494 } |
472 framebuffer_complete_state_count_id_ = 0; | 495 framebuffer_complete_state_count_id_ = 0; |
473 } | 496 } |
474 | 497 |
475 void Framebuffer::AttachTexture( | 498 void Framebuffer::AttachTexture( |
476 GLenum attachment, Texture* texture, GLenum target, | 499 GLenum attachment, Texture* texture, GLenum target, |
477 GLint level) { | 500 GLint level) { |
478 DCHECK(attachment == GL_COLOR_ATTACHMENT0 || | |
479 attachment == GL_DEPTH_ATTACHMENT || | |
480 attachment == GL_STENCIL_ATTACHMENT || | |
481 attachment == GL_DEPTH_STENCIL_ATTACHMENT); | |
482 const Attachment* a = GetAttachment(attachment); | 501 const Attachment* a = GetAttachment(attachment); |
483 if (a) | 502 if (a) |
484 a->DetachFromFramebuffer(); | 503 a->DetachFromFramebuffer(); |
485 if (texture) { | 504 if (texture) { |
486 attachments_[attachment] = scoped_refptr<Attachment>( | 505 attachments_[attachment] = scoped_refptr<Attachment>( |
487 new TextureAttachment(texture, target, level)); | 506 new TextureAttachment(texture, target, level)); |
488 texture->AttachToFramebuffer(); | 507 texture->AttachToFramebuffer(); |
489 } else { | 508 } else { |
490 attachments_.erase(attachment); | 509 attachments_.erase(attachment); |
491 } | 510 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 Framebuffer* framebuffer) { | 555 Framebuffer* framebuffer) { |
537 DCHECK(framebuffer); | 556 DCHECK(framebuffer); |
538 return framebuffer->framebuffer_complete_state_count_id() == | 557 return framebuffer->framebuffer_complete_state_count_id() == |
539 framebuffer_state_change_count_; | 558 framebuffer_state_change_count_; |
540 } | 559 } |
541 | 560 |
542 } // namespace gles2 | 561 } // namespace gles2 |
543 } // namespace gpu | 562 } // namespace gpu |
544 | 563 |
545 | 564 |
OLD | NEW |