[Android] Implement 3-way sensor fallback for Device Orientation.
[chromium-blink-merge.git] / content / renderer / media / renderer_gpu_video_accelerator_factories.cc
blobff0be6ac112a8118b4ae57b972f490f36fdde520
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 media::VideoPixelFormat video_frame_output_format,
35 bool enable_video_accelerator) {
36 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
37 new RendererGpuVideoAcceleratorFactories(
38 gpu_channel_host, task_runner, context_provider,
39 enable_gpu_memory_buffer_video_frames, image_texture_target,
40 video_frame_output_format, enable_video_accelerator);
41 // Post task from outside constructor, since AddRef()/Release() is unsafe from
42 // within.
43 task_runner->PostTask(
44 FROM_HERE,
45 base::Bind(&RendererGpuVideoAcceleratorFactories::BindContext,
46 factories));
47 return factories;
50 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
51 GpuChannelHost* gpu_channel_host,
52 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
53 const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
54 bool enable_gpu_memory_buffer_video_frames,
55 unsigned image_texture_target,
56 media::VideoPixelFormat video_frame_output_format,
57 bool enable_video_accelerator)
58 : task_runner_(task_runner),
59 gpu_channel_host_(gpu_channel_host),
60 context_provider_(context_provider),
61 enable_gpu_memory_buffer_video_frames_(
62 enable_gpu_memory_buffer_video_frames),
63 image_texture_target_(image_texture_target),
64 video_frame_output_format_(video_frame_output_format),
65 video_accelerator_enabled_(enable_video_accelerator),
66 gpu_memory_buffer_manager_(ChildThreadImpl::current()
67 ->gpu_memory_buffer_manager()),
68 thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {
69 DCHECK(gpu_channel_host_.get());
72 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
74 void RendererGpuVideoAcceleratorFactories::BindContext() {
75 DCHECK(task_runner_->BelongsToCurrentThread());
76 if (!context_provider_->BindToCurrentThread())
77 context_provider_ = NULL;
80 WebGraphicsContext3DCommandBufferImpl*
81 RendererGpuVideoAcceleratorFactories::GetContext3d() {
82 DCHECK(task_runner_->BelongsToCurrentThread());
83 if (!context_provider_.get())
84 return NULL;
85 if (context_provider_->ContextGL()->GetGraphicsResetStatusKHR() !=
86 GL_NO_ERROR) {
87 context_provider_->VerifyContexts();
88 context_provider_ = NULL;
89 gl_helper_.reset(NULL);
90 return NULL;
92 return context_provider_->WebContext3D();
95 GLHelper* RendererGpuVideoAcceleratorFactories::GetGLHelper() {
96 if (!GetContext3d())
97 return NULL;
99 if (gl_helper_.get() == NULL) {
100 gl_helper_.reset(new GLHelper(GetContext3d()->GetImplementation(),
101 GetContext3d()->GetContextSupport()));
104 return gl_helper_.get();
107 bool RendererGpuVideoAcceleratorFactories::IsGpuVideoAcceleratorEnabled() {
108 return video_accelerator_enabled_;
111 scoped_ptr<media::VideoDecodeAccelerator>
112 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() {
113 DCHECK(video_accelerator_enabled_);
114 DCHECK(task_runner_->BelongsToCurrentThread());
116 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
117 if (context && context->GetCommandBufferProxy())
118 return context->GetCommandBufferProxy()->CreateVideoDecoder();
120 return nullptr;
123 scoped_ptr<media::VideoEncodeAccelerator>
124 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator() {
125 DCHECK(video_accelerator_enabled_);
126 DCHECK(task_runner_->BelongsToCurrentThread());
128 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
129 if (context && context->GetCommandBufferProxy())
130 return context->GetCommandBufferProxy()->CreateVideoEncoder();
132 return nullptr;
135 bool RendererGpuVideoAcceleratorFactories::CreateTextures(
136 int32 count,
137 const gfx::Size& size,
138 std::vector<uint32>* texture_ids,
139 std::vector<gpu::Mailbox>* texture_mailboxes,
140 uint32 texture_target) {
141 DCHECK(task_runner_->BelongsToCurrentThread());
142 DCHECK(texture_target);
144 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
145 if (!context)
146 return false;
148 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
149 texture_ids->resize(count);
150 texture_mailboxes->resize(count);
151 gles2->GenTextures(count, &texture_ids->at(0));
152 for (int i = 0; i < count; ++i) {
153 gles2->ActiveTexture(GL_TEXTURE0);
154 uint32 texture_id = texture_ids->at(i);
155 gles2->BindTexture(texture_target, texture_id);
156 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
157 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
158 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
159 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
160 if (texture_target == GL_TEXTURE_2D) {
161 gles2->TexImage2D(texture_target,
163 GL_RGBA,
164 size.width(),
165 size.height(),
167 GL_RGBA,
168 GL_UNSIGNED_BYTE,
169 NULL);
171 gles2->GenMailboxCHROMIUM(texture_mailboxes->at(i).name);
172 gles2->ProduceTextureCHROMIUM(texture_target,
173 texture_mailboxes->at(i).name);
176 // We need ShallowFlushCHROMIUM() here to order the command buffer commands
177 // with respect to IPC to the GPU process, to guarantee that the decoder in
178 // the GPU process can use these textures as soon as it receives IPC
179 // notification of them.
180 gles2->ShallowFlushCHROMIUM();
181 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
182 return true;
185 void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) {
186 DCHECK(task_runner_->BelongsToCurrentThread());
188 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
189 if (!context)
190 return;
192 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
193 gles2->DeleteTextures(1, &texture_id);
194 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
197 void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) {
198 DCHECK(task_runner_->BelongsToCurrentThread());
200 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
201 if (!context)
202 return;
204 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
205 gles2->WaitSyncPointCHROMIUM(sync_point);
207 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to
208 // flush the command buffers to ensure that.
209 gles2->ShallowFlushCHROMIUM();
212 scoped_ptr<gfx::GpuMemoryBuffer>
213 RendererGpuVideoAcceleratorFactories::AllocateGpuMemoryBuffer(
214 const gfx::Size& size,
215 gfx::BufferFormat format,
216 gfx::BufferUsage usage) {
217 DCHECK(task_runner_->BelongsToCurrentThread());
218 scoped_ptr<gfx::GpuMemoryBuffer> buffer =
219 gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(size, format, usage);
220 return buffer.Pass();
223 bool RendererGpuVideoAcceleratorFactories::IsTextureRGSupported() {
224 DCHECK(task_runner_->BelongsToCurrentThread());
226 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
227 if (!context)
228 return false;
229 return context->GetImplementation()->capabilities().texture_rg;
232 bool RendererGpuVideoAcceleratorFactories::
233 ShouldUseGpuMemoryBuffersForVideoFrames() const {
234 return enable_gpu_memory_buffer_video_frames_;
237 unsigned RendererGpuVideoAcceleratorFactories::ImageTextureTarget() {
238 return image_texture_target_;
241 media::VideoPixelFormat
242 RendererGpuVideoAcceleratorFactories::VideoFrameOutputFormat() {
243 return video_frame_output_format_;
246 gpu::gles2::GLES2Interface*
247 RendererGpuVideoAcceleratorFactories::GetGLES2Interface() {
248 DCHECK(task_runner_->BelongsToCurrentThread());
250 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
251 if (!context)
252 return nullptr;
253 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
254 return gles2;
257 scoped_ptr<base::SharedMemory>
258 RendererGpuVideoAcceleratorFactories::CreateSharedMemory(size_t size) {
259 DCHECK(task_runner_->BelongsToCurrentThread());
260 scoped_ptr<base::SharedMemory> mem(
261 ChildThreadImpl::AllocateSharedMemory(size, thread_safe_sender_.get()));
262 if (mem && !mem->Map(size))
263 return nullptr;
264 return mem;
267 scoped_refptr<base::SingleThreadTaskRunner>
268 RendererGpuVideoAcceleratorFactories::GetTaskRunner() {
269 return task_runner_;
272 media::VideoDecodeAccelerator::SupportedProfiles
273 RendererGpuVideoAcceleratorFactories::
274 GetVideoDecodeAcceleratorSupportedProfiles() {
275 return GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeProfiles(
276 gpu_channel_host_->gpu_info()
277 .video_decode_accelerator_supported_profiles);
280 media::VideoEncodeAccelerator::SupportedProfiles
281 RendererGpuVideoAcceleratorFactories::
282 GetVideoEncodeAcceleratorSupportedProfiles() {
283 return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
284 gpu_channel_host_->gpu_info()
285 .video_encode_accelerator_supported_profiles);
288 } // namespace content