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

Side by Side Diff: content/common/gpu/media/gpu_video_decode_accelerator.cc

Issue 24762003: Set the texture to cleared in VideoDecodeAccelerator::PictureReady. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address review comments Created 7 years, 2 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/common/gpu/media/gpu_video_decode_accelerator.h" 5 #include "content/common/gpu/media/gpu_video_decode_accelerator.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 16 matching lines...) Expand all
27 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" 27 #include "content/common/gpu/media/dxva_video_decode_accelerator.h"
28 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 28 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
29 #include "content/common/gpu/media/exynos_video_decode_accelerator.h" 29 #include "content/common/gpu/media/exynos_video_decode_accelerator.h"
30 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) 30 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
31 #include "ui/gl/gl_context_glx.h" 31 #include "ui/gl/gl_context_glx.h"
32 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" 32 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
33 #elif defined(OS_ANDROID) 33 #elif defined(OS_ANDROID)
34 #include "content/common/gpu/media/android_video_decode_accelerator.h" 34 #include "content/common/gpu/media/android_video_decode_accelerator.h"
35 #endif 35 #endif
36 36
37 #include "gpu/command_buffer/service/texture_manager.h"
38 #include "ui/gfx/size.h" 37 #include "ui/gfx/size.h"
39 38
40 namespace content { 39 namespace content {
41 40
42 static bool MakeDecoderContextCurrent( 41 static bool MakeDecoderContextCurrent(
43 const base::WeakPtr<GpuCommandBufferStub> stub) { 42 const base::WeakPtr<GpuCommandBufferStub> stub) {
44 if (!stub.get()) { 43 if (!stub.get()) {
45 DLOG(ERROR) << "Stub is gone; won't MakeCurrent()."; 44 DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
46 return false; 45 return false;
47 } 46 }
48 47
49 if (!stub->decoder()->MakeCurrent()) { 48 if (!stub->decoder()->MakeCurrent()) {
50 DLOG(ERROR) << "Failed to MakeCurrent()"; 49 DLOG(ERROR) << "Failed to MakeCurrent()";
51 return false; 50 return false;
52 } 51 }
53 52
54 return true; 53 return true;
55 } 54 }
56 55
56 // A helper class that works like AutoLock but only acquires the lock when
57 // DCHECK is on.
58 class DebugAutoLock {
59 public:
60 explicit DebugAutoLock(base::Lock& lock) : lock_(lock) {
61 if (DCHECK_IS_ON())
62 lock_.Acquire();
63 }
64
65 ~DebugAutoLock() {
66 if (DCHECK_IS_ON()) {
67 lock_.AssertAcquired();
68 lock_.Release();
69 }
70 }
71
72 private:
73 base::Lock& lock_;
74 DISALLOW_COPY_AND_ASSIGN(DebugAutoLock);
75 };
76
57 class GpuVideoDecodeAccelerator::MessageFilter 77 class GpuVideoDecodeAccelerator::MessageFilter
58 : public IPC::ChannelProxy::MessageFilter { 78 : public IPC::ChannelProxy::MessageFilter {
59 public: 79 public:
60 MessageFilter(GpuVideoDecodeAccelerator* owner, int32 host_route_id) 80 MessageFilter(GpuVideoDecodeAccelerator* owner, int32 host_route_id)
61 : owner_(owner), host_route_id_(host_route_id) {} 81 : owner_(owner), host_route_id_(host_route_id) {}
62 82
63 virtual void OnChannelError() OVERRIDE { channel_ = NULL; } 83 virtual void OnChannelError() OVERRIDE { channel_ = NULL; }
64 84
65 virtual void OnChannelClosing() OVERRIDE { channel_ = NULL; } 85 virtual void OnChannelClosing() OVERRIDE { channel_ = NULL; }
66 86
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 189 }
170 190
171 void GpuVideoDecodeAccelerator::DismissPictureBuffer( 191 void GpuVideoDecodeAccelerator::DismissPictureBuffer(
172 int32 picture_buffer_id) { 192 int32 picture_buffer_id) {
173 // Notify client that picture buffer is now unused. 193 // Notify client that picture buffer is now unused.
174 if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( 194 if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer(
175 host_route_id_, picture_buffer_id))) { 195 host_route_id_, picture_buffer_id))) {
176 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) " 196 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) "
177 << "failed"; 197 << "failed";
178 } 198 }
199 DebugAutoLock auto_lock(lock_);
200 uncleared_textures_.erase(picture_buffer_id);
179 } 201 }
180 202
181 void GpuVideoDecodeAccelerator::PictureReady( 203 void GpuVideoDecodeAccelerator::PictureReady(
182 const media::Picture& picture) { 204 const media::Picture& picture) {
205 // VDA may call PictureReady on IO thread. SetTextureCleared should run on
206 // the child thread. VDA is responsible to call PictureReady on the child
207 // thread when a picture buffer is delivered the first time.
208 if (child_message_loop_->BelongsToCurrentThread()) {
209 if (!SetTextureCleared(picture))
210 return;
211 } else {
212 DCHECK(io_message_loop_->BelongsToCurrentThread());
213 if (DCHECK_IS_ON()) {
214 DebugAutoLock auto_lock(lock_);
215 DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id()));
216 }
217 }
218
183 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( 219 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
184 host_route_id_, 220 host_route_id_,
185 picture.picture_buffer_id(), 221 picture.picture_buffer_id(),
186 picture.bitstream_buffer_id()))) { 222 picture.bitstream_buffer_id()))) {
187 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; 223 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed";
188 } 224 }
189 } 225 }
190 226
191 void GpuVideoDecodeAccelerator::NotifyError( 227 void GpuVideoDecodeAccelerator::NotifyError(
192 media::VideoDecodeAccelerator::Error error) { 228 media::VideoDecodeAccelerator::Error error) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 if (buffer_ids.size() != texture_ids.size()) { 334 if (buffer_ids.size() != texture_ids.size()) {
299 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 335 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
300 return; 336 return;
301 } 337 }
302 338
303 gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); 339 gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder();
304 gpu::gles2::TextureManager* texture_manager = 340 gpu::gles2::TextureManager* texture_manager =
305 command_decoder->GetContextGroup()->texture_manager(); 341 command_decoder->GetContextGroup()->texture_manager();
306 342
307 std::vector<media::PictureBuffer> buffers; 343 std::vector<media::PictureBuffer> buffers;
344 std::vector<scoped_refptr<gpu::gles2::TextureRef> > textures;
308 for (uint32 i = 0; i < buffer_ids.size(); ++i) { 345 for (uint32 i = 0; i < buffer_ids.size(); ++i) {
309 if (buffer_ids[i] < 0) { 346 if (buffer_ids[i] < 0) {
310 DLOG(ERROR) << "Buffer id " << buffer_ids[i] << " out of range"; 347 DLOG(ERROR) << "Buffer id " << buffer_ids[i] << " out of range";
311 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 348 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
312 return; 349 return;
313 } 350 }
314 gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture( 351 gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture(
315 texture_ids[i]); 352 texture_ids[i]);
316 if (!texture_ref) { 353 if (!texture_ref) {
317 DLOG(ERROR) << "Failed to find texture id " << texture_ids[i]; 354 DLOG(ERROR) << "Failed to find texture id " << texture_ids[i];
318 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 355 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
319 return; 356 return;
320 } 357 }
321 gpu::gles2::Texture* info = texture_ref->texture(); 358 gpu::gles2::Texture* info = texture_ref->texture();
322 if (info->target() != texture_target_) { 359 if (info->target() != texture_target_) {
323 DLOG(ERROR) << "Texture target mismatch for texture id " 360 DLOG(ERROR) << "Texture target mismatch for texture id "
324 << texture_ids[i]; 361 << texture_ids[i];
325 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 362 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
326 return; 363 return;
327 } 364 }
328 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES) { 365 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES) {
329 // GL_TEXTURE_EXTERNAL_OES textures have their dimensions defined by the 366 // GL_TEXTURE_EXTERNAL_OES textures have their dimensions defined by the
330 // underlying EGLImage. Use |texture_dimensions_| for this size. The 367 // underlying EGLImage. Use |texture_dimensions_| for this size.
331 // textures cannot be rendered to or cleared, so we set |cleared| true to
332 // skip clearing.
333 texture_manager->SetLevelInfo(texture_ref, 368 texture_manager->SetLevelInfo(texture_ref,
334 GL_TEXTURE_EXTERNAL_OES, 369 GL_TEXTURE_EXTERNAL_OES,
335 0, 370 0,
336 0, 371 0,
337 texture_dimensions_.width(), 372 texture_dimensions_.width(),
338 texture_dimensions_.height(), 373 texture_dimensions_.height(),
339 1, 374 1,
340 0, 375 0,
341 0, 376 0,
342 0, 377 0,
343 true); 378 false);
344 } else { 379 } else {
345 // For other targets, texture dimensions should already be defined. 380 // For other targets, texture dimensions should already be defined.
346 GLsizei width = 0, height = 0; 381 GLsizei width = 0, height = 0;
347 info->GetLevelSize(texture_target_, 0, &width, &height); 382 info->GetLevelSize(texture_target_, 0, &width, &height);
348 if (width != texture_dimensions_.width() || 383 if (width != texture_dimensions_.width() ||
349 height != texture_dimensions_.height()) { 384 height != texture_dimensions_.height()) {
350 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i]; 385 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i];
351 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 386 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
352 return; 387 return;
353 } 388 }
354 } 389 }
355 if (!texture_manager->ClearRenderableLevels(command_decoder, texture_ref)) {
356 DLOG(ERROR) << "Failed to Clear texture id " << texture_ids[i];
357 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
358 return;
359 }
360 uint32 service_texture_id; 390 uint32 service_texture_id;
361 if (!command_decoder->GetServiceTextureId( 391 if (!command_decoder->GetServiceTextureId(
362 texture_ids[i], &service_texture_id)) { 392 texture_ids[i], &service_texture_id)) {
363 DLOG(ERROR) << "Failed to translate texture!"; 393 DLOG(ERROR) << "Failed to translate texture!";
364 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 394 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
365 return; 395 return;
366 } 396 }
367 buffers.push_back(media::PictureBuffer( 397 buffers.push_back(media::PictureBuffer(
368 buffer_ids[i], texture_dimensions_, service_texture_id)); 398 buffer_ids[i], texture_dimensions_, service_texture_id));
399 textures.push_back(texture_ref);
369 } 400 }
370 video_decode_accelerator_->AssignPictureBuffers(buffers); 401 video_decode_accelerator_->AssignPictureBuffers(buffers);
402 DebugAutoLock auto_lock(lock_);
403 for (uint32 i = 0; i < buffer_ids.size(); ++i)
404 uncleared_textures_[buffer_ids[i]] = textures[i];
371 } 405 }
372 406
373 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( 407 void GpuVideoDecodeAccelerator::OnReusePictureBuffer(
374 int32 picture_buffer_id) { 408 int32 picture_buffer_id) {
375 DCHECK(video_decode_accelerator_.get()); 409 DCHECK(video_decode_accelerator_.get());
376 video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id); 410 video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id);
377 } 411 }
378 412
379 void GpuVideoDecodeAccelerator::OnFlush() { 413 void GpuVideoDecodeAccelerator::OnFlush() {
380 DCHECK(video_decode_accelerator_.get()); 414 DCHECK(video_decode_accelerator_.get());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 } 473 }
440 474
441 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { 475 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
442 DCHECK(stub_); 476 DCHECK(stub_);
443 if (filter_.get() && io_message_loop_->BelongsToCurrentThread()) 477 if (filter_.get() && io_message_loop_->BelongsToCurrentThread())
444 return filter_->SendOnIOThread(message); 478 return filter_->SendOnIOThread(message);
445 DCHECK(child_message_loop_->BelongsToCurrentThread()); 479 DCHECK(child_message_loop_->BelongsToCurrentThread());
446 return stub_->channel()->Send(message); 480 return stub_->channel()->Send(message);
447 } 481 }
448 482
483 bool GpuVideoDecodeAccelerator::SetTextureCleared(
484 const media::Picture& picture) {
485 DCHECK(child_message_loop_->BelongsToCurrentThread());
486 DebugAutoLock auto_lock(lock_);
487 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it;
488 it = uncleared_textures_.find(picture.picture_buffer_id());
489 if (it == uncleared_textures_.end())
490 return true;
Ami GONE FROM CHROMIUM 2013/09/30 18:03:03 NOTREACHED?
Ami GONE FROM CHROMIUM 2013/09/30 18:03:03 return false? (as it is, this function always retu
wuchengli 2013/10/01 03:49:43 Done. Changed to return void.
491
492 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second;
493 GLenum target = texture_ref->texture()->target();
494 gpu::gles2::TextureManager* texture_manager =
495 stub_->decoder()->GetContextGroup()->texture_manager();
496 texture_manager->SetLevelCleared(texture_ref, target, 0, true);
497 uncleared_textures_.erase(it);
498 return true;
499 }
500
449 } // namespace content 501 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698