diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-10 15:10:38 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-10 15:10:38 +0000 |
commit | 3aaba5762cad76554156b3d70dc6ea9629a4cc89 (patch) | |
tree | 5559e5f791eb475c078af6d059a272f3dc17aeab | |
parent | daf17c543de27c01e7a200576f83dea20bdf8832 (diff) | |
download | chromium_src-3aaba5762cad76554156b3d70dc6ea9629a4cc89.zip chromium_src-3aaba5762cad76554156b3d70dc6ea9629a4cc89.tar.gz chromium_src-3aaba5762cad76554156b3d70dc6ea9629a4cc89.tar.bz2 |
Fullscreen video in Android WebView
Make StreamTextureFactory and StreamTextureProxy abstract
base classes, and create a stub StreamTextureFactory for
Android Webview using synchronous compositor.
This provides enough plumbing to make full screen video
work in Android WebView. In-page video still requires
the in-process context to support streaming texture
manager.
BUG=239760
Review URL: https://chromiumcodereview.appspot.com/22766004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216864 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/android/in_process/synchronous_compositor_impl.cc | 15 | ||||
-rw-r--r-- | content/content_renderer.gypi | 5 | ||||
-rw-r--r-- | content/renderer/media/android/stream_texture_factory_android.h | 59 | ||||
-rw-r--r-- | content/renderer/media/android/stream_texture_factory_android_impl.cc (renamed from content/renderer/media/android/stream_texture_factory_android.cc) | 63 | ||||
-rw-r--r-- | content/renderer/media/android/stream_texture_factory_android_impl.h | 47 | ||||
-rw-r--r-- | content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc | 34 | ||||
-rw-r--r-- | content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h | 35 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 15 |
8 files changed, 206 insertions, 67 deletions
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc index 041511e..74048d8 100644 --- a/content/browser/android/in_process/synchronous_compositor_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_impl.cc @@ -66,10 +66,16 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { } virtual scoped_refptr<cc::ContextProvider> - GetOffscreenContextProviderForMainThread() OVERRIDE { - NOTIMPLEMENTED() - << "Synchronous compositor does not support main thread context yet."; - return scoped_refptr<cc::ContextProvider>(); + GetOffscreenContextProviderForMainThread() OVERRIDE { + if (!offscreen_context_for_main_thread_.get() || + offscreen_context_for_main_thread_->DestroyedOnMainThread()) { + offscreen_context_for_main_thread_ = + webkit::gpu::ContextProviderInProcess::Create(); + if (offscreen_context_for_main_thread_.get() && + !offscreen_context_for_main_thread_->BindToCurrentThread()) + offscreen_context_for_main_thread_ = NULL; + } + return offscreen_context_for_main_thread_; } // This is called on both renderer main thread (offscreen context creation @@ -95,6 +101,7 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { // Only guards construction of |offscreen_context_for_compositor_thread_|, // not usage. base::Lock offscreen_context_for_compositor_thread_creation_lock_; + scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_; scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_; }; diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 1fe517a..4b011ab 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -163,8 +163,11 @@ 'renderer/media/android/proxy_media_keys.h', 'renderer/media/android/renderer_media_player_manager.cc', 'renderer/media/android/renderer_media_player_manager.h', - 'renderer/media/android/stream_texture_factory_android.cc', 'renderer/media/android/stream_texture_factory_android.h', + 'renderer/media/android/stream_texture_factory_android_impl.cc', + 'renderer/media/android/stream_texture_factory_android_impl.h', + 'renderer/media/android/stream_texture_factory_android_synchronous_impl.cc', + 'renderer/media/android/stream_texture_factory_android_synchronous_impl.h', 'renderer/media/android/webmediaplayer_android.cc', 'renderer/media/android/webmediaplayer_android.h', 'renderer/media/android/webmediaplayer_proxy_android.cc', diff --git a/content/renderer/media/android/stream_texture_factory_android.h b/content/renderer/media/android/stream_texture_factory_android.h index f496348..d41d857 100644 --- a/content/renderer/media/android/stream_texture_factory_android.h +++ b/content/renderer/media/android/stream_texture_factory_android.h @@ -7,51 +7,33 @@ #include "base/memory/scoped_ptr.h" #include "cc/layers/video_frame_provider.h" -#include "content/renderer/gpu/stream_texture_host_android.h" #include "gpu/command_buffer/common/mailbox.h" - -namespace WebKit { -class WebGraphicsContext3D; -} +#include "ui/gfx/size.h" namespace content { // The proxy class for the gpu thread to notify the compositor thread // when a new video frame is available. -class StreamTextureProxy : public StreamTextureHost::Listener { +class StreamTextureProxy { public: - explicit StreamTextureProxy(StreamTextureHost* host); - virtual ~StreamTextureProxy(); + virtual ~StreamTextureProxy() {} // Initialize and bind to the current thread, which becomes the thread that // a connected client will receive callbacks on. - void BindToCurrentThread(int32 stream_id); + virtual void BindToCurrentThread(int32 stream_id) = 0; - bool IsBoundToThread() { return loop_.get() != NULL; } + virtual bool IsBoundToThread() = 0; // Setting the target for callback when a frame is available. This function // could be called on both the main thread and the compositor thread. - void SetClient(cc::VideoFrameProvider::Client* client); + virtual void SetClient(cc::VideoFrameProvider::Client* client) = 0; - // StreamTextureHost::Listener implementation: - virtual void OnFrameAvailable() OVERRIDE; - virtual void OnMatrixChanged(const float matrix[16]) OVERRIDE; + // Causes this instance to be deleted on the thread it is bound to. + virtual void Release() = 0; struct Deleter { inline void operator()(StreamTextureProxy* ptr) const { ptr->Release(); } }; - - private: - // Causes this instance to be deleted on the thread it is bound to. - void Release(); - - scoped_ptr<StreamTextureHost> host_; - scoped_refptr<base::MessageLoopProxy> loop_; - - base::Lock client_lock_; - cc::VideoFrameProvider::Client* client_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxy); }; typedef scoped_ptr<StreamTextureProxy, StreamTextureProxy::Deleter> @@ -60,43 +42,34 @@ typedef scoped_ptr<StreamTextureProxy, StreamTextureProxy::Deleter> // Factory class for managing stream textures. class StreamTextureFactory { public: - StreamTextureFactory(WebKit::WebGraphicsContext3D* context, - GpuChannelHost* channel, - int view_id); - ~StreamTextureFactory(); + virtual ~StreamTextureFactory() {} // Create the StreamTextureProxy object. - StreamTextureProxy* CreateProxy(); + virtual StreamTextureProxy* CreateProxy() = 0; // Send an IPC message to the browser process to request a java surface // object for the given stream_id. After the the surface is created, // it will be passed back to the WebMediaPlayerAndroid object identified by // the player_id. - void EstablishPeer(int32 stream_id, int player_id); + virtual void EstablishPeer(int32 stream_id, int player_id) = 0; // Create the streamTexture and return the stream Id and create a client-side // texture id to refer to the streamTexture. The texture id is produced into // a mailbox so it can be used to ship in a VideoFrame, with a sync point for // when the mailbox can be accessed. - unsigned CreateStreamTexture( + virtual unsigned CreateStreamTexture( unsigned texture_target, unsigned* texture_id, gpu::Mailbox* texture_mailbox, - unsigned* texture_mailbox_sync_point); + unsigned* texture_mailbox_sync_point) = 0; // Destroy the streamTexture for the given texture id, as well as the // client side texture. - void DestroyStreamTexture(unsigned texture_id); + virtual void DestroyStreamTexture(unsigned texture_id) = 0; // Set the streamTexture size for the given stream Id. - void SetStreamTextureSize(int32 texture_id, const gfx::Size& size); - - private: - WebKit::WebGraphicsContext3D* context_; - scoped_refptr<GpuChannelHost> channel_; - int view_id_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureFactory); + virtual void SetStreamTextureSize(int32 texture_id, + const gfx::Size& size) = 0; }; } // namespace content diff --git a/content/renderer/media/android/stream_texture_factory_android.cc b/content/renderer/media/android/stream_texture_factory_android_impl.cc index a2e2c5f..721b680 100644 --- a/content/renderer/media/android/stream_texture_factory_android.cc +++ b/content/renderer/media/android/stream_texture_factory_android_impl.cc @@ -2,23 +2,52 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/media/android/stream_texture_factory_android.h" +#include "content/renderer/media/android/stream_texture_factory_android_impl.h" #include "content/common/gpu/client/gpu_channel_host.h" #include "content/common/gpu/gpu_messages.h" +#include "content/renderer/gpu/stream_texture_host_android.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "ui/gfx/size.h" namespace content { -StreamTextureProxy::StreamTextureProxy(StreamTextureHost* host) +namespace { + +class StreamTextureProxyImpl : public StreamTextureProxy, + public StreamTextureHost::Listener { + public: + explicit StreamTextureProxyImpl(StreamTextureHost* host); + virtual ~StreamTextureProxyImpl(); + + // StreamTextureProxy implementation: + virtual void BindToCurrentThread(int32 stream_id) OVERRIDE; + virtual bool IsBoundToThread() OVERRIDE { return loop_.get() != NULL; } + virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE; + virtual void Release() OVERRIDE; + + // StreamTextureHost::Listener implementation: + virtual void OnFrameAvailable() OVERRIDE; + virtual void OnMatrixChanged(const float matrix[16]) OVERRIDE; + + private: + scoped_ptr<StreamTextureHost> host_; + scoped_refptr<base::MessageLoopProxy> loop_; + + base::Lock client_lock_; + cc::VideoFrameProvider::Client* client_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl); +}; + +StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host) : host_(host), client_(NULL) { host->SetListener(this); } -StreamTextureProxy::~StreamTextureProxy() {} +StreamTextureProxyImpl::~StreamTextureProxyImpl() {} -void StreamTextureProxy::Release() { +void StreamTextureProxyImpl::Release() { SetClient(NULL); if (loop_.get() && loop_.get() != base::MessageLoopProxy::current()) loop_->DeleteSoon(FROM_HERE, this); @@ -26,29 +55,31 @@ void StreamTextureProxy::Release() { delete this; } -void StreamTextureProxy::SetClient(cc::VideoFrameProvider::Client* client) { +void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) { base::AutoLock lock(client_lock_); client_ = client; } -void StreamTextureProxy::BindToCurrentThread(int stream_id) { +void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) { loop_ = base::MessageLoopProxy::current(); host_->Initialize(stream_id); } -void StreamTextureProxy::OnFrameAvailable() { +void StreamTextureProxyImpl::OnFrameAvailable() { base::AutoLock lock(client_lock_); if (client_) client_->DidReceiveFrame(); } -void StreamTextureProxy::OnMatrixChanged(const float matrix[16]) { +void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) { base::AutoLock lock(client_lock_); if (client_) client_->DidUpdateMatrix(matrix); } -StreamTextureFactory::StreamTextureFactory( +} // namespace + +StreamTextureFactoryImpl::StreamTextureFactoryImpl( WebKit::WebGraphicsContext3D* context, GpuChannelHost* channel, int view_id) @@ -57,21 +88,21 @@ StreamTextureFactory::StreamTextureFactory( DCHECK(channel); } -StreamTextureFactory::~StreamTextureFactory() {} +StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {} -StreamTextureProxy* StreamTextureFactory::CreateProxy() { +StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() { DCHECK(channel_.get()); StreamTextureHost* host = new StreamTextureHost(channel_.get()); - return new StreamTextureProxy(host); + return new StreamTextureProxyImpl(host); } -void StreamTextureFactory::EstablishPeer(int32 stream_id, int player_id) { +void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id, int player_id) { DCHECK(channel_.get()); channel_->Send( new GpuChannelMsg_EstablishStreamTexture(stream_id, view_id_, player_id)); } -unsigned StreamTextureFactory::CreateStreamTexture( +unsigned StreamTextureFactoryImpl::CreateStreamTexture( unsigned texture_target, unsigned* texture_id, gpu::Mailbox* texture_mailbox, @@ -91,7 +122,7 @@ unsigned StreamTextureFactory::CreateStreamTexture( return stream_id; } -void StreamTextureFactory::DestroyStreamTexture(unsigned texture_id) { +void StreamTextureFactoryImpl::DestroyStreamTexture(unsigned texture_id) { if (context_->makeContextCurrent()) { // TODO(sievers): Make the destroyStreamTexture implicit when the last // texture referencing it is lost. @@ -101,7 +132,7 @@ void StreamTextureFactory::DestroyStreamTexture(unsigned texture_id) { } } -void StreamTextureFactory::SetStreamTextureSize( +void StreamTextureFactoryImpl::SetStreamTextureSize( int32 stream_id, const gfx::Size& size) { channel_->Send(new GpuChannelMsg_SetStreamTextureSize(stream_id, size)); } diff --git a/content/renderer/media/android/stream_texture_factory_android_impl.h b/content/renderer/media/android/stream_texture_factory_android_impl.h new file mode 100644 index 0000000..20aacdd --- /dev/null +++ b/content/renderer/media/android/stream_texture_factory_android_impl.h @@ -0,0 +1,47 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_IMPL_H_ + +#include "content/renderer/media/android/stream_texture_factory_android.h" + +namespace WebKit { +class WebGraphicsContext3D; +} + +namespace content { + +class GpuChannelHost; + +class StreamTextureFactoryImpl : public StreamTextureFactory { + public: + StreamTextureFactoryImpl(WebKit::WebGraphicsContext3D* context, + GpuChannelHost* channel, + int view_id); + virtual ~StreamTextureFactoryImpl(); + + // StreamTextureFactory implementation. + virtual StreamTextureProxy* CreateProxy() OVERRIDE; + virtual void EstablishPeer(int32 stream_id, int player_id) OVERRIDE; + virtual unsigned CreateStreamTexture( + unsigned texture_target, + unsigned* texture_id, + gpu::Mailbox* texture_mailbox, + unsigned* texture_mailbox_sync_point) OVERRIDE; + virtual void DestroyStreamTexture(unsigned texture_id) OVERRIDE; + virtual void SetStreamTextureSize(int32 texture_id, + const gfx::Size& size) OVERRIDE; + + private: + WebKit::WebGraphicsContext3D* context_; + scoped_refptr<GpuChannelHost> channel_; + int view_id_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureFactoryImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_IMPL_H_ diff --git a/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc new file mode 100644 index 0000000..88878d5 --- /dev/null +++ b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc @@ -0,0 +1,34 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h" + +namespace content { + +StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl() {} +StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {} + +StreamTextureProxy* StreamTextureFactorySynchronousImpl::CreateProxy() { + return NULL; +} + +void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id, + int player_id) {} + +unsigned StreamTextureFactorySynchronousImpl::CreateStreamTexture( + unsigned texture_target, + unsigned* texture_id, + gpu::Mailbox* texture_mailbox, + unsigned* texture_mailbox_sync_point) { + return 0; +} + +void StreamTextureFactorySynchronousImpl::DestroyStreamTexture( + unsigned texture_id) {} + +void StreamTextureFactorySynchronousImpl::SetStreamTextureSize( + int32 texture_id, + const gfx::Size& size) {} + +} // namespace content diff --git a/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h new file mode 100644 index 0000000..52fc65a --- /dev/null +++ b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h @@ -0,0 +1,35 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_SYNCHRONOUS_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_SYNCHRONOUS_IMPL_H_ + +#include "content/renderer/media/android/stream_texture_factory_android.h" + +namespace content { + +// Factory for when using synchronous compositor in Android WebView. +class StreamTextureFactorySynchronousImpl : public StreamTextureFactory { + public: + StreamTextureFactorySynchronousImpl(); + virtual ~StreamTextureFactorySynchronousImpl(); + + virtual StreamTextureProxy* CreateProxy() OVERRIDE; + virtual void EstablishPeer(int32 stream_id, int player_id) OVERRIDE; + virtual unsigned CreateStreamTexture( + unsigned texture_target, + unsigned* texture_id, + gpu::Mailbox* texture_mailbox, + unsigned* texture_mailbox_sync_point) OVERRIDE; + virtual void DestroyStreamTexture(unsigned texture_id) OVERRIDE; + virtual void SetStreamTextureSize(int32 texture_id, + const gfx::Size& size) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(StreamTextureFactorySynchronousImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_SYNCHRONOUS_IMPL_H_ diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 5299bdd..f88b2b2 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -218,7 +218,8 @@ #include "content/renderer/android/email_detector.h" #include "content/renderer/android/phone_number_detector.h" #include "content/renderer/media/android/renderer_media_player_manager.h" -#include "content/renderer/media/android/stream_texture_factory_android.h" +#include "content/renderer/media/android/stream_texture_factory_android_impl.h" +#include "content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h" #include "content/renderer/media/android/webmediaplayer_android.h" #include "content/renderer/media/android/webmediaplayer_proxy_android.h" #include "skia/ext/platform_canvas.h" @@ -3022,6 +3023,15 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer( media_player_proxy_ = new WebMediaPlayerProxyAndroid( this, media_player_manager_.get()); } + + scoped_ptr<StreamTextureFactory> stream_texture_factory; + if (UsingSynchronousRendererCompositor()) { + stream_texture_factory.reset(new StreamTextureFactorySynchronousImpl); + } else { + stream_texture_factory.reset(new StreamTextureFactoryImpl( + context_provider->Context3d(), gpu_channel_host, routing_id_)); + } + scoped_ptr<WebMediaPlayerAndroid> web_media_player_android( new WebMediaPlayerAndroid( frame, @@ -3029,8 +3039,7 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer( AsWeakPtr(), media_player_manager_.get(), media_player_proxy_, - new StreamTextureFactory( - context_provider->Context3d(), gpu_channel_host, routing_id_), + stream_texture_factory.release(), new RenderMediaLog())); #if defined(ENABLE_WEBRTC) && defined(GOOGLE_TV) if (media_stream_client_->IsMediaStream(url)) { |