OLD | NEW |
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/SkPixelRef.h" | 17 #include "third_party/skia/include/core/SkPixelRef.h" |
18 | 18 |
19 namespace content { | 19 namespace content { |
20 | 20 |
21 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {} | 21 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {} |
22 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( | 22 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( |
23 GpuChannelHost* gpu_channel_host, | 23 GpuChannelHost* gpu_channel_host, |
24 const scoped_refptr<ContextProviderCommandBuffer>& context_provider) | 24 const scoped_refptr<ContextProviderCommandBuffer>& context_provider) |
25 : message_loop_( | 25 : task_runner_( |
26 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), | 26 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), |
27 gpu_channel_host_(gpu_channel_host), | 27 gpu_channel_host_(gpu_channel_host), |
28 context_provider_(context_provider), | 28 context_provider_(context_provider), |
29 thread_safe_sender_(ChildThread::current()->thread_safe_sender()), | 29 thread_safe_sender_(ChildThread::current()->thread_safe_sender()), |
30 aborted_waiter_(true, false), | 30 aborted_waiter_(true, false), |
31 message_loop_async_waiter_(false, false) { | 31 task_runner_async_waiter_(false, false) { |
32 // |context_provider_| is only required to support HW-accelerated decode. | 32 // |context_provider_| is only required to support HW-accelerated decode. |
33 if (!context_provider_) | 33 if (!context_provider_) |
34 return; | 34 return; |
35 | 35 |
36 if (message_loop_->BelongsToCurrentThread()) { | 36 if (task_runner_->BelongsToCurrentThread()) { |
37 AsyncBindContext(); | 37 AsyncBindContext(); |
38 message_loop_async_waiter_.Reset(); | 38 task_runner_async_waiter_.Reset(); |
39 return; | 39 return; |
40 } | 40 } |
41 // Wait for the context to be acquired. | 41 // Wait for the context to be acquired. |
42 message_loop_->PostTask( | 42 task_runner_->PostTask( |
43 FROM_HERE, | 43 FROM_HERE, |
44 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncBindContext, | 44 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncBindContext, |
45 // Unretained to avoid ref/deref'ing |*this|, which is not yet | 45 // Unretained to avoid ref/deref'ing |*this|, which is not yet |
46 // stored in a scoped_refptr. Safe because the Wait() below | 46 // stored in a scoped_refptr. Safe because the Wait() below |
47 // keeps us alive until this task completes. | 47 // keeps us alive until this task completes. |
48 base::Unretained(this))); | 48 base::Unretained(this))); |
49 message_loop_async_waiter_.Wait(); | 49 task_runner_async_waiter_.Wait(); |
50 } | 50 } |
51 | 51 |
52 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories() | 52 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories() |
53 : aborted_waiter_(true, false), | 53 : aborted_waiter_(true, false), |
54 message_loop_async_waiter_(false, false) {} | 54 task_runner_async_waiter_(false, false) {} |
55 | 55 |
56 WebGraphicsContext3DCommandBufferImpl* | 56 WebGraphicsContext3DCommandBufferImpl* |
57 RendererGpuVideoAcceleratorFactories::GetContext3d() { | 57 RendererGpuVideoAcceleratorFactories::GetContext3d() { |
58 DCHECK(message_loop_->BelongsToCurrentThread()); | 58 DCHECK(task_runner_->BelongsToCurrentThread()); |
59 if (!context_provider_) | 59 if (!context_provider_) |
60 return NULL; | 60 return NULL; |
61 WebGraphicsContext3DCommandBufferImpl* context = | 61 WebGraphicsContext3DCommandBufferImpl* context = |
62 context_provider_->Context3d(); | 62 context_provider_->Context3d(); |
63 if (context->isContextLost()) { | 63 if (context->isContextLost()) { |
64 context_provider_->VerifyContexts(); | 64 context_provider_->VerifyContexts(); |
65 context_provider_ = NULL; | 65 context_provider_ = NULL; |
66 return NULL; | 66 return NULL; |
67 } | 67 } |
68 return context; | 68 return context; |
69 } | 69 } |
70 | 70 |
71 void RendererGpuVideoAcceleratorFactories::AsyncBindContext() { | 71 void RendererGpuVideoAcceleratorFactories::AsyncBindContext() { |
72 DCHECK(message_loop_->BelongsToCurrentThread()); | 72 DCHECK(task_runner_->BelongsToCurrentThread()); |
73 if (!context_provider_->BindToCurrentThread()) | 73 if (!context_provider_->BindToCurrentThread()) |
74 context_provider_ = NULL; | 74 context_provider_ = NULL; |
75 message_loop_async_waiter_.Signal(); | 75 task_runner_async_waiter_.Signal(); |
76 } | 76 } |
77 | 77 |
78 scoped_ptr<media::VideoDecodeAccelerator> | 78 scoped_ptr<media::VideoDecodeAccelerator> |
79 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( | 79 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( |
80 media::VideoCodecProfile profile, | 80 media::VideoCodecProfile profile, |
81 media::VideoDecodeAccelerator::Client* client) { | 81 media::VideoDecodeAccelerator::Client* client) { |
82 if (message_loop_->BelongsToCurrentThread()) { | 82 if (task_runner_->BelongsToCurrentThread()) { |
83 AsyncCreateVideoDecodeAccelerator(profile, client); | 83 AsyncCreateVideoDecodeAccelerator(profile, client); |
84 message_loop_async_waiter_.Reset(); | 84 task_runner_async_waiter_.Reset(); |
85 return vda_.Pass(); | 85 return vda_.Pass(); |
86 } | 86 } |
87 // The VDA is returned in the vda_ member variable by the | 87 // The VDA is returned in the vda_ member variable by the |
88 // AsyncCreateVideoDecodeAccelerator() function. | 88 // AsyncCreateVideoDecodeAccelerator() function. |
89 message_loop_->PostTask(FROM_HERE, | 89 task_runner_->PostTask(FROM_HERE, |
90 base::Bind(&RendererGpuVideoAcceleratorFactories:: | 90 base::Bind(&RendererGpuVideoAcceleratorFactories:: |
91 AsyncCreateVideoDecodeAccelerator, | 91 AsyncCreateVideoDecodeAccelerator, |
92 this, | 92 this, |
93 profile, | 93 profile, |
94 client)); | 94 client)); |
95 | 95 |
96 base::WaitableEvent* objects[] = {&aborted_waiter_, | 96 base::WaitableEvent* objects[] = {&aborted_waiter_, |
97 &message_loop_async_waiter_}; | 97 &task_runner_async_waiter_}; |
98 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { | 98 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { |
99 // If we are aborting and the VDA is created by the | 99 // If we are aborting and the VDA is created by the |
100 // AsyncCreateVideoDecodeAccelerator() function later we need to ensure | 100 // AsyncCreateVideoDecodeAccelerator() function later we need to ensure |
101 // that it is destroyed on the same thread. | 101 // that it is destroyed on the same thread. |
102 message_loop_->PostTask(FROM_HERE, | 102 task_runner_->PostTask(FROM_HERE, |
103 base::Bind(&RendererGpuVideoAcceleratorFactories:: | 103 base::Bind(&RendererGpuVideoAcceleratorFactories:: |
104 AsyncDestroyVideoDecodeAccelerator, | 104 AsyncDestroyVideoDecodeAccelerator, |
105 this)); | 105 this)); |
106 return scoped_ptr<media::VideoDecodeAccelerator>(); | 106 return scoped_ptr<media::VideoDecodeAccelerator>(); |
107 } | 107 } |
108 return vda_.Pass(); | 108 return vda_.Pass(); |
109 } | 109 } |
110 | 110 |
111 scoped_ptr<media::VideoEncodeAccelerator> | 111 scoped_ptr<media::VideoEncodeAccelerator> |
112 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator( | 112 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator( |
113 media::VideoEncodeAccelerator::Client* client) { | 113 media::VideoEncodeAccelerator::Client* client) { |
114 DCHECK(message_loop_->BelongsToCurrentThread()); | 114 DCHECK(task_runner_->BelongsToCurrentThread()); |
115 | 115 |
116 return gpu_channel_host_->CreateVideoEncoder(client); | 116 return gpu_channel_host_->CreateVideoEncoder(client); |
117 } | 117 } |
118 | 118 |
119 void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator( | 119 void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator( |
120 media::VideoCodecProfile profile, | 120 media::VideoCodecProfile profile, |
121 media::VideoDecodeAccelerator::Client* client) { | 121 media::VideoDecodeAccelerator::Client* client) { |
122 DCHECK(message_loop_->BelongsToCurrentThread()); | 122 DCHECK(task_runner_->BelongsToCurrentThread()); |
123 | 123 |
124 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); | 124 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); |
125 if (context && context->GetCommandBufferProxy()) { | 125 if (context && context->GetCommandBufferProxy()) { |
126 vda_ = gpu_channel_host_->CreateVideoDecoder( | 126 vda_ = gpu_channel_host_->CreateVideoDecoder( |
127 context->GetCommandBufferProxy()->GetRouteID(), profile, client); | 127 context->GetCommandBufferProxy()->GetRouteID(), profile, client); |
128 } | 128 } |
129 message_loop_async_waiter_.Signal(); | 129 task_runner_async_waiter_.Signal(); |
130 } | 130 } |
131 | 131 |
132 uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( | 132 uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( |
133 int32 count, | 133 int32 count, |
134 const gfx::Size& size, | 134 const gfx::Size& size, |
135 std::vector<uint32>* texture_ids, | 135 std::vector<uint32>* texture_ids, |
136 std::vector<gpu::Mailbox>* texture_mailboxes, | 136 std::vector<gpu::Mailbox>* texture_mailboxes, |
137 uint32 texture_target) { | 137 uint32 texture_target) { |
138 DCHECK(message_loop_->BelongsToCurrentThread()); | 138 DCHECK(task_runner_->BelongsToCurrentThread()); |
139 DCHECK(texture_target); | 139 DCHECK(texture_target); |
140 | 140 |
141 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); | 141 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); |
142 if (!context) | 142 if (!context) |
143 return 0; | 143 return 0; |
144 | 144 |
145 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); | 145 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); |
146 texture_ids->resize(count); | 146 texture_ids->resize(count); |
147 texture_mailboxes->resize(count); | 147 texture_mailboxes->resize(count); |
148 gles2->GenTextures(count, &texture_ids->at(0)); | 148 gles2->GenTextures(count, &texture_ids->at(0)); |
(...skipping 24 matching lines...) Expand all Loading... |
173 // We need a glFlush here to guarantee the decoder (in the GPU process) can | 173 // We need a glFlush here to guarantee the decoder (in the GPU process) can |
174 // use the texture ids we return here. Since textures are expected to be | 174 // use the texture ids we return here. Since textures are expected to be |
175 // reused, this should not be unacceptably expensive. | 175 // reused, this should not be unacceptably expensive. |
176 gles2->Flush(); | 176 gles2->Flush(); |
177 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 177 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
178 | 178 |
179 return gles2->InsertSyncPointCHROMIUM(); | 179 return gles2->InsertSyncPointCHROMIUM(); |
180 } | 180 } |
181 | 181 |
182 void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) { | 182 void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) { |
183 DCHECK(message_loop_->BelongsToCurrentThread()); | 183 DCHECK(task_runner_->BelongsToCurrentThread()); |
184 | 184 |
185 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); | 185 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); |
186 if (!context) | 186 if (!context) |
187 return; | 187 return; |
188 | 188 |
189 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); | 189 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); |
190 gles2->DeleteTextures(1, &texture_id); | 190 gles2->DeleteTextures(1, &texture_id); |
191 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 191 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
192 } | 192 } |
193 | 193 |
194 void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) { | 194 void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) { |
195 DCHECK(message_loop_->BelongsToCurrentThread()); | 195 DCHECK(task_runner_->BelongsToCurrentThread()); |
196 | 196 |
197 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); | 197 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); |
198 if (!context) | 198 if (!context) |
199 return; | 199 return; |
200 | 200 |
201 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); | 201 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); |
202 gles2->WaitSyncPointCHROMIUM(sync_point); | 202 gles2->WaitSyncPointCHROMIUM(sync_point); |
203 | 203 |
204 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to | 204 // Callers expect the WaitSyncPoint to affect the next IPCs. Make sure to |
205 // flush the command buffers to ensure that. | 205 // flush the command buffers to ensure that. |
206 gles2->ShallowFlushCHROMIUM(); | 206 gles2->ShallowFlushCHROMIUM(); |
207 } | 207 } |
208 | 208 |
209 void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, | 209 void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, |
210 const gfx::Size& size, | 210 const gfx::Size& size, |
211 const SkBitmap& pixels) { | 211 const SkBitmap& pixels) { |
212 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. | 212 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. |
213 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to | 213 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to |
214 // ensure that the underlying pixels in the SkBitmap passed in remain valid | 214 // ensure that the underlying pixels in the SkBitmap passed in remain valid |
215 // until the AsyncReadPixels() call completes. | 215 // until the AsyncReadPixels() call completes. |
216 read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); | 216 read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); |
217 | 217 |
218 if (!message_loop_->BelongsToCurrentThread()) { | 218 if (!task_runner_->BelongsToCurrentThread()) { |
219 message_loop_->PostTask( | 219 task_runner_->PostTask( |
220 FROM_HERE, | 220 FROM_HERE, |
221 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels, | 221 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels, |
222 this, | 222 this, |
223 texture_id, | 223 texture_id, |
224 size)); | 224 size)); |
225 base::WaitableEvent* objects[] = {&aborted_waiter_, | 225 base::WaitableEvent* objects[] = {&aborted_waiter_, |
226 &message_loop_async_waiter_}; | 226 &task_runner_async_waiter_}; |
227 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) | 227 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) |
228 return; | 228 return; |
229 } else { | 229 } else { |
230 AsyncReadPixels(texture_id, size); | 230 AsyncReadPixels(texture_id, size); |
231 message_loop_async_waiter_.Reset(); | 231 task_runner_async_waiter_.Reset(); |
232 } | 232 } |
233 read_pixels_bitmap_.setPixelRef(NULL); | 233 read_pixels_bitmap_.setPixelRef(NULL); |
234 } | 234 } |
235 | 235 |
236 void RendererGpuVideoAcceleratorFactories::AsyncReadPixels( | 236 void RendererGpuVideoAcceleratorFactories::AsyncReadPixels( |
237 uint32 texture_id, | 237 uint32 texture_id, |
238 const gfx::Size& size) { | 238 const gfx::Size& size) { |
239 DCHECK(message_loop_->BelongsToCurrentThread()); | 239 DCHECK(task_runner_->BelongsToCurrentThread()); |
240 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); | 240 WebGraphicsContext3DCommandBufferImpl* context = GetContext3d(); |
241 if (!context) { | 241 if (!context) { |
242 message_loop_async_waiter_.Signal(); | 242 task_runner_async_waiter_.Signal(); |
243 return; | 243 return; |
244 } | 244 } |
245 | 245 |
246 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); | 246 gpu::gles2::GLES2Implementation* gles2 = context->GetImplementation(); |
247 | 247 |
248 GLuint tmp_texture; | 248 GLuint tmp_texture; |
249 gles2->GenTextures(1, &tmp_texture); | 249 gles2->GenTextures(1, &tmp_texture); |
250 gles2->BindTexture(GL_TEXTURE_2D, tmp_texture); | 250 gles2->BindTexture(GL_TEXTURE_2D, tmp_texture); |
251 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 251 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
252 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 252 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
(...skipping 20 matching lines...) Expand all Loading... |
273 gles2->ReadPixels(0, | 273 gles2->ReadPixels(0, |
274 0, | 274 0, |
275 size.width(), | 275 size.width(), |
276 size.height(), | 276 size.height(), |
277 skia_format, | 277 skia_format, |
278 GL_UNSIGNED_BYTE, | 278 GL_UNSIGNED_BYTE, |
279 read_pixels_bitmap_.pixelRef()->pixels()); | 279 read_pixels_bitmap_.pixelRef()->pixels()); |
280 gles2->DeleteFramebuffers(1, &fb); | 280 gles2->DeleteFramebuffers(1, &fb); |
281 gles2->DeleteTextures(1, &tmp_texture); | 281 gles2->DeleteTextures(1, &tmp_texture); |
282 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 282 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
283 message_loop_async_waiter_.Signal(); | 283 task_runner_async_waiter_.Signal(); |
284 } | 284 } |
285 | 285 |
286 base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( | 286 base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( |
287 size_t size) { | 287 size_t size) { |
288 DCHECK(message_loop_->BelongsToCurrentThread()); | 288 DCHECK(task_runner_->BelongsToCurrentThread()); |
289 return ChildThread::AllocateSharedMemory(size, thread_safe_sender_.get()); | 289 return ChildThread::AllocateSharedMemory(size, thread_safe_sender_.get()); |
290 } | 290 } |
291 | 291 |
292 scoped_refptr<base::MessageLoopProxy> | 292 scoped_refptr<base::SingleThreadTaskRunner> |
293 RendererGpuVideoAcceleratorFactories::GetMessageLoop() { | 293 RendererGpuVideoAcceleratorFactories::GetTaskRunner() { |
294 return message_loop_; | 294 return task_runner_; |
295 } | 295 } |
296 | 296 |
297 void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); } | 297 void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); } |
298 | 298 |
299 bool RendererGpuVideoAcceleratorFactories::IsAborted() { | 299 bool RendererGpuVideoAcceleratorFactories::IsAborted() { |
300 return aborted_waiter_.IsSignaled(); | 300 return aborted_waiter_.IsSignaled(); |
301 } | 301 } |
302 | 302 |
303 scoped_refptr<RendererGpuVideoAcceleratorFactories> | 303 scoped_refptr<RendererGpuVideoAcceleratorFactories> |
304 RendererGpuVideoAcceleratorFactories::Clone() { | 304 RendererGpuVideoAcceleratorFactories::Clone() { |
305 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories = | 305 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories = |
306 new RendererGpuVideoAcceleratorFactories(); | 306 new RendererGpuVideoAcceleratorFactories(); |
307 factories->message_loop_ = message_loop_; | 307 factories->task_runner_ = task_runner_; |
308 factories->gpu_channel_host_ = gpu_channel_host_; | 308 factories->gpu_channel_host_ = gpu_channel_host_; |
309 factories->context_provider_ = context_provider_; | 309 factories->context_provider_ = context_provider_; |
310 factories->thread_safe_sender_ = thread_safe_sender_; | 310 factories->thread_safe_sender_ = thread_safe_sender_; |
311 return factories; | 311 return factories; |
312 } | 312 } |
313 | 313 |
314 void | 314 void |
315 RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() { | 315 RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() { |
316 // OK to release because Destroy() will delete the VDA instance. | 316 // OK to release because Destroy() will delete the VDA instance. |
317 if (vda_) | 317 if (vda_) |
318 vda_.release()->Destroy(); | 318 vda_.release()->Destroy(); |
319 } | 319 } |
320 | 320 |
321 } // namespace content | 321 } // namespace content |
OLD | NEW |