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

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

Issue 13890012: Integrate VDA with WebRTC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Create new VDA thread, copy gpu_factories, and add DestructionObserver Created 7 years, 6 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_decoder_factories.h" 5 #include "content/renderer/media/renderer_gpu_video_decoder_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"
(...skipping 11 matching lines...) Expand all
22 GpuChannelHost* gpu_channel_host, 22 GpuChannelHost* gpu_channel_host,
23 const scoped_refptr<base::MessageLoopProxy>& message_loop, 23 const scoped_refptr<base::MessageLoopProxy>& message_loop,
24 WebGraphicsContext3DCommandBufferImpl* context) 24 WebGraphicsContext3DCommandBufferImpl* context)
25 : message_loop_(message_loop), 25 : message_loop_(message_loop),
26 gpu_channel_host_(gpu_channel_host), 26 gpu_channel_host_(gpu_channel_host),
27 aborted_waiter_(true, false), 27 aborted_waiter_(true, false),
28 compositor_loop_async_waiter_(false, false), 28 compositor_loop_async_waiter_(false, false),
29 render_thread_async_waiter_(false, false) { 29 render_thread_async_waiter_(false, false) {
30 if (message_loop_->BelongsToCurrentThread()) { 30 if (message_loop_->BelongsToCurrentThread()) {
31 AsyncGetContext(context); 31 AsyncGetContext(context);
32 compositor_loop_async_waiter_.Reset();
32 return; 33 return;
33 } 34 }
34 // Threaded compositor requires us to wait for the context to be acquired. 35 // Threaded compositor requires us to wait for the context to be acquired.
35 message_loop_->PostTask(FROM_HERE, base::Bind( 36 message_loop_->PostTask(FROM_HERE, base::Bind(
36 &RendererGpuVideoDecoderFactories::AsyncGetContext, 37 &RendererGpuVideoDecoderFactories::AsyncGetContext,
37 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a 38 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a
38 // scoped_refptr. Safe because the Wait() below keeps us alive until this 39 // scoped_refptr. Safe because the Wait() below keeps us alive until this
39 // task completes. 40 // task completes.
40 base::Unretained(this), 41 base::Unretained(this),
41 // OK to pass raw because the pointee is only deleted on the compositor 42 // OK to pass raw because the pointee is only deleted on the compositor
42 // thread, and only as the result of a PostTask from the render thread 43 // thread, and only as the result of a PostTask from the render thread
43 // which can only happen after this function returns, so our PostTask will 44 // which can only happen after this function returns, so our PostTask will
44 // run first. 45 // run first.
45 context)); 46 context));
46 compositor_loop_async_waiter_.Wait(); 47 compositor_loop_async_waiter_.Wait();
47 } 48 }
48 49
50 RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
51 scoped_refptr<base::MessageLoopProxy> message_loop,
52 scoped_refptr<GpuChannelHost> gpu_channel_host,
53 base::WeakPtr<WebGraphicsContext3DCommandBufferImpl> context)
54 : message_loop_(message_loop),
55 gpu_channel_host_(gpu_channel_host),
56 context_(context),
57 aborted_waiter_(true, false),
58 compositor_loop_async_waiter_(false, false),
59 render_thread_async_waiter_(false, false) {
60 }
61
62 RendererGpuVideoDecoderFactories* RendererGpuVideoDecoderFactories::Copy() {
63 return new RendererGpuVideoDecoderFactories(
64 message_loop_, gpu_channel_host_, context_);
65 }
66
49 void RendererGpuVideoDecoderFactories::AsyncGetContext( 67 void RendererGpuVideoDecoderFactories::AsyncGetContext(
50 WebGraphicsContext3DCommandBufferImpl* context) { 68 WebGraphicsContext3DCommandBufferImpl* context) {
51 context_ = context->AsWeakPtr(); 69 context_ = context->AsWeakPtr();
52 if (context_) { 70 if (context_) {
53 if (context_->makeContextCurrent()) { 71 if (context_->makeContextCurrent()) {
54 // Called once per media player, but is a no-op after the first one in 72 // Called once per media player, but is a no-op after the first one in
55 // each renderer. 73 // each renderer.
56 context_->insertEventMarkerEXT("GpuVDAContext3D"); 74 context_->insertEventMarkerEXT("GpuVDAContext3D");
57 } 75 }
58 } 76 }
59 compositor_loop_async_waiter_.Signal(); 77 compositor_loop_async_waiter_.Signal();
60 } 78 }
61 79
62 media::VideoDecodeAccelerator* 80 media::VideoDecodeAccelerator*
63 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( 81 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator(
64 media::VideoCodecProfile profile, 82 media::VideoCodecProfile profile,
65 media::VideoDecodeAccelerator::Client* client) { 83 media::VideoDecodeAccelerator::Client* client) {
66 DCHECK(!message_loop_->BelongsToCurrentThread()); 84 if (message_loop_->BelongsToCurrentThread()) {
85 AsyncCreateVideoDecodeAccelerator(profile, client);
86 compositor_loop_async_waiter_.Reset();
87 return vda_.release();
88 }
67 // The VDA is returned in the vda_ member variable by the 89 // The VDA is returned in the vda_ member variable by the
68 // AsyncCreateVideoDecodeAccelerator() function. 90 // AsyncCreateVideoDecodeAccelerator() function.
69 message_loop_->PostTask(FROM_HERE, base::Bind( 91 message_loop_->PostTask(FROM_HERE, base::Bind(
70 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, 92 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator,
71 this, profile, client)); 93 this, profile, client));
72 94
73 base::WaitableEvent* objects[] = {&aborted_waiter_, 95 base::WaitableEvent* objects[] = {&aborted_waiter_,
74 &compositor_loop_async_waiter_}; 96 &compositor_loop_async_waiter_};
75 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { 97 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
76 // If we are aborting and the VDA is created by the 98 // If we are aborting and the VDA is created by the
(...skipping 17 matching lines...) Expand all
94 context_->GetCommandBufferProxy()->GetRouteID(), 116 context_->GetCommandBufferProxy()->GetRouteID(),
95 profile, client); 117 profile, client);
96 } 118 }
97 compositor_loop_async_waiter_.Signal(); 119 compositor_loop_async_waiter_.Signal();
98 } 120 }
99 121
100 bool RendererGpuVideoDecoderFactories::CreateTextures( 122 bool RendererGpuVideoDecoderFactories::CreateTextures(
101 int32 count, const gfx::Size& size, 123 int32 count, const gfx::Size& size,
102 std::vector<uint32>* texture_ids, 124 std::vector<uint32>* texture_ids,
103 uint32 texture_target) { 125 uint32 texture_target) {
104 DCHECK(!message_loop_->BelongsToCurrentThread()); 126 if (message_loop_->BelongsToCurrentThread()) {
127 AsyncCreateTextures(count, size, texture_target);
128 texture_ids->swap(created_textures_);
129 compositor_loop_async_waiter_.Reset();
130 return true;
131 }
105 message_loop_->PostTask(FROM_HERE, base::Bind( 132 message_loop_->PostTask(FROM_HERE, base::Bind(
106 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, 133 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
107 count, size, texture_target)); 134 count, size, texture_target));
108 135
109 base::WaitableEvent* objects[] = {&aborted_waiter_, 136 base::WaitableEvent* objects[] = {&aborted_waiter_,
110 &compositor_loop_async_waiter_}; 137 &compositor_loop_async_waiter_};
111 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 138 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
112 return false; 139 return false;
113 texture_ids->swap(created_textures_); 140 texture_ids->swap(created_textures_);
114 return true; 141 return true;
(...skipping 26 matching lines...) Expand all
141 } 168 }
142 // We need a glFlush here to guarantee the decoder (in the GPU process) can 169 // We need a glFlush here to guarantee the decoder (in the GPU process) can
143 // use the texture ids we return here. Since textures are expected to be 170 // use the texture ids we return here. Since textures are expected to be
144 // reused, this should not be unacceptably expensive. 171 // reused, this should not be unacceptably expensive.
145 gles2->Flush(); 172 gles2->Flush();
146 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 173 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
147 compositor_loop_async_waiter_.Signal(); 174 compositor_loop_async_waiter_.Signal();
148 } 175 }
149 176
150 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { 177 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
151 DCHECK(!message_loop_->BelongsToCurrentThread()); 178 if (message_loop_->BelongsToCurrentThread()) {
179 AsyncDeleteTexture(texture_id);
180 return;
181 }
152 message_loop_->PostTask(FROM_HERE, base::Bind( 182 message_loop_->PostTask(FROM_HERE, base::Bind(
153 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); 183 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id));
154 } 184 }
155 185
156 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { 186 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
157 DCHECK(message_loop_->BelongsToCurrentThread()); 187 DCHECK(message_loop_->BelongsToCurrentThread());
158 if (!context_) 188 if (!context_)
159 return; 189 return;
160 190
161 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 191 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 return aborted_waiter_.IsSignaled(); 287 return aborted_waiter_.IsSignaled();
258 } 288 }
259 289
260 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { 290 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
261 // OK to release because Destroy() will delete the VDA instance. 291 // OK to release because Destroy() will delete the VDA instance.
262 if (vda_) 292 if (vda_)
263 vda_.release()->Destroy(); 293 vda_.release()->Destroy();
264 } 294 }
265 295
266 } // namespace content 296 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698