commit0c4e9d8781aea6e52fdb4a7aee978817910c67ea
authordongseong.hwang Thu Jan 08 20:11:13 2015
committerCommit bot Thu Jan 08 20:12:02 2015
media: Optimize HW Video to 2D Canvas copy. Currently, when we draws GPU decoded Video on accelerated 2D Canvas, chromium reads back pixel from GPU and then uploads the pixel to GPU to make a SkBitmap. It‘s so inefficient for both speed and battery. On the other hand, only Android copies GPU-GPU in this case, but Android doesn‘t have cache mechanism which SkCanvasVideoRenderer provides. This CL makes all platforms copy gpu-gpu with cache mechanism. Cache mechanism is useful when 2d canvas draws a video frame many times. e.g. http://craftymind.com/factory/html5video/CanvasVideo.html In addition, fix white video background on Android when not loaded. Other platforms draw black background thanks to SkCanvasVideoRenderer::Paint(). In detail of the changes; 1. Implement gpu-gpu copy in SkCanvasVideoRenderer::Paint() like previous WebMediaPlayerAndroid::paint(). 2. Move duplicated GPU code on WebMediaPlayerImpl and WebMediaPlayerAndroid to SkCanvasVideoRenderer. Perf data on i5 IvyBridge blink_perf.all:Canvas_draw-video-to-hw-accelerated-canvas-2d 15.8x speed up: 116.27 runs/s -> 1847.23 runs/s NOTE: measure after disabling cache in SkCanvasVideoRenderer BUG=401058, 263667 Review URL: https://codereview.chromium.org/445013002 Cr-Commit-Position: refs/heads/[email protected]{#310577}
- content/renderer/media/android/webmediaplayer_android.cc[diff]
- content/renderer/media/android/webmediaplayer_android.h[diff]
- content/renderer/media/webmediaplayer_ms.cc[diff]
- content/renderer/render_frame_impl.cc[diff]
- media/BUILD.gn[diff]
- media/DEPS[diff]
- media/blink/BUILD.gn[diff]
- media/blink/DEPS[diff]
- media/blink/media_blink.gyp[diff]
- media/blink/webmediaplayer_impl.cc[diff]
- media/blink/webmediaplayer_impl.h[diff]
- media/blink/webmediaplayer_params.cc[diff]
- media/blink/webmediaplayer_params.h[diff]
- media/filters/context_3d.h[Added
- diff] - media/filters/skcanvas_video_renderer.cc[diff]
- media/filters/skcanvas_video_renderer.h[diff]
- media/filters/skcanvas_video_renderer_unittest.cc[diff]
- media/media.gyp[diff]
- mojo/services/html_viewer/webmediaplayer_factory.cc[diff]
从视频复制到图片,GPU到GPU直接传递,不需要经过CPU内存?
// static void SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture( gpu::gles2::GLES2Interface* gl, VideoFrame* video_frame, unsigned int texture, unsigned int level, unsigned int internal_format, unsigned int type, bool premultiply_alpha, bool flip_y) { DCHECK(video_frame && video_frame->format() == VideoFrame::NATIVE_TEXTURE); const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); DCHECK(mailbox_holder->texture_target == GL_TEXTURE_2D || mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES); 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. gl->PixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, premultiply_alpha); // 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->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_texture, texture, level, internal_format, type); gl->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, false); gl->PixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false); gl->DeleteTextures(1, &source_texture); gl->Flush(); SyncPointClientImpl client(gl); video_frame->UpdateReleaseSyncPoint(&client); }
主要实现代码在这里,主要缺点是:从代码可以看出,仍然需要GPU内部到GPU的内存复制,做不到Zero-Copy(要是能够做到GPU内存指针的swap,或C++11里的move构造,就更好了)。但是显然比GPU-->CPU-->GPU这种中转效率上要好一点
理论上来讲,可以实现GPU硬件加速的WebView到View的GPU snapshot快照截图的直接传递。
时间: 2024-10-07 21:26:47