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/strings/stringprintf.h" | 7 #include "base/strings/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/framebuffer_completeness_cache.h" |
9 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 10 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
10 #include "gpu/command_buffer/service/texture_manager.h" | 11 #include "gpu/command_buffer/service/texture_manager.h" |
11 #include "ui/gl/gl_bindings.h" | 12 #include "ui/gl/gl_bindings.h" |
12 | 13 |
13 namespace gpu { | 14 namespace gpu { |
14 namespace gles2 { | 15 namespace gles2 { |
15 | 16 |
16 DecoderFramebufferState::DecoderFramebufferState() | 17 DecoderFramebufferState::DecoderFramebufferState() |
17 : clear_state_dirty(false), | 18 : clear_state_dirty(false), |
18 bound_read_framebuffer(NULL), | 19 bound_read_framebuffer(NULL), |
19 bound_draw_framebuffer(NULL) { | 20 bound_draw_framebuffer(NULL) { |
20 } | 21 } |
21 | 22 |
22 DecoderFramebufferState::~DecoderFramebufferState() { | 23 DecoderFramebufferState::~DecoderFramebufferState() { |
23 } | 24 } |
24 | 25 |
25 Framebuffer::FramebufferComboCompleteMap* | |
26 Framebuffer::framebuffer_combo_complete_map_; | |
27 | |
28 // Framebuffer completeness is not cacheable on OS X because of dynamic | |
29 // graphics switching. | |
30 // http://crbug.com/180876 | |
31 #if defined(OS_MACOSX) | |
32 bool Framebuffer::allow_framebuffer_combo_complete_map_ = false; | |
33 #else | |
34 bool Framebuffer::allow_framebuffer_combo_complete_map_ = true; | |
35 #endif | |
36 | |
37 void Framebuffer::ClearFramebufferCompleteComboMap() { | |
38 if (framebuffer_combo_complete_map_) { | |
39 framebuffer_combo_complete_map_->clear(); | |
40 } | |
41 } | |
42 | |
43 class RenderbufferAttachment | 26 class RenderbufferAttachment |
44 : public Framebuffer::Attachment { | 27 : public Framebuffer::Attachment { |
45 public: | 28 public: |
46 explicit RenderbufferAttachment( | 29 explicit RenderbufferAttachment( |
47 Renderbuffer* renderbuffer) | 30 Renderbuffer* renderbuffer) |
48 : renderbuffer_(renderbuffer) { | 31 : renderbuffer_(renderbuffer) { |
49 } | 32 } |
50 | 33 |
51 GLsizei width() const override { return renderbuffer_->width(); } | 34 GLsizei width() const override { return renderbuffer_->width(); } |
52 | 35 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 GLsizei samples_; | 236 GLsizei samples_; |
254 | 237 |
255 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); | 238 DISALLOW_COPY_AND_ASSIGN(TextureAttachment); |
256 }; | 239 }; |
257 | 240 |
258 FramebufferManager::TextureDetachObserver::TextureDetachObserver() {} | 241 FramebufferManager::TextureDetachObserver::TextureDetachObserver() {} |
259 | 242 |
260 FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {} | 243 FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {} |
261 | 244 |
262 FramebufferManager::FramebufferManager( | 245 FramebufferManager::FramebufferManager( |
263 uint32 max_draw_buffers, uint32 max_color_attachments, | 246 uint32 max_draw_buffers, |
264 ContextGroup::ContextType context_type) | 247 uint32 max_color_attachments, |
| 248 ContextGroup::ContextType context_type, |
| 249 const scoped_refptr<FramebufferCompletenessCache>& |
| 250 framebuffer_combo_complete_cache) |
265 : framebuffer_state_change_count_(1), | 251 : framebuffer_state_change_count_(1), |
266 framebuffer_count_(0), | 252 framebuffer_count_(0), |
267 have_context_(true), | 253 have_context_(true), |
268 max_draw_buffers_(max_draw_buffers), | 254 max_draw_buffers_(max_draw_buffers), |
269 max_color_attachments_(max_color_attachments), | 255 max_color_attachments_(max_color_attachments), |
270 context_type_(context_type) { | 256 context_type_(context_type), |
| 257 framebuffer_combo_complete_cache_(framebuffer_combo_complete_cache) { |
271 DCHECK_GT(max_draw_buffers_, 0u); | 258 DCHECK_GT(max_draw_buffers_, 0u); |
272 DCHECK_GT(max_color_attachments_, 0u); | 259 DCHECK_GT(max_color_attachments_, 0u); |
273 } | 260 } |
274 | 261 |
275 FramebufferManager::~FramebufferManager() { | 262 FramebufferManager::~FramebufferManager() { |
276 DCHECK(framebuffers_.empty()); | 263 DCHECK(framebuffers_.empty()); |
277 // If this triggers, that means something is keeping a reference to a | 264 // If this triggers, that means something is keeping a reference to a |
278 // Framebuffer belonging to this. | 265 // Framebuffer belonging to this. |
279 CHECK_EQ(framebuffer_count_, 0u); | 266 CHECK_EQ(framebuffer_count_, 0u); |
280 } | 267 } |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 } | 483 } |
497 } | 484 } |
498 | 485 |
499 // This does not mean the framebuffer is actually complete. It just means our | 486 // This does not mean the framebuffer is actually complete. It just means our |
500 // checks passed. | 487 // checks passed. |
501 return GL_FRAMEBUFFER_COMPLETE; | 488 return GL_FRAMEBUFFER_COMPLETE; |
502 } | 489 } |
503 | 490 |
504 GLenum Framebuffer::GetStatus( | 491 GLenum Framebuffer::GetStatus( |
505 TextureManager* texture_manager, GLenum target) const { | 492 TextureManager* texture_manager, GLenum target) const { |
| 493 if (!manager_->GetFramebufferComboCompleteCache()) { |
| 494 return glCheckFramebufferStatusEXT(target); |
| 495 } |
506 // Check if we have this combo already. | 496 // Check if we have this combo already. |
507 std::string signature; | 497 std::string signature; |
508 if (allow_framebuffer_combo_complete_map_) { | |
509 size_t signature_size = sizeof(target); | |
510 for (AttachmentMap::const_iterator it = attachments_.begin(); | |
511 it != attachments_.end(); ++it) { | |
512 Attachment* attachment = it->second.get(); | |
513 signature_size += sizeof(it->first) + | |
514 attachment->GetSignatureSize(texture_manager); | |
515 } | |
516 | 498 |
517 signature.reserve(signature_size); | 499 size_t signature_size = sizeof(target); |
518 signature.append(reinterpret_cast<const char*>(&target), sizeof(target)); | 500 for (AttachmentMap::const_iterator it = attachments_.begin(); |
| 501 it != attachments_.end(); ++it) { |
| 502 Attachment* attachment = it->second.get(); |
| 503 signature_size += |
| 504 sizeof(it->first) + attachment->GetSignatureSize(texture_manager); |
| 505 } |
519 | 506 |
520 for (AttachmentMap::const_iterator it = attachments_.begin(); | 507 signature.reserve(signature_size); |
521 it != attachments_.end(); ++it) { | 508 signature.append(reinterpret_cast<const char*>(&target), sizeof(target)); |
522 Attachment* attachment = it->second.get(); | |
523 signature.append(reinterpret_cast<const char*>(&it->first), | |
524 sizeof(it->first)); | |
525 attachment->AddToSignature(texture_manager, &signature); | |
526 } | |
527 DCHECK(signature.size() == signature_size); | |
528 | 509 |
529 if (!framebuffer_combo_complete_map_) { | 510 for (AttachmentMap::const_iterator it = attachments_.begin(); |
530 framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap(); | 511 it != attachments_.end(); ++it) { |
531 } | 512 Attachment* attachment = it->second.get(); |
| 513 signature.append(reinterpret_cast<const char*>(&it->first), |
| 514 sizeof(it->first)); |
| 515 attachment->AddToSignature(texture_manager, &signature); |
| 516 } |
| 517 DCHECK(signature.size() == signature_size); |
532 | 518 |
533 FramebufferComboCompleteMap::const_iterator it = | 519 if (manager_->GetFramebufferComboCompleteCache()->IsComplete(signature)) { |
534 framebuffer_combo_complete_map_->find(signature); | 520 return GL_FRAMEBUFFER_COMPLETE; |
535 if (it != framebuffer_combo_complete_map_->end()) { | |
536 return GL_FRAMEBUFFER_COMPLETE; | |
537 } | |
538 } | 521 } |
539 | 522 |
540 GLenum result = glCheckFramebufferStatusEXT(target); | 523 GLenum result = glCheckFramebufferStatusEXT(target); |
541 | 524 |
542 // Insert the new result into the combo map. | 525 if (result == GL_FRAMEBUFFER_COMPLETE) { |
543 if (allow_framebuffer_combo_complete_map_ && | 526 manager_->GetFramebufferComboCompleteCache()->SetComplete(signature); |
544 result == GL_FRAMEBUFFER_COMPLETE) { | |
545 framebuffer_combo_complete_map_->insert(std::make_pair(signature, true)); | |
546 } | 527 } |
547 | 528 |
548 return result; | 529 return result; |
549 } | 530 } |
550 | 531 |
551 bool Framebuffer::IsCleared() const { | 532 bool Framebuffer::IsCleared() const { |
552 // are all the attachments cleaared? | 533 // are all the attachments cleaared? |
553 for (AttachmentMap::const_iterator it = attachments_.begin(); | 534 for (AttachmentMap::const_iterator it = attachments_.begin(); |
554 it != attachments_.end(); ++it) { | 535 it != attachments_.end(); ++it) { |
555 Attachment* attachment = it->second.get(); | 536 Attachment* attachment = it->second.get(); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 texture_detach_observers_.begin(); | 752 texture_detach_observers_.begin(); |
772 it != texture_detach_observers_.end(); | 753 it != texture_detach_observers_.end(); |
773 ++it) { | 754 ++it) { |
774 TextureDetachObserver* observer = *it; | 755 TextureDetachObserver* observer = *it; |
775 observer->OnTextureRefDetachedFromFramebuffer(texture); | 756 observer->OnTextureRefDetachedFromFramebuffer(texture); |
776 } | 757 } |
777 } | 758 } |
778 | 759 |
779 } // namespace gles2 | 760 } // namespace gles2 |
780 } // namespace gpu | 761 } // namespace gpu |
781 | |
782 | |
OLD | NEW |