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

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

Issue 20632002: Add media::VideoEncodeAccelerator with WebRTC integration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: 7fd9dbd5 More debugging statements, some fixes Created 7 years, 4 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_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/gpu_channel_host.h" 12 #include "content/common/gpu/client/gpu_channel_host.h"
13 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 13 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
14 #include "gpu/command_buffer/client/gles2_implementation.h" 14 #include "gpu/command_buffer/client/gles2_implementation.h"
15 #include "gpu/ipc/command_buffer_proxy.h" 15 #include "gpu/ipc/command_buffer_proxy.h"
16 #include "third_party/skia/include/core/SkPixelRef.h" 16 #include "third_party/skia/include/core/SkPixelRef.h"
17 17
18 namespace content { 18 namespace content {
19 19
20 RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} 20 RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
21 RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( 21 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
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 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 message_loop_async_waiter_(false, false), 29 message_loop_async_waiter_(false, false),
30 render_thread_async_waiter_(false, false) { 30 render_thread_async_waiter_(false, false) {
31 if (message_loop_->BelongsToCurrentThread()) { 31 if (context) {
Ami GONE FROM CHROMIUM 2013/07/31 23:01:12 how can this fail? if it's necessary, please rever
sheu 2013/08/02 01:27:49 If we disable HW-accelerated decode, we won't get
32 AsyncGetContext(context); 32 if (message_loop_->BelongsToCurrentThread()) {
33 message_loop_async_waiter_.Reset(); 33 AsyncGetContext(context);
34 return; 34 message_loop_async_waiter_.Reset();
35 return;
36 }
37 // Wait for the context to be acquired.
38 message_loop_->PostTask(
39 FROM_HERE,
40 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncGetContext,
41 // Unretained to avoid ref/deref'ing |*this|, which is not
42 // yet stored in a scoped_refptr. Safe because the Wait()
43 // below keeps us alive until this task completes.
44 base::Unretained(this),
45 // OK to pass raw because the pointee is only deleted on the
46 // compositor thread, and only as the result of a PostTask
47 // from the render thread which can only happen after this
48 // function returns, so our PostTask will run first.
49 context));
50 message_loop_async_waiter_.Wait();
35 } 51 }
36 // Wait for the context to be acquired.
37 message_loop_->PostTask(FROM_HERE, base::Bind(
38 &RendererGpuVideoDecoderFactories::AsyncGetContext,
39 // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a
40 // scoped_refptr. Safe because the Wait() below keeps us alive until this
41 // task completes.
42 base::Unretained(this),
43 // OK to pass raw because the pointee is only deleted on the compositor
44 // thread, and only as the result of a PostTask from the render thread
45 // which can only happen after this function returns, so our PostTask will
46 // run first.
47 context));
48 message_loop_async_waiter_.Wait();
49 } 52 }
50 53
51 RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories() 54 RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories()
52 : aborted_waiter_(true, false), 55 : aborted_waiter_(true, false),
53 message_loop_async_waiter_(false, false), 56 message_loop_async_waiter_(false, false),
54 render_thread_async_waiter_(false, false) {} 57 render_thread_async_waiter_(false, false) {}
55 58
56 void RendererGpuVideoDecoderFactories::AsyncGetContext( 59 void RendererGpuVideoAcceleratorFactories::AsyncGetContext(
57 WebGraphicsContext3DCommandBufferImpl* context) { 60 WebGraphicsContext3DCommandBufferImpl* context) {
58 context_ = context->AsWeakPtr(); 61 context_ = context->AsWeakPtr();
59 if (context_.get()) { 62 if (context_.get()) {
60 if (context_->makeContextCurrent()) { 63 if (context_->makeContextCurrent()) {
61 // Called once per media player, but is a no-op after the first one in 64 // Called once per media player, but is a no-op after the first one in
62 // each renderer. 65 // each renderer.
63 context_->insertEventMarkerEXT("GpuVDAContext3D"); 66 context_->insertEventMarkerEXT("GpuVDAContext3D");
64 } 67 }
65 } 68 }
66 message_loop_async_waiter_.Signal(); 69 message_loop_async_waiter_.Signal();
67 } 70 }
68 71
69 media::VideoDecodeAccelerator* 72 scoped_ptr<media::VideoDecodeAccelerator>
70 RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( 73 RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator(
71 media::VideoCodecProfile profile, 74 media::VideoCodecProfile profile,
72 media::VideoDecodeAccelerator::Client* client) { 75 media::VideoDecodeAccelerator::Client* client) {
73 if (message_loop_->BelongsToCurrentThread()) { 76 if (message_loop_->BelongsToCurrentThread()) {
74 AsyncCreateVideoDecodeAccelerator(profile, client); 77 AsyncCreateVideoDecodeAccelerator(profile, client);
75 message_loop_async_waiter_.Reset(); 78 message_loop_async_waiter_.Reset();
76 return vda_.release(); 79 return vda_.Pass();
77 } 80 }
78 // The VDA is returned in the vda_ member variable by the 81 // The VDA is returned in the vda_ member variable by the
79 // AsyncCreateVideoDecodeAccelerator() function. 82 // AsyncCreateVideoDecodeAccelerator() function.
80 message_loop_->PostTask(FROM_HERE, base::Bind( 83 message_loop_->PostTask(FROM_HERE,
81 &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, 84 base::Bind(&RendererGpuVideoAcceleratorFactories::
82 this, profile, client)); 85 AsyncCreateVideoDecodeAccelerator,
Ami GONE FROM CHROMIUM 2013/07/31 23:01:12 Ugh, is this what clang-format makes?? If yes, IM
sheu 2013/08/02 01:27:49 It's just because the scoped function name is so l
Ami GONE FROM CHROMIUM 2013/08/02 18:42:40 I disagree, possibly because I believe the clang-f
86 this,
87 profile,
88 client));
83 89
84 base::WaitableEvent* objects[] = {&aborted_waiter_, 90 base::WaitableEvent* objects[] = {&aborted_waiter_,
85 &message_loop_async_waiter_}; 91 &message_loop_async_waiter_};
86 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { 92 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
87 // If we are aborting and the VDA is created by the 93 // If we are aborting and the VDA is created by the
88 // AsyncCreateVideoDecodeAccelerator() function later we need to ensure 94 // AsyncCreateVideoDecodeAccelerator() function later we need to ensure
89 // that it is destroyed on the same thread. 95 // that it is destroyed on the same thread.
90 message_loop_->PostTask(FROM_HERE, base::Bind( 96 message_loop_->PostTask(FROM_HERE,
91 &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator, 97 base::Bind(&RendererGpuVideoAcceleratorFactories::
92 this)); 98 AsyncDestroyVideoDecodeAccelerator,
93 return NULL; 99 this));
100 return scoped_ptr<media::VideoDecodeAccelerator>();
94 } 101 }
95 return vda_.release(); 102 return vda_.Pass();
96 } 103 }
97 104
98 void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( 105 scoped_ptr<media::VideoEncodeAccelerator>
99 media::VideoCodecProfile profile, 106 RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator(
100 media::VideoDecodeAccelerator::Client* client) { 107 media::VideoEncodeAccelerator::Client* client) {
108 if (message_loop_->BelongsToCurrentThread()) {
109 AsyncCreateVideoEncodeAccelerator(client);
110 message_loop_async_waiter_.Reset();
111 return vea_.Pass();
112 }
113 // The VEA is returned in the vea_ member variable by the
114 // AsyncCreateVideoEncodeAccelerator() function.
115 message_loop_->PostTask(FROM_HERE,
116 base::Bind(&RendererGpuVideoAcceleratorFactories::
117 AsyncCreateVideoEncodeAccelerator,
118 this,
119 client));
120
121 base::WaitableEvent* objects[] = {&aborted_waiter_,
122 &message_loop_async_waiter_};
123 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
124 // If we are aborting and the VDA is created by the
125 // AsyncCreateVideoEncodeAccelerator() function later we need to ensure
126 // that it is destroyed on the same thread.
127 message_loop_->PostTask(FROM_HERE,
128 base::Bind(&RendererGpuVideoAcceleratorFactories::
129 AsyncDestroyVideoEncodeAccelerator,
130 this));
131 return scoped_ptr<media::VideoEncodeAccelerator>();
132 }
133 return vea_.Pass();
134 }
135
136 void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator(
137 media::VideoCodecProfile profile,
138 media::VideoDecodeAccelerator::Client* client) {
101 DCHECK(message_loop_->BelongsToCurrentThread()); 139 DCHECK(message_loop_->BelongsToCurrentThread());
102 140
103 if (context_.get() && context_->GetCommandBufferProxy()) { 141 if (context_.get() && context_->GetCommandBufferProxy()) {
104 vda_ = gpu_channel_host_->CreateVideoDecoder( 142 vda_ = gpu_channel_host_->CreateVideoDecoder(
105 context_->GetCommandBufferProxy()->GetRouteID(), profile, client); 143 context_->GetCommandBufferProxy()->GetRouteID(), profile, client);
106 } 144 }
107 message_loop_async_waiter_.Signal(); 145 message_loop_async_waiter_.Signal();
108 } 146 }
109 147
110 uint32 RendererGpuVideoDecoderFactories::CreateTextures( 148 void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoEncodeAccelerator(
111 int32 count, const gfx::Size& size, 149 media::VideoEncodeAccelerator::Client* client) {
150 DCHECK(message_loop_->BelongsToCurrentThread());
151
152 vea_ = gpu_channel_host_->CreateVideoEncoder(client).Pass();
153 message_loop_async_waiter_.Signal();
154 }
155
156 uint32 RendererGpuVideoAcceleratorFactories::CreateTextures(
157 int32 count,
158 const gfx::Size& size,
112 std::vector<uint32>* texture_ids, 159 std::vector<uint32>* texture_ids,
113 std::vector<gpu::Mailbox>* texture_mailboxes, 160 std::vector<gpu::Mailbox>* texture_mailboxes,
114 uint32 texture_target) { 161 uint32 texture_target) {
115 uint32 sync_point = 0; 162 uint32 sync_point = 0;
116 163
117 if (message_loop_->BelongsToCurrentThread()) { 164 if (message_loop_->BelongsToCurrentThread()) {
118 AsyncCreateTextures(count, size, texture_target, &sync_point); 165 AsyncCreateTextures(count, size, texture_target, &sync_point);
119 texture_ids->swap(created_textures_); 166 texture_ids->swap(created_textures_);
120 texture_mailboxes->swap(created_texture_mailboxes_); 167 texture_mailboxes->swap(created_texture_mailboxes_);
121 message_loop_async_waiter_.Reset(); 168 message_loop_async_waiter_.Reset();
122 return sync_point; 169 return sync_point;
123 } 170 }
124 message_loop_->PostTask(FROM_HERE, base::Bind( 171 message_loop_->PostTask(
125 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, 172 FROM_HERE,
126 count, size, texture_target, &sync_point)); 173 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateTextures,
174 this,
175 count,
176 size,
177 texture_target,
178 &sync_point));
127 179
128 base::WaitableEvent* objects[] = {&aborted_waiter_, 180 base::WaitableEvent* objects[] = {&aborted_waiter_,
129 &message_loop_async_waiter_}; 181 &message_loop_async_waiter_};
130 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 182 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
131 return 0; 183 return 0;
132 texture_ids->swap(created_textures_); 184 texture_ids->swap(created_textures_);
133 texture_mailboxes->swap(created_texture_mailboxes_); 185 texture_mailboxes->swap(created_texture_mailboxes_);
134 return sync_point; 186 return sync_point;
135 } 187 }
136 188
137 void RendererGpuVideoDecoderFactories::AsyncCreateTextures( 189 void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures(
138 int32 count, const gfx::Size& size, uint32 texture_target, 190 int32 count,
191 const gfx::Size& size,
192 uint32 texture_target,
139 uint32* sync_point) { 193 uint32* sync_point) {
140 DCHECK(message_loop_->BelongsToCurrentThread()); 194 DCHECK(message_loop_->BelongsToCurrentThread());
141 DCHECK(texture_target); 195 DCHECK(texture_target);
142 196
143 if (!context_.get()) { 197 if (!context_.get()) {
144 message_loop_async_waiter_.Signal(); 198 message_loop_async_waiter_.Signal();
145 return; 199 return;
146 } 200 }
147 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 201 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
148 created_textures_.resize(count); 202 created_textures_.resize(count);
149 created_texture_mailboxes_.resize(count); 203 created_texture_mailboxes_.resize(count);
150 gles2->GenTextures(count, &created_textures_[0]); 204 gles2->GenTextures(count, &created_textures_[0]);
151 for (int i = 0; i < count; ++i) { 205 for (int i = 0; i < count; ++i) {
152 gles2->ActiveTexture(GL_TEXTURE0); 206 gles2->ActiveTexture(GL_TEXTURE0);
153 uint32 texture_id = created_textures_[i]; 207 uint32 texture_id = created_textures_[i];
154 gles2->BindTexture(texture_target, texture_id); 208 gles2->BindTexture(texture_target, texture_id);
155 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 209 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
156 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 210 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
157 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 211 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
158 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 212 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
159 if (texture_target == GL_TEXTURE_2D) { 213 if (texture_target == GL_TEXTURE_2D) {
160 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), 214 gles2->TexImage2D(texture_target,
161 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 215 0,
216 GL_RGBA,
217 size.width(),
218 size.height(),
219 0,
220 GL_RGBA,
221 GL_UNSIGNED_BYTE,
222 NULL);
162 } 223 }
163 gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name); 224 gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name);
164 gles2->ProduceTextureCHROMIUM(texture_target, 225 gles2->ProduceTextureCHROMIUM(texture_target,
165 created_texture_mailboxes_[i].name); 226 created_texture_mailboxes_[i].name);
166 } 227 }
167 228
168 // We need a glFlush here to guarantee the decoder (in the GPU process) can 229 // We need a glFlush here to guarantee the decoder (in the GPU process) can
169 // use the texture ids we return here. Since textures are expected to be 230 // use the texture ids we return here. Since textures are expected to be
170 // reused, this should not be unacceptably expensive. 231 // reused, this should not be unacceptably expensive.
171 gles2->Flush(); 232 gles2->Flush();
172 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 233 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
173 234
174 *sync_point = gles2->InsertSyncPointCHROMIUM(); 235 *sync_point = gles2->InsertSyncPointCHROMIUM();
175 message_loop_async_waiter_.Signal(); 236 message_loop_async_waiter_.Signal();
176 } 237 }
177 238
178 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { 239 void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) {
179 if (message_loop_->BelongsToCurrentThread()) { 240 if (message_loop_->BelongsToCurrentThread()) {
180 AsyncDeleteTexture(texture_id); 241 AsyncDeleteTexture(texture_id);
181 return; 242 return;
182 } 243 }
183 message_loop_->PostTask(FROM_HERE, base::Bind( 244 message_loop_->PostTask(
184 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); 245 FROM_HERE,
246 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture,
247 this,
248 texture_id));
185 } 249 }
186 250
187 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { 251 void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture(
252 uint32 texture_id) {
188 DCHECK(message_loop_->BelongsToCurrentThread()); 253 DCHECK(message_loop_->BelongsToCurrentThread());
189 if (!context_.get()) 254 if (!context_.get())
190 return; 255 return;
191 256
192 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 257 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
193 gles2->DeleteTextures(1, &texture_id); 258 gles2->DeleteTextures(1, &texture_id);
194 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 259 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
195 } 260 }
196 261
197 void RendererGpuVideoDecoderFactories::WaitSyncPoint(uint32 sync_point) { 262 void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) {
198 if (message_loop_->BelongsToCurrentThread()) { 263 if (message_loop_->BelongsToCurrentThread()) {
199 AsyncWaitSyncPoint(sync_point); 264 AsyncWaitSyncPoint(sync_point);
200 message_loop_async_waiter_.Reset(); 265 message_loop_async_waiter_.Reset();
201 return; 266 return;
202 } 267 }
203 268
204 message_loop_->PostTask(FROM_HERE, base::Bind( 269 message_loop_->PostTask(
205 &RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint, 270 FROM_HERE,
206 this, 271 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint,
207 sync_point)); 272 this,
273 sync_point));
208 base::WaitableEvent* objects[] = {&aborted_waiter_, 274 base::WaitableEvent* objects[] = {&aborted_waiter_,
209 &message_loop_async_waiter_}; 275 &message_loop_async_waiter_};
210 base::WaitableEvent::WaitMany(objects, arraysize(objects)); 276 base::WaitableEvent::WaitMany(objects, arraysize(objects));
211 } 277 }
212 278
213 void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) { 279 void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint(
280 uint32 sync_point) {
214 DCHECK(message_loop_->BelongsToCurrentThread()); 281 DCHECK(message_loop_->BelongsToCurrentThread());
215 if (!context_) { 282 if (!context_) {
216 message_loop_async_waiter_.Signal(); 283 message_loop_async_waiter_.Signal();
217 return; 284 return;
218 } 285 }
219 286
220 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 287 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
221 gles2->WaitSyncPointCHROMIUM(sync_point); 288 gles2->WaitSyncPointCHROMIUM(sync_point);
222 message_loop_async_waiter_.Signal(); 289 message_loop_async_waiter_.Signal();
223 } 290 }
224 291
225 void RendererGpuVideoDecoderFactories::ReadPixels( 292 void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id,
226 uint32 texture_id, uint32 texture_target, const gfx::Size& size, 293 uint32 texture_target,
227 const SkBitmap& pixels) { 294 const gfx::Size& size,
295 const SkBitmap& pixels) {
228 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. 296 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
229 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to 297 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to
230 // ensure that the underlying pixels in the SkBitmap passed in remain valid 298 // ensure that the underlying pixels in the SkBitmap passed in remain valid
231 // until the AsyncReadPixels() call completes. 299 // until the AsyncReadPixels() call completes.
232 read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); 300 read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
233 301
234 if (!message_loop_->BelongsToCurrentThread()) { 302 if (!message_loop_->BelongsToCurrentThread()) {
235 message_loop_->PostTask(FROM_HERE, base::Bind( 303 message_loop_->PostTask(
236 &RendererGpuVideoDecoderFactories::AsyncReadPixels, this, 304 FROM_HERE,
237 texture_id, texture_target, size)); 305 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels,
306 this,
307 texture_id,
308 texture_target,
309 size));
238 base::WaitableEvent* objects[] = {&aborted_waiter_, 310 base::WaitableEvent* objects[] = {&aborted_waiter_,
239 &message_loop_async_waiter_}; 311 &message_loop_async_waiter_};
240 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 312 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
241 return; 313 return;
242 } else { 314 } else {
243 AsyncReadPixels(texture_id, texture_target, size); 315 AsyncReadPixels(texture_id, texture_target, size);
244 message_loop_async_waiter_.Reset(); 316 message_loop_async_waiter_.Reset();
245 } 317 }
246 read_pixels_bitmap_.setPixelRef(NULL); 318 read_pixels_bitmap_.setPixelRef(NULL);
247 } 319 }
248 320
249 void RendererGpuVideoDecoderFactories::AsyncReadPixels( 321 void RendererGpuVideoAcceleratorFactories::AsyncReadPixels(
250 uint32 texture_id, uint32 texture_target, const gfx::Size& size) { 322 uint32 texture_id,
323 uint32 texture_target,
324 const gfx::Size& size) {
251 DCHECK(message_loop_->BelongsToCurrentThread()); 325 DCHECK(message_loop_->BelongsToCurrentThread());
252 if (!context_.get()) { 326 if (!context_.get()) {
253 message_loop_async_waiter_.Signal(); 327 message_loop_async_waiter_.Signal();
254 return; 328 return;
255 } 329 }
256 330
257 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 331 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
258 332
259 GLuint tmp_texture; 333 GLuint tmp_texture;
260 gles2->GenTextures(1, &tmp_texture); 334 gles2->GenTextures(1, &tmp_texture);
261 gles2->BindTexture(texture_target, tmp_texture); 335 gles2->BindTexture(texture_target, tmp_texture);
262 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 336 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
263 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 337 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
264 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 338 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
265 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 339 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
266 context_->copyTextureCHROMIUM( 340 context_->copyTextureCHROMIUM(
267 texture_target, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE); 341 texture_target, texture_id, tmp_texture, 0, GL_RGBA, GL_UNSIGNED_BYTE);
268 342
269 GLuint fb; 343 GLuint fb;
270 gles2->GenFramebuffers(1, &fb); 344 gles2->GenFramebuffers(1, &fb);
271 gles2->BindFramebuffer(GL_FRAMEBUFFER, fb); 345 gles2->BindFramebuffer(GL_FRAMEBUFFER, fb);
272 gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 346 gles2->FramebufferTexture2D(
273 texture_target, tmp_texture, 0); 347 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, tmp_texture, 0);
274 gles2->PixelStorei(GL_PACK_ALIGNMENT, 4); 348 gles2->PixelStorei(GL_PACK_ALIGNMENT, 4);
275 gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT, 349 gles2->ReadPixels(0,
276 GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels()); 350 0,
351 size.width(),
352 size.height(),
353 GL_BGRA_EXT,
354 GL_UNSIGNED_BYTE,
355 read_pixels_bitmap_.pixelRef()->pixels());
277 gles2->DeleteFramebuffers(1, &fb); 356 gles2->DeleteFramebuffers(1, &fb);
278 gles2->DeleteTextures(1, &tmp_texture); 357 gles2->DeleteTextures(1, &tmp_texture);
279 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 358 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
280 message_loop_async_waiter_.Signal(); 359 message_loop_async_waiter_.Signal();
281 } 360 }
282 361
283 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( 362 base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory(
284 size_t size) { 363 size_t size) {
285 if (main_message_loop_->BelongsToCurrentThread()) { 364 if (main_message_loop_->BelongsToCurrentThread()) {
286 return ChildThread::current()->AllocateSharedMemory(size); 365 return ChildThread::current()->AllocateSharedMemory(size);
287 } 366 }
288 main_message_loop_->PostTask(FROM_HERE, base::Bind( 367 main_message_loop_->PostTask(
289 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, 368 FROM_HERE,
290 size)); 369 base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory,
370 this,
371 size));
291 372
292 base::WaitableEvent* objects[] = {&aborted_waiter_, 373 base::WaitableEvent* objects[] = {&aborted_waiter_,
293 &render_thread_async_waiter_}; 374 &render_thread_async_waiter_};
294 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 375 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
295 return NULL; 376 return NULL;
296 return shared_memory_segment_.release(); 377 return shared_memory_segment_.release();
297 } 378 }
298 379
299 void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) { 380 void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory(
381 size_t size) {
300 DCHECK_EQ(base::MessageLoop::current(), 382 DCHECK_EQ(base::MessageLoop::current(),
301 ChildThread::current()->message_loop()); 383 ChildThread::current()->message_loop());
302 384
303 shared_memory_segment_.reset( 385 shared_memory_segment_.reset(
304 ChildThread::current()->AllocateSharedMemory(size)); 386 ChildThread::current()->AllocateSharedMemory(size));
305 render_thread_async_waiter_.Signal(); 387 render_thread_async_waiter_.Signal();
306 } 388 }
307 389
308 scoped_refptr<base::MessageLoopProxy> 390 scoped_refptr<base::MessageLoopProxy>
309 RendererGpuVideoDecoderFactories::GetMessageLoop() { 391 RendererGpuVideoAcceleratorFactories::GetMessageLoop() {
310 return message_loop_; 392 return message_loop_;
311 } 393 }
312 394
313 void RendererGpuVideoDecoderFactories::Abort() { 395 void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); }
314 aborted_waiter_.Signal();
315 }
316 396
317 bool RendererGpuVideoDecoderFactories::IsAborted() { 397 bool RendererGpuVideoAcceleratorFactories::IsAborted() {
318 return aborted_waiter_.IsSignaled(); 398 return aborted_waiter_.IsSignaled();
319 } 399 }
320 400
321 scoped_refptr<media::GpuVideoDecoderFactories> 401 scoped_refptr<media::GpuVideoAcceleratorFactories>
322 RendererGpuVideoDecoderFactories::Clone() { 402 RendererGpuVideoAcceleratorFactories::Clone() {
323 scoped_refptr<RendererGpuVideoDecoderFactories> factories = 403 scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
324 new RendererGpuVideoDecoderFactories(); 404 new RendererGpuVideoAcceleratorFactories();
325 factories->message_loop_ = message_loop_; 405 factories->message_loop_ = message_loop_;
326 factories->main_message_loop_ = main_message_loop_; 406 factories->main_message_loop_ = main_message_loop_;
327 factories->gpu_channel_host_ = gpu_channel_host_; 407 factories->gpu_channel_host_ = gpu_channel_host_;
328 factories->context_ = context_; 408 factories->context_ = context_;
329 return factories; 409 return factories;
330 } 410 }
331 411
332 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { 412 void
413 RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() {
333 // OK to release because Destroy() will delete the VDA instance. 414 // OK to release because Destroy() will delete the VDA instance.
334 if (vda_) 415 if (vda_)
335 vda_.release()->Destroy(); 416 vda_.release()->Destroy();
336 } 417 }
337 418
419 void
420 RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoEncodeAccelerator() {
421 // OK to release because Destroy() will delete the VDA instance.
422 if (vea_)
423 vea_.release()->Destroy();
424 }
425
338 } // namespace content 426 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698