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" |
11 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
12 #include "content/common/child_thread.h" | 12 #include "content/common/child_thread.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 "gpu/command_buffer/client/gles2_implementation.h" | 15 #include "gpu/command_buffer/client/gles2_implementation.h" |
16 #include "gpu/ipc/command_buffer_proxy.h" | 16 #include "gpu/ipc/command_buffer_proxy.h" |
17 | 17 |
18 RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} | 18 RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} |
19 RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( | 19 RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( |
20 GpuChannelHost* gpu_channel_host, MessageLoop* message_loop, | 20 GpuChannelHost* gpu_channel_host, |
| 21 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
21 const base::WeakPtr<WebGraphicsContext3DCommandBufferImpl>& context) | 22 const base::WeakPtr<WebGraphicsContext3DCommandBufferImpl>& context) |
22 : message_loop_(message_loop), | 23 : message_loop_(message_loop), |
23 gpu_channel_host_(gpu_channel_host), | 24 gpu_channel_host_(gpu_channel_host), |
24 context_(context) { | 25 context_(context) { |
25 DCHECK(context_); | 26 DCHECK(context_); |
26 context_->DetachFromThread(); | 27 context_->DetachFromThread(); |
27 if (MessageLoop::current() == message_loop_) { | 28 if (message_loop_->BelongsToCurrentThread()) { |
28 AsyncGetContext(NULL); | 29 AsyncGetContext(NULL); |
29 return; | 30 return; |
30 } | 31 } |
31 // Threaded compositor requires us to wait for the context to be acquired. | 32 // Threaded compositor requires us to wait for the context to be acquired. |
32 base::WaitableEvent waiter(false, false); | 33 base::WaitableEvent waiter(false, false); |
33 message_loop_->PostTask(FROM_HERE, base::Bind( | 34 message_loop_->PostTask(FROM_HERE, base::Bind( |
34 &RendererGpuVideoDecoderFactories::AsyncGetContext, | 35 &RendererGpuVideoDecoderFactories::AsyncGetContext, |
35 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a | 36 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a |
36 // scoped_refptr. Safe because the Wait() below keeps us alive until this | 37 // scoped_refptr. Safe because the Wait() below keeps us alive until this |
37 // task completes. | 38 // task completes. |
38 base::Unretained(this), &waiter)); | 39 base::Unretained(this), &waiter)); |
39 waiter.Wait(); | 40 waiter.Wait(); |
40 } | 41 } |
41 | 42 |
42 void RendererGpuVideoDecoderFactories::AsyncGetContext( | 43 void RendererGpuVideoDecoderFactories::AsyncGetContext( |
43 base::WaitableEvent* waiter) { | 44 base::WaitableEvent* waiter) { |
44 if (context_) | 45 if (context_) |
45 context_->makeContextCurrent(); | 46 context_->makeContextCurrent(); |
46 if (waiter) | 47 if (waiter) |
47 waiter->Signal(); | 48 waiter->Signal(); |
48 } | 49 } |
49 | 50 |
50 media::VideoDecodeAccelerator* | 51 media::VideoDecodeAccelerator* |
51 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( | 52 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( |
52 media::VideoCodecProfile profile, | 53 media::VideoCodecProfile profile, |
53 media::VideoDecodeAccelerator::Client* client) { | 54 media::VideoDecodeAccelerator::Client* client) { |
54 DCHECK_NE(MessageLoop::current(), message_loop_); | 55 DCHECK(!message_loop_->BelongsToCurrentThread()); |
55 media::VideoDecodeAccelerator* vda = NULL; | 56 media::VideoDecodeAccelerator* vda = NULL; |
56 base::WaitableEvent waiter(false, false); | 57 base::WaitableEvent waiter(false, false); |
57 message_loop_->PostTask(FROM_HERE, base::Bind( | 58 message_loop_->PostTask(FROM_HERE, base::Bind( |
58 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, | 59 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, |
59 this, profile, client, &vda, &waiter)); | 60 this, profile, client, &vda, &waiter)); |
60 waiter.Wait(); | 61 waiter.Wait(); |
61 return vda; | 62 return vda; |
62 } | 63 } |
63 | 64 |
64 void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( | 65 void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( |
65 media::VideoCodecProfile profile, | 66 media::VideoCodecProfile profile, |
66 media::VideoDecodeAccelerator::Client* client, | 67 media::VideoDecodeAccelerator::Client* client, |
67 media::VideoDecodeAccelerator** vda, | 68 media::VideoDecodeAccelerator** vda, |
68 base::WaitableEvent* waiter) { | 69 base::WaitableEvent* waiter) { |
69 DCHECK_EQ(MessageLoop::current(), message_loop_); | 70 DCHECK(message_loop_->BelongsToCurrentThread()); |
70 if (context_ && context_->GetCommandBufferProxy()) { | 71 if (context_ && context_->GetCommandBufferProxy()) { |
71 *vda = gpu_channel_host_->CreateVideoDecoder( | 72 *vda = gpu_channel_host_->CreateVideoDecoder( |
72 context_->GetCommandBufferProxy()->GetRouteID(), | 73 context_->GetCommandBufferProxy()->GetRouteID(), |
73 profile, client); | 74 profile, client); |
74 } else { | 75 } else { |
75 *vda = NULL; | 76 *vda = NULL; |
76 } | 77 } |
77 waiter->Signal(); | 78 waiter->Signal(); |
78 } | 79 } |
79 | 80 |
80 bool RendererGpuVideoDecoderFactories::CreateTextures( | 81 bool RendererGpuVideoDecoderFactories::CreateTextures( |
81 int32 count, const gfx::Size& size, | 82 int32 count, const gfx::Size& size, |
82 std::vector<uint32>* texture_ids, | 83 std::vector<uint32>* texture_ids, |
83 uint32 texture_target) { | 84 uint32 texture_target) { |
84 DCHECK_NE(MessageLoop::current(), message_loop_); | 85 DCHECK(!message_loop_->BelongsToCurrentThread()); |
85 bool success = false; | 86 bool success = false; |
86 base::WaitableEvent waiter(false, false); | 87 base::WaitableEvent waiter(false, false); |
87 message_loop_->PostTask(FROM_HERE, base::Bind( | 88 message_loop_->PostTask(FROM_HERE, base::Bind( |
88 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, | 89 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, |
89 count, size, texture_ids, texture_target, &success, &waiter)); | 90 count, size, texture_ids, texture_target, &success, &waiter)); |
90 waiter.Wait(); | 91 waiter.Wait(); |
91 return success; | 92 return success; |
92 } | 93 } |
93 | 94 |
94 void RendererGpuVideoDecoderFactories::AsyncCreateTextures( | 95 void RendererGpuVideoDecoderFactories::AsyncCreateTextures( |
95 int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids, | 96 int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids, |
96 uint32 texture_target, bool* success, base::WaitableEvent* waiter) { | 97 uint32 texture_target, bool* success, base::WaitableEvent* waiter) { |
97 DCHECK_EQ(MessageLoop::current(), message_loop_); | 98 DCHECK(message_loop_->BelongsToCurrentThread()); |
98 DCHECK(texture_target); | 99 DCHECK(texture_target); |
99 if (!context_) { | 100 if (!context_) { |
100 *success = false; | 101 *success = false; |
101 waiter->Signal(); | 102 waiter->Signal(); |
102 return; | 103 return; |
103 } | 104 } |
104 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); | 105 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); |
105 texture_ids->resize(count); | 106 texture_ids->resize(count); |
106 gles2->GenTextures(count, &texture_ids->at(0)); | 107 gles2->GenTextures(count, &texture_ids->at(0)); |
107 for (int i = 0; i < count; ++i) { | 108 for (int i = 0; i < count; ++i) { |
(...skipping 12 matching lines...) Expand all Loading... |
120 // We need a glFlush here to guarantee the decoder (in the GPU process) can | 121 // We need a glFlush here to guarantee the decoder (in the GPU process) can |
121 // use the texture ids we return here. Since textures are expected to be | 122 // use the texture ids we return here. Since textures are expected to be |
122 // reused, this should not be unacceptably expensive. | 123 // reused, this should not be unacceptably expensive. |
123 gles2->Flush(); | 124 gles2->Flush(); |
124 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 125 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
125 *success = true; | 126 *success = true; |
126 waiter->Signal(); | 127 waiter->Signal(); |
127 } | 128 } |
128 | 129 |
129 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { | 130 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { |
130 DCHECK_NE(MessageLoop::current(), message_loop_); | 131 DCHECK(!message_loop_->BelongsToCurrentThread()); |
131 message_loop_->PostTask(FROM_HERE, base::Bind( | 132 message_loop_->PostTask(FROM_HERE, base::Bind( |
132 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); | 133 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); |
133 } | 134 } |
134 | 135 |
135 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { | 136 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { |
136 DCHECK_EQ(MessageLoop::current(), message_loop_); | 137 DCHECK(message_loop_->BelongsToCurrentThread()); |
137 if (!context_) | 138 if (!context_) |
138 return; | 139 return; |
139 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); | 140 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); |
140 gles2->DeleteTextures(1, &texture_id); | 141 gles2->DeleteTextures(1, &texture_id); |
141 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); | 142 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); |
142 } | 143 } |
143 | 144 |
144 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( | 145 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( |
145 size_t size) { | 146 size_t size) { |
146 DCHECK_NE(MessageLoop::current(), ChildThread::current()->message_loop()); | 147 DCHECK_NE(MessageLoop::current(), ChildThread::current()->message_loop()); |
147 base::SharedMemory* shm = NULL; | 148 base::SharedMemory* shm = NULL; |
148 base::WaitableEvent waiter(false, false); | 149 base::WaitableEvent waiter(false, false); |
149 ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind( | 150 ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind( |
150 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, | 151 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, |
151 size, &shm, &waiter)); | 152 size, &shm, &waiter)); |
152 waiter.Wait(); | 153 waiter.Wait(); |
153 return shm; | 154 return shm; |
154 } | 155 } |
155 | 156 |
156 void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory( | 157 void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory( |
157 size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) { | 158 size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) { |
158 DCHECK_EQ(MessageLoop::current(), ChildThread::current()->message_loop()); | 159 DCHECK_EQ(MessageLoop::current(), ChildThread::current()->message_loop()); |
159 *shm = ChildThread::current()->AllocateSharedMemory(size); | 160 *shm = ChildThread::current()->AllocateSharedMemory(size); |
160 waiter->Signal(); | 161 waiter->Signal(); |
161 } | 162 } |
OLD | NEW |