Index: gpu/command_buffer/service/async_pixel_transfer_manager_compressed.cc |
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_compressed.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_compressed.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8784b0590d17f74332f956a4ec31f5661eef7d33 |
--- /dev/null |
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_compressed.cc |
@@ -0,0 +1,231 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/synchronization/waitable_event.h" |
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h" |
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_compressed.h" |
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_egl.h" |
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" |
+ |
+namespace gpu { |
+ |
+namespace { |
+ |
+class AsyncPixelTransferDelegateCompressed : public AsyncPixelTransferDelegate { |
+ public: |
+ AsyncPixelTransferDelegateCompressed( |
+ AsyncPixelTransferManagerCompressed* manager, |
+ AsyncPixelTransferDelegate* delegate, |
+ AsyncPixelTransferManagerCompressed::Mode mode); |
+ virtual ~AsyncPixelTransferDelegateCompressed(); |
+ |
+ // Implement AsyncPixelTransferDelegate: |
+ void AsyncTexImage2D( |
+ const AsyncTexImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params, |
+ const base::Closure& bind_callback) override; |
+ void AsyncTexSubImage2D( |
+ const AsyncTexSubImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params) override; |
+ void AsyncCompressedTexImage2D( |
+ const AsyncCompressedTexImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params, |
+ const base::Closure& bind_callback) override; |
+ void AsyncCompressedTexSubImage2D( |
+ const AsyncCompressedTexSubImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params) override; |
+ bool TransferIsInProgress() override; |
+ void WaitForTransferCompletion() override; |
+ |
+ private: |
+ void EnumerateDelegate(); |
+ |
+ AsyncPixelTransferDelegate* delegate() { return delegate_.get(); } |
+ |
+ AsyncPixelTransferManagerCompressed* manager_; |
+ scoped_ptr<AsyncPixelTransferDelegate> delegate_; |
+ |
+ AsyncPixelTransferManagerCompressed::Mode mode_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateCompressed); |
+}; |
+ |
+AsyncPixelTransferDelegateCompressed::AsyncPixelTransferDelegateCompressed( |
+ AsyncPixelTransferManagerCompressed* manager, |
+ AsyncPixelTransferDelegate* delegate, |
+ AsyncPixelTransferManagerCompressed::Mode mode) |
+ : manager_(manager), delegate_(delegate), mode_(mode) {} |
+ |
+AsyncPixelTransferDelegateCompressed::~AsyncPixelTransferDelegateCompressed() { |
+ manager_->shared_state().delegates.remove(this); |
+} |
+ |
+void AsyncPixelTransferDelegateCompressed::AsyncTexImage2D( |
+ const AsyncTexImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params, |
+ const base::Closure& bind_callback) { |
+ DCHECK_EQ(mode_, AsyncPixelTransferManagerCompressed::MODE_EGL); |
+ manager_->SwitchMode(AsyncPixelTransferManagerCompressed::MODE_EGL); |
+ EnumerateDelegate(); |
+ delegate_->AsyncTexImage2D(tex_params, mem_params, bind_callback); |
+} |
+ |
+void AsyncPixelTransferDelegateCompressed::AsyncTexSubImage2D( |
+ const AsyncTexSubImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params) { |
+ DCHECK_EQ(mode_, AsyncPixelTransferManagerCompressed::MODE_EGL); |
+ manager_->SwitchMode(AsyncPixelTransferManagerCompressed::MODE_EGL); |
+ EnumerateDelegate(); |
+ delegate_->AsyncTexSubImage2D(tex_params, mem_params); |
+} |
+ |
+void AsyncPixelTransferDelegateCompressed::AsyncCompressedTexImage2D( |
+ const AsyncCompressedTexImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params, |
+ const base::Closure& bind_callback) { |
+ DCHECK_EQ(mode_, AsyncPixelTransferManagerCompressed::MODE_IDLE); |
+ manager_->SwitchMode(AsyncPixelTransferManagerCompressed::MODE_IDLE); |
+ EnumerateDelegate(); |
+ delegate_->AsyncCompressedTexImage2D(tex_params, mem_params, bind_callback); |
+} |
+ |
+void AsyncPixelTransferDelegateCompressed::AsyncCompressedTexSubImage2D( |
+ const AsyncCompressedTexSubImage2DParams& tex_params, |
+ const AsyncMemoryParams& mem_params) { |
+ DCHECK_EQ(mode_, AsyncPixelTransferManagerCompressed::MODE_IDLE); |
+ manager_->SwitchMode(AsyncPixelTransferManagerCompressed::MODE_IDLE); |
+ EnumerateDelegate(); |
+ delegate_->AsyncCompressedTexSubImage2D(tex_params, mem_params); |
+} |
+ |
+bool AsyncPixelTransferDelegateCompressed::TransferIsInProgress() { |
+ return delegate_->TransferIsInProgress(); |
+} |
+ |
+void AsyncPixelTransferDelegateCompressed::WaitForTransferCompletion() { |
+ // Wait for all preceding delegates to complete. |
+ AsyncPixelTransferManagerCompressed::SharedState::DelegateList::iterator self; |
+ self = std::find(manager_->shared_state().delegates.begin(), |
+ manager_->shared_state().delegates.end(), |
+ this); |
+ DCHECK(self != manager_->shared_state().delegates.end()); |
+ AsyncPixelTransferManagerCompressed::SharedState::DelegateList::iterator it; |
+ for (it = manager_->shared_state().delegates.begin(); it != self; it++) { |
+ reinterpret_cast<AsyncPixelTransferDelegateCompressed*>(*it)-> |
+ delegate()->WaitForTransferCompletion(); |
+ } |
+ DCHECK(it != manager_->shared_state().delegates.end()); |
+ |
+ // Wait for this delegate to complete. |
+ delegate_->WaitForTransferCompletion(); |
+} |
+ |
+void AsyncPixelTransferDelegateCompressed::EnumerateDelegate() { |
+ manager_->shared_state().delegates.remove(this); |
+ manager_->shared_state().delegates.push_back(this); |
+} |
+ |
+} // namespace |
+ |
+AsyncPixelTransferManagerCompressed::AsyncPixelTransferManagerCompressed() |
+ : mode_(MODE_EGL) { |
+ egl_manager_.reset(new AsyncPixelTransferManagerEGL); |
+ idle_manager_.reset(new AsyncPixelTransferManagerIdle); |
+} |
+ |
+AsyncPixelTransferManagerCompressed::~AsyncPixelTransferManagerCompressed() { |
+ shared_state_.delegates.clear(); |
+} |
+ |
+void AsyncPixelTransferManagerCompressed::BindCompletedAsyncTransfers() { |
+ egl_manager_->BindCompletedAsyncTransfers(); |
+ idle_manager_->BindCompletedAsyncTransfers(); |
+} |
+ |
+void AsyncPixelTransferManagerCompressed::AsyncNotifyCompletion( |
+ const AsyncMemoryParams& mem_params, |
+ AsyncPixelTransferCompletionObserver* observer) { |
+ current_manager()->AsyncNotifyCompletion(mem_params, observer); |
+} |
+ |
+uint32 AsyncPixelTransferManagerCompressed::GetTextureUploadCount() { |
+ return (egl_manager_->GetTextureUploadCount() + |
+ idle_manager_->GetTextureUploadCount()); |
+} |
+ |
+base::TimeDelta |
+AsyncPixelTransferManagerCompressed::GetTotalTextureUploadTime() { |
+ return (egl_manager_->GetTotalTextureUploadTime() + |
+ idle_manager_->GetTotalTextureUploadTime()); |
+} |
+ |
+void AsyncPixelTransferManagerCompressed::ProcessMorePendingTransfers() { |
+ // Only AsyncPixelTransferManagerIdle implements this and we need to do this |
+ // even in EGL mode when EGL thread is suspended. |
+ idle_manager_->ProcessMorePendingTransfers(); |
+} |
+ |
+bool AsyncPixelTransferManagerCompressed::NeedsProcessMorePendingTransfers() { |
+ // Only AsyncPixelTransferManagerIdle uses this. |
+ DCHECK(!egl_manager_->NeedsProcessMorePendingTransfers()); |
+ return idle_manager_->NeedsProcessMorePendingTransfers(); |
+} |
+ |
+void AsyncPixelTransferManagerCompressed::WaitAllAsyncTexImage2D() { |
+ if (shared_state_.delegates.empty()) |
+ return; |
+ |
+ shared_state_.delegates.back()->WaitForTransferCompletion(); |
+} |
+ |
+AsyncPixelTransferDelegate* |
+AsyncPixelTransferManagerCompressed::CreatePixelTransferDelegateImpl( |
+ gles2::TextureRef* ref, |
+ const AsyncTexImage2DParams& define_params) { |
+ AsyncPixelTransferDelegate* delegate = |
+ egl_manager_->CreatePixelTransferDelegateImpl(ref, define_params); |
+ DCHECK(delegate); |
+ return new AsyncPixelTransferDelegateCompressed(this, delegate, MODE_EGL); |
+} |
+ |
+AsyncPixelTransferDelegate* |
+AsyncPixelTransferManagerCompressed::CreatePixelTransferDelegateImpl( |
+ gles2::TextureRef* ref, |
+ const AsyncCompressedTexImage2DParams& define_params) { |
+ AsyncPixelTransferDelegate* delegate = |
+ idle_manager_->CreatePixelTransferDelegateImpl(ref, define_params); |
+ DCHECK(delegate); |
+ return new AsyncPixelTransferDelegateCompressed(this, delegate, MODE_IDLE); |
+} |
+ |
+void AsyncPixelTransferManagerCompressed::SwitchMode(Mode new_mode) { |
+ if (new_mode == mode_) |
+ return; |
+ |
+ if (new_mode == MODE_EGL && mode_ == MODE_IDLE) { |
+ // Wait for already queued Idle tasks to finish before letting future EGL |
+ // tasks run. |
+ if (idle_manager_->NeedsProcessMorePendingTransfers()) { |
+ base::WaitableEvent* waitable = new base::WaitableEvent(false, false); |
+ egl_manager_->SuspendUploads(waitable); |
+ idle_manager_->SignalWhenUploadsCompleted(waitable); |
+ } |
+ } else if (new_mode == MODE_IDLE && mode_ == MODE_EGL) { |
+ // Wait for already queued EGL tasks to finish before letting future Idle |
+ // tasks run. |
+ base::WaitableEvent* waitable = new base::WaitableEvent(false, false); |
+ idle_manager_->SuspendUploads(waitable); |
+ egl_manager_->SignalWhenUploadsCompleted(waitable); |
+ } else { |
+ NOTREACHED(); |
+ } |
+ |
+ mode_ = new_mode; |
+} |
+ |
+AsyncPixelTransferManagerCompressed::SharedState::SharedState() {} |
+ |
+AsyncPixelTransferManagerCompressed::SharedState::~SharedState() {} |
+ |
+} // namespace gpu |