Index: media/gpu/command_buffer_helper.cc |
diff --git a/media/gpu/command_buffer_helper.cc b/media/gpu/command_buffer_helper.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cba3421ebcb9c271d8cc2d4ce37ff2686a09df28 |
--- /dev/null |
+++ b/media/gpu/command_buffer_helper.cc |
@@ -0,0 +1,176 @@ |
+// Copyright 2017 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 "media/gpu/command_buffer_helper.h" |
+ |
+#include "base/macros.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/threading/thread_checker.h" |
+#include "gpu/command_buffer/common/mailbox.h" |
+#include "gpu/command_buffer/common/sync_token.h" |
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
+#include "gpu/command_buffer/service/mailbox_manager.h" |
+#include "gpu/command_buffer/service/texture_manager.h" |
+#include "gpu/ipc/service/gpu_command_buffer_stub.h" |
+ |
+namespace media { |
+ |
+class CommandBufferHelperImpl |
+ : public CommandBufferHelper, |
+ private gpu::GpuCommandBufferStub::DestructionObserver { |
+ public: |
+ explicit CommandBufferHelperImpl(gpu::GpuCommandBufferStub* stub) |
+ : stub_(stub) { |
+ stub_->AddDestructionObserver(this); |
+ } |
+ |
+ ~CommandBufferHelperImpl() override { |
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
+ if (stub_) |
+ stub_->RemoveDestructionObserver(this); |
+ } |
+ |
+ bool MakeContextCurrent() override { |
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
+ if (!stub_) |
+ return false; |
+ gpu::gles2::GLES2Decoder* decoder = stub_->decoder(); |
+ if (!decoder) |
+ return false; |
+ return decoder->MakeCurrent(); |
+ } |
+ |
+ scoped_refptr<gpu::gles2::TextureRef> CreateTexture(GLenum target, |
+ GLenum internal_format, |
+ GLsizei width, |
+ GLsizei height, |
+ GLenum format, |
+ GLenum type) override { |
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
+ if (!stub_) |
+ return nullptr; |
+ gpu::gles2::GLES2Decoder* decoder = stub_->decoder(); |
+ if (!decoder) |
+ return nullptr; |
+ gpu::gles2::ContextGroup* group = decoder->GetContextGroup(); |
+ if (!group) |
+ return nullptr; |
+ gpu::gles2::TextureManager* texture_manager = group->texture_manager(); |
+ if (!texture_manager) |
+ return nullptr; |
+ |
+ // We can't use texture_manager->CreateTexture(), since it requires a unique |
+ // |client_id|. Instead we create the texture directly, and create our own |
+ // TextureRef for it. |
+ // TODO(sandersd): Perhaps it was a mistake to share the command buffer? |
+ GLuint texture_id; |
+ glGenTextures(1, &texture_id); |
+ glBindTexture(target, texture_id); |
+ |
+ scoped_refptr<gpu::gles2::TextureRef> texture_ref = |
+ gpu::gles2::TextureRef::Create(texture_manager, 0, texture_id); |
+ texture_manager->SetTarget(texture_ref.get(), target); |
+ texture_manager->SetLevelInfo(texture_ref.get(), // ref |
+ target, // target |
+ 0, // level |
+ internal_format, // internal_format |
+ width, // width |
+ height, // height |
+ 1, // depth |
+ 0, // border |
+ format, // format |
+ type, // type |
+ gfx::Rect()); // cleared_rect |
+ |
+ texture_manager->SetParameteri(__func__, decoder->GetErrorState(), |
+ texture_ref.get(), GL_TEXTURE_MAG_FILTER, |
+ GL_LINEAR); |
+ texture_manager->SetParameteri(__func__, decoder->GetErrorState(), |
+ texture_ref.get(), GL_TEXTURE_MIN_FILTER, |
+ GL_LINEAR); |
+ |
+ texture_manager->SetParameteri(__func__, decoder->GetErrorState(), |
+ texture_ref.get(), GL_TEXTURE_WRAP_S, |
+ GL_CLAMP_TO_EDGE); |
+ texture_manager->SetParameteri(__func__, decoder->GetErrorState(), |
+ texture_ref.get(), GL_TEXTURE_WRAP_T, |
+ GL_CLAMP_TO_EDGE); |
+ |
+ texture_manager->SetParameteri(__func__, decoder->GetErrorState(), |
+ texture_ref.get(), GL_TEXTURE_BASE_LEVEL, 0); |
+ texture_manager->SetParameteri(__func__, decoder->GetErrorState(), |
+ texture_ref.get(), GL_TEXTURE_MAX_LEVEL, 0); |
+ |
+ // TODO(sandersd): Do we always want to allocate for GL_TEXTURE_2D? What |
+ // about GL_TEXTURE_RECTANGLE? |
+ if (target == GL_TEXTURE_2D) { |
+ glTexImage2D(target, // target |
+ 0, // level |
+ internal_format, // internal_format |
+ width, // width |
+ height, // height |
+ 0, // border |
+ format, // format |
+ type, // type |
+ nullptr); // data |
+ } |
+ |
+ decoder->RestoreActiveTextureUnitBinding(target); |
+ return texture_ref; |
+ } |
+ |
+ base::Optional<gpu::SyncToken> CreateSyncToken() override { |
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
+ |
+ if (!stub_) |
+ return base::nullopt; |
+ |
+ // TODO(sandersd): Is there a way to get the correct namespace? Should we be |
+ // setting the verified flag? Is 0 correct? Can we insert our own sync |
+ // point? |
+ return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, |
+ stub_->stream_id(), stub_->command_buffer_id(), 0); |
watk
2017/06/14 00:01:38
Are you intending this TODO to be of the kind "let
sandersd (OOO until July 31)
2017/06/14 00:03:02
This is in the category of 'I don't understand thi
|
+ } |
+ |
+ base::Optional<gpu::Mailbox> CreateMailbox( |
+ gpu::gles2::TextureRef* texture_ref) override { |
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
+ if (!stub_) |
+ return base::nullopt; |
+ gpu::gles2::GLES2Decoder* decoder = stub_->decoder(); |
+ if (!decoder) |
+ return base::nullopt; |
+ gpu::gles2::ContextGroup* group = decoder->GetContextGroup(); |
+ if (!group) |
+ return base::nullopt; |
+ gpu::gles2::MailboxManager* mailbox_manager = group->mailbox_manager(); |
+ if (!mailbox_manager) |
+ return base::nullopt; |
+ |
+ gpu::Mailbox mailbox = gpu::Mailbox::Generate(); |
+ mailbox_manager->ProduceTexture(mailbox, texture_ref->texture()); |
+ return mailbox; |
+ } |
+ |
+ private: |
+ void OnWillDestroyStub() override { |
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
+ stub_ = nullptr; |
+ } |
+ |
+ gpu::GpuCommandBufferStub* stub_ = nullptr; |
watk
2017/06/14 00:01:38
Unconventional to have an initializer here and in
sandersd (OOO until July 31)
2017/06/16 22:31:38
Done.
|
+ THREAD_CHECKER(thread_checker_); |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CommandBufferHelperImpl); |
+}; |
+ |
+// static |
+std::unique_ptr<CommandBufferHelper> CommandBufferHelper::Create( |
+ gpu::GpuCommandBufferStub* stub) { |
+ if (!stub) |
+ return nullptr; |
+ return base::MakeUnique<CommandBufferHelperImpl>(stub); |
+} |
+ |
+} // namespace media |