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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 } | 60 } |
61 | 61 |
62 virtual bool cleared() const OVERRIDE { | 62 virtual bool cleared() const OVERRIDE { |
63 return renderbuffer_->cleared(); | 63 return renderbuffer_->cleared(); |
64 } | 64 } |
65 | 65 |
66 virtual void SetCleared( | 66 virtual void SetCleared( |
67 RenderbufferManager* renderbuffer_manager, | 67 RenderbufferManager* renderbuffer_manager, |
68 TextureManager* /* texture_manager */, | 68 TextureManager* /* texture_manager */, |
69 bool cleared) OVERRIDE { | 69 bool cleared) OVERRIDE { |
70 renderbuffer_manager->SetCleared(renderbuffer_, cleared); | 70 renderbuffer_manager->SetCleared(renderbuffer_.get(), cleared); |
71 } | 71 } |
72 | 72 |
73 virtual bool IsTexture( | 73 virtual bool IsTexture( |
74 TextureRef* /* texture */) const OVERRIDE { | 74 TextureRef* /* texture */) const OVERRIDE { |
75 return false; | 75 return false; |
76 } | 76 } |
77 | 77 |
78 virtual bool IsRenderbuffer( | 78 virtual bool IsRenderbuffer( |
79 Renderbuffer* renderbuffer) const OVERRIDE { | 79 Renderbuffer* renderbuffer) const OVERRIDE { |
80 return renderbuffer_ == renderbuffer; | 80 return renderbuffer_.get() == renderbuffer; |
81 } | 81 } |
82 | 82 |
83 virtual bool CanRenderTo() const OVERRIDE { | 83 virtual bool CanRenderTo() const OVERRIDE { |
84 return true; | 84 return true; |
85 } | 85 } |
86 | 86 |
87 virtual void DetachFromFramebuffer() const OVERRIDE { | 87 virtual void DetachFromFramebuffer() const OVERRIDE { |
88 // Nothing to do for renderbuffers. | 88 // Nothing to do for renderbuffers. |
89 } | 89 } |
90 | 90 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 } | 158 } |
159 | 159 |
160 virtual bool cleared() const OVERRIDE { | 160 virtual bool cleared() const OVERRIDE { |
161 return texture_ref_->texture()->IsLevelCleared(target_, level_); | 161 return texture_ref_->texture()->IsLevelCleared(target_, level_); |
162 } | 162 } |
163 | 163 |
164 virtual void SetCleared( | 164 virtual void SetCleared( |
165 RenderbufferManager* /* renderbuffer_manager */, | 165 RenderbufferManager* /* renderbuffer_manager */, |
166 TextureManager* texture_manager, | 166 TextureManager* texture_manager, |
167 bool cleared) OVERRIDE { | 167 bool cleared) OVERRIDE { |
168 texture_manager->SetLevelCleared(texture_ref_, target_, level_, cleared); | 168 texture_manager->SetLevelCleared( |
| 169 texture_ref_.get(), target_, level_, cleared); |
169 } | 170 } |
170 | 171 |
171 virtual bool IsTexture(TextureRef* texture) const OVERRIDE { | 172 virtual bool IsTexture(TextureRef* texture) const OVERRIDE { |
172 return texture == texture_ref_.get(); | 173 return texture == texture_ref_.get(); |
173 } | 174 } |
174 | 175 |
175 virtual bool IsRenderbuffer( | 176 virtual bool IsRenderbuffer( |
176 Renderbuffer* /* renderbuffer */) | 177 Renderbuffer* /* renderbuffer */) |
177 const OVERRIDE { | 178 const OVERRIDE { |
178 return false; | 179 return false; |
(...skipping 21 matching lines...) Expand all Loading... |
200 } | 201 } |
201 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType( | 202 uint32 need = GLES2Util::GetChannelsNeededForAttachmentType( |
202 attachment_type, max_color_attachments); | 203 attachment_type, max_color_attachments); |
203 uint32 have = GLES2Util::GetChannelsForFormat(internal_format); | 204 uint32 have = GLES2Util::GetChannelsForFormat(internal_format); |
204 return (need & have) != 0; | 205 return (need & have) != 0; |
205 } | 206 } |
206 | 207 |
207 virtual void AddToSignature( | 208 virtual void AddToSignature( |
208 TextureManager* texture_manager, std::string* signature) const OVERRIDE { | 209 TextureManager* texture_manager, std::string* signature) const OVERRIDE { |
209 DCHECK(signature); | 210 DCHECK(signature); |
210 texture_manager->AddToSignature(texture_ref_, target_, level_, signature); | 211 texture_manager->AddToSignature( |
| 212 texture_ref_.get(), target_, level_, signature); |
211 } | 213 } |
212 | 214 |
213 protected: | 215 protected: |
214 virtual ~TextureAttachment() {} | 216 virtual ~TextureAttachment() {} |
215 | 217 |
216 private: | 218 private: |
217 scoped_refptr<TextureRef> texture_ref_; | 219 scoped_refptr<TextureRef> texture_ref_; |
218 GLenum target_; | 220 GLenum target_; |
219 GLint level_; | 221 GLint level_; |
220 | 222 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 manager_->StopTracking(this); | 300 manager_->StopTracking(this); |
299 manager_ = NULL; | 301 manager_ = NULL; |
300 } | 302 } |
301 } | 303 } |
302 | 304 |
303 bool Framebuffer::HasUnclearedAttachment( | 305 bool Framebuffer::HasUnclearedAttachment( |
304 GLenum attachment) const { | 306 GLenum attachment) const { |
305 AttachmentMap::const_iterator it = | 307 AttachmentMap::const_iterator it = |
306 attachments_.find(attachment); | 308 attachments_.find(attachment); |
307 if (it != attachments_.end()) { | 309 if (it != attachments_.end()) { |
308 const Attachment* attachment = it->second; | 310 const Attachment* attachment = it->second.get(); |
309 return !attachment->cleared(); | 311 return !attachment->cleared(); |
310 } | 312 } |
311 return false; | 313 return false; |
312 } | 314 } |
313 | 315 |
314 void Framebuffer::MarkAttachmentAsCleared( | 316 void Framebuffer::MarkAttachmentAsCleared( |
315 RenderbufferManager* renderbuffer_manager, | 317 RenderbufferManager* renderbuffer_manager, |
316 TextureManager* texture_manager, | 318 TextureManager* texture_manager, |
317 GLenum attachment, | 319 GLenum attachment, |
318 bool cleared) { | 320 bool cleared) { |
319 AttachmentMap::iterator it = attachments_.find(attachment); | 321 AttachmentMap::iterator it = attachments_.find(attachment); |
320 if (it != attachments_.end()) { | 322 if (it != attachments_.end()) { |
321 Attachment* a = it->second; | 323 Attachment* a = it->second.get(); |
322 if (a->cleared() != cleared) { | 324 if (a->cleared() != cleared) { |
323 a->SetCleared(renderbuffer_manager, | 325 a->SetCleared(renderbuffer_manager, |
324 texture_manager, | 326 texture_manager, |
325 cleared); | 327 cleared); |
326 } | 328 } |
327 } | 329 } |
328 } | 330 } |
329 | 331 |
330 void Framebuffer::MarkAttachmentsAsCleared( | 332 void Framebuffer::MarkAttachmentsAsCleared( |
331 RenderbufferManager* renderbuffer_manager, | 333 RenderbufferManager* renderbuffer_manager, |
332 TextureManager* texture_manager, | 334 TextureManager* texture_manager, |
333 bool cleared) { | 335 bool cleared) { |
334 for (AttachmentMap::iterator it = attachments_.begin(); | 336 for (AttachmentMap::iterator it = attachments_.begin(); |
335 it != attachments_.end(); ++it) { | 337 it != attachments_.end(); ++it) { |
336 Attachment* attachment = it->second; | 338 Attachment* attachment = it->second.get(); |
337 if (attachment->cleared() != cleared) { | 339 if (attachment->cleared() != cleared) { |
338 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); | 340 attachment->SetCleared(renderbuffer_manager, texture_manager, cleared); |
339 } | 341 } |
340 } | 342 } |
341 } | 343 } |
342 | 344 |
343 bool Framebuffer::HasDepthAttachment() const { | 345 bool Framebuffer::HasDepthAttachment() const { |
344 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 346 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || |
345 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); | 347 attachments_.find(GL_DEPTH_ATTACHMENT) != attachments_.end(); |
346 } | 348 } |
347 | 349 |
348 bool Framebuffer::HasStencilAttachment() const { | 350 bool Framebuffer::HasStencilAttachment() const { |
349 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || | 351 return attachments_.find(GL_DEPTH_STENCIL_ATTACHMENT) != attachments_.end() || |
350 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); | 352 attachments_.find(GL_STENCIL_ATTACHMENT) != attachments_.end(); |
351 } | 353 } |
352 | 354 |
353 GLenum Framebuffer::GetColorAttachmentFormat() const { | 355 GLenum Framebuffer::GetColorAttachmentFormat() const { |
354 AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); | 356 AttachmentMap::const_iterator it = attachments_.find(GL_COLOR_ATTACHMENT0); |
355 if (it == attachments_.end()) { | 357 if (it == attachments_.end()) { |
356 return 0; | 358 return 0; |
357 } | 359 } |
358 const Attachment* attachment = it->second; | 360 const Attachment* attachment = it->second.get(); |
359 return attachment->internal_format(); | 361 return attachment->internal_format(); |
360 } | 362 } |
361 | 363 |
362 GLenum Framebuffer::IsPossiblyComplete() const { | 364 GLenum Framebuffer::IsPossiblyComplete() const { |
363 if (attachments_.empty()) { | 365 if (attachments_.empty()) { |
364 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; | 366 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; |
365 } | 367 } |
366 | 368 |
367 GLsizei width = -1; | 369 GLsizei width = -1; |
368 GLsizei height = -1; | 370 GLsizei height = -1; |
369 for (AttachmentMap::const_iterator it = attachments_.begin(); | 371 for (AttachmentMap::const_iterator it = attachments_.begin(); |
370 it != attachments_.end(); ++it) { | 372 it != attachments_.end(); ++it) { |
371 GLenum attachment_type = it->first; | 373 GLenum attachment_type = it->first; |
372 Attachment* attachment = it->second; | 374 Attachment* attachment = it->second.get(); |
373 if (!attachment->ValidForAttachmentType( | 375 if (!attachment->ValidForAttachmentType(attachment_type, |
374 attachment_type, manager_->max_color_attachments_)) { | 376 manager_->max_color_attachments_)) { |
375 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | 377 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
376 } | 378 } |
377 if (width < 0) { | 379 if (width < 0) { |
378 width = attachment->width(); | 380 width = attachment->width(); |
379 height = attachment->height(); | 381 height = attachment->height(); |
380 if (width == 0 || height == 0) { | 382 if (width == 0 || height == 0) { |
381 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; | 383 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
382 } | 384 } |
383 } else { | 385 } else { |
384 if (attachment->width() != width || attachment->height() != height) { | 386 if (attachment->width() != width || attachment->height() != height) { |
(...skipping 12 matching lines...) Expand all Loading... |
397 } | 399 } |
398 | 400 |
399 GLenum Framebuffer::GetStatus( | 401 GLenum Framebuffer::GetStatus( |
400 TextureManager* texture_manager, GLenum target) const { | 402 TextureManager* texture_manager, GLenum target) const { |
401 // Check if we have this combo already. | 403 // Check if we have this combo already. |
402 std::string signature; | 404 std::string signature; |
403 if (allow_framebuffer_combo_complete_map_) { | 405 if (allow_framebuffer_combo_complete_map_) { |
404 signature = base::StringPrintf("|FBO|target=%04x", target); | 406 signature = base::StringPrintf("|FBO|target=%04x", target); |
405 for (AttachmentMap::const_iterator it = attachments_.begin(); | 407 for (AttachmentMap::const_iterator it = attachments_.begin(); |
406 it != attachments_.end(); ++it) { | 408 it != attachments_.end(); ++it) { |
407 Attachment* attachment = it->second; | 409 Attachment* attachment = it->second.get(); |
408 signature += base::StringPrintf( | 410 signature += |
409 "|Attachment|attachmentpoint=%04x", it->first); | 411 base::StringPrintf("|Attachment|attachmentpoint=%04x", it->first); |
410 attachment->AddToSignature(texture_manager, &signature); | 412 attachment->AddToSignature(texture_manager, &signature); |
411 } | 413 } |
412 | 414 |
413 if (!framebuffer_combo_complete_map_) { | 415 if (!framebuffer_combo_complete_map_) { |
414 framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap(); | 416 framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap(); |
415 } | 417 } |
416 | 418 |
417 FramebufferComboCompleteMap::const_iterator it = | 419 FramebufferComboCompleteMap::const_iterator it = |
418 framebuffer_combo_complete_map_->find(signature); | 420 framebuffer_combo_complete_map_->find(signature); |
419 if (it != framebuffer_combo_complete_map_->end()) { | 421 if (it != framebuffer_combo_complete_map_->end()) { |
420 return GL_FRAMEBUFFER_COMPLETE; | 422 return GL_FRAMEBUFFER_COMPLETE; |
421 } | 423 } |
422 } | 424 } |
423 | 425 |
424 GLenum result = glCheckFramebufferStatusEXT(target); | 426 GLenum result = glCheckFramebufferStatusEXT(target); |
425 | 427 |
426 // Insert the new result into the combo map. | 428 // Insert the new result into the combo map. |
427 if (allow_framebuffer_combo_complete_map_ && | 429 if (allow_framebuffer_combo_complete_map_ && |
428 result == GL_FRAMEBUFFER_COMPLETE) { | 430 result == GL_FRAMEBUFFER_COMPLETE) { |
429 framebuffer_combo_complete_map_->insert(std::make_pair(signature, true)); | 431 framebuffer_combo_complete_map_->insert(std::make_pair(signature, true)); |
430 } | 432 } |
431 | 433 |
432 return result; | 434 return result; |
433 } | 435 } |
434 | 436 |
435 bool Framebuffer::IsCleared() const { | 437 bool Framebuffer::IsCleared() const { |
436 // are all the attachments cleaared? | 438 // are all the attachments cleaared? |
437 for (AttachmentMap::const_iterator it = attachments_.begin(); | 439 for (AttachmentMap::const_iterator it = attachments_.begin(); |
438 it != attachments_.end(); ++it) { | 440 it != attachments_.end(); ++it) { |
439 Attachment* attachment = it->second; | 441 Attachment* attachment = it->second.get(); |
440 if (!attachment->cleared()) { | 442 if (!attachment->cleared()) { |
441 return false; | 443 return false; |
442 } | 444 } |
443 } | 445 } |
444 return true; | 446 return true; |
445 } | 447 } |
446 | 448 |
447 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { | 449 GLenum Framebuffer::GetDrawBuffer(GLenum draw_buffer) const { |
448 GLsizei index = static_cast<GLsizei>( | 450 GLsizei index = static_cast<GLsizei>( |
449 draw_buffer - GL_DRAW_BUFFER0_ARB); | 451 draw_buffer - GL_DRAW_BUFFER0_ARB); |
450 CHECK(index >= 0 && | 452 CHECK(index >= 0 && |
451 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); | 453 index < static_cast<GLsizei>(manager_->max_draw_buffers_)); |
452 return draw_buffers_[index]; | 454 return draw_buffers_[index]; |
453 } | 455 } |
454 | 456 |
455 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { | 457 void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { |
456 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); | 458 DCHECK(n <= static_cast<GLsizei>(manager_->max_draw_buffers_)); |
457 for (GLsizei i = 0; i < n; ++i) | 459 for (GLsizei i = 0; i < n; ++i) |
458 draw_buffers_[i] = bufs[i]; | 460 draw_buffers_[i] = bufs[i]; |
459 } | 461 } |
460 | 462 |
461 void Framebuffer::UnbindRenderbuffer( | 463 void Framebuffer::UnbindRenderbuffer( |
462 GLenum target, Renderbuffer* renderbuffer) { | 464 GLenum target, Renderbuffer* renderbuffer) { |
463 bool done; | 465 bool done; |
464 do { | 466 do { |
465 done = true; | 467 done = true; |
466 for (AttachmentMap::const_iterator it = attachments_.begin(); | 468 for (AttachmentMap::const_iterator it = attachments_.begin(); |
467 it != attachments_.end(); ++it) { | 469 it != attachments_.end(); ++it) { |
468 Attachment* attachment = it->second; | 470 Attachment* attachment = it->second.get(); |
469 if (attachment->IsRenderbuffer(renderbuffer)) { | 471 if (attachment->IsRenderbuffer(renderbuffer)) { |
470 // TODO(gman): manually detach renderbuffer. | 472 // TODO(gman): manually detach renderbuffer. |
471 // glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0); | 473 // glFramebufferRenderbufferEXT(target, it->first, GL_RENDERBUFFER, 0); |
472 AttachRenderbuffer(it->first, NULL); | 474 AttachRenderbuffer(it->first, NULL); |
473 done = false; | 475 done = false; |
474 break; | 476 break; |
475 } | 477 } |
476 } | 478 } |
477 } while (!done); | 479 } while (!done); |
478 } | 480 } |
479 | 481 |
480 void Framebuffer::UnbindTexture( | 482 void Framebuffer::UnbindTexture( |
481 GLenum target, TextureRef* texture_ref) { | 483 GLenum target, TextureRef* texture_ref) { |
482 bool done; | 484 bool done; |
483 do { | 485 do { |
484 done = true; | 486 done = true; |
485 for (AttachmentMap::const_iterator it = attachments_.begin(); | 487 for (AttachmentMap::const_iterator it = attachments_.begin(); |
486 it != attachments_.end(); ++it) { | 488 it != attachments_.end(); ++it) { |
487 Attachment* attachment = it->second; | 489 Attachment* attachment = it->second.get(); |
488 if (attachment->IsTexture(texture_ref)) { | 490 if (attachment->IsTexture(texture_ref)) { |
489 // TODO(gman): manually detach texture. | 491 // TODO(gman): manually detach texture. |
490 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); | 492 // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); |
491 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0); | 493 AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0); |
492 done = false; | 494 done = false; |
493 break; | 495 break; |
494 } | 496 } |
495 } | 497 } |
496 } while (!done); | 498 } while (!done); |
497 } | 499 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 attachments_.erase(attachment); | 540 attachments_.erase(attachment); |
539 } | 541 } |
540 framebuffer_complete_state_count_id_ = 0; | 542 framebuffer_complete_state_count_id_ = 0; |
541 } | 543 } |
542 | 544 |
543 const Framebuffer::Attachment* | 545 const Framebuffer::Attachment* |
544 Framebuffer::GetAttachment( | 546 Framebuffer::GetAttachment( |
545 GLenum attachment) const { | 547 GLenum attachment) const { |
546 AttachmentMap::const_iterator it = attachments_.find(attachment); | 548 AttachmentMap::const_iterator it = attachments_.find(attachment); |
547 if (it != attachments_.end()) { | 549 if (it != attachments_.end()) { |
548 return it->second; | 550 return it->second.get(); |
549 } | 551 } |
550 return NULL; | 552 return NULL; |
551 } | 553 } |
552 | 554 |
553 bool FramebufferManager::GetClientId( | 555 bool FramebufferManager::GetClientId( |
554 GLuint service_id, GLuint* client_id) const { | 556 GLuint service_id, GLuint* client_id) const { |
555 // This doesn't need to be fast. It's only used during slow queries. | 557 // This doesn't need to be fast. It's only used during slow queries. |
556 for (FramebufferMap::const_iterator it = framebuffers_.begin(); | 558 for (FramebufferMap::const_iterator it = framebuffers_.begin(); |
557 it != framebuffers_.end(); ++it) { | 559 it != framebuffers_.end(); ++it) { |
558 if (it->second->service_id() == service_id) { | 560 if (it->second->service_id() == service_id) { |
(...skipping 25 matching lines...) Expand all Loading... |
584 Framebuffer* framebuffer) { | 586 Framebuffer* framebuffer) { |
585 DCHECK(framebuffer); | 587 DCHECK(framebuffer); |
586 return framebuffer->framebuffer_complete_state_count_id() == | 588 return framebuffer->framebuffer_complete_state_count_id() == |
587 framebuffer_state_change_count_; | 589 framebuffer_state_change_count_; |
588 } | 590 } |
589 | 591 |
590 } // namespace gles2 | 592 } // namespace gles2 |
591 } // namespace gpu | 593 } // namespace gpu |
592 | 594 |
593 | 595 |
OLD | NEW |