Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: content/renderer/media/renderer_gpu_video_accelerator_factories.cc

Issue 144303004: Revert of Revert of Revert of Remove threading from RendererGpuVideoAcceleratorFactories (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dthread
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" 5 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "content/child/child_thread.h" 11 #include "content/child/child_thread.h"
12 #include "content/common/gpu/client/context_provider_command_buffer.h" 12 #include "content/common/gpu/client/context_provider_command_buffer.h"
13 #include "content/common/gpu/client/gpu_channel_host.h" 13 #include "content/common/gpu/client/gpu_channel_host.h"
14 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 14 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
15 #include "content/renderer/render_thread_impl.h" 15 #include "content/renderer/render_thread_impl.h"
16 #include "gpu/command_buffer/client/gles2_implementation.h" 16 #include "gpu/command_buffer/client/gles2_implementation.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "third_party/skia/include/core/SkPixelRef.h" 17 #include "third_party/skia/include/core/SkPixelRef.h"
19 18
20 namespace content { 19 namespace content {
21 20
22 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {} 21 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
23 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( 22 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
24 GpuChannelHost* gpu_channel_host, 23 GpuChannelHost* gpu_channel_host,
25 const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
26 const scoped_refptr<ContextProviderCommandBuffer>& context_provider) 24 const scoped_refptr<ContextProviderCommandBuffer>& context_provider)
27 : task_runner_(message_loop_proxy), 25 : task_runner_(
26 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()),
28 gpu_channel_host_(gpu_channel_host), 27 gpu_channel_host_(gpu_channel_host),
29 context_provider_(context_provider), 28 context_provider_(context_provider),
30 thread_safe_sender_(ChildThread::current()->thread_safe_sender()) {} 29 thread_safe_sender_(ChildThread::current()->thread_safe_sender()),
30 aborted_waiter_(true, false),
31 task_runner_async_waiter_(false, false) {
32 // |context_provider_| is only required to support HW-accelerated decode.
33 if (!context_provider_)
34 return;
35
36 if (task_runner_->BelongsToCurrentThread()) {
37 AsyncBindContext();
38 task_runner_async_waiter_.Reset();
39 return;
40 }
41 // Wait for the context to be acquired.
42 task_runner_->PostTask(
43 FROM_HERE,
44 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncBindContext,
45 // Unretained to avoid ref/deref'ing |*this|, which is not yet
46 // stored in a scoped_refptr. Safe because the Wait() below
47 // keeps us alive until this task completes.
48 base::Unretained(this)));
49 task_runner_async_waiter_.Wait();
50 }
51
52 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories()
53 : aborted_waiter_(true, false),
54 task_runner_async_waiter_(false, false) {}
31 55
32 WebGraphicsContext3DCommandBufferImpl* 56 WebGraphicsContext3DCommandBufferImpl*
33 RendererGpuVideoAcceleratorFactories::GetContext3d() { 57 RendererGpuVideoAcceleratorFactories::GetContext3d() {
34 DCHECK(task_runner_->BelongsToCurrentThread()); 58 DCHECK(task_runner_->BelongsToCurrentThread());
35 if (!context_provider_) 59 if (!context_provider_)
36 return NULL; 60 return NULL;
37 if (context_provider_->IsContextLost()) { 61 if (context_provider_->IsContextLost()) {
38 context_provider_->VerifyContexts(); 62 context_provider_->VerifyContexts();
39 context_provider_ = NULL; 63 context_provider_ = NULL;
40 return NULL; 64 return NULL;
41 } 65 }
42 return context_provider_->WebContext3D(); 66 return context_provider_->WebContext3D();
43 } 67 }
44 68
69 void RendererGpuVideoAcceleratorFactories::AsyncBindContext() {
70 DCHECK(task_runner_->BelongsToCurrentThread());
71 if (!context_provider_->BindToCurrentThread())
72 context_provider_ = NULL;
73 task_runner_async_waiter_.Signal();
74 }
75
45 scoped_ptr<media::VideoDecodeAccelerator> 76 scoped_ptr<media::VideoDecodeAccelerator>
46 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( 77 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator(
47 media::VideoCodecProfile profile, 78 media::VideoCodecProfile profile,
48 media::VideoDecodeAccelerator::Client* client) { 79 media::VideoDecodeAccelerator::Client* client) {
49 DCHECK(task_runner_->BelongsToCurrentThread()); 80 if (task_runner_->BelongsToCurrentThread()) {
81 AsyncCreateVideoDecodeAccelerator(profile, client);
82 task_runner_async_waiter_.Reset();
83 return vda_.Pass();
84 }
85 // The VDA is returned in the vda_ member variable by the
86 // AsyncCreateVideoDecodeAccelerator() function.
87 task_runner_->PostTask(FROM_HERE,
88 base::Bind(&RendererGpuVideoAcceleratorFactories::
89 AsyncCreateVideoDecodeAccelerator,
90 this,
91 profile,
92 client));
50 93
51 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); 94 base::WaitableEvent* objects[] = {&aborted_waiter_,
52 if (context && context->GetCommandBufferProxy()) { 95 &task_runner_async_waiter_};
53 return gpu_channel_host_->CreateVideoDecoder( 96 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
54 context->GetCommandBufferProxy()->GetRouteID(), profile, client); 97 // If we are aborting and the VDA is created by the
98 // AsyncCreateVideoDecodeAccelerator() function later we need to ensure
99 // that it is destroyed on the same thread.
100 task_runner_->PostTask(FROM_HERE,
101 base::Bind(&RendererGpuVideoAcceleratorFactories::
102 AsyncDestroyVideoDecodeAccelerator,
103 this));
104 return scoped_ptr<media::VideoDecodeAccelerator>();
55 } 105 }
56 106 return vda_.Pass();
57 return scoped_ptr<media::VideoDecodeAccelerator>();
58 } 107 }
59 108
60 scoped_ptr<media::VideoEncodeAccelerator> 109 scoped_ptr<media::VideoEncodeAccelerator>
61 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator( 110 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator(
62 media::VideoEncodeAccelerator::Client* client) { 111 media::VideoEncodeAccelerator::Client* client) {
63 DCHECK(task_runner_->BelongsToCurrentThread()); 112 DCHECK(task_runner_->BelongsToCurrentThread());
64 113
65 return gpu_channel_host_->CreateVideoEncoder(client); 114 return gpu_channel_host_->CreateVideoEncoder(client);
66 } 115 }
67 116
117 void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator(
118 media::VideoCodecProfile profile,
119 media::VideoDecodeAccelerator::Client* client) {
120 DCHECK(task_runner_->BelongsToCurrentThread());
121
122 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
123 if (context && context->GetCommandBufferProxy()) {
124 vda_ = gpu_channel_host_->CreateVideoDecoder(
125 context->GetCommandBufferProxy()->GetRouteID(), profile, client);
126 }
127 task_runner_async_waiter_.Signal();
128 }
129
68 uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( 130 uint32 RendererGpuVideoAcceleratorFactories::CreateTextures(
69 int32 count, 131 int32 count,
70 const gfx::Size& size, 132 const gfx::Size& size,
71 std::vector<uint32>* texture_ids, 133 std::vector<uint32>* texture_ids,
72 std::vector<gpu::Mailbox>* texture_mailboxes, 134 std::vector<gpu::Mailbox>* texture_mailboxes,
73 uint32 texture_target) { 135 uint32 texture_target) {
74 DCHECK(task_runner_->BelongsToCurrentThread()); 136 DCHECK(task_runner_->BelongsToCurrentThread());
75 DCHECK(texture_target); 137 DCHECK(texture_target);
76 138
77 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); 139 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 return; 197 return;
136 198
137 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); 199 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
138 gles2->WaitSyncPointCHROMIUM(sync_point); 200 gles2->WaitSyncPointCHROMIUM(sync_point);
139 201
140 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to 202 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to
141 // flush the command buffers to ensure that. 203 // flush the command buffers to ensure that.
142 gles2->ShallowFlushCHROMIUM(); 204 gles2->ShallowFlushCHROMIUM();
143 } 205 }
144 206
145 void RendererGpuVideoAcceleratorFactories::ReadPixels( 207 void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id,
208 const gfx::Size& size,
209 const SkBitmap& pixels) {
210 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
211 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to
212 // ensure that the underlying pixels in the SkBitmap passed in remain valid
213 // until the AsyncReadPixels() call completes.
214 read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
215
216 if (!task_runner_->BelongsToCurrentThread()) {
217 task_runner_->PostTask(
218 FROM_HERE,
219 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels,
220 this,
221 texture_id,
222 size));
223 base::WaitableEvent* objects[] = {&aborted_waiter_,
224 &task_runner_async_waiter_};
225 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
226 return;
227 } else {
228 AsyncReadPixels(texture_id, size);
229 task_runner_async_waiter_.Reset();
230 }
231 read_pixels_bitmap_.setPixelRef(NULL);
232 }
233
234 void RendererGpuVideoAcceleratorFactories::AsyncReadPixels(
146 uint32 texture_id, 235 uint32 texture_id,
147 const gfx::Rect& visible_rect, 236 const gfx::Size& size) {
148 const SkBitmap& pixels) {
149 DCHECK(task_runner_->BelongsToCurrentThread()); 237 DCHECK(task_runner_->BelongsToCurrentThread());
150
151 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); 238 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d();
152 if (!context) 239 if (!context) {
240 task_runner_async_waiter_.Signal();
153 return; 241 return;
242 }
154 243
155 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); 244 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation();
156 245
157 GLuint tmp_texture; 246 GLuint tmp_texture;
158 gles2->GenTextures(1, &tmp_texture); 247 gles2->GenTextures(1, &tmp_texture);
159 gles2->BindTexture(GL_TEXTURE_2D, tmp_texture); 248 gles2->BindTexture(GL_TEXTURE_2D, tmp_texture);
160 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 249 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
161 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 250 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 251 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
163 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 252 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
164 context->copyTextureCHROMIUM( 253 context->copyTextureCHROMIUM(
165 GL_TEXTURE_2D, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE); 254 GL_TEXTURE_2D, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE);
166 255
167 GLuint fb; 256 GLuint fb;
168 gles2->GenFramebuffers(1, &fb); 257 gles2->GenFramebuffers(1, &fb);
169 gles2->BindFramebuffer(GL_FRAMEBUFFER, fb); 258 gles2->BindFramebuffer(GL_FRAMEBUFFER, fb);
170 gles2->FramebufferTexture2D( 259 gles2->FramebufferTexture2D(
171 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_texture, 0); 260 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_texture, 0);
172 gles2->PixelStorei(GL_PACK_ALIGNMENT, 4); 261 gles2->PixelStorei(GL_PACK_ALIGNMENT, 4);
173 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ 262 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \
174 SK_A32_SHIFT == 24 263 SK_A32_SHIFT == 24
175 GLenum skia_format = GL_BGRA_EXT; 264 GLenum skia_format = GL_BGRA_EXT;
176 #elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \ 265 #elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
177 SK_A32_SHIFT == 24 266 SK_A32_SHIFT == 24
178 GLenum skia_format = GL_RGBA; 267 GLenum skia_format = GL_RGBA;
179 #else 268 #else
180 #error Unexpected Skia ARGB_8888 layout! 269 #error Unexpected Skia ARGB_8888 layout!
181 #endif 270 #endif
182 gles2->ReadPixels(visible_rect.x(), 271 gles2->ReadPixels(0,
183 visible_rect.y(), 272 0,
184 visible_rect.width(), 273 size.width(),
185 visible_rect.height(), 274 size.height(),
186 skia_format, 275 skia_format,
187 GL_UNSIGNED_BYTE, 276 GL_UNSIGNED_BYTE,
188 pixels.pixelRef()->pixels()); 277 read_pixels_bitmap_.pixelRef()->pixels());
189 gles2->DeleteFramebuffers(1, &fb); 278 gles2->DeleteFramebuffers(1, &fb);
190 gles2->DeleteTextures(1, &tmp_texture); 279 gles2->DeleteTextures(1, &tmp_texture);
191 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 280 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
281 task_runner_async_waiter_.Signal();
192 } 282 }
193 283
194 base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( 284 base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory(
195 size_t size) { 285 size_t size) {
196 DCHECK(task_runner_->BelongsToCurrentThread()); 286 DCHECK(task_runner_->BelongsToCurrentThread());
197 return ChildThread::AllocateSharedMemory(size, thread_safe_sender_.get()); 287 return ChildThread::AllocateSharedMemory(size, thread_safe_sender_.get());
198 } 288 }
199 289
200 scoped_refptr<base::SingleThreadTaskRunner> 290 scoped_refptr<base::SingleThreadTaskRunner>
201 RendererGpuVideoAcceleratorFactories::GetTaskRunner() { 291 RendererGpuVideoAcceleratorFactories::GetTaskRunner() {
202 return task_runner_; 292 return task_runner_;
203 } 293 }
204 294
295 void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); }
296
297 bool RendererGpuVideoAcceleratorFactories::IsAborted() {
298 return aborted_waiter_.IsSignaled();
299 }
300
301 scoped_refptr<RendererGpuVideoAcceleratorFactories>
302 RendererGpuVideoAcceleratorFactories::Clone() {
303 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
304 new RendererGpuVideoAcceleratorFactories();
305 factories->task_runner_ = task_runner_;
306 factories->gpu_channel_host_ = gpu_channel_host_;
307 factories->context_provider_ = context_provider_;
308 factories->thread_safe_sender_ = thread_safe_sender_;
309 return factories;
310 }
311
312 void
313 RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() {
314 // OK to release because Destroy() will delete the VDA instance.
315 if (vda_)
316 vda_.release()->Destroy();
317 }
318
205 } // namespace content 319 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/renderer_gpu_video_accelerator_factories.h ('k') | content/renderer/media/rtc_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698