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

Side by Side Diff: media/renderers/skcanvas_video_renderer.cc

Issue 2127053004: Optimize webgl texImage2D from YUV video textures. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@skianocopy
Patch Set: remove unnecessary change Created 4 years, 5 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
« no previous file with comments | « media/renderers/skcanvas_video_renderer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "media/renderers/skcanvas_video_renderer.h" 5 #include "media/renderers/skcanvas_video_renderer.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "gpu/GLES2/gl2extchromium.h" 10 #include "gpu/GLES2/gl2extchromium.h"
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 // frame has an unexpected format. 351 // frame has an unexpected format.
352 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || 352 if (!video_frame.get() || video_frame->natural_size().IsEmpty() ||
353 !(media::IsYuvPlanar(video_frame->format()) || 353 !(media::IsYuvPlanar(video_frame->format()) ||
354 video_frame->HasTextures())) { 354 video_frame->HasTextures())) {
355 canvas->drawRect(dest, paint); 355 canvas->drawRect(dest, paint);
356 canvas->flush(); 356 canvas->flush();
357 return; 357 return;
358 } 358 }
359 359
360 gpu::gles2::GLES2Interface* gl = context_3d.gl; 360 gpu::gles2::GLES2Interface* gl = context_3d.gl;
361 361 if (!UpdateLastImage(video_frame, context_3d))
362 if (!last_image_ || video_frame->timestamp() != last_timestamp_) { 362 return;
363 ResetCache();
364 // Generate a new image.
365 // Note: Skia will hold onto |video_frame| via |video_generator| only when
366 // |video_frame| is software.
367 // Holding |video_frame| longer than this call when using GPUVideoDecoder
368 // could cause problems since the pool of VideoFrames has a fixed size.
369 if (video_frame->HasTextures()) {
370 DCHECK(context_3d.gr_context);
371 DCHECK(gl);
372 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) {
373 last_image_ =
374 NewSkImageFromVideoFrameYUVTextures(video_frame.get(), context_3d);
375 } else {
376 last_image_ =
377 NewSkImageFromVideoFrameNative(video_frame.get(), context_3d);
378 }
379 } else {
380 auto* video_generator = new VideoImageGenerator(video_frame);
381 last_image_ = SkImage::MakeFromGenerator(video_generator);
382 }
383 if (!last_image_) // Couldn't create the SkImage.
384 return;
385 last_timestamp_ = video_frame->timestamp();
386 }
387 last_image_deleting_timer_.Reset();
388 363
389 paint.setXfermodeMode(mode); 364 paint.setXfermodeMode(mode);
390 paint.setFilterQuality(kLow_SkFilterQuality); 365 paint.setFilterQuality(kLow_SkFilterQuality);
391 366
392 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; 367 const bool need_rotation = video_rotation != VIDEO_ROTATION_0;
393 const bool need_scaling = 368 const bool need_scaling =
394 dest_rect.size() != 369 dest_rect.size() !=
395 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); 370 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions()));
396 const bool need_translation = !dest_rect.origin().IsOrigin(); 371 const bool need_translation = !dest_rect.origin().IsOrigin();
397 bool need_transform = need_rotation || need_scaling || need_translation; 372 bool need_transform = need_rotation || need_scaling || need_translation;
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 // "flip_y == false" means to keep the intrinsic orientation. 639 // "flip_y == false" means to keep the intrinsic orientation.
665 gl->CopyTextureCHROMIUM(source_texture, texture, internal_format, type, 640 gl->CopyTextureCHROMIUM(source_texture, texture, internal_format, type,
666 flip_y, premultiply_alpha, false); 641 flip_y, premultiply_alpha, false);
667 gl->DeleteTextures(1, &source_texture); 642 gl->DeleteTextures(1, &source_texture);
668 gl->Flush(); 643 gl->Flush();
669 644
670 SyncTokenClientImpl client(gl); 645 SyncTokenClientImpl client(gl);
671 video_frame->UpdateReleaseSyncToken(&client); 646 video_frame->UpdateReleaseSyncToken(&client);
672 } 647 }
673 648
649 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
650 const Context3D& context_3d,
651 gpu::gles2::GLES2Interface* destination_gl,
652 const scoped_refptr<VideoFrame>& video_frame,
653 unsigned int texture,
654 unsigned int internal_format,
655 unsigned int type,
656 bool premultiply_alpha,
657 bool flip_y) {
658 DCHECK(thread_checker_.CalledOnValidThread());
659 DCHECK(video_frame);
660 DCHECK(video_frame->HasTextures());
661 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) {
662 if (!context_3d.gr_context)
663 return false;
664 if (!UpdateLastImage(video_frame, context_3d))
665 return false;
666
667 const GrGLTextureInfo* texture_info =
668 skia::GrBackendObjectToGrGLTextureInfo(
669 last_image_->getTextureHandle(true));
670
671 gpu::gles2::GLES2Interface* canvas_gl = context_3d.gl;
672 gpu::MailboxHolder mailbox_holder;
673 mailbox_holder.texture_target = texture_info->fTarget;
674 canvas_gl->GenMailboxCHROMIUM(mailbox_holder.mailbox.name);
675 canvas_gl->ProduceTextureDirectCHROMIUM(texture_info->fID,
676 mailbox_holder.texture_target,
677 mailbox_holder.mailbox.name);
678
679 // Wait for mailbox creation on canvas context before consuming it and
680 // copying from it on the consumer context.
681 const GLuint64 fence_sync = canvas_gl->InsertFenceSyncCHROMIUM();
682 canvas_gl->ShallowFlushCHROMIUM();
683 canvas_gl->GenSyncTokenCHROMIUM(fence_sync,
684 mailbox_holder.sync_token.GetData());
685
686 destination_gl->WaitSyncTokenCHROMIUM(
687 mailbox_holder.sync_token.GetConstData());
688 uint32_t intermediate_texture =
689 destination_gl->CreateAndConsumeTextureCHROMIUM(
690 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
691
692 destination_gl->CopyTextureCHROMIUM(intermediate_texture, texture,
693 internal_format, type, flip_y,
694 premultiply_alpha, false);
695 destination_gl->DeleteTextures(1, &intermediate_texture);
696
697 // Wait for destination context to consume mailbox before deleting it in
698 // canvas context.
699 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM();
700 destination_gl->ShallowFlushCHROMIUM();
701 gpu::SyncToken dest_sync_token;
702 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync,
703 dest_sync_token.GetData());
704 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData());
705
706 SyncTokenClientImpl client(canvas_gl);
707 video_frame->UpdateReleaseSyncToken(&client);
708 } else {
709 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(),
710 texture, internal_format, type,
711 premultiply_alpha, flip_y);
712 }
713
714 return true;
715 }
716
674 void SkCanvasVideoRenderer::ResetCache() { 717 void SkCanvasVideoRenderer::ResetCache() {
675 DCHECK(thread_checker_.CalledOnValidThread()); 718 DCHECK(thread_checker_.CalledOnValidThread());
676 // Clear cached values. 719 // Clear cached values.
677 last_image_ = nullptr; 720 last_image_ = nullptr;
678 last_timestamp_ = kNoTimestamp; 721 last_timestamp_ = kNoTimestamp;
679 } 722 }
680 723
724 bool SkCanvasVideoRenderer::UpdateLastImage(
725 const scoped_refptr<VideoFrame>& video_frame,
726 const Context3D& context_3d) {
727 if (!last_image_ || video_frame->timestamp() != last_timestamp_) {
728 ResetCache();
729 // Generate a new image.
730 // Note: Skia will hold onto |video_frame| via |video_generator| only when
731 // |video_frame| is software.
732 // Holding |video_frame| longer than this call when using GPUVideoDecoder
733 // could cause problems since the pool of VideoFrames has a fixed size.
734 if (video_frame->HasTextures()) {
735 DCHECK(context_3d.gr_context);
736 DCHECK(context_3d.gl);
737 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) {
738 last_image_ =
739 NewSkImageFromVideoFrameYUVTextures(video_frame.get(), context_3d);
740 } else {
741 last_image_ =
742 NewSkImageFromVideoFrameNative(video_frame.get(), context_3d);
743 }
744 } else {
745 auto* video_generator = new VideoImageGenerator(video_frame);
746 last_image_ = SkImage::MakeFromGenerator(video_generator);
747 }
748 if (!last_image_) // Couldn't create the SkImage.
749 return false;
750 last_timestamp_ = video_frame->timestamp();
751 }
752 last_image_deleting_timer_.Reset();
753 DCHECK(!!last_image_);
754 return true;
755 }
756
681 } // namespace media 757 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/skcanvas_video_renderer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698