Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / gpu / command_buffer / service / framebuffer_manager.cc
blob9a1b77cdfce90133e57274917bf9f482962c87d8
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
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/framebuffer_manager.h"
6 #include "base/logging.h"
7 #include "base/strings/stringprintf.h"
8 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
9 #include "gpu/command_buffer/service/renderbuffer_manager.h"
10 #include "gpu/command_buffer/service/texture_manager.h"
11 #include "ui/gl/gl_bindings.h"
13 namespace gpu {
14 namespace gles2 {
16 DecoderFramebufferState::DecoderFramebufferState()
17 : clear_state_dirty(false),
18 bound_read_framebuffer(NULL),
19 bound_draw_framebuffer(NULL) {
22 DecoderFramebufferState::~DecoderFramebufferState() {
25 Framebuffer::FramebufferComboCompleteMap*
26 Framebuffer::framebuffer_combo_complete_map_;
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
37 void Framebuffer::ClearFramebufferCompleteComboMap() {
38 if (framebuffer_combo_complete_map_) {
39 framebuffer_combo_complete_map_->clear();
43 class RenderbufferAttachment
44 : public Framebuffer::Attachment {
45 public:
46 explicit RenderbufferAttachment(
47 Renderbuffer* renderbuffer)
48 : renderbuffer_(renderbuffer) {
51 GLsizei width() const override { return renderbuffer_->width(); }
53 GLsizei height() const override { return renderbuffer_->height(); }
55 GLenum internal_format() const override {
56 return renderbuffer_->internal_format();
59 GLenum texture_type() const override { return 0; }
61 GLsizei samples() const override { return renderbuffer_->samples(); }
63 GLuint object_name() const override { return renderbuffer_->client_id(); }
65 bool cleared() const override { return renderbuffer_->cleared(); }
67 void SetCleared(RenderbufferManager* renderbuffer_manager,
68 TextureManager* /* texture_manager */,
69 bool cleared) override {
70 renderbuffer_manager->SetCleared(renderbuffer_.get(), cleared);
73 bool IsTexture(TextureRef* /* texture */) const override { return false; }
75 bool IsRenderbuffer(Renderbuffer* renderbuffer) const override {
76 return renderbuffer_.get() == renderbuffer;
79 bool CanRenderTo() const override { return true; }
81 void DetachFromFramebuffer(Framebuffer* framebuffer) const override {
82 // Nothing to do for renderbuffers.
85 bool ValidForAttachmentType(GLenum attachment_type,
86 uint32 max_color_attachments) override {
87 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType(
88 attachment_type, max_color_attachments);
89 uint32 have = GLES2Util::GetChannelsForFormat(internal_format());
90 return (need & have) != 0;
93 Renderbuffer* renderbuffer() const {
94 return renderbuffer_.get();
97 size_t GetSignatureSize(TextureManager* texture_manager) const override {
98 return renderbuffer_->GetSignatureSize();
101 void AddToSignature(TextureManager* texture_manager,
102 std::string* signature) const override {
103 DCHECK(signature);
104 renderbuffer_->AddToSignature(signature);
107 void OnWillRenderTo() const override {}
108 void OnDidRenderTo() const override {}
109 bool FormsFeedbackLoop(TextureRef* /* texture */,
110 GLint /*level */) const override {
111 return false;
114 protected:
115 ~RenderbufferAttachment() override {}
117 private:
118 scoped_refptr<Renderbuffer> renderbuffer_;
120 DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment);
123 class TextureAttachment
124 : public Framebuffer::Attachment {
125 public:
126 TextureAttachment(
127 TextureRef* texture_ref, GLenum target, GLint level, GLsizei samples)
128 : texture_ref_(texture_ref),
129 target_(target),
130 level_(level),
131 samples_(samples) {
134 GLsizei width() const override {
135 GLsizei temp_width = 0;
136 GLsizei temp_height = 0;
137 texture_ref_->texture()->GetLevelSize(
138 target_, level_, &temp_width, &temp_height, nullptr);
139 return temp_width;
142 GLsizei height() const override {
143 GLsizei temp_width = 0;
144 GLsizei temp_height = 0;
145 texture_ref_->texture()->GetLevelSize(
146 target_, level_, &temp_width, &temp_height, nullptr);
147 return temp_height;
150 GLenum internal_format() const override {
151 GLenum temp_type = 0;
152 GLenum temp_internal_format = 0;
153 texture_ref_->texture()->GetLevelType(
154 target_, level_, &temp_type, &temp_internal_format);
155 return temp_internal_format;
158 GLenum texture_type() const override {
159 GLenum temp_type = 0;
160 GLenum temp_internal_format = 0;
161 texture_ref_->texture()->GetLevelType(
162 target_, level_, &temp_type, &temp_internal_format);
163 return temp_type;
166 GLsizei samples() const override { return samples_; }
168 GLuint object_name() const override { return texture_ref_->client_id(); }
170 bool cleared() const override {
171 return texture_ref_->texture()->IsLevelCleared(target_, level_);
174 void SetCleared(RenderbufferManager* /* renderbuffer_manager */,
175 TextureManager* texture_manager,
176 bool cleared) override {
177 texture_manager->SetLevelCleared(
178 texture_ref_.get(), target_, level_, cleared);
181 bool IsTexture(TextureRef* texture) const override {
182 return texture == texture_ref_.get();
185 bool IsRenderbuffer(Renderbuffer* /* renderbuffer */) const override {
186 return false;
189 TextureRef* texture() const {
190 return texture_ref_.get();
193 bool CanRenderTo() const override {
194 return texture_ref_->texture()->CanRenderTo();
197 void DetachFromFramebuffer(Framebuffer* framebuffer) const override {
198 texture_ref_->texture()->DetachFromFramebuffer();
199 framebuffer->OnTextureRefDetached(texture_ref_.get());
202 bool ValidForAttachmentType(GLenum attachment_type,
203 uint32 max_color_attachments) override {
204 GLenum type = 0;
205 GLenum internal_format = 0;
206 if (!texture_ref_->texture()->GetLevelType(
207 target_, level_, &type, &internal_format)) {
208 return false;
210 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType(
211 attachment_type, max_color_attachments);
212 uint32 have = GLES2Util::GetChannelsForFormat(internal_format);
214 // Workaround for NVIDIA drivers that incorrectly expose these formats as
215 // renderable:
216 if (internal_format == GL_LUMINANCE || internal_format == GL_ALPHA ||
217 internal_format == GL_LUMINANCE_ALPHA) {
218 return false;
220 return (need & have) != 0;
223 size_t GetSignatureSize(TextureManager* texture_manager) const override {
224 return texture_manager->GetSignatureSize();
227 void AddToSignature(TextureManager* texture_manager,
228 std::string* signature) const override {
229 DCHECK(signature);
230 texture_manager->AddToSignature(
231 texture_ref_.get(), target_, level_, signature);
234 void OnWillRenderTo() const override {
235 texture_ref_->texture()->OnWillModifyPixels();
238 void OnDidRenderTo() const override {
239 texture_ref_->texture()->OnDidModifyPixels();
242 bool FormsFeedbackLoop(TextureRef* texture, GLint level) const override {
243 return texture == texture_ref_.get() && level == level_;
246 protected:
247 ~TextureAttachment() override {}
249 private:
250 scoped_refptr<TextureRef> texture_ref_;
251 GLenum target_;
252 GLint level_;
253 GLsizei samples_;
255 DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
258 FramebufferManager::TextureDetachObserver::TextureDetachObserver() {}
260 FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {}
262 FramebufferManager::FramebufferManager(
263 uint32 max_draw_buffers, uint32 max_color_attachments,
264 ContextGroup::ContextType context_type)
265 : framebuffer_state_change_count_(1),
266 framebuffer_count_(0),
267 have_context_(true),
268 max_draw_buffers_(max_draw_buffers),
269 max_color_attachments_(max_color_attachments),
270 context_type_(context_type) {
271 DCHECK_GT(max_draw_buffers_, 0u);
272 DCHECK_GT(max_color_attachments_, 0u);
275 FramebufferManager::~FramebufferManager() {
276 DCHECK(framebuffers_.empty());
277 // If this triggers, that means something is keeping a reference to a
278 // Framebuffer belonging to this.
279 CHECK_EQ(framebuffer_count_, 0u);
282 void Framebuffer::MarkAsDeleted() {
283 deleted_ = true;
284 while (!attachments_.empty()) {
285 Attachment* attachment = attachments_.begin()->second.get();
286 attachment->DetachFromFramebuffer(this);
287 attachments_.erase(attachments_.begin());
291 void FramebufferManager::Destroy(bool have_context) {
292 have_context_ = have_context;
293 framebuffers_.clear();
296 void FramebufferManager::StartTracking(
297 Framebuffer* /* framebuffer */) {
298 ++framebuffer_count_;
301 void FramebufferManager::StopTracking(
302 Framebuffer* /* framebuffer */) {
303 --framebuffer_count_;
306 void FramebufferManager::CreateFramebuffer(
307 GLuint client_id, GLuint service_id) {
308 std::pair<FramebufferMap::iterator, bool> result =
309 framebuffers_.insert(
310 std::make_pair(
311 client_id,
312 scoped_refptr<Framebuffer>(
313 new Framebuffer(this, service_id))));
314 DCHECK(result.second);
317 Framebuffer::Framebuffer(
318 FramebufferManager* manager, GLuint service_id)
319 : manager_(manager),
320 deleted_(false),
321 service_id_(service_id),
322 has_been_bound_(false),
323 framebuffer_complete_state_count_id_(0),
324 read_buffer_(GL_COLOR_ATTACHMENT0) {
325 manager->StartTracking(this);
326 DCHECK_GT(manager->max_draw_buffers_, 0u);
327 draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]);
328 draw_buffers_[0] = GL_COLOR_ATTACHMENT0;
329 for (uint32 i = 1; i < manager->max_draw_buffers_; ++i)
330 draw_buffers_[i] = GL_NONE;
333 Framebuffer::~Framebuffer() {
334 if (manager_) {
335 if (manager_->have_context_) {
336 GLuint id = service_id();
337 glDeleteFramebuffersEXT(1, &id);
339 manager_->StopTracking(this);
340 manager_ = NULL;
344 bool Framebuffer::HasUnclearedAttachment(
345 GLenum attachment) const {
346 AttachmentMap::const_iterator it =
347 attachments_.find(attachment);
348 if (it != attachments_.end()) {
349 const Attachment* attachment = it->second.get();
350 return !attachment->cleared();
352 return false;
355 bool Framebuffer::HasUnclearedColorAttachments() const {
356 for (AttachmentMap::const_iterator it = attachments_.begin();
357 it != attachments_.end(); ++it) {
358 if (it->first >= GL_COLOR_ATTACHMENT0 &&
359 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) {
360 const Attachment* attachment = it->second.get();
361 if (!attachment->cleared())
362 return true;
365 return false;
368 void Framebuffer::ChangeDrawBuffersHelper(bool recover) const {
369 scoped_ptr<GLenum[]> buffers(new GLenum[manager_->max_draw_buffers_]);
370 for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i)
371 buffers[i] = GL_NONE;
372 for (AttachmentMap::const_iterator it = attachments_.begin();
373 it != attachments_.end(); ++it) {
374 if (it->first >= GL_COLOR_ATTACHMENT0 &&
375 it->first < GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) {
376 buffers[it->first - GL_COLOR_ATTACHMENT0] = it->first;
379 bool different = false;
380 for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i) {
381 if (buffers[i] != draw_buffers_[i]) {
382 different = true;
383 break;
386 if (different) {
387 if (recover)
388 glDrawBuffersARB(manager_->max_draw_buffers_, draw_buffers_.get());
389 else
390 glDrawBuffersARB(manager_->max_draw_buffers_, buffers.get());
394 void Framebuffer::PrepareDrawBuffersForClear() const {
395 bool recover = false;
396 ChangeDrawBuffersHelper(recover);
399 void Framebuffer::RestoreDrawBuffersAfterClear() const {
400 bool recover = true;
401 ChangeDrawBuffersHelper(recover);
404 void Framebuffer::MarkAttachmentAsCleared(
405 RenderbufferManager* renderbuffer_manager,
406 TextureManager* texture_manager,
407 GLenum attachment,
408 bool cleared) {
409 AttachmentMap::iterator it = attachments_.find(attachment);
410 if (it != attachments_.end()) {
411 Attachment* a = it->second.get();
412 if (a->cleared() != cleared) {
413 a->SetCleared(renderbuffer_manager,
414 texture_manager,
415 cleared);
420 void Framebuffer::MarkAttachmentsAsCleared(
421 RenderbufferManager* renderbuffer_manager,
422 TextureManager* texture_manager,
423 bool cleared) {
424 for (AttachmentMap::iterator it = attachments_.begin();
425 it != attachments_.end(); ++it) {
426 Attachment* attachment = it->second.get();
427 if (attachment->cleared() != cleared) {
428 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared);
433 bool Framebuffer::HasDepthAttachment() const {
434 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() ||
435 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end();
438 bool Framebuffer::HasStencilAttachment() const {
439 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() ||
440 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end();
443 GLenum Framebuffer::GetReadBufferInternalFormat() const {
444 if (read_buffer_ == GL_NONE)
445 return 0;
446 AttachmentMap::const_iterator it = attachments_.find(read_buffer_);
447 if (it == attachments_.end()) {
448 return 0;
450 const Attachment* attachment = it->second.get();
451 return attachment->internal_format();
454 GLenum Framebuffer::GetReadBufferTextureType() const {
455 if (read_buffer_ == GL_NONE)
456 return 0;
457 AttachmentMap::const_iterator it = attachments_.find(read_buffer_);
458 if (it == attachments_.end()) {
459 return 0;
461 const Attachment* attachment = it->second.get();
462 return attachment->texture_type();
465 GLenum Framebuffer::IsPossiblyComplete() const {
466 if (attachments_.empty()) {
467 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
470 GLsizei width = -1;
471 GLsizei height = -1;
472 for (AttachmentMap::const_iterator it = attachments_.begin();
473 it != attachments_.end(); ++it) {
474 GLenum attachment_type = it->first;
475 Attachment* attachment = it->second.get();
476 if (!attachment->ValidForAttachmentType(attachment_type,
477 manager_->max_color_attachments_)) {
478 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
480 if (width < 0) {
481 width = attachment->width();
482 height = attachment->height();
483 if (width == 0 || height == 0) {
484 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
486 } else if (manager_->context_type() != ContextGroup::CONTEXT_TYPE_WEBGL2) {
487 // TODO(zmo): revisit this if we create ES3 contexts for clients other
488 // than WebGL 2.
489 if (attachment->width() != width || attachment->height() != height) {
490 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
494 if (!attachment->CanRenderTo()) {
495 return GL_FRAMEBUFFER_UNSUPPORTED;
499 // This does not mean the framebuffer is actually complete. It just means our
500 // checks passed.
501 return GL_FRAMEBUFFER_COMPLETE;
504 GLenum Framebuffer::GetStatus(
505 TextureManager* texture_manager, GLenum target) const {
506 // Check if we have this combo already.
507 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);
517 signature.reserve(signature_size);
518 signature.append(reinterpret_cast<const char*>(&target), sizeof(target));
520 for (AttachmentMap::const_iterator it = attachments_.begin();
521 it != attachments_.end(); ++it) {
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);
527 DCHECK(signature.size() == signature_size);
529 if (!framebuffer_combo_complete_map_) {
530 framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap();
533 FramebufferComboCompleteMap::const_iterator it =
534 framebuffer_combo_complete_map_->find(signature);
535 if (it != framebuffer_combo_complete_map_->end()) {
536 return GL_FRAMEBUFFER_COMPLETE;
540 GLenum result = glCheckFramebufferStatusEXT(target);
542 // Insert the new result into the combo map.
543 if (allow_framebuffer_combo_complete_map_ &&
544 result == GL_FRAMEBUFFER_COMPLETE) {
545 framebuffer_combo_complete_map_->insert(std::make_pair(signature, true));
548 return result;
551 bool Framebuffer::IsCleared() const {
552 // are all the attachments cleaared?
553 for (AttachmentMap::const_iterator it = attachments_.begin();
554 it != attachments_.end(); ++it) {
555 Attachment* attachment = it->second.get();
556 if (!attachment->cleared()) {
557 return false;
560 return true;
563 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const {
564 GLsizei index = static_cast<GLsizei>(
565 draw_buffer - GL_DRAW_BUFFER0_ARB);
566 CHECK(index >= 0 &&
567 index < static_cast<GLsizei>(manager_->max_draw_buffers_));
568 return draw_buffers_[index];
571 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) {
572 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_));
573 for (GLsizei i = 0; i < n; ++i)
574 draw_buffers_[i] = bufs[i];
577 bool Framebuffer::HasAlphaMRT() const {
578 for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i) {
579 if (draw_buffers_[i] != GL_NONE) {
580 const Attachment* attachment = GetAttachment(draw_buffers_[i]);
581 if (!attachment)
582 continue;
583 if ((GLES2Util::GetChannelsForFormat(
584 attachment->internal_format()) & 0x0008) != 0)
585 return true;
588 return false;
591 bool Framebuffer::HasSameInternalFormatsMRT() const {
592 GLenum internal_format = 0;
593 for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i) {
594 if (draw_buffers_[i] != GL_NONE) {
595 const Attachment* attachment = GetAttachment(draw_buffers_[i]);
596 if (!attachment)
597 continue;
598 if (!internal_format) {
599 internal_format = attachment->internal_format();
600 } else if (internal_format != attachment->internal_format()) {
601 return false;
605 return true;
608 void Framebuffer::UnbindRenderbuffer(
609 GLenum target, Renderbuffer* renderbuffer) {
610 bool done;
611 do {
612 done = true;
613 for (AttachmentMap::const_iterator it = attachments_.begin();
614 it != attachments_.end(); ++it) {
615 Attachment* attachment = it->second.get();
616 if (attachment->IsRenderbuffer(renderbuffer)) {
617 // TODO(gman): manually detach renderbuffer.
618 // glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0);
619 AttachRenderbuffer(it->first, NULL);
620 done = false;
621 break;
624 } while (!done);
627 void Framebuffer::UnbindTexture(
628 GLenum target, TextureRef* texture_ref) {
629 bool done;
630 do {
631 done = true;
632 for (AttachmentMap::const_iterator it = attachments_.begin();
633 it != attachments_.end(); ++it) {
634 Attachment* attachment = it->second.get();
635 if (attachment->IsTexture(texture_ref)) {
636 // TODO(gman): manually detach texture.
637 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0);
638 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0, 0);
639 done = false;
640 break;
643 } while (!done);
646 Framebuffer* FramebufferManager::GetFramebuffer(
647 GLuint client_id) {
648 FramebufferMap::iterator it = framebuffers_.find(client_id);
649 return it != framebuffers_.end() ? it->second.get() : NULL;
652 void FramebufferManager::RemoveFramebuffer(GLuint client_id) {
653 FramebufferMap::iterator it = framebuffers_.find(client_id);
654 if (it != framebuffers_.end()) {
655 it->second->MarkAsDeleted();
656 framebuffers_.erase(it);
660 void Framebuffer::DoUnbindGLAttachmentsForWorkaround(GLenum target) {
661 // Replace all attachments with the default Renderbuffer.
662 for (AttachmentMap::const_iterator it = attachments_.begin();
663 it != attachments_.end(); ++it) {
664 glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0);
668 void Framebuffer::AttachRenderbuffer(
669 GLenum attachment, Renderbuffer* renderbuffer) {
670 const Attachment* a = GetAttachment(attachment);
671 if (a)
672 a->DetachFromFramebuffer(this);
673 if (renderbuffer) {
674 attachments_[attachment] = scoped_refptr<Attachment>(
675 new RenderbufferAttachment(renderbuffer));
676 } else {
677 attachments_.erase(attachment);
679 framebuffer_complete_state_count_id_ = 0;
682 void Framebuffer::AttachTexture(
683 GLenum attachment, TextureRef* texture_ref, GLenum target,
684 GLint level, GLsizei samples) {
685 const Attachment* a = GetAttachment(attachment);
686 if (a)
687 a->DetachFromFramebuffer(this);
688 if (texture_ref) {
689 attachments_[attachment] = scoped_refptr<Attachment>(
690 new TextureAttachment(texture_ref, target, level, samples));
691 texture_ref->texture()->AttachToFramebuffer();
692 } else {
693 attachments_.erase(attachment);
695 framebuffer_complete_state_count_id_ = 0;
698 const Framebuffer::Attachment*
699 Framebuffer::GetAttachment(
700 GLenum attachment) const {
701 AttachmentMap::const_iterator it = attachments_.find(attachment);
702 if (it != attachments_.end()) {
703 return it->second.get();
705 return NULL;
708 const Framebuffer::Attachment* Framebuffer::GetReadBufferAttachment() const {
709 if (read_buffer_ == GL_NONE)
710 return nullptr;
711 return GetAttachment(read_buffer_);
714 void Framebuffer::OnTextureRefDetached(TextureRef* texture) {
715 manager_->OnTextureRefDetached(texture);
718 void Framebuffer::OnWillRenderTo() const {
719 for (AttachmentMap::const_iterator it = attachments_.begin();
720 it != attachments_.end(); ++it) {
721 it->second->OnWillRenderTo();
725 void Framebuffer::OnDidRenderTo() const {
726 for (AttachmentMap::const_iterator it = attachments_.begin();
727 it != attachments_.end(); ++it) {
728 it->second->OnDidRenderTo();
732 bool FramebufferManager::GetClientId(
733 GLuint service_id, GLuint* client_id) const {
734 // This doesn't need to be fast. It's only used during slow queries.
735 for (FramebufferMap::const_iterator it = framebuffers_.begin();
736 it != framebuffers_.end(); ++it) {
737 if (it->second->service_id() == service_id) {
738 *client_id = it->first;
739 return true;
742 return false;
745 void FramebufferManager::MarkAttachmentsAsCleared(
746 Framebuffer* framebuffer,
747 RenderbufferManager* renderbuffer_manager,
748 TextureManager* texture_manager) {
749 DCHECK(framebuffer);
750 framebuffer->MarkAttachmentsAsCleared(renderbuffer_manager,
751 texture_manager,
752 true);
753 MarkAsComplete(framebuffer);
756 void FramebufferManager::MarkAsComplete(
757 Framebuffer* framebuffer) {
758 DCHECK(framebuffer);
759 framebuffer->MarkAsComplete(framebuffer_state_change_count_);
762 bool FramebufferManager::IsComplete(
763 Framebuffer* framebuffer) {
764 DCHECK(framebuffer);
765 return framebuffer->framebuffer_complete_state_count_id() ==
766 framebuffer_state_change_count_;
769 void FramebufferManager::OnTextureRefDetached(TextureRef* texture) {
770 for (TextureDetachObserverVector::iterator it =
771 texture_detach_observers_.begin();
772 it != texture_detach_observers_.end();
773 ++it) {
774 TextureDetachObserver* observer = *it;
775 observer->OnTextureRefDetachedFromFramebuffer(texture);
779 } // namespace gles2
780 } // namespace gpu