diff options
author | dongseong.hwang <dongseong.hwang@intel.com> | 2015-01-08 12:11:13 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-08 20:12:02 +0000 |
commit | 0c4e9d8781aea6e52fdb4a7aee978817910c67ea (patch) | |
tree | f7028dbfd1cba76dacf55f9f0389c4752c6fbd8c /media/blink | |
parent | d2386aadf6c8350dabff4f820f2b73f44c487caa (diff) | |
download | chromium_src-0c4e9d8781aea6e52fdb4a7aee978817910c67ea.zip chromium_src-0c4e9d8781aea6e52fdb4a7aee978817910c67ea.tar.gz chromium_src-0c4e9d8781aea6e52fdb4a7aee978817910c67ea.tar.bz2 |
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/master@{#310577}
Diffstat (limited to 'media/blink')
-rw-r--r-- | media/blink/BUILD.gn | 1 | ||||
-rw-r--r-- | media/blink/DEPS | 5 | ||||
-rw-r--r-- | media/blink/media_blink.gyp | 1 | ||||
-rw-r--r-- | media/blink/webmediaplayer_impl.cc | 87 | ||||
-rw-r--r-- | media/blink/webmediaplayer_impl.h | 7 | ||||
-rw-r--r-- | media/blink/webmediaplayer_params.cc | 4 | ||||
-rw-r--r-- | media/blink/webmediaplayer_params.h | 16 |
7 files changed, 47 insertions, 74 deletions
diff --git a/media/blink/BUILD.gn b/media/blink/BUILD.gn index f9f5f98..46fecb0 100644 --- a/media/blink/BUILD.gn +++ b/media/blink/BUILD.gn @@ -8,6 +8,7 @@ component("blink") { "//base", "//cc", "//cc/blink", + "//gpu/blink", "//media", "//media:shared_memory_support", "//net", diff --git a/media/blink/DEPS b/media/blink/DEPS index 5c05816..e92dacb 100644 --- a/media/blink/DEPS +++ b/media/blink/DEPS @@ -1,10 +1,11 @@ include_rules = [ + "+cc/blink/web_layer_impl.h", "+cc/layers/video_frame_provider.h", "+cc/layers/video_layer.h", - "+cc/blink/web_layer_impl.h", + "+gpu/blink", "+media", "+net/base", "+net/http", "+third_party/WebKit/public/platform", "+third_party/WebKit/public/web", -]
\ No newline at end of file +] diff --git a/media/blink/media_blink.gyp b/media/blink/media_blink.gyp index 35d0480..71751fe 100644 --- a/media/blink/media_blink.gyp +++ b/media/blink/media_blink.gyp @@ -12,6 +12,7 @@ '../../base/base.gyp:base', '../../cc/cc.gyp:cc', '../../cc/blink/cc_blink.gyp:cc_blink', + '../../gpu/blink/gpu_blink.gyp:gpu_blink', '../../ui/gfx/gfx.gyp:gfx_geometry', '../../net/net.gyp:net', '../../third_party/WebKit/public/blink.gyp:blink', diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index f138f0e..4b67c9d 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc @@ -22,8 +22,7 @@ #include "base/synchronization/waitable_event.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/video_layer.h" -#include "gpu/GLES2/gl2extchromium.h" -#include "gpu/command_buffer/common/mailbox_holder.h" +#include "gpu/blink/webgraphicscontext3d_impl.h" #include "media/audio/null_audio_sink.h" #include "media/base/bind_to_current_loop.h" #include "media/base/cdm_context.h" @@ -39,7 +38,6 @@ #include "media/blink/webcontentdecryptionmodule_impl.h" #include "media/blink/webinbandtexttrack_impl.h" #include "media/blink/webmediaplayer_delegate.h" -#include "media/blink/webmediaplayer_params.h" #include "media/blink/webmediaplayer_util.h" #include "media/blink/webmediasource_impl.h" #include "media/filters/chunk_demuxer.h" @@ -81,23 +79,6 @@ namespace { const double kMinRate = 0.0625; const double kMaxRate = 16.0; -class SyncPointClientImpl : public media::VideoFrame::SyncPointClient { - public: - explicit SyncPointClientImpl( - blink::WebGraphicsContext3D* web_graphics_context) - : web_graphics_context_(web_graphics_context) {} - ~SyncPointClientImpl() override {} - uint32 InsertSyncPoint() override { - return web_graphics_context_->insertSyncPoint(); - } - void WaitSyncPoint(uint32 sync_point) override { - web_graphics_context_->waitSyncPoint(sync_point); - } - - private: - blink::WebGraphicsContext3D* web_graphics_context_; -}; - } // namespace namespace media { @@ -153,6 +134,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( client_(client), delegate_(delegate), defer_load_cb_(params.defer_load_cb()), + context_3d_cb_(params.context_3d_cb()), supports_save_(true), chunk_demuxer_(NULL), compositor_task_runner_(params.compositor_task_runner()), @@ -538,13 +520,18 @@ void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, GetCurrentFrameFromCompositor(); gfx::Rect gfx_rect(rect); - - skcanvas_video_renderer_.Paint(video_frame, - canvas, - gfx_rect, - alpha, - mode, - pipeline_metadata_.video_rotation); + Context3D context_3d; + if (video_frame.get() && + video_frame->format() == VideoFrame::NATIVE_TEXTURE) { + if (!context_3d_cb_.is_null()) { + context_3d = context_3d_cb_.Run(); + } + // GPU Process crashed. + if (!context_3d.gl) + return; + } + skcanvas_video_renderer_.Paint(video_frame, canvas, gfx_rect, alpha, mode, + pipeline_metadata_.video_rotation, context_3d); } bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { @@ -604,43 +591,19 @@ bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( scoped_refptr<VideoFrame> video_frame = GetCurrentFrameFromCompositor(); - if (!video_frame.get()) - return false; - if (video_frame->format() != VideoFrame::NATIVE_TEXTURE) - return false; - - const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); - if (mailbox_holder->texture_target != GL_TEXTURE_2D) + if (!video_frame.get() || + video_frame->format() != VideoFrame::NATIVE_TEXTURE) { return false; + } - web_graphics_context->waitSyncPoint(mailbox_holder->sync_point); - uint32 source_texture = web_graphics_context->createAndConsumeTextureCHROMIUM( - GL_TEXTURE_2D, mailbox_holder->mailbox.name); - - // The video is stored in a unmultiplied format, so premultiply - // if necessary. - web_graphics_context->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. - web_graphics_context->pixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); - web_graphics_context->copyTextureCHROMIUM(GL_TEXTURE_2D, - source_texture, - texture, - level, - internal_format, - type); - web_graphics_context->pixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, false); - web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, - false); - - web_graphics_context->deleteTexture(source_texture); - web_graphics_context->flush(); - - SyncPointClientImpl client(web_graphics_context); - video_frame->UpdateReleaseSyncPoint(&client); + // TODO(dshwang): need more elegant way to convert WebGraphicsContext3D to + // GLES2Interface. + gpu::gles2::GLES2Interface* gl = + static_cast<gpu_blink::WebGraphicsContext3DImpl*>(web_graphics_context) + ->GetGLInterface(); + SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture( + gl, video_frame.get(), texture, level, internal_format, type, + premultiply_alpha, flip_y); return true; } diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 07f1932..db540f6 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h @@ -23,15 +23,16 @@ #include "media/blink/buffered_data_source_host_impl.h" #include "media/blink/encrypted_media_player_support.h" #include "media/blink/video_frame_compositor.h" +#include "media/blink/webmediaplayer_params.h" #include "media/filters/skcanvas_video_renderer.h" #include "third_party/WebKit/public/platform/WebAudioSourceProvider.h" #include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h" -#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "third_party/WebKit/public/platform/WebMediaPlayer.h" #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" #include "url/gurl.h" namespace blink { +class WebGraphicsContext3D; class WebLocalFrame; } @@ -52,7 +53,6 @@ class MediaLog; class VideoFrameCompositor; class WebAudioSourceProviderImpl; class WebMediaPlayerDelegate; -class WebMediaPlayerParams; class WebTextTrackImpl; // The canonical implementation of blink::WebMediaPlayer that's backed by @@ -278,7 +278,8 @@ class MEDIA_EXPORT WebMediaPlayerImpl base::WeakPtr<WebMediaPlayerDelegate> delegate_; - base::Callback<void(const base::Closure&)> defer_load_cb_; + WebMediaPlayerParams::DeferLoadCB defer_load_cb_; + WebMediaPlayerParams::Context3DCB context_3d_cb_; // Routes audio playback to either AudioRendererSink or WebAudio. scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_; diff --git a/media/blink/webmediaplayer_params.cc b/media/blink/webmediaplayer_params.cc index b7382ec..df7f5b9 100644 --- a/media/blink/webmediaplayer_params.cc +++ b/media/blink/webmediaplayer_params.cc @@ -11,17 +11,19 @@ namespace media { WebMediaPlayerParams::WebMediaPlayerParams( - const base::Callback<void(const base::Closure&)>& defer_load_cb, + const DeferLoadCB& defer_load_cb, const scoped_refptr<AudioRendererSink>& audio_renderer_sink, const scoped_refptr<MediaLog>& media_log, const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, + const Context3DCB& context_3d_cb, blink::WebContentDecryptionModule* initial_cdm) : defer_load_cb_(defer_load_cb), audio_renderer_sink_(audio_renderer_sink), media_log_(media_log), media_task_runner_(media_task_runner), compositor_task_runner_(compositor_task_runner), + context_3d_cb_(context_3d_cb), initial_cdm_(initial_cdm) { } diff --git a/media/blink/webmediaplayer_params.h b/media/blink/webmediaplayer_params.h index 121ee14..6893ed6 100644 --- a/media/blink/webmediaplayer_params.h +++ b/media/blink/webmediaplayer_params.h @@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" #include "media/base/media_export.h" +#include "media/filters/context_3d.h" namespace base { class SingleThreadTaskRunner; @@ -28,22 +29,22 @@ class MediaLog; class MEDIA_EXPORT WebMediaPlayerParams { public: typedef base::Callback<void(const base::Closure&)> DeferLoadCB; + typedef base::Callback<Context3D()> Context3DCB; - // |defer_load_cb|, |audio_renderer_sink|, and |compositor_task_runner| may be - // null. + // |defer_load_cb|, |audio_renderer_sink|, |compositor_task_runner|, and + // |context_3d_cb| may be null. WebMediaPlayerParams( const DeferLoadCB& defer_load_cb, const scoped_refptr<AudioRendererSink>& audio_renderer_sink, const scoped_refptr<MediaLog>& media_log, const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, + const Context3DCB& context_3d, blink::WebContentDecryptionModule* initial_cdm); ~WebMediaPlayerParams(); - base::Callback<void(const base::Closure&)> defer_load_cb() const { - return defer_load_cb_; - } + DeferLoadCB defer_load_cb() const { return defer_load_cb_; } const scoped_refptr<AudioRendererSink>& audio_renderer_sink() const { return audio_renderer_sink_; @@ -66,12 +67,15 @@ class MEDIA_EXPORT WebMediaPlayerParams { return initial_cdm_; } + Context3DCB context_3d_cb() const { return context_3d_cb_; } + private: - base::Callback<void(const base::Closure&)> defer_load_cb_; + DeferLoadCB defer_load_cb_; scoped_refptr<AudioRendererSink> audio_renderer_sink_; scoped_refptr<MediaLog> media_log_; scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; + Context3DCB context_3d_cb_; blink::WebContentDecryptionModule* initial_cdm_; DISALLOW_IMPLICIT_CONSTRUCTORS(WebMediaPlayerParams); |