Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(743)

Side by Side Diff: gpu/command_buffer/service/framebuffer_manager.cc

Issue 1278333003: Fix crash caused by concurrent access to framebuffer_combo_complete_map_. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments; return unittesting of cache behaviour. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {
258 #if defined(OS_MACOSX)
259 // Framebuffer completeness is not cacheable on OS X because of dynamic
260 // graphics switching.
261 // http://crbug.com/180876
262 framebuffer_combo_complete_cache_ = NULL;
no sievers 2015/08/19 23:39:47 Isn't it easier to pass in NULL on Mac from GpuCom
no sievers 2015/08/19 23:47:00 And you can add a TODO, because I think we can do
Ken Russell (switch to Gerrit) 2015/08/20 00:04:10 To the best of my knowledge, Optimus switching doe
Tobias Sargeant 2015/08/20 11:05:13 Moving it to the ContextGroup constructor instead.
Tobias Sargeant 2015/08/20 11:05:13 Done.
263 #endif
271 DCHECK_GT(max_draw_buffers_, 0u); 264 DCHECK_GT(max_draw_buffers_, 0u);
272 DCHECK_GT(max_color_attachments_, 0u); 265 DCHECK_GT(max_color_attachments_, 0u);
273 } 266 }
274 267
275 FramebufferManager::~FramebufferManager() { 268 FramebufferManager::~FramebufferManager() {
276 DCHECK(framebuffers_.empty()); 269 DCHECK(framebuffers_.empty());
277 // If this triggers, that means something is keeping a reference to a 270 // If this triggers, that means something is keeping a reference to a
278 // Framebuffer belonging to this. 271 // Framebuffer belonging to this.
279 CHECK_EQ(framebuffer_count_, 0u); 272 CHECK_EQ(framebuffer_count_, 0u);
280 } 273 }
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 } 489 }
497 } 490 }
498 491
499 // This does not mean the framebuffer is actually complete. It just means our 492 // This does not mean the framebuffer is actually complete. It just means our
500 // checks passed. 493 // checks passed.
501 return GL_FRAMEBUFFER_COMPLETE; 494 return GL_FRAMEBUFFER_COMPLETE;
502 } 495 }
503 496
504 GLenum Framebuffer::GetStatus( 497 GLenum Framebuffer::GetStatus(
505 TextureManager* texture_manager, GLenum target) const { 498 TextureManager* texture_manager, GLenum target) const {
499 if (!manager_->GetFramebufferComboCompleteCache()) {
500 return glCheckFramebufferStatusEXT(target);
501 }
506 // Check if we have this combo already. 502 // Check if we have this combo already.
507 std::string signature; 503 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 504
517 signature.reserve(signature_size); 505 size_t signature_size = sizeof(target);
518 signature.append(reinterpret_cast<const char*>(&target), sizeof(target)); 506 for (AttachmentMap::const_iterator it = attachments_.begin();
507 it != attachments_.end(); ++it) {
508 Attachment* attachment = it->second.get();
509 signature_size +=
510 sizeof(it->first) + attachment->GetSignatureSize(texture_manager);
511 }
519 512
520 for (AttachmentMap::const_iterator it = attachments_.begin(); 513 signature.reserve(signature_size);
521 it != attachments_.end(); ++it) { 514 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 515
529 if (!framebuffer_combo_complete_map_) { 516 for (AttachmentMap::const_iterator it = attachments_.begin();
530 framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap(); 517 it != attachments_.end(); ++it) {
531 } 518 Attachment* attachment = it->second.get();
519 signature.append(reinterpret_cast<const char*>(&it->first),
520 sizeof(it->first));
521 attachment->AddToSignature(texture_manager, &signature);
522 }
523 DCHECK(signature.size() == signature_size);
532 524
533 FramebufferComboCompleteMap::const_iterator it = 525 if (manager_->GetFramebufferComboCompleteCache()->IsComplete(signature)) {
534 framebuffer_combo_complete_map_->find(signature); 526 return GL_FRAMEBUFFER_COMPLETE;
535 if (it != framebuffer_combo_complete_map_->end()) {
536 return GL_FRAMEBUFFER_COMPLETE;
537 }
538 } 527 }
539 528
540 GLenum result = glCheckFramebufferStatusEXT(target); 529 GLenum result = glCheckFramebufferStatusEXT(target);
541 530
542 // Insert the new result into the combo map. 531 if (result == GL_FRAMEBUFFER_COMPLETE) {
543 if (allow_framebuffer_combo_complete_map_ && 532 manager_->GetFramebufferComboCompleteCache()->SetComplete(signature);
544 result == GL_FRAMEBUFFER_COMPLETE) {
545 framebuffer_combo_complete_map_->insert(std::make_pair(signature, true));
546 } 533 }
547 534
548 return result; 535 return result;
549 } 536 }
550 537
551 bool Framebuffer::IsCleared() const { 538 bool Framebuffer::IsCleared() const {
552 // are all the attachments cleaared? 539 // are all the attachments cleaared?
553 for (AttachmentMap::const_iterator it = attachments_.begin(); 540 for (AttachmentMap::const_iterator it = attachments_.begin();
554 it != attachments_.end(); ++it) { 541 it != attachments_.end(); ++it) {
555 Attachment* attachment = it->second.get(); 542 Attachment* attachment = it->second.get();
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 texture_detach_observers_.begin(); 758 texture_detach_observers_.begin();
772 it != texture_detach_observers_.end(); 759 it != texture_detach_observers_.end();
773 ++it) { 760 ++it) {
774 TextureDetachObserver* observer = *it; 761 TextureDetachObserver* observer = *it;
775 observer->OnTextureRefDetachedFromFramebuffer(texture); 762 observer->OnTextureRefDetachedFromFramebuffer(texture);
776 } 763 }
777 } 764 }
778 765
779 } // namespace gles2 766 } // namespace gles2
780 } // namespace gpu 767 } // namespace gpu
781
782
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698