OLD | NEW |
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 12 matching lines...) Expand all Loading... |
23 const scoped_refptr<base::MessageLoopProxy>& compositor_message_loop, | 23 const scoped_refptr<base::MessageLoopProxy>& compositor_message_loop, |
24 WebGraphicsContext3DCommandBufferImpl* context) | 24 WebGraphicsContext3DCommandBufferImpl* context) |
25 : compositor_message_loop_(compositor_message_loop), | 25 : compositor_message_loop_(compositor_message_loop), |
26 main_message_loop_(base::MessageLoopProxy::current()), | 26 main_message_loop_(base::MessageLoopProxy::current()), |
27 gpu_channel_host_(gpu_channel_host), | 27 gpu_channel_host_(gpu_channel_host), |
28 aborted_waiter_(true, false), | 28 aborted_waiter_(true, false), |
29 compositor_loop_async_waiter_(false, false), | 29 compositor_loop_async_waiter_(false, false), |
30 render_thread_async_waiter_(false, false) { | 30 render_thread_async_waiter_(false, false) { |
31 if (compositor_message_loop_->BelongsToCurrentThread()) { | 31 if (compositor_message_loop_->BelongsToCurrentThread()) { |
32 AsyncGetContext(context); | 32 AsyncGetContext(context); |
| 33 compositor_loop_async_waiter_.Reset(); |
33 return; | 34 return; |
34 } | 35 } |
35 // Threaded compositor requires us to wait for the context to be acquired. | 36 // Threaded compositor requires us to wait for the context to be acquired. |
36 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( | 37 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( |
37 &RendererGpuVideoDecoderFactories::AsyncGetContext, | 38 &RendererGpuVideoDecoderFactories::AsyncGetContext, |
38 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a | 39 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a |
39 // scoped_refptr. Safe because the Wait() below keeps us alive until this | 40 // scoped_refptr. Safe because the Wait() below keeps us alive until this |
40 // task completes. | 41 // task completes. |
41 base::Unretained(this), | 42 base::Unretained(this), |
42 // OK to pass raw because the pointee is only deleted on the compositor | 43 // OK to pass raw because the pointee is only deleted on the compositor |
(...skipping 15 matching lines...) Expand all Loading... |
58 } | 59 } |
59 } | 60 } |
60 compositor_loop_async_waiter_.Signal(); | 61 compositor_loop_async_waiter_.Signal(); |
61 } | 62 } |
62 | 63 |
63 media::VideoDecodeAccelerator* | 64 media::VideoDecodeAccelerator* |
64 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( | 65 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( |
65 media::VideoCodecProfile profile, | 66 media::VideoCodecProfile profile, |
66 media::VideoDecodeAccelerator::Client* client) { | 67 media::VideoDecodeAccelerator::Client* client) { |
67 DCHECK(!compositor_message_loop_->BelongsToCurrentThread()); | 68 DCHECK(!compositor_message_loop_->BelongsToCurrentThread()); |
| 69 if (compositor_message_loop_->BelongsToCurrentThread()) { |
| 70 AsyncCreateVideoDecodeAccelerator(profile, client); |
| 71 compositor_loop_async_waiter_.Reset(); |
| 72 return vda_.release(); |
| 73 } |
68 // The VDA is returned in the vda_ member variable by the | 74 // The VDA is returned in the vda_ member variable by the |
69 // AsyncCreateVideoDecodeAccelerator() function. | 75 // AsyncCreateVideoDecodeAccelerator() function. |
70 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( | 76 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( |
71 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, | 77 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, |
72 this, profile, client)); | 78 this, profile, client)); |
73 | 79 |
74 base::WaitableEvent* objects[] = {&aborted_waiter_, | 80 base::WaitableEvent* objects[] = {&aborted_waiter_, |
75 &compositor_loop_async_waiter_}; | 81 &compositor_loop_async_waiter_}; |
76 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { | 82 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { |
77 // If we are aborting and the VDA is created by the | 83 // If we are aborting and the VDA is created by the |
(...skipping 19 matching lines...) Expand all Loading... |
97 compositor_loop_async_waiter_.Signal(); | 103 compositor_loop_async_waiter_.Signal(); |
98 } | 104 } |
99 | 105 |
100 uint32 RendererGpuVideoDecoderFactories::CreateTextures( | 106 uint32 RendererGpuVideoDecoderFactories::CreateTextures( |
101 int32 count, const gfx::Size& size, | 107 int32 count, const gfx::Size& size, |
102 std::vector<uint32>* texture_ids, | 108 std::vector<uint32>* texture_ids, |
103 std::vector<gpu::Mailbox>* texture_mailboxes, | 109 std::vector<gpu::Mailbox>* texture_mailboxes, |
104 uint32 texture_target) { | 110 uint32 texture_target) { |
105 uint32 sync_point = 0; | 111 uint32 sync_point = 0; |
106 | 112 |
107 DCHECK(!compositor_message_loop_->BelongsToCurrentThread()); | 113 if (compositor_message_loop_->BelongsToCurrentThread()) { |
| 114 AsyncCreateTextures(count, size, texture_target, &sync_point); |
| 115 texture_ids->swap(created_textures_); |
| 116 texture_mailboxes->swap(created_texture_mailboxes_); |
| 117 compositor_loop_async_waiter_.Reset(); |
| 118 return sync_point; |
| 119 } |
108 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( | 120 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( |
109 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, | 121 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, |
110 count, size, texture_target, &sync_point)); | 122 count, size, texture_target, &sync_point)); |
111 | 123 |
112 base::WaitableEvent* objects[] = {&aborted_waiter_, | 124 base::WaitableEvent* objects[] = {&aborted_waiter_, |
113 &compositor_loop_async_waiter_}; | 125 &compositor_loop_async_waiter_}; |
114 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) | 126 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) |
115 return 0; | 127 return 0; |
116 texture_ids->swap(created_textures_); | 128 texture_ids->swap(created_textures_); |
117 texture_mailboxes->swap(created_texture_mailboxes_); | 129 texture_mailboxes->swap(created_texture_mailboxes_); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 // use the texture ids we return here. Since textures are expected to be | 165 // use the texture ids we return here. Since textures are expected to be |
154 // reused, this should not be unacceptably expensive. | 166 // reused, this should not be unacceptably expensive. |
155 gles2->Flush(); | 167 gles2->Flush(); |
156 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 168 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
157 | 169 |
158 *sync_point = gles2->InsertSyncPointCHROMIUM(); | 170 *sync_point = gles2->InsertSyncPointCHROMIUM(); |
159 compositor_loop_async_waiter_.Signal(); | 171 compositor_loop_async_waiter_.Signal(); |
160 } | 172 } |
161 | 173 |
162 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { | 174 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { |
163 DCHECK(!compositor_message_loop_->BelongsToCurrentThread()); | 175 if (compositor_message_loop_->BelongsToCurrentThread()) { |
| 176 AsyncDeleteTexture(texture_id); |
| 177 return; |
| 178 } |
164 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( | 179 compositor_message_loop_->PostTask(FROM_HERE, base::Bind( |
165 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); | 180 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); |
166 } | 181 } |
167 | 182 |
168 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { | 183 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { |
169 DCHECK(compositor_message_loop_->BelongsToCurrentThread()); | 184 DCHECK(compositor_message_loop_->BelongsToCurrentThread()); |
170 if (!context_.get()) | 185 if (!context_.get()) |
171 return; | 186 return; |
172 | 187 |
173 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); | 188 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT, | 269 gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT, |
255 GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels()); | 270 GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels()); |
256 gles2->DeleteFramebuffers(1, &fb); | 271 gles2->DeleteFramebuffers(1, &fb); |
257 gles2->DeleteTextures(1, &tmp_texture); | 272 gles2->DeleteTextures(1, &tmp_texture); |
258 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 273 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
259 compositor_loop_async_waiter_.Signal(); | 274 compositor_loop_async_waiter_.Signal(); |
260 } | 275 } |
261 | 276 |
262 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( | 277 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( |
263 size_t size) { | 278 size_t size) { |
264 DCHECK(!main_message_loop_->BelongsToCurrentThread()); | 279 if (main_message_loop_->BelongsToCurrentThread()) { |
| 280 return ChildThread::current()->AllocateSharedMemory(size); |
| 281 } |
265 main_message_loop_->PostTask(FROM_HERE, base::Bind( | 282 main_message_loop_->PostTask(FROM_HERE, base::Bind( |
266 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, | 283 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, |
267 size)); | 284 size)); |
268 | 285 |
269 base::WaitableEvent* objects[] = {&aborted_waiter_, | 286 base::WaitableEvent* objects[] = {&aborted_waiter_, |
270 &render_thread_async_waiter_}; | 287 &render_thread_async_waiter_}; |
271 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) | 288 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) |
272 return NULL; | 289 return NULL; |
273 return shared_memory_segment_.release(); | 290 return shared_memory_segment_.release(); |
274 } | 291 } |
(...skipping 20 matching lines...) Expand all Loading... |
295 return aborted_waiter_.IsSignaled(); | 312 return aborted_waiter_.IsSignaled(); |
296 } | 313 } |
297 | 314 |
298 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { | 315 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { |
299 // OK to release because Destroy() will delete the VDA instance. | 316 // OK to release because Destroy() will delete the VDA instance. |
300 if (vda_) | 317 if (vda_) |
301 vda_.release()->Destroy(); | 318 vda_.release()->Destroy(); |
302 } | 319 } |
303 | 320 |
304 } // namespace content | 321 } // namespace content |
OLD | NEW |