Index: media/blink/skcanvas_video_renderer.cc |
diff --git a/media/blink/skcanvas_video_renderer.cc b/media/blink/skcanvas_video_renderer.cc |
index 90297f7dc8f1db1321143a86659b1af5ab49357c..4b715b2575e7a838bdaba2c03075f8958e142b44 100644 |
--- a/media/blink/skcanvas_video_renderer.cc |
+++ b/media/blink/skcanvas_video_renderer.cc |
@@ -154,8 +154,8 @@ skia::RefPtr<SkImage> NewSkImageFromVideoFrameNative( |
DCHECK(source_texture); |
gl->BindTexture(GL_TEXTURE_2D, source_texture); |
SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
- gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, |
- false); |
+ gl, video_frame, GL_TEXTURE_2D, source_texture, GL_RGBA, |
+ GL_UNSIGNED_BYTE, 0, true, false); |
} else { |
gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); |
source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
@@ -172,6 +172,59 @@ skia::RefPtr<SkImage> NewSkImageFromVideoFrameNative( |
SkImage::NewFromAdoptedTexture(context_3d.gr_context, desc)); |
} |
+void CopyVideoFrameSingleTextureToGLTextureInternal( |
+ gpu::gles2::GLES2Interface* gl, |
+ VideoFrame* video_frame, |
+ bool is_full_copy, |
+ unsigned int target, |
+ unsigned int texture, |
+ unsigned int internal_format, |
+ unsigned int type, |
+ int level, |
+ int xoffset, |
+ int yoffset, |
+ bool premultiply_alpha, |
+ bool flip_y) { |
+ DCHECK(video_frame); |
+ DCHECK(video_frame->HasTextures()); |
+ DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format())); |
+ |
+ 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; |
+ |
+ gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); |
+ uint32 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. |
+ if (is_full_copy) { |
+ DCHECK(!xoffset && !yoffset); |
+ gl->CopyTextureCHROMIUM(target, source_texture, texture, internal_format, |
+ type, flip_y, premultiply_alpha, false); |
+ } else { |
+ DCHECK_EQ(static_cast<unsigned int>(GL_FALSE), internal_format); |
+ DCHECK_EQ(static_cast<unsigned int>(GL_FALSE), type); |
+ gl->CopySubTextureCHROMIUM( |
+ target, source_texture, texture, xoffset, yoffset, 0, 0, |
+ video_frame->natural_size().width(), |
+ video_frame->natural_size().height(), flip_y, premultiply_alpha, false); |
+ } |
+ |
+ gl->DeleteTextures(1, &source_texture); |
+ gl->Flush(); |
+ |
+ SyncPointClientImpl client(gl); |
+ video_frame->UpdateReleaseSyncPoint(&client); |
+} |
+ |
} // anonymous namespace |
// Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. |
@@ -533,40 +586,32 @@ void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
gpu::gles2::GLES2Interface* gl, |
VideoFrame* video_frame, |
+ unsigned int target, |
unsigned int texture, |
unsigned int internal_format, |
unsigned int type, |
+ int level, |
bool premultiply_alpha, |
bool flip_y) { |
- DCHECK(video_frame); |
- DCHECK(video_frame->HasTextures()); |
- DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format())); |
- |
- 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; |
- |
- gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); |
- uint32 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(GL_TEXTURE_2D, source_texture, texture, |
- internal_format, type, |
- flip_y, premultiply_alpha, false); |
- |
- gl->DeleteTextures(1, &source_texture); |
- gl->Flush(); |
+ CopyVideoFrameSingleTextureToGLTextureInternal( |
+ gl, video_frame, true, target, texture, internal_format, type, level, 0, |
+ 0, premultiply_alpha, flip_y); |
+} |
- SyncPointClientImpl client(gl); |
- video_frame->UpdateReleaseSyncPoint(&client); |
+// static |
+void SkCanvasVideoRenderer::CopySubVideoFrameSingleTextureToGLTexture( |
+ gpu::gles2::GLES2Interface* gl, |
+ VideoFrame* video_frame, |
+ unsigned int target, |
+ unsigned int texture, |
+ int level, |
+ int xoffset, |
+ int yoffset, |
+ bool premultiply_alpha, |
+ bool flip_y) { |
+ CopyVideoFrameSingleTextureToGLTextureInternal( |
+ gl, video_frame, false, target, texture, GL_FALSE, GL_FALSE, level, |
+ xoffset, yoffset, premultiply_alpha, flip_y); |
} |
void SkCanvasVideoRenderer::ResetCache() { |