Roll src/third_party/WebKit d10c917:a1123a1 (svn 198729:198730)
[chromium-blink-merge.git] / content / renderer / media / renderer_gpu_video_accelerator_factories.cc
blob5c2f41680a9ec55788bb5b6ae28253ba9d01920d
1 // Copyright 2013 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.
5 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h>
10 #include "base/bind.h"
11 #include "content/child/child_gpu_memory_buffer_manager.h"
12 #include "content/child/child_thread_impl.h"
13 #include "content/common/gpu/client/context_provider_command_buffer.h"
14 #include "content/common/gpu/client/gl_helper.h"
15 #include "content/common/gpu/client/gpu_channel_host.h"
16 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
17 #include "content/common/gpu/media/gpu_video_accelerator_util.h"
18 #include "content/renderer/render_thread_impl.h"
19 #include "gpu/command_buffer/client/gles2_implementation.h"
20 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
21 #include "media/video/video_decode_accelerator.h"
22 #include "media/video/video_encode_accelerator.h"
24 namespace content {
26 // static
27 scoped_refptr<RendererGpuVideoAcceleratorFactories>
28 RendererGpuVideoAcceleratorFactories::Create(
29 GpuChannelHost* gpu_channel_host,
30 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
31 const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
32 unsigned image_texture_target,
33 bool enable_video_accelerator) {
34 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
35 new RendererGpuVideoAcceleratorFactories(gpu_channel_host, task_runner,
36 context_provider,
37 image_texture_target,
38 enable_video_accelerator);
39 // Post task from outside constructor, since AddRef()/Release() is unsafe from
40 // within.
41 task_runner->PostTask(
42 FROM_HERE,
43 base::Bind(&RendererGpuVideoAcceleratorFactories::BindContext,
44 factories));
45 return factories;
48 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
49 GpuChannelHost* gpu_channel_host,
50 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
51 const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
52 unsigned image_texture_target,
53 bool enable_video_accelerator)
54 : task_runner_(task_runner),
55 gpu_channel_host_(gpu_channel_host),
56 context_provider_(context_provider),
57 image_texture_target_(image_texture_target),
58 video_accelerator_enabled_(enable_video_accelerator),
59 gpu_memory_buffer_manager_(
60 ChildThreadImpl::current()->gpu_memory_buffer_manager()),
61 thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {
64 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
66 void RendererGpuVideoAcceleratorFactories::BindContext() {
67 DCHECK(task_runner_->BelongsToCurrentThread());
68 if (!context_provider_->BindToCurrentThread())
69 context_provider_ = NULL;
72 WebGraphicsContext3DCommandBufferImpl*
73 RendererGpuVideoAcceleratorFactories::GetContext3d() {
74 DCHECK(task_runner_->BelongsToCurrentThread());
75 if (!context_provider_.get())
76 return NULL;
77 if (context_provider_->ContextGL()->GetGraphicsResetStatusKHR() !=
78 GL_NO_ERROR) {
79 context_provider_->VerifyContexts();
80 context_provider_ = NULL;
81 gl_helper_.reset(NULL);
82 return NULL;
84 return context_provider_->WebContext3D();
87 GLHelper* RendererGpuVideoAcceleratorFactories::GetGLHelper() {
88 if (!GetContext3d())
89 return NULL;
91 if (gl_helper_.get() == NULL) {
92 gl_helper_.reset(new GLHelper(GetContext3d()->GetImplementation(),
93 GetContext3d()->GetContextSupport()));
96 return gl_helper_.get();
99 bool RendererGpuVideoAcceleratorFactories::IsGpuVideoAcceleratorEnabled() {
100 return video_accelerator_enabled_;
103 scoped_ptr<media::VideoDecodeAccelerator>
104 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() {
105 DCHECK(video_accelerator_enabled_);
106 DCHECK(task_runner_->BelongsToCurrentThread());
108 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
109 if (context && context->GetCommandBufferProxy()) {
110 return gpu_channel_host_->CreateVideoDecoder(
111 context->GetCommandBufferProxy()->GetRouteID());
114 return scoped_ptr<media::VideoDecodeAccelerator>();
117 scoped_ptr<media::VideoEncodeAccelerator>
118 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator() {
119 DCHECK(video_accelerator_enabled_);
120 DCHECK(task_runner_->BelongsToCurrentThread());
122 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
123 if (context && context->GetCommandBufferProxy()) {
124 return gpu_channel_host_->CreateVideoEncoder(
125 context->GetCommandBufferProxy()->GetRouteID());
128 return scoped_ptr<media::VideoEncodeAccelerator>();
131 bool RendererGpuVideoAcceleratorFactories::CreateTextures(
132 int32 count,
133 const gfx::Size& size,
134 std::vector<uint32>* texture_ids,
135 std::vector<gpu::Mailbox>* texture_mailboxes,
136 uint32 texture_target) {
137 DCHECK(task_runner_->BelongsToCurrentThread());
138 DCHECK(texture_target);
140 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
141 if (!context)
142 return false;
144 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
145 texture_ids->resize(count);
146 texture_mailboxes->resize(count);
147 gles2->GenTextures(count, &texture_ids->at(0));
148 for (int i = 0; i < count; ++i) {
149 gles2->ActiveTexture(GL_TEXTURE0);
150 uint32 texture_id = texture_ids->at(i);
151 gles2->BindTexture(texture_target, texture_id);
152 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
153 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
154 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
155 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
156 if (texture_target == GL_TEXTURE_2D) {
157 gles2->TexImage2D(texture_target,
159 GL_RGBA,
160 size.width(),
161 size.height(),
163 GL_RGBA,
164 GL_UNSIGNED_BYTE,
165 NULL);
167 gles2->GenMailboxCHROMIUM(texture_mailboxes->at(i).name);
168 gles2->ProduceTextureCHROMIUM(texture_target,
169 texture_mailboxes->at(i).name);
172 // We need ShallowFlushCHROMIUM() here to order the command buffer commands
173 // with respect to IPC to the GPU process, to guarantee that the decoder in
174 // the GPU process can use these textures as soon as it receives IPC
175 // notification of them.
176 gles2->ShallowFlushCHROMIUM();
177 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
178 return true;
181 void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) {
182 DCHECK(task_runner_->BelongsToCurrentThread());
184 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
185 if (!context)
186 return;
188 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
189 gles2->DeleteTextures(1, &texture_id);
190 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
193 void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) {
194 DCHECK(task_runner_->BelongsToCurrentThread());
196 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
197 if (!context)
198 return;
200 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
201 gles2->WaitSyncPointCHROMIUM(sync_point);
203 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to
204 // flush the command buffers to ensure that.
205 gles2->ShallowFlushCHROMIUM();
208 scoped_ptr<gfx::GpuMemoryBuffer>
209 RendererGpuVideoAcceleratorFactories::AllocateGpuMemoryBuffer(
210 const gfx::Size& size,
211 gfx::GpuMemoryBuffer::Format format,
212 gfx::GpuMemoryBuffer::Usage usage) {
213 DCHECK(task_runner_->BelongsToCurrentThread());
214 scoped_ptr<gfx::GpuMemoryBuffer> buffer =
215 gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(size, format, usage);
216 return buffer.Pass();
219 bool RendererGpuVideoAcceleratorFactories::IsTextureRGSupported() {
220 DCHECK(task_runner_->BelongsToCurrentThread());
222 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
223 if (!context)
224 return false;
225 return context->GetImplementation()->capabilities().texture_rg;
228 unsigned RendererGpuVideoAcceleratorFactories::ImageTextureTarget() {
229 return image_texture_target_;
232 gpu::gles2::GLES2Interface*
233 RendererGpuVideoAcceleratorFactories::GetGLES2Interface() {
234 DCHECK(task_runner_->BelongsToCurrentThread());
236 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
237 if (!context)
238 return nullptr;
239 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
240 return gles2;
243 scoped_ptr<base::SharedMemory>
244 RendererGpuVideoAcceleratorFactories::CreateSharedMemory(size_t size) {
245 DCHECK(task_runner_->BelongsToCurrentThread());
246 scoped_ptr<base::SharedMemory> mem(
247 ChildThreadImpl::AllocateSharedMemory(size, thread_safe_sender_.get()));
248 if (mem && !mem->Map(size))
249 return nullptr;
250 return mem;
253 scoped_refptr<base::SingleThreadTaskRunner>
254 RendererGpuVideoAcceleratorFactories::GetTaskRunner() {
255 return task_runner_;
258 media::VideoDecodeAccelerator::SupportedProfiles
259 RendererGpuVideoAcceleratorFactories::
260 GetVideoDecodeAcceleratorSupportedProfiles() {
261 return GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeProfiles(
262 gpu_channel_host_->gpu_info()
263 .video_decode_accelerator_supported_profiles);
266 media::VideoEncodeAccelerator::SupportedProfiles
267 RendererGpuVideoAcceleratorFactories::
268 GetVideoEncodeAcceleratorSupportedProfiles() {
269 return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
270 gpu_channel_host_->gpu_info()
271 .video_encode_accelerator_supported_profiles);
274 } // namespace content