diff options
author | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 23:49:32 +0000 |
---|---|---|
committer | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 23:49:32 +0000 |
commit | d32353fec987fdbecaeb6695966c75f9a900ce92 (patch) | |
tree | 1d79c0e81a5a0c05957fe398bc9d58ff74e45460 /content | |
parent | b7885fbd50a725f0ed690d0b45e2e74a0f34e4eb (diff) | |
download | chromium_src-d32353fec987fdbecaeb6695966c75f9a900ce92.zip chromium_src-d32353fec987fdbecaeb6695966c75f9a900ce92.tar.gz chromium_src-d32353fec987fdbecaeb6695966c75f9a900ce92.tar.bz2 |
Android: SurfaceTexture-based image transport
This is an interim solution for where the embedder cannot use a command buffer context running on the gpu thread for frontend rendering (i.e. for the browser compositor), for example draw functor/callback based UI drawing.
On Android, sharing GL resources across threads is not a given and SurfaceTexture is therefore the only compatible option.
TBR=jam@chromium.org for .gyp change
BUG=161409
Review URL: https://codereview.chromium.org/11343058
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168332 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
10 files changed, 388 insertions, 72 deletions
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index bed4799..442e752 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -23,8 +23,11 @@ #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurface.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebSolidColorLayer.h" #include "ui/gfx/android/java_bitmap.h" #include "webkit/compositor_bindings/web_compositor_support_impl.h" +#include "webkit/glue/webthread_impl.h" +#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h" using webkit::WebCompositorSupportImpl; @@ -37,6 +40,8 @@ namespace { static bool g_initialized = false; static base::LazyInstance<WebCompositorSupportImpl> g_compositor_support = LAZY_INSTANCE_INITIALIZER; +static WebKit::WebThread* g_impl_thread = NULL; +static bool g_use_direct_gl = false; // Adapts a pure WebGraphicsContext3D into a WebCompositorOutputSurface. class WebGraphicsContextToOutputSurfaceAdapter : @@ -91,11 +96,20 @@ Compositor* Compositor::Create(Client* client) { // static void Compositor::Initialize() { - g_compositor_support.Get().initialize(NULL); + DCHECK(!CompositorImpl::IsInitialized()); + g_compositor_support.Get().initialize(g_impl_thread); g_initialized = true; } // static +void Compositor::InitializeWithFlags(uint32 flags) { + g_use_direct_gl = flags & DIRECT_CONTEXT_ON_DRAW_THREAD; + if (flags & ENABLE_COMPOSITOR_THREAD) + g_impl_thread = new webkit_glue::WebThreadImpl("Browser Compositor"); + Compositor::Initialize(); +} + +// static WebCompositorSupportImpl* CompositorImpl::CompositorSupport() { DCHECK(g_initialized); return g_compositor_support.Pointer(); @@ -106,6 +120,11 @@ bool CompositorImpl::IsInitialized() { return g_initialized; } +// static +bool CompositorImpl::UsesDirectGL() { + return g_use_direct_gl; +} + CompositorImpl::CompositorImpl(Compositor::Client* client) : window_(NULL), surface_id_(0), @@ -135,7 +154,7 @@ void CompositorImpl::SetWindowSurface(ANativeWindow* window) { ANativeWindow_release(window_); window_ = NULL; surface_id_ = 0; - host_.reset(); + SetVisible(false); } if (window) { @@ -145,8 +164,14 @@ void CompositorImpl::SetWindowSurface(ANativeWindow* window) { tracker->SetSurfaceHandle( surface_id_, gfx::GLSurfaceHandle(gfx::kDummyPluginWindow, false)); + SetVisible(true); + } +} - DCHECK(!host_.get()); +void CompositorImpl::SetVisible(bool visible) { + if (!visible) { + host_.reset(); + } else if (!host_.get()) { WebKit::WebLayerTreeView::Settings settings; settings.refreshRate = 60.0; host_.reset(g_compositor_support.Get().createLayerTreeView( @@ -243,28 +268,38 @@ void CompositorImpl::applyScrollAndScale(const WebKit::WebSize& scrollDelta, } WebKit::WebCompositorOutputSurface* CompositorImpl::createOutputSurface() { - DCHECK(window_ && surface_id_); - WebKit::WebGraphicsContext3D::Attributes attrs; - attrs.shareResources = true; - attrs.noAutomaticFlushes = true; - GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance(); - GURL url("chrome://gpu/Compositor::createContext3D"); - base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; - scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( - new WebGraphicsContext3DCommandBufferImpl( - surface_id_, - url, - factory, - swap_client)); - if (!context->Initialize( - attrs, - false, - CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) { - LOG(ERROR) << "Failed to create 3D context for compositor."; - return NULL; + if (g_use_direct_gl) { + WebKit::WebGraphicsContext3D::Attributes attrs; + attrs.shareResources = false; + attrs.noAutomaticFlushes = true; + scoped_ptr<webkit::gpu::WebGraphicsContext3DInProcessImpl> context( + webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow( + attrs, + window_, + NULL)); + return new WebGraphicsContextToOutputSurfaceAdapter(context.release()); + } else { + DCHECK(window_ && surface_id_); + WebKit::WebGraphicsContext3D::Attributes attrs; + attrs.shareResources = true; + attrs.noAutomaticFlushes = true; + GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance(); + GURL url("chrome://gpu/Compositor::createContext3D"); + base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; + scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( + new WebGraphicsContext3DCommandBufferImpl(surface_id_, + url, + factory, + swap_client)); + if (!context->Initialize( + attrs, + false, + CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) { + LOG(ERROR) << "Failed to create 3D context for compositor."; + return NULL; + } + return new WebGraphicsContextToOutputSurfaceAdapter(context.release()); } - - return new WebGraphicsContextToOutputSurfaceAdapter(context.release()); } void CompositorImpl::didRecreateOutputSurface(bool success) { diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 379145a..eebc6d1 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h @@ -35,9 +35,13 @@ class CONTENT_EXPORT CompositorImpl : public Compositor, static webkit::WebCompositorSupportImpl* CompositorSupport(); static bool IsInitialized(); + // Returns true if initialized with DIRECT_CONTEXT_ON_DRAW_THREAD. + static bool UsesDirectGL(); + // Compositor implementation. virtual void SetRootLayer(WebKit::WebLayer* root) OVERRIDE; virtual void SetWindowSurface(ANativeWindow* window) OVERRIDE; + virtual void SetVisible(bool visible) OVERRIDE; virtual void SetWindowBounds(const gfx::Size& size) OVERRIDE; virtual bool CompositeAndReadback( void *pixels, const gfx::Rect& rect) OVERRIDE; diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc index deef500..a2b8f10 100644 --- a/content/browser/renderer_host/image_transport_factory_android.cc +++ b/content/browser/renderer_host/image_transport_factory_android.cc @@ -6,40 +6,97 @@ #include "base/memory/singleton.h" #include "content/browser/gpu/browser_gpu_channel_host_factory.h" +#include "content/browser/renderer_host/compositor_impl_android.h" #include "content/common/gpu/gpu_process_launch_causes.h" #include "content/common/gpu/client/gl_helper.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" +#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h" namespace content { -// static -ImageTransportFactoryAndroid* ImageTransportFactoryAndroid::GetInstance() { - return Singleton<ImageTransportFactoryAndroid>::get(); +namespace { + +static ImageTransportFactoryAndroid* g_factory = NULL; + +class DirectGLImageTransportFactory : public ImageTransportFactoryAndroid { + public: + DirectGLImageTransportFactory(); + virtual ~DirectGLImageTransportFactory(); + + virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE { + return gfx::GLSurfaceHandle(); + } + virtual void DestroySharedSurfaceHandle( + const gfx::GLSurfaceHandle& handle) OVERRIDE {} + virtual uint32_t InsertSyncPoint() OVERRIDE { return 0; } + virtual WebKit::WebGraphicsContext3D* GetContext3D() OVERRIDE { + return context_.get(); + } + virtual GLHelper* GetGLHelper() OVERRIDE { return NULL; } + + private: + scoped_ptr<webkit::gpu::WebGraphicsContext3DInProcessImpl> context_; + + DISALLOW_COPY_AND_ASSIGN(DirectGLImageTransportFactory); +}; + +DirectGLImageTransportFactory::DirectGLImageTransportFactory() { + WebKit::WebGraphicsContext3D::Attributes attrs; + attrs.shareResources = false; + attrs.noAutomaticFlushes = true; + context_.reset( + webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow( + attrs, + NULL, + NULL)); } -ImageTransportFactoryAndroid::ImageTransportFactoryAndroid() { +DirectGLImageTransportFactory::~DirectGLImageTransportFactory() { +} + +class CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid { + public: + CmdBufferImageTransportFactory(); + virtual ~CmdBufferImageTransportFactory(); + + virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE; + virtual void DestroySharedSurfaceHandle( + const gfx::GLSurfaceHandle& handle) OVERRIDE; + virtual uint32_t InsertSyncPoint() OVERRIDE; + virtual WebKit::WebGraphicsContext3D* GetContext3D() OVERRIDE { + return context_.get(); + } + virtual GLHelper* GetGLHelper() OVERRIDE; + + private: + scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context_; + scoped_ptr<GLHelper> gl_helper_; + + DISALLOW_COPY_AND_ASSIGN(CmdBufferImageTransportFactory); +}; + +CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() { WebKit::WebGraphicsContext3D::Attributes attrs; attrs.shareResources = true; GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance(); GURL url("chrome://gpu/ImageTransportFactoryAndroid"); base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; - context_.reset( - new WebGraphicsContext3DCommandBufferImpl( - 0, // offscreen - url, - factory, - swap_client)); + context_.reset(new WebGraphicsContext3DCommandBufferImpl(0, // offscreen + url, + factory, + swap_client)); context_->Initialize( attrs, false, CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE); } -ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() { +CmdBufferImageTransportFactory::~CmdBufferImageTransportFactory() { } -gfx::GLSurfaceHandle ImageTransportFactoryAndroid::CreateSharedSurfaceHandle() { +gfx::GLSurfaceHandle +CmdBufferImageTransportFactory::CreateSharedSurfaceHandle() { if (!context_->makeContextCurrent()) { NOTREACHED() << "Failed to make shared graphics context current"; return gfx::GLSurfaceHandle(); @@ -57,7 +114,7 @@ gfx::GLSurfaceHandle ImageTransportFactoryAndroid::CreateSharedSurfaceHandle() { return handle; } -void ImageTransportFactoryAndroid::DestroySharedSurfaceHandle( +void CmdBufferImageTransportFactory::DestroySharedSurfaceHandle( const gfx::GLSurfaceHandle& handle) { if (!context_->makeContextCurrent()) { NOTREACHED() << "Failed to make shared graphics context current"; @@ -69,19 +126,35 @@ void ImageTransportFactoryAndroid::DestroySharedSurfaceHandle( context_->finish(); } -uint32_t ImageTransportFactoryAndroid::InsertSyncPoint() { +uint32_t CmdBufferImageTransportFactory::InsertSyncPoint() { return context_->insertSyncPoint(); } -WebKit::WebGraphicsContext3D* ImageTransportFactoryAndroid::GetContext3D() { - return context_.get(); -} - -GLHelper* ImageTransportFactoryAndroid::GetGLHelper() { +GLHelper* CmdBufferImageTransportFactory::GetGLHelper() { if (!gl_helper_.get()) gl_helper_.reset(new GLHelper(GetContext3D(), NULL)); return gl_helper_.get(); } -} // namespace content +} // anonymous namespace + +// static +ImageTransportFactoryAndroid* ImageTransportFactoryAndroid::GetInstance() { + if (!g_factory) { + if (CompositorImpl::UsesDirectGL()) + g_factory = new DirectGLImageTransportFactory(); + else + g_factory = new CmdBufferImageTransportFactory(); + } + + return g_factory; +} + +ImageTransportFactoryAndroid::ImageTransportFactoryAndroid() { +} + +ImageTransportFactoryAndroid::~ImageTransportFactoryAndroid() { +} + +} // namespace content diff --git a/content/browser/renderer_host/image_transport_factory_android.h b/content/browser/renderer_host/image_transport_factory_android.h index 34d9a58..669d516 100644 --- a/content/browser/renderer_host/image_transport_factory_android.h +++ b/content/browser/renderer_host/image_transport_factory_android.h @@ -8,32 +8,34 @@ #include "base/memory/scoped_ptr.h" #include "ui/gfx/native_widget_types.h" +namespace gfx { +class GLShareGroup; +} + namespace WebKit { - class WebGraphicsContext3D; +class WebGraphicsContext3D; } namespace content { class GLHelper; -class WebGraphicsContext3DCommandBufferImpl; class ImageTransportFactoryAndroid { public: - ImageTransportFactoryAndroid(); - ~ImageTransportFactoryAndroid(); + virtual ~ImageTransportFactoryAndroid(); static ImageTransportFactoryAndroid* GetInstance(); - gfx::GLSurfaceHandle CreateSharedSurfaceHandle(); - void DestroySharedSurfaceHandle(const gfx::GLSurfaceHandle& handle); + virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() = 0; + virtual void DestroySharedSurfaceHandle( + const gfx::GLSurfaceHandle& handle) = 0; - uint32_t InsertSyncPoint(); + virtual uint32_t InsertSyncPoint() = 0; - WebKit::WebGraphicsContext3D* GetContext3D(); - GLHelper* GetGLHelper(); + virtual WebKit::WebGraphicsContext3D* GetContext3D() = 0; + virtual GLHelper* GetGLHelper() = 0; - private: - scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context_; - scoped_ptr<GLHelper> gl_helper_; +protected: + ImageTransportFactoryAndroid(); }; } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index ae2fb837..8b4b59f 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -15,6 +15,7 @@ #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/image_transport_factory_android.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/surface_texture_transport_client_android.h" #include "content/common/android/device_info.h" #include "content/common/gpu/client/gl_helper.h" #include "content/common/gpu/gpu_messages.h" @@ -22,6 +23,7 @@ #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebExternalTextureLayer.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" #include "ui/gfx/android/java_bitmap.h" #include "webkit/compositor_bindings/web_compositor_support_impl.h" @@ -55,16 +57,25 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( content_view_core_(NULL), ime_adapter_android_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), cached_background_color_(SK_ColorWHITE), - texture_layer_(WebKit::WebExternalTextureLayer::create()), texture_id_in_layer_(0) { + if (CompositorImpl::UsesDirectGL()) { + surface_texture_transport_.reset(new SurfaceTextureTransportClient()); + layer_ = surface_texture_transport_->Initialize(); + } else { + // TODO: Cannot use CompositorImpl::CompositorSupport() in unit tests. + texture_layer_.reset(WebKit::WebExternalTextureLayer::create()); + layer_ = texture_layer_->layer(); + } + host_->SetView(this); SetContentViewCore(content_view_core); // RenderWidgetHost is initialized as visible. If is_hidden_ is true, tell // RenderWidgetHost to hide. if (is_hidden_) host_->WasHidden(); - texture_layer_->layer()->setOpaque(true); - texture_layer_->layer()->setDrawsContent(!is_hidden_); + + layer_->setOpaque(true); + layer_->setDrawsContent(!is_hidden_); } RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { @@ -116,6 +127,9 @@ void RenderWidgetHostViewAndroid::WasHidden() { } void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) { + if (surface_texture_transport_.get()) + surface_texture_transport_->SetSize(size); + host_->WasResized(); } @@ -229,13 +243,13 @@ void RenderWidgetHostViewAndroid::Show() { if (content_view_core_) is_hidden_ = false; - texture_layer_->layer()->setDrawsContent(true); + layer_->setDrawsContent(true); } void RenderWidgetHostViewAndroid::Hide() { is_hidden_ = true; - texture_layer_->layer()->setDrawsContent(false); + layer_->setDrawsContent(false); } bool RenderWidgetHostViewAndroid::IsShowing() { @@ -293,7 +307,7 @@ void RenderWidgetHostViewAndroid::RenderViewGone( void RenderWidgetHostViewAndroid::Destroy() { if (content_view_core_) { - content_view_core_->RemoveWebLayer(texture_layer_->layer()); + content_view_core_->RemoveWebLayer(layer_); content_view_core_ = NULL; } @@ -378,7 +392,8 @@ void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped( const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, int gpu_host_id) { texture_layer_->setTextureId(params.surface_handle); - texture_layer_->layer()->setBounds(params.size); + DCHECK(texture_layer_->layer() == layer_); + layer_->setBounds(params.size); texture_id_in_layer_ = params.surface_handle; texture_size_in_layer_ = params.size; @@ -416,11 +431,17 @@ void RenderWidgetHostViewAndroid::StartContentIntent( gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() { if (CompositorImpl::IsInitialized()) { // The app uses the browser-side compositor. - if (shared_surface_.is_null()) - shared_surface_ = - ImageTransportFactoryAndroid::GetInstance()-> - CreateSharedSurfaceHandle(); - return shared_surface_; + if (surface_texture_transport_.get()) { + return surface_texture_transport_->GetCompositingSurface( + host_->surface_id()); + } else { + if (shared_surface_.is_null()) { + shared_surface_ = + ImageTransportFactoryAndroid::GetInstance()-> + CreateSharedSurfaceHandle(); + } + return shared_surface_; + } } // On Android, we cannot generate a window handle that can be passed to the @@ -542,11 +563,11 @@ void RenderWidgetHostViewAndroid::UpdateFrameInfo( void RenderWidgetHostViewAndroid::SetContentViewCore( ContentViewCoreImpl* content_view_core) { if (content_view_core_) - content_view_core_->RemoveWebLayer(texture_layer_->layer()); + content_view_core_->RemoveWebLayer(layer_); content_view_core_ = content_view_core; if (content_view_core_) - content_view_core_->AttachWebLayer(texture_layer_->layer()); + content_view_core_->AttachWebLayer(layer_); } void RenderWidgetHostViewAndroid::HasTouchEventHandlers( diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 0f075cd..44ed407 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -12,7 +12,6 @@ #include "content/browser/renderer_host/ime_adapter_android.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "third_party/skia/include/core/SkColor.h" -#include "third_party/WebKit/Source/Platform/chromium/public/WebExternalTextureLayer.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" #include "ui/gfx/size.h" @@ -22,6 +21,8 @@ struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params; struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params; namespace WebKit { +class WebExternalTextureLayer; +class WebLayer; class WebTouchEvent; class WebMouseEvent; } @@ -30,6 +31,7 @@ namespace content { class ContentViewCoreImpl; class RenderWidgetHost; class RenderWidgetHostImpl; +class SurfaceTextureTransportClient; struct NativeWebKeyboardEvent; // ----------------------------------------------------------------------------- @@ -162,6 +164,11 @@ class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase { // The texture layer for this view when using browser-side compositing. scoped_ptr<WebKit::WebExternalTextureLayer> texture_layer_; + // The layer used for rendering the contents of this view. + // It is either owned by texture_layer_ or surface_texture_transport_ + // depending on the mode. + WebKit::WebLayer* layer_; + // The most recent texture id that was pushed to the texture layer. unsigned int texture_id_in_layer_; @@ -172,6 +179,9 @@ class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase { // compositor) for this view. gfx::GLSurfaceHandle shared_surface_; + // Used for image transport when needing to share resources across threads. + scoped_ptr<SurfaceTextureTransportClient> surface_texture_transport_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAndroid); }; diff --git a/content/browser/renderer_host/surface_texture_transport_client_android.cc b/content/browser/renderer_host/surface_texture_transport_client_android.cc new file mode 100644 index 0000000..685ee4e --- /dev/null +++ b/content/browser/renderer_host/surface_texture_transport_client_android.cc @@ -0,0 +1,100 @@ +// Copyright (c) 2012 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/browser/renderer_host/surface_texture_transport_client_android.h" + +#include <android/native_window_jni.h> + +#include "base/bind.h" +#include "content/browser/gpu/gpu_surface_tracker.h" +#include "content/browser/renderer_host/compositor_impl_android.h" +#include "content/browser/renderer_host/image_transport_factory_android.h" +#include "content/common/android/surface_texture_bridge.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebVideoLayer.h" +#include "webkit/compositor_bindings/web_compositor_support_impl.h" +#include "webkit/media/webvideoframe_impl.h" + +namespace { + +static const uint32 kGLTextureExternalOES = 0x8D65; + +} // anonymous namespace + +namespace content { + +SurfaceTextureTransportClient::SurfaceTextureTransportClient() + : window_(NULL), + texture_id_(0) { +} + +SurfaceTextureTransportClient::~SurfaceTextureTransportClient() { + if (window_) + ANativeWindow_release(window_); +} + +WebKit::WebLayer* SurfaceTextureTransportClient::Initialize() { + // Use a SurfaceTexture to stream frames to the UI thread. + video_layer_.reset( + CompositorImpl::CompositorSupport()->createVideoLayer(this)); + surface_texture_ = new SurfaceTextureBridge(0); + surface_texture_->SetFrameAvailableCallback( + base::Bind( + &SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable, + base::Unretained(this))); + surface_texture_->DetachFromGLContext(); + return video_layer_->layer(); +} + +gfx::GLSurfaceHandle +SurfaceTextureTransportClient::GetCompositingSurface(int surface_id) { + DCHECK(surface_id); + if (!window_) + window_ = surface_texture_->CreateSurface(); + + GpuSurfaceTracker::Get()->SetNativeWidget(surface_id, window_); + return gfx::GLSurfaceHandle(gfx::kDummyPluginWindow, false); +} + +void SurfaceTextureTransportClient::SetSize(const gfx::Size& size) { + surface_texture_->SetDefaultBufferSize(size.width(), size.height()); + video_layer_->layer()->setBounds(size); + video_frame_.reset(); +} + +WebKit::WebVideoFrame* SurfaceTextureTransportClient::getCurrentFrame() { + if (!texture_id_) { + WebKit::WebGraphicsContext3D* context = + ImageTransportFactoryAndroid::GetInstance()->GetContext3D(); + context->makeContextCurrent(); + texture_id_ = context->createTexture(); + } + if (!video_frame_.get()) { + surface_texture_->AttachToGLContext(texture_id_); + const gfx::Size size = video_layer_->layer()->bounds(); + video_frame_.reset( + new webkit_media::WebVideoFrameImpl( + media::VideoFrame::WrapNativeTexture( + texture_id_, kGLTextureExternalOES, + size, + gfx::Rect(gfx::Point(), size), + size, + base::TimeDelta(), + media::VideoFrame::ReadPixelsCB(), + base::Closure()))); + } + surface_texture_->UpdateTexImage(); + + return video_frame_.get(); +} + +void SurfaceTextureTransportClient::putCurrentFrame( + WebKit::WebVideoFrame* frame) { +} + +void SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable() { + video_layer_->layer()->invalidate(); +} + +} // namespace content diff --git a/content/browser/renderer_host/surface_texture_transport_client_android.h b/content/browser/renderer_host/surface_texture_transport_client_android.h new file mode 100644 index 0000000..26e87c5 --- /dev/null +++ b/content/browser/renderer_host/surface_texture_transport_client_android.h @@ -0,0 +1,51 @@ +// Copyright (c) 2012 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_BROWSER_RENDERER_HOST_SURFACE_TEXTURE_TRANSPORT_CLIENT_ANDROID_H_ +#define CONTENT_BROWSER_RENDERER_HOST_SURFACE_TEXTURE_TRANSPORT_CLIENT_ANDROID_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebVideoFrameProvider.h" +#include "ui/gfx/native_widget_types.h" + +struct ANativeWindow; + +namespace WebKit { +class WebLayer; +class WebVideoLayer; +} + +namespace content { +class SurfaceTextureBridge; + +class SurfaceTextureTransportClient : public WebKit::WebVideoFrameProvider { + public: + SurfaceTextureTransportClient(); + virtual ~SurfaceTextureTransportClient(); + + WebKit::WebLayer* Initialize(); + gfx::GLSurfaceHandle GetCompositingSurface(int surface_id); + void SetSize(const gfx::Size& size); + + // WebKit::WebVideoFrameProvider implementation. + virtual void setVideoFrameProviderClient(Client*) OVERRIDE {} + virtual WebKit::WebVideoFrame* getCurrentFrame() OVERRIDE; + virtual void putCurrentFrame(WebKit::WebVideoFrame* frame) OVERRIDE; + + private: + void OnSurfaceTextureFrameAvailable(); + + scoped_ptr<WebKit::WebVideoLayer> video_layer_; + scoped_refptr<SurfaceTextureBridge> surface_texture_; + ANativeWindow* window_; + scoped_ptr<WebKit::WebVideoFrame> video_frame_; + uint32 texture_id_; + + DISALLOW_COPY_AND_ASSIGN(SurfaceTextureTransportClient); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_SURFACE_TEXTURE_TRANSPORT_CLIENT_ANDROID_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index f4d9151..02cad6f 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -723,6 +723,8 @@ 'browser/renderer_host/socket_stream_dispatcher_host.h', 'browser/renderer_host/socket_stream_host.cc', 'browser/renderer_host/socket_stream_host.h', + 'browser/renderer_host/surface_texture_transport_client_android.cc', + 'browser/renderer_host/surface_texture_transport_client_android.h', 'browser/renderer_host/sync_resource_handler.cc', 'browser/renderer_host/sync_resource_handler.h', 'browser/renderer_host/tap_suppression_controller_aura.cc', diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h index 11c1dbd..998c22d 100644 --- a/content/public/browser/android/compositor.h +++ b/content/public/browser/android/compositor.h @@ -38,9 +38,22 @@ class CONTENT_EXPORT Compositor { virtual ~Compositor() {} // Performs the global initialization needed before any compositor - // instance can be used. + // instance can be used. This should be called only once. static void Initialize(); + enum CompositorFlags { + // Creates a direct GL context on the thread that draws + // (i.e. main or impl thread). + DIRECT_CONTEXT_ON_DRAW_THREAD = 1, + + // Runs the compositor in threaded mode. + ENABLE_COMPOSITOR_THREAD = 1 << 1, + }; + + // Initialize with flags. This should only be called once instead + // of Initialize(). + static void InitializeWithFlags(uint32 flags); + // Creates and returns a compositor instance. static Compositor* Create(Client* client); @@ -50,6 +63,11 @@ class CONTENT_EXPORT Compositor { // Set the output surface bounds. virtual void SetWindowBounds(const gfx::Size& size) = 0; + // Sets the window visibility. When becoming invisible, resources will get + // freed and other calls into the compositor are not allowed until after + // having been made visible again. + virtual void SetVisible(bool visible) = 0; + // Set the output surface handle which the compositor renders into. virtual void SetWindowSurface(ANativeWindow* window) = 0; |