Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 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. | |
| 4 | |
| 5 #include "media/gpu/command_buffer_helper.h" | |
| 6 | |
| 7 #include "base/macros.h" | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "base/threading/thread_checker.h" | |
| 10 #include "gpu/command_buffer/common/mailbox.h" | |
| 11 #include "gpu/command_buffer/common/sync_token.h" | |
| 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | |
| 13 #include "gpu/command_buffer/service/mailbox_manager.h" | |
| 14 #include "gpu/command_buffer/service/texture_manager.h" | |
| 15 #include "gpu/ipc/service/gpu_command_buffer_stub.h" | |
| 16 | |
| 17 namespace media { | |
| 18 | |
| 19 class CommandBufferHelperImpl | |
| 20 : public CommandBufferHelper, | |
| 21 private gpu::GpuCommandBufferStub::DestructionObserver { | |
| 22 public: | |
| 23 explicit CommandBufferHelperImpl(gpu::GpuCommandBufferStub* stub) | |
|
sunnyps
2017/06/23 00:57:59
nit: Make the helper take a decoder instead of the
sandersd (OOO until July 31)
2017/06/26 21:00:27
I'm not sure about this, because it means that Cre
| |
| 24 : stub_(stub) { | |
| 25 stub_->AddDestructionObserver(this); | |
| 26 } | |
| 27 | |
| 28 ~CommandBufferHelperImpl() override { | |
| 29 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
| 30 if (stub_) | |
| 31 stub_->RemoveDestructionObserver(this); | |
| 32 } | |
| 33 | |
| 34 bool MakeContextCurrent() override { | |
| 35 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
| 36 if (!stub_) | |
| 37 return false; | |
| 38 gpu::gles2::GLES2Decoder* decoder = stub_->decoder(); | |
| 39 if (!decoder) | |
| 40 return false; | |
| 41 return decoder->MakeCurrent(); | |
| 42 } | |
| 43 | |
| 44 scoped_refptr<gpu::gles2::TextureRef> CreateTexture(GLenum target, | |
| 45 GLenum internal_format, | |
| 46 GLsizei width, | |
| 47 GLsizei height, | |
| 48 GLenum format, | |
| 49 GLenum type) override { | |
| 50 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
| 51 if (!stub_) | |
| 52 return nullptr; | |
| 53 gpu::gles2::GLES2Decoder* decoder = stub_->decoder(); | |
| 54 if (!decoder) | |
| 55 return nullptr; | |
| 56 gpu::gles2::ContextGroup* group = decoder->GetContextGroup(); | |
| 57 if (!group) | |
| 58 return nullptr; | |
| 59 gpu::gles2::TextureManager* texture_manager = group->texture_manager(); | |
| 60 if (!texture_manager) | |
| 61 return nullptr; | |
| 62 | |
| 63 // We can't use texture_manager->CreateTexture(), since it requires a unique | |
| 64 // |client_id|. Instead we create the texture directly, and create our own | |
| 65 // TextureRef for it. | |
| 66 GLuint texture_id; | |
| 67 glGenTextures(1, &texture_id); | |
| 68 glBindTexture(target, texture_id); | |
| 69 | |
| 70 scoped_refptr<gpu::gles2::TextureRef> texture_ref = | |
| 71 gpu::gles2::TextureRef::Create(texture_manager, 0, texture_id); | |
| 72 texture_manager->SetTarget(texture_ref.get(), target); | |
| 73 texture_manager->SetLevelInfo(texture_ref.get(), // ref | |
| 74 target, // target | |
| 75 0, // level | |
| 76 internal_format, // internal_format | |
| 77 width, // width | |
| 78 height, // height | |
| 79 1, // depth | |
| 80 0, // border | |
| 81 format, // format | |
| 82 type, // type | |
| 83 gfx::Rect()); // cleared_rect | |
| 84 | |
| 85 texture_manager->SetParameteri(__func__, decoder->GetErrorState(), | |
| 86 texture_ref.get(), GL_TEXTURE_MAG_FILTER, | |
| 87 GL_LINEAR); | |
| 88 texture_manager->SetParameteri(__func__, decoder->GetErrorState(), | |
| 89 texture_ref.get(), GL_TEXTURE_MIN_FILTER, | |
| 90 GL_LINEAR); | |
| 91 | |
| 92 texture_manager->SetParameteri(__func__, decoder->GetErrorState(), | |
| 93 texture_ref.get(), GL_TEXTURE_WRAP_S, | |
| 94 GL_CLAMP_TO_EDGE); | |
| 95 texture_manager->SetParameteri(__func__, decoder->GetErrorState(), | |
| 96 texture_ref.get(), GL_TEXTURE_WRAP_T, | |
| 97 GL_CLAMP_TO_EDGE); | |
| 98 | |
| 99 texture_manager->SetParameteri(__func__, decoder->GetErrorState(), | |
| 100 texture_ref.get(), GL_TEXTURE_BASE_LEVEL, 0); | |
| 101 texture_manager->SetParameteri(__func__, decoder->GetErrorState(), | |
| 102 texture_ref.get(), GL_TEXTURE_MAX_LEVEL, 0); | |
| 103 | |
| 104 // TODO(sandersd): Do we always want to allocate for GL_TEXTURE_2D? | |
| 105 if (target == GL_TEXTURE_2D) { | |
| 106 glTexImage2D(target, // target | |
| 107 0, // level | |
| 108 internal_format, // internal_format | |
| 109 width, // width | |
| 110 height, // height | |
| 111 0, // border | |
| 112 format, // format | |
| 113 type, // type | |
| 114 nullptr); // data | |
| 115 } | |
| 116 | |
| 117 decoder->RestoreActiveTextureUnitBinding(target); | |
| 118 return texture_ref; | |
| 119 } | |
| 120 | |
| 121 base::Optional<gpu::SyncToken> CreateSyncToken() override { | |
| 122 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
| 123 if (!stub_) | |
| 124 return base::nullopt; | |
| 125 | |
| 126 // TODO(sandersd): Handle namespaces other than GPU_IO, for example the | |
| 127 // IN_PROCESS kind used in GPU tests. For now, VdaVideoDecoder clients | |
| 128 // should only use GPU_IO command buffers. | |
| 129 gpu::SyncToken sync_token = | |
| 130 gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, stub_->stream_id(), | |
| 131 stub_->command_buffer_id(), 0); | |
| 132 sync_token.SetVerifyFlush(); | |
| 133 return sync_token; | |
| 134 } | |
| 135 | |
| 136 base::Optional<gpu::Mailbox> CreateMailbox( | |
| 137 gpu::gles2::TextureRef* texture_ref) override { | |
| 138 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
| 139 if (!stub_) | |
| 140 return base::nullopt; | |
| 141 gpu::gles2::GLES2Decoder* decoder = stub_->decoder(); | |
| 142 if (!decoder) | |
| 143 return base::nullopt; | |
| 144 gpu::gles2::ContextGroup* group = decoder->GetContextGroup(); | |
| 145 if (!group) | |
| 146 return base::nullopt; | |
| 147 gpu::gles2::MailboxManager* mailbox_manager = group->mailbox_manager(); | |
| 148 if (!mailbox_manager) | |
| 149 return base::nullopt; | |
| 150 | |
| 151 gpu::Mailbox mailbox = gpu::Mailbox::Generate(); | |
| 152 mailbox_manager->ProduceTexture(mailbox, texture_ref->texture()); | |
| 153 return mailbox; | |
| 154 } | |
| 155 | |
| 156 private: | |
| 157 void OnWillDestroyStub() override { | |
| 158 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
| 159 stub_ = nullptr; | |
| 160 } | |
| 161 | |
| 162 gpu::GpuCommandBufferStub* stub_; | |
| 163 THREAD_CHECKER(thread_checker_); | |
| 164 | |
| 165 DISALLOW_COPY_AND_ASSIGN(CommandBufferHelperImpl); | |
| 166 }; | |
| 167 | |
| 168 // static | |
| 169 std::unique_ptr<CommandBufferHelper> CommandBufferHelper::Create( | |
| 170 gpu::GpuCommandBufferStub* stub) { | |
| 171 if (!stub) | |
| 172 return nullptr; | |
| 173 return base::MakeUnique<CommandBufferHelperImpl>(stub); | |
| 174 } | |
| 175 | |
| 176 } // namespace media | |
| OLD | NEW |