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

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: hold on to converted SkImages 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 UpdateLastImage(video_frame, context_3d);
362 if (!last_image_ || video_frame->timestamp() != last_timestamp_) { 362 if (!last_image_)
363 ResetCache(); 363 return;
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 364
389 paint.setXfermodeMode(mode); 365 paint.setXfermodeMode(mode);
390 paint.setFilterQuality(kLow_SkFilterQuality); 366 paint.setFilterQuality(kLow_SkFilterQuality);
391 367
392 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; 368 const bool need_rotation = video_rotation != VIDEO_ROTATION_0;
393 const bool need_scaling = 369 const bool need_scaling =
394 dest_rect.size() != 370 dest_rect.size() !=
395 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); 371 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions()));
396 const bool need_translation = !dest_rect.origin().IsOrigin(); 372 const bool need_translation = !dest_rect.origin().IsOrigin();
397 bool need_transform = need_rotation || need_scaling || need_translation; 373 bool need_transform = need_rotation || need_scaling || need_translation;
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 // "flip_y == false" means to keep the intrinsic orientation. 647 // "flip_y == false" means to keep the intrinsic orientation.
672 gl->CopyTextureCHROMIUM(source_texture, texture, internal_format, type, 648 gl->CopyTextureCHROMIUM(source_texture, texture, internal_format, type,
673 flip_y, premultiply_alpha, false); 649 flip_y, premultiply_alpha, false);
674 gl->DeleteTextures(1, &source_texture); 650 gl->DeleteTextures(1, &source_texture);
675 gl->Flush(); 651 gl->Flush();
676 652
677 SyncTokenClientImpl client(gl); 653 SyncTokenClientImpl client(gl);
678 video_frame->UpdateReleaseSyncToken(&client); 654 video_frame->UpdateReleaseSyncToken(&client);
679 } 655 }
680 656
657 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
658 const Context3D& context_3d,
659 gpu::gles2::GLES2Interface* destination_gl,
660 const scoped_refptr<VideoFrame>& video_frame,
661 unsigned int texture,
662 unsigned int internal_format,
663 unsigned int type,
664 bool premultiply_alpha,
665 bool flip_y) {
666 DCHECK(thread_checker_.CalledOnValidThread());
667 DCHECK(video_frame);
668 DCHECK(video_frame->HasTextures());
669 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) {
670 if (!context_3d.gr_context)
671 return false;
672 UpdateLastImage(video_frame, context_3d);
673 if (!last_image_)
sandersd (OOO until July 31) 2016/07/18 23:46:57 Given this pattern is used by both call sites, per
674 return false;
675
676 const GrGLTextureInfo* texture_info =
677 skia::GrBackendObjectToGrGLTextureInfo(
678 last_image_->getTextureHandle(true));
679
680 gpu::gles2::GLES2Interface* canvas_gl = context_3d.gl;
681 gpu::MailboxHolder mailbox_holder;
682 mailbox_holder.texture_target = texture_info->fTarget;
683 canvas_gl->GenMailboxCHROMIUM(mailbox_holder.mailbox.name);
684 canvas_gl->ProduceTextureDirectCHROMIUM(texture_info->fID,
685 mailbox_holder.texture_target,
686 mailbox_holder.mailbox.name);
687
688 // Wait for mailbox creation on canvas context before consuming it and
689 // copying from it on the consumer context.
690 const GLuint64 fence_sync = canvas_gl->InsertFenceSyncCHROMIUM();
691 canvas_gl->ShallowFlushCHROMIUM();
692 canvas_gl->GenSyncTokenCHROMIUM(fence_sync,
693 mailbox_holder.sync_token.GetData());
694
695 destination_gl->WaitSyncTokenCHROMIUM(
696 mailbox_holder.sync_token.GetConstData());
697 uint32_t source_texture2 = destination_gl->CreateAndConsumeTextureCHROMIUM(
Daniele Castagna 2016/07/13 20:51:01 nit: why 2?
698 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
699
700 destination_gl->CopyTextureCHROMIUM(source_texture2, texture,
701 internal_format, type, flip_y,
702 premultiply_alpha, false);
703 destination_gl->DeleteTextures(1, &source_texture2);
704
705 // Wait for copy to complete before source texture destruction.
Daniele Castagna 2016/07/13 20:51:01 By source texture you mean texture_info->fID, not
706 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM();
707 destination_gl->ShallowFlushCHROMIUM();
708 gpu::SyncToken dest_sync_token;
709 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync,
710 dest_sync_token.GetData());
711 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData());
712
713 SyncTokenClientImpl client(canvas_gl);
714 video_frame->UpdateReleaseSyncToken(&client);
715 } else {
716 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(),
717 texture, internal_format, type,
718 premultiply_alpha, flip_y);
719 }
720
721 return true;
722 }
723
681 void SkCanvasVideoRenderer::ResetCache() { 724 void SkCanvasVideoRenderer::ResetCache() {
682 DCHECK(thread_checker_.CalledOnValidThread()); 725 DCHECK(thread_checker_.CalledOnValidThread());
683 // Clear cached values. 726 // Clear cached values.
684 last_image_ = nullptr; 727 last_image_ = nullptr;
685 last_timestamp_ = kNoTimestamp(); 728 last_timestamp_ = kNoTimestamp();
686 } 729 }
687 730
731 void SkCanvasVideoRenderer::UpdateLastImage(
732 const scoped_refptr<VideoFrame>& video_frame,
733 const Context3D& context_3d) {
734 if (!last_image_ || video_frame->timestamp() != last_timestamp_) {
735 ResetCache();
736 // Generate a new image.
737 // Note: Skia will hold onto |video_frame| via |video_generator| only when
738 // |video_frame| is software.
739 // Holding |video_frame| longer than this call when using GPUVideoDecoder
740 // could cause problems since the pool of VideoFrames has a fixed size.
741 if (video_frame->HasTextures()) {
742 DCHECK(context_3d.gr_context);
743 DCHECK(context_3d.gl);
744 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) {
745 last_image_ =
746 NewSkImageFromVideoFrameYUVTextures(video_frame.get(), context_3d);
747 } else {
748 last_image_ =
749 NewSkImageFromVideoFrameNative(video_frame.get(), context_3d);
750 }
751 } else {
752 auto* video_generator = new VideoImageGenerator(video_frame);
753 last_image_ = SkImage::MakeFromGenerator(video_generator);
754 }
755 if (!last_image_) // Couldn't create the SkImage.
756 return;
757 last_timestamp_ = video_frame->timestamp();
758 }
759 last_image_deleting_timer_.Reset();
760 }
761
688 } // namespace media 762 } // 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