| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/buffer.h" | 5 #include "components/exo/buffer.h" |
| 6 | 6 |
| 7 #include <GLES2/gl2.h> | 7 #include <GLES2/gl2.h> |
| 8 #include <GLES2/gl2ext.h> | 8 #include <GLES2/gl2ext.h> |
| 9 #include <GLES2/gl2extchromium.h> | 9 #include <GLES2/gl2extchromium.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 use_zero_copy_(use_zero_copy), | 365 use_zero_copy_(use_zero_copy), |
| 366 is_overlay_candidate_(is_overlay_candidate), | 366 is_overlay_candidate_(is_overlay_candidate), |
| 367 use_count_(0) {} | 367 use_count_(0) {} |
| 368 | 368 |
| 369 Buffer::~Buffer() {} | 369 Buffer::~Buffer() {} |
| 370 | 370 |
| 371 std::unique_ptr<cc::SingleReleaseCallback> Buffer::ProduceTextureMailbox( | 371 std::unique_ptr<cc::SingleReleaseCallback> Buffer::ProduceTextureMailbox( |
| 372 cc::TextureMailbox* texture_mailbox, | 372 cc::TextureMailbox* texture_mailbox, |
| 373 bool secure_output_only, | 373 bool secure_output_only, |
| 374 bool client_usage) { | 374 bool client_usage) { |
| 375 // Non-client usage can only be allowed when the client is not allowed to | 375 DCHECK(attach_count_); |
| 376 // use the buffer. If the buffer has been released to the client then it | |
| 377 // can no longer be used as the client might be writing to it. | |
| 378 if (!client_usage && !use_count_) | |
| 379 return nullptr; | |
| 380 | |
| 381 DLOG_IF(WARNING, use_count_ && client_usage) | 376 DLOG_IF(WARNING, use_count_ && client_usage) |
| 382 << "Producing a texture mailbox for a buffer that has not been released"; | 377 << "Producing a texture mailbox for a buffer that has not been released"; |
| 383 | 378 |
| 384 // Some clients think that they can reuse a buffer before it's released by | 379 // Some clients think that they can reuse a buffer before it's released by |
| 385 // performing a fast blit into the buffer. This behavior is bad as it prevents | 380 // performing a fast blit into the buffer. This behavior is bad as it prevents |
| 386 // the client from knowing when the buffer is actually released (e.g. the | 381 // the client from knowing when the buffer is actually released (e.g. the |
| 387 // release notification for the previous use of buffer can arrive after the | 382 // release notification for the previous use of buffer can arrive after the |
| 388 // buffer has been reused). We stop running the release callback when this | 383 // buffer has been reused). We stop running the release callback when this |
| 389 // type of behavior is detected as having the buffer always be busy will | 384 // type of behavior is detected as having the buffer always be busy will |
| 390 // result in fewer drawing artifacts. | 385 // result in fewer drawing artifacts. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 gpu_memory_buffer_->GetSize(), gfx::GpuMemoryBufferId(), | 452 gpu_memory_buffer_->GetSize(), gfx::GpuMemoryBufferId(), |
| 458 false /* is_overlay_candidate */, secure_output_only); | 453 false /* is_overlay_candidate */, secure_output_only); |
| 459 // The mailbox texture will be released when no longer used by the | 454 // The mailbox texture will be released when no longer used by the |
| 460 // compositor. | 455 // compositor. |
| 461 return cc::SingleReleaseCallback::Create( | 456 return cc::SingleReleaseCallback::Create( |
| 462 base::Bind(&Buffer::Texture::Release, base::Unretained(texture), | 457 base::Bind(&Buffer::Texture::Release, base::Unretained(texture), |
| 463 base::Bind(&Buffer::ReleaseTexture, AsWeakPtr(), | 458 base::Bind(&Buffer::ReleaseTexture, AsWeakPtr(), |
| 464 base::Passed(&texture_)))); | 459 base::Passed(&texture_)))); |
| 465 } | 460 } |
| 466 | 461 |
| 462 void Buffer::OnAttach() { |
| 463 DLOG_IF(WARNING, attach_count_ > 0u) |
| 464 << "Reattaching a buffer that is already attached to another surface."; |
| 465 attach_count_++; |
| 466 } |
| 467 |
| 468 void Buffer::OnDetach() { |
| 469 DCHECK_GT(attach_count_, 0u); |
| 470 --attach_count_; |
| 471 CheckReleaseCallback(); |
| 472 } |
| 473 |
| 467 gfx::Size Buffer::GetSize() const { | 474 gfx::Size Buffer::GetSize() const { |
| 468 return gpu_memory_buffer_->GetSize(); | 475 return gpu_memory_buffer_->GetSize(); |
| 469 } | 476 } |
| 470 | 477 |
| 471 std::unique_ptr<base::trace_event::TracedValue> Buffer::AsTracedValue() const { | 478 std::unique_ptr<base::trace_event::TracedValue> Buffer::AsTracedValue() const { |
| 472 std::unique_ptr<base::trace_event::TracedValue> value( | 479 std::unique_ptr<base::trace_event::TracedValue> value( |
| 473 new base::trace_event::TracedValue()); | 480 new base::trace_event::TracedValue()); |
| 474 gfx::Size size = gpu_memory_buffer_->GetSize(); | 481 gfx::Size size = gpu_memory_buffer_->GetSize(); |
| 475 value->SetInteger("width", size.width()); | 482 value->SetInteger("width", size.width()); |
| 476 value->SetInteger("height", size.height()); | 483 value->SetInteger("height", size.height()); |
| 477 value->SetInteger("format", | 484 value->SetInteger("format", |
| 478 static_cast<int>(gpu_memory_buffer_->GetFormat())); | 485 static_cast<int>(gpu_memory_buffer_->GetFormat())); |
| 479 return value; | 486 return value; |
| 480 } | 487 } |
| 481 | 488 |
| 482 //////////////////////////////////////////////////////////////////////////////// | 489 //////////////////////////////////////////////////////////////////////////////// |
| 483 // Buffer, private: | 490 // Buffer, private: |
| 484 | 491 |
| 485 void Buffer::Release() { | 492 void Buffer::Release() { |
| 486 DCHECK_GT(use_count_, 0u); | 493 DCHECK_GT(use_count_, 0u); |
| 487 if (--use_count_) | 494 --use_count_; |
| 495 CheckReleaseCallback(); |
| 496 } |
| 497 |
| 498 void Buffer::CheckReleaseCallback() { |
| 499 if (attach_count_ || use_count_) |
| 488 return; | 500 return; |
| 489 | 501 |
| 490 // Run release callback to notify the client that buffer has been released. | 502 // Run release callback to notify the client that buffer has been released. |
| 491 if (!release_callback_.is_null()) | 503 if (!release_callback_.is_null()) |
| 492 release_callback_.Run(); | 504 release_callback_.Run(); |
| 493 } | 505 } |
| 494 | 506 |
| 495 void Buffer::ReleaseTexture(std::unique_ptr<Texture> texture) { | 507 void Buffer::ReleaseTexture(std::unique_ptr<Texture> texture) { |
| 496 texture_ = std::move(texture); | 508 texture_ = std::move(texture); |
| 497 } | 509 } |
| 498 | 510 |
| 499 void Buffer::ReleaseContentsTexture(std::unique_ptr<Texture> texture) { | 511 void Buffer::ReleaseContentsTexture(std::unique_ptr<Texture> texture) { |
| 500 TRACE_EVENT0("exo", "Buffer::ReleaseContentsTexture"); | 512 TRACE_EVENT0("exo", "Buffer::ReleaseContentsTexture"); |
| 501 | 513 |
| 502 contents_texture_ = std::move(texture); | 514 contents_texture_ = std::move(texture); |
| 503 Release(); | 515 Release(); |
| 504 } | 516 } |
| 505 | 517 |
| 506 } // namespace exo | 518 } // namespace exo |
| OLD | NEW |