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

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: refactor SendPictureReady by kcwu's suggestion 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(debug_uncleared_textures_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 SetTextureCleared(picture);
210 } else {
211 DCHECK(io_message_loop_->BelongsToCurrentThread());
212 if (DCHECK_IS_ON()) {
213 DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
214 DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id()));
215 }
216 }
217
183 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( 218 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
184 host_route_id_, 219 host_route_id_,
185 picture.picture_buffer_id(), 220 picture.picture_buffer_id(),
186 picture.bitstream_buffer_id()))) { 221 picture.bitstream_buffer_id()))) {
187 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; 222 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed";
188 } 223 }
189 } 224 }
190 225
191 void GpuVideoDecodeAccelerator::NotifyError( 226 void GpuVideoDecodeAccelerator::NotifyError(
192 media::VideoDecodeAccelerator::Error error) { 227 media::VideoDecodeAccelerator::Error error) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 if (buffer_ids.size() != texture_ids.size()) { 333 if (buffer_ids.size() != texture_ids.size()) {
299 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 334 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
300 return; 335 return;
301 } 336 }
302 337
303 gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); 338 gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder();
304 gpu::gles2::TextureManager* texture_manager = 339 gpu::gles2::TextureManager* texture_manager =
305 command_decoder->GetContextGroup()->texture_manager(); 340 command_decoder->GetContextGroup()->texture_manager();
306 341
307 std::vector<media::PictureBuffer> buffers; 342 std::vector<media::PictureBuffer> buffers;
343 std::vector<scoped_refptr<gpu::gles2::TextureRef> > textures;
308 for (uint32 i = 0; i < buffer_ids.size(); ++i) { 344 for (uint32 i = 0; i < buffer_ids.size(); ++i) {
309 if (buffer_ids[i] < 0) { 345 if (buffer_ids[i] < 0) {
310 DLOG(ERROR) << "Buffer id " << buffer_ids[i] << " out of range"; 346 DLOG(ERROR) << "Buffer id " << buffer_ids[i] << " out of range";
311 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 347 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
312 return; 348 return;
313 } 349 }
314 gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture( 350 gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture(
315 texture_ids[i]); 351 texture_ids[i]);
316 if (!texture_ref) { 352 if (!texture_ref) {
317 DLOG(ERROR) << "Failed to find texture id " << texture_ids[i]; 353 DLOG(ERROR) << "Failed to find texture id " << texture_ids[i];
318 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 354 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
319 return; 355 return;
320 } 356 }
321 gpu::gles2::Texture* info = texture_ref->texture(); 357 gpu::gles2::Texture* info = texture_ref->texture();
322 if (info->target() != texture_target_) { 358 if (info->target() != texture_target_) {
323 DLOG(ERROR) << "Texture target mismatch for texture id " 359 DLOG(ERROR) << "Texture target mismatch for texture id "
324 << texture_ids[i]; 360 << texture_ids[i];
325 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 361 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
326 return; 362 return;
327 } 363 }
328 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES) { 364 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES) {
329 // GL_TEXTURE_EXTERNAL_OES textures have their dimensions defined by the 365 // GL_TEXTURE_EXTERNAL_OES textures have their dimensions defined by the
330 // underlying EGLImage. Use |texture_dimensions_| for this size. The 366 // 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, 367 texture_manager->SetLevelInfo(texture_ref,
334 GL_TEXTURE_EXTERNAL_OES, 368 GL_TEXTURE_EXTERNAL_OES,
335 0, 369 0,
336 0, 370 0,
337 texture_dimensions_.width(), 371 texture_dimensions_.width(),
338 texture_dimensions_.height(), 372 texture_dimensions_.height(),
339 1, 373 1,
340 0, 374 0,
341 0, 375 0,
342 0, 376 0,
343 true); 377 false);
344 } else { 378 } else {
345 // For other targets, texture dimensions should already be defined. 379 // For other targets, texture dimensions should already be defined.
346 GLsizei width = 0, height = 0; 380 GLsizei width = 0, height = 0;
347 info->GetLevelSize(texture_target_, 0, &width, &height); 381 info->GetLevelSize(texture_target_, 0, &width, &height);
348 if (width != texture_dimensions_.width() || 382 if (width != texture_dimensions_.width() ||
349 height != texture_dimensions_.height()) { 383 height != texture_dimensions_.height()) {
350 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i]; 384 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i];
351 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); 385 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
352 return; 386 return;
353 } 387 }
354 } 388 }
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; 389 uint32 service_texture_id;
361 if (!command_decoder->GetServiceTextureId( 390 if (!command_decoder->GetServiceTextureId(
362 texture_ids[i], &service_texture_id)) { 391 texture_ids[i], &service_texture_id)) {
363 DLOG(ERROR) << "Failed to translate texture!"; 392 DLOG(ERROR) << "Failed to translate texture!";
364 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 393 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
365 return; 394 return;
366 } 395 }
367 buffers.push_back(media::PictureBuffer( 396 buffers.push_back(media::PictureBuffer(
368 buffer_ids[i], texture_dimensions_, service_texture_id)); 397 buffer_ids[i], texture_dimensions_, service_texture_id));
398 textures.push_back(texture_ref);
369 } 399 }
370 video_decode_accelerator_->AssignPictureBuffers(buffers); 400 video_decode_accelerator_->AssignPictureBuffers(buffers);
401 DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
402 for (uint32 i = 0; i < buffer_ids.size(); ++i)
403 uncleared_textures_[buffer_ids[i]] = textures[i];
371 } 404 }
372 405
373 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( 406 void GpuVideoDecodeAccelerator::OnReusePictureBuffer(
374 int32 picture_buffer_id) { 407 int32 picture_buffer_id) {
375 DCHECK(video_decode_accelerator_.get()); 408 DCHECK(video_decode_accelerator_.get());
376 video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id); 409 video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id);
377 } 410 }
378 411
379 void GpuVideoDecodeAccelerator::OnFlush() { 412 void GpuVideoDecodeAccelerator::OnFlush() {
380 DCHECK(video_decode_accelerator_.get()); 413 DCHECK(video_decode_accelerator_.get());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 } 472 }
440 473
441 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { 474 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
442 DCHECK(stub_); 475 DCHECK(stub_);
443 if (filter_.get() && io_message_loop_->BelongsToCurrentThread()) 476 if (filter_.get() && io_message_loop_->BelongsToCurrentThread())
444 return filter_->SendOnIOThread(message); 477 return filter_->SendOnIOThread(message);
445 DCHECK(child_message_loop_->BelongsToCurrentThread()); 478 DCHECK(child_message_loop_->BelongsToCurrentThread());
446 return stub_->channel()->Send(message); 479 return stub_->channel()->Send(message);
447 } 480 }
448 481
482 void GpuVideoDecodeAccelerator::SetTextureCleared(
483 const media::Picture& picture) {
484 DCHECK(child_message_loop_->BelongsToCurrentThread());
485 DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
486 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it;
487 it = uncleared_textures_.find(picture.picture_buffer_id());
488 if (it == uncleared_textures_.end())
489 return; // the texture has been cleared
490
491 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second;
492 GLenum target = texture_ref->texture()->target();
493 gpu::gles2::TextureManager* texture_manager =
494 stub_->decoder()->GetContextGroup()->texture_manager();
495 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0));
496 texture_manager->SetLevelCleared(texture_ref, target, 0, true);
497 uncleared_textures_.erase(it);
498 }
499
449 } // namespace content 500 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/gpu_video_decode_accelerator.h ('k') | content/common/gpu/media/video_decode_accelerator_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698