Chromium Code Reviews| Index: media/renderers/skcanvas_video_renderer.cc |
| diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc |
| index 74e72bc5a4c5338b654097de6de29fa321a9b611..0d520ad23f140705be6c9f8680d9f5d2da96b73d 100644 |
| --- a/media/renderers/skcanvas_video_renderer.cc |
| +++ b/media/renderers/skcanvas_video_renderer.cc |
| @@ -358,33 +358,9 @@ void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, |
| } |
| gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| - |
| - if (!last_image_ || video_frame->timestamp() != last_timestamp_) { |
| - ResetCache(); |
| - // Generate a new image. |
| - // Note: Skia will hold onto |video_frame| via |video_generator| only when |
| - // |video_frame| is software. |
| - // Holding |video_frame| longer than this call when using GPUVideoDecoder |
| - // could cause problems since the pool of VideoFrames has a fixed size. |
| - if (video_frame->HasTextures()) { |
| - DCHECK(context_3d.gr_context); |
| - DCHECK(gl); |
| - if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { |
| - last_image_ = |
| - NewSkImageFromVideoFrameYUVTextures(video_frame.get(), context_3d); |
| - } else { |
| - last_image_ = |
| - NewSkImageFromVideoFrameNative(video_frame.get(), context_3d); |
| - } |
| - } else { |
| - auto* video_generator = new VideoImageGenerator(video_frame); |
| - last_image_ = SkImage::MakeFromGenerator(video_generator); |
| - } |
| - if (!last_image_) // Couldn't create the SkImage. |
| - return; |
| - last_timestamp_ = video_frame->timestamp(); |
| - } |
| - last_image_deleting_timer_.Reset(); |
| + UpdateLastImage(video_frame, context_3d); |
| + if (!last_image_) |
| + return; |
| paint.setXfermodeMode(mode); |
| paint.setFilterQuality(kLow_SkFilterQuality); |
| @@ -678,6 +654,73 @@ void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
| video_frame->UpdateReleaseSyncToken(&client); |
| } |
| +bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
| + const Context3D& context_3d, |
| + gpu::gles2::GLES2Interface* destination_gl, |
| + const scoped_refptr<VideoFrame>& video_frame, |
| + unsigned int texture, |
| + unsigned int internal_format, |
| + unsigned int type, |
| + bool premultiply_alpha, |
| + bool flip_y) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + DCHECK(video_frame); |
| + DCHECK(video_frame->HasTextures()); |
| + if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { |
| + if (!context_3d.gr_context) |
| + return false; |
| + UpdateLastImage(video_frame, context_3d); |
| + if (!last_image_) |
|
sandersd (OOO until July 31)
2016/07/18 23:46:57
Given this pattern is used by both call sites, per
|
| + return false; |
| + |
| + const GrGLTextureInfo* texture_info = |
| + skia::GrBackendObjectToGrGLTextureInfo( |
| + last_image_->getTextureHandle(true)); |
| + |
| + gpu::gles2::GLES2Interface* canvas_gl = context_3d.gl; |
| + gpu::MailboxHolder mailbox_holder; |
| + mailbox_holder.texture_target = texture_info->fTarget; |
| + canvas_gl->GenMailboxCHROMIUM(mailbox_holder.mailbox.name); |
| + canvas_gl->ProduceTextureDirectCHROMIUM(texture_info->fID, |
| + mailbox_holder.texture_target, |
| + mailbox_holder.mailbox.name); |
| + |
| + // Wait for mailbox creation on canvas context before consuming it and |
| + // copying from it on the consumer context. |
| + const GLuint64 fence_sync = canvas_gl->InsertFenceSyncCHROMIUM(); |
| + canvas_gl->ShallowFlushCHROMIUM(); |
| + canvas_gl->GenSyncTokenCHROMIUM(fence_sync, |
| + mailbox_holder.sync_token.GetData()); |
| + |
| + destination_gl->WaitSyncTokenCHROMIUM( |
| + mailbox_holder.sync_token.GetConstData()); |
| + uint32_t source_texture2 = destination_gl->CreateAndConsumeTextureCHROMIUM( |
|
Daniele Castagna
2016/07/13 20:51:01
nit: why 2?
|
| + mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| + |
| + destination_gl->CopyTextureCHROMIUM(source_texture2, texture, |
| + internal_format, type, flip_y, |
| + premultiply_alpha, false); |
| + destination_gl->DeleteTextures(1, &source_texture2); |
| + |
| + // 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
|
| + const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); |
| + destination_gl->ShallowFlushCHROMIUM(); |
| + gpu::SyncToken dest_sync_token; |
| + destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, |
| + dest_sync_token.GetData()); |
| + canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); |
| + |
| + SyncTokenClientImpl client(canvas_gl); |
| + video_frame->UpdateReleaseSyncToken(&client); |
| + } else { |
| + CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(), |
| + texture, internal_format, type, |
| + premultiply_alpha, flip_y); |
| + } |
| + |
| + return true; |
| +} |
| + |
| void SkCanvasVideoRenderer::ResetCache() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // Clear cached values. |
| @@ -685,4 +728,35 @@ void SkCanvasVideoRenderer::ResetCache() { |
| last_timestamp_ = kNoTimestamp(); |
| } |
| +void SkCanvasVideoRenderer::UpdateLastImage( |
| + const scoped_refptr<VideoFrame>& video_frame, |
| + const Context3D& context_3d) { |
| + if (!last_image_ || video_frame->timestamp() != last_timestamp_) { |
| + ResetCache(); |
| + // Generate a new image. |
| + // Note: Skia will hold onto |video_frame| via |video_generator| only when |
| + // |video_frame| is software. |
| + // Holding |video_frame| longer than this call when using GPUVideoDecoder |
| + // could cause problems since the pool of VideoFrames has a fixed size. |
| + if (video_frame->HasTextures()) { |
| + DCHECK(context_3d.gr_context); |
| + DCHECK(context_3d.gl); |
| + if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { |
| + last_image_ = |
| + NewSkImageFromVideoFrameYUVTextures(video_frame.get(), context_3d); |
| + } else { |
| + last_image_ = |
| + NewSkImageFromVideoFrameNative(video_frame.get(), context_3d); |
| + } |
| + } else { |
| + auto* video_generator = new VideoImageGenerator(video_frame); |
| + last_image_ = SkImage::MakeFromGenerator(video_generator); |
| + } |
| + if (!last_image_) // Couldn't create the SkImage. |
| + return; |
| + last_timestamp_ = video_frame->timestamp(); |
| + } |
| + last_image_deleting_timer_.Reset(); |
| +} |
| + |
| } // namespace media |