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..96be54ab9d0337046218c23977ab0d7459209567 100644 |
--- a/media/renderers/skcanvas_video_renderer.cc |
+++ b/media/renderers/skcanvas_video_renderer.cc |
@@ -182,9 +182,9 @@ sk_sp<SkImage> NewSkImageFromVideoFrameNative(VideoFrame* video_frame, |
gl->GenTextures(1, &source_texture); |
DCHECK(source_texture); |
gl->BindTexture(GL_TEXTURE_2D, source_texture); |
- SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
- gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, |
- false); |
+ SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
+ context_3d, gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, |
+ true, false); |
} else { |
gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
@@ -642,8 +642,9 @@ void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
} |
// static |
-void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
- gpu::gles2::GLES2Interface* gl, |
+bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
+ const Context3D& context_3d, |
+ gpu::gles2::GLES2Interface* destination_gl, |
VideoFrame* video_frame, |
unsigned int texture, |
unsigned int internal_format, |
@@ -652,30 +653,79 @@ void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
bool flip_y) { |
DCHECK(video_frame); |
DCHECK(video_frame->HasTextures()); |
+ if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { |
+ if (!context_3d.gr_context) |
+ return false; |
+ sk_sp<SkImage> image = |
+ NewSkImageFromVideoFrameYUVTextures(video_frame, context_3d); |
+ |
+ const GrGLTextureInfo* texture_info = |
+ skia::GrBackendObjectToGrGLTextureInfo(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, |
Daniele Castagna
2016/07/11 18:23:36
Isn't this assuming that SkImage has only one text
|
+ 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( |
+ mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
- const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
- DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
- mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || |
- mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) |
- << mailbox_holder.texture_target; |
+ destination_gl->CopyTextureCHROMIUM(source_texture2, texture, |
Daniele Castagna
2016/07/11 18:23:36
We're not validating internal_format anywhere if n
|
+ internal_format, type, flip_y, |
+ premultiply_alpha, false); |
+ destination_gl->DeleteTextures(1, &source_texture2); |
+ |
+ // Wait for copy to complete before source texture destruction. |
+ 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 { |
+ const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
+ DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
+ mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || |
+ mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) |
+ << mailbox_holder.texture_target; |
+ |
+ destination_gl->WaitSyncTokenCHROMIUM( |
+ mailbox_holder.sync_token.GetConstData()); |
+ uint32_t source_texture = destination_gl->CreateAndConsumeTextureCHROMIUM( |
+ mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
+ |
+ // The video is stored in a unmultiplied format, so premultiply |
+ // if necessary. |
+ // Application itself needs to take care of setting the right |flip_y| |
+ // value down to get the expected result. |
+ // "flip_y == true" means to reverse the video orientation while |
+ // "flip_y == false" means to keep the intrinsic orientation. |
+ destination_gl->CopyTextureCHROMIUM(source_texture, texture, |
+ internal_format, type, flip_y, |
+ premultiply_alpha, false); |
+ destination_gl->DeleteTextures(1, &source_texture); |
+ destination_gl->Flush(); |
+ |
+ SyncTokenClientImpl client(destination_gl); |
+ video_frame->UpdateReleaseSyncToken(&client); |
+ } |
- gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
- uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
- mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
- |
- // The video is stored in a unmultiplied format, so premultiply |
- // if necessary. |
- // Application itself needs to take care of setting the right |flip_y| |
- // value down to get the expected result. |
- // "flip_y == true" means to reverse the video orientation while |
- // "flip_y == false" means to keep the intrinsic orientation. |
- gl->CopyTextureCHROMIUM(source_texture, texture, internal_format, type, |
- flip_y, premultiply_alpha, false); |
- gl->DeleteTextures(1, &source_texture); |
- gl->Flush(); |
- |
- SyncTokenClientImpl client(gl); |
- video_frame->UpdateReleaseSyncToken(&client); |
+ return true; |
} |
void SkCanvasVideoRenderer::ResetCache() { |