Roll src/third_party/WebKit a452221:9ff6d11 (svn 202117:202119)
[chromium-blink-merge.git] / content / renderer / media / renderer_gpu_video_accelerator_factories.cc
blob2af59d94269bf19820ae526d4fb8a70aa5353258
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 bool enable_gpu_memory_buffer_video_frames,
33 unsigned image_texture_target,
34 bool enable_video_accelerator) {
35 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
36 new RendererGpuVideoAcceleratorFactories(
37 gpu_channel_host, task_runner, context_provider,
38 enable_gpu_memory_buffer_video_frames, image_texture_target,
39 enable_video_accelerator);
40 // Post task from outside constructor, since AddRef()/Release() is unsafe from
41 // within.
42 task_runner->PostTask(
43 FROM_HERE,
44 base::Bind(&RendererGpuVideoAcceleratorFactories::BindContext,
45 factories));
46 return factories;
49 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
50 GpuChannelHost* gpu_channel_host,
51 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
52 const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
53 bool enable_gpu_memory_buffer_video_frames,
54 unsigned image_texture_target,
55 bool enable_video_accelerator)
56 : task_runner_(task_runner),
57 gpu_channel_host_(gpu_channel_host),
58 context_provider_(context_provider),
59 enable_gpu_memory_buffer_video_frames_(
60 enable_gpu_memory_buffer_video_frames),
61 image_texture_target_(image_texture_target),
62 video_accelerator_enabled_(enable_video_accelerator),
63 gpu_memory_buffer_manager_(ChildThreadImpl::current()
64 ->gpu_memory_buffer_manager()),
65 thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {
66 DCHECK(gpu_channel_host_.get());
69 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
71 void RendererGpuVideoAcceleratorFactories::BindContext() {
72 DCHECK(task_runner_->BelongsToCurrentThread());
73 if (!context_provider_->BindToCurrentThread())
74 context_provider_ = NULL;
77 WebGraphicsContext3DCommandBufferImpl*
78 RendererGpuVideoAcceleratorFactories::GetContext3d() {
79 DCHECK(task_runner_->BelongsToCurrentThread());
80 if (!context_provider_.get())
81 return NULL;
82 if (context_provider_->ContextGL()->GetGraphicsResetStatusKHR() !=
83 GL_NO_ERROR) {
84 context_provider_->VerifyContexts();
85 context_provider_ = NULL;
86 gl_helper_.reset(NULL);
87 return NULL;
89 return context_provider_->WebContext3D();
92 GLHelper* RendererGpuVideoAcceleratorFactories::GetGLHelper() {
93 if (!GetContext3d())
94 return NULL;
96 if (gl_helper_.get() == NULL) {
97 gl_helper_.reset(new GLHelper(GetContext3d()->GetImplementation(),
98 GetContext3d()->GetContextSupport()));
101 return gl_helper_.get();
104 bool RendererGpuVideoAcceleratorFactories::IsGpuVideoAcceleratorEnabled() {
105 return video_accelerator_enabled_;
108 scoped_ptr<media::VideoDecodeAccelerator>
109 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() {
110 DCHECK(video_accelerator_enabled_);
111 DCHECK(task_runner_->BelongsToCurrentThread());
113 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
114 if (context && context->GetCommandBufferProxy())
115 return context->GetCommandBufferProxy()->CreateVideoDecoder();
117 return nullptr;
120 scoped_ptr<media::VideoEncodeAccelerator>
121 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator() {
122 DCHECK(video_accelerator_enabled_);
123 DCHECK(task_runner_->BelongsToCurrentThread());
125 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
126 if (context && context->GetCommandBufferProxy())
127 return context->GetCommandBufferProxy()->CreateVideoEncoder();
129 return nullptr;
132 bool RendererGpuVideoAcceleratorFactories::CreateTextures(
133 int32 count,
134 const gfx::Size& size,
135 std::vector<uint32>* texture_ids,
136 std::vector<gpu::Mailbox>* texture_mailboxes,
137 uint32 texture_target) {
138 DCHECK(task_runner_->BelongsToCurrentThread());
139 DCHECK(texture_target);
141 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
142 if (!context)
143 return false;
145 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
146 texture_ids->resize(count);
147 texture_mailboxes->resize(count);
148 gles2->GenTextures(count, &texture_ids->at(0));
149 for (int i = 0; i < count; ++i) {
150 gles2->ActiveTexture(GL_TEXTURE0);
151 uint32 texture_id = texture_ids->at(i);
152 gles2->BindTexture(texture_target, texture_id);
153 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
154 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
155 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
156 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
157 if (texture_target == GL_TEXTURE_2D) {
158 gles2->TexImage2D(texture_target,
160 GL_RGBA,
161 size.width(),
162 size.height(),
164 GL_RGBA,
165 GL_UNSIGNED_BYTE,
166 NULL);
168 gles2->GenMailboxCHROMIUM(texture_mailboxes->at(i).name);
169 gles2->ProduceTextureCHROMIUM(texture_target,
170 texture_mailboxes->at(i).name);
173 // We need ShallowFlushCHROMIUM() here to order the command buffer commands
174 // with respect to IPC to the GPU process, to guarantee that the decoder in
175 // the GPU process can use these textures as soon as it receives IPC
176 // notification of them.
177 gles2->ShallowFlushCHROMIUM();
178 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
179 return true;
182 void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) {
183 DCHECK(task_runner_->BelongsToCurrentThread());
185 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
186 if (!context)
187 return;
189 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
190 gles2->DeleteTextures(1, &texture_id);
191 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
194 void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) {
195 DCHECK(task_runner_->BelongsToCurrentThread());
197 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
198 if (!context)
199 return;
201 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
202 gles2->WaitSyncPointCHROMIUM(sync_point);
204 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to
205 // flush the command buffers to ensure that.
206 gles2->ShallowFlushCHROMIUM();
209 scoped_ptr<gfx::GpuMemoryBuffer>
210 RendererGpuVideoAcceleratorFactories::AllocateGpuMemoryBuffer(
211 const gfx::Size& size,
212 gfx::BufferFormat format,
213 gfx::BufferUsage usage) {
214 DCHECK(task_runner_->BelongsToCurrentThread());
215 scoped_ptr<gfx::GpuMemoryBuffer> buffer =
216 gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(size, format, usage);
217 return buffer.Pass();
219 bool RendererGpuVideoAcceleratorFactories::
220 ShouldUseGpuMemoryBuffersForVideoFrames() const {
221 return enable_gpu_memory_buffer_video_frames_;
224 unsigned RendererGpuVideoAcceleratorFactories::ImageTextureTarget() {
225 return image_texture_target_;
228 media::VideoPixelFormat
229 RendererGpuVideoAcceleratorFactories::VideoFrameOutputFormat() {
230 DCHECK(task_runner_->BelongsToCurrentThread());
232 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
233 if (context) {
234 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
235 if (gles2->capabilities().image_ycbcr_422)
236 return media::PIXEL_FORMAT_UYVY;
237 if (gles2->capabilities().texture_rg)
238 return media::PIXEL_FORMAT_I420;
241 return media::PIXEL_FORMAT_UNKNOWN;
244 gpu::gles2::GLES2Interface*
245 RendererGpuVideoAcceleratorFactories::GetGLES2Interface() {
246 DCHECK(task_runner_->BelongsToCurrentThread());
248 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
249 if (!context)
250 return nullptr;
251 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
252 return gles2;
255 scoped_ptr<base::SharedMemory>
256 RendererGpuVideoAcceleratorFactories::CreateSharedMemory(size_t size) {
257 DCHECK(task_runner_->BelongsToCurrentThread());
258 scoped_ptr<base::SharedMemory> mem(
259 ChildThreadImpl::AllocateSharedMemory(size, thread_safe_sender_.get()));
260 if (mem && !mem->Map(size))
261 return nullptr;
262 return mem;
265 scoped_refptr<base::SingleThreadTaskRunner>
266 RendererGpuVideoAcceleratorFactories::GetTaskRunner() {
267 return task_runner_;
270 media::VideoDecodeAccelerator::SupportedProfiles
271 RendererGpuVideoAcceleratorFactories::
272 GetVideoDecodeAcceleratorSupportedProfiles() {
273 return GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeProfiles(
274 gpu_channel_host_->gpu_info()
275 .video_decode_accelerator_supported_profiles);
278 media::VideoEncodeAccelerator::SupportedProfiles
279 RendererGpuVideoAcceleratorFactories::
280 GetVideoEncodeAcceleratorSupportedProfiles() {
281 return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
282 gpu_channel_host_->gpu_info()
283 .video_encode_accelerator_supported_profiles);
286 } // namespace content