diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-01 18:18:21 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-01 18:18:21 +0000 |
commit | 86f557dfc7f23c5044cdf9dca214836562be8a27 (patch) | |
tree | 1f889037b2133857d2dd60275f60c000a3678ea4 /android_webview | |
parent | 3184f90bff4653bfb7a90ec4a1398559c4668247 (diff) | |
download | chromium_src-86f557dfc7f23c5044cdf9dca214836562be8a27.zip chromium_src-86f557dfc7f23c5044cdf9dca214836562be8a27.tar.gz chromium_src-86f557dfc7f23c5044cdf9dca214836562be8a27.tar.bz2 |
Introduce SynchronousCompositor + Client
Makes a direct API from aw/browser into the content/renderer
compositor (for use in single process only).
Plumb through the webview SW draw path as first step to removing
the synchronous IPC path.
BUG=230226
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/14445008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197660 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
11 files changed, 234 insertions, 50 deletions
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp index 52c84ad..5ed9151 100644 --- a/android_webview/android_webview.gyp +++ b/android_webview/android_webview.gyp @@ -131,6 +131,10 @@ 'browser/gpu_memory_buffer_factory_impl.h', 'browser/gpu_memory_buffer_impl.cc', 'browser/gpu_memory_buffer_impl.h', + 'browser/in_process_renderer/in_process_renderer_client.cc', + 'browser/in_process_renderer/in_process_renderer_client.h', + 'browser/in_process_renderer/in_process_view_renderer.cc', + 'browser/in_process_renderer/in_process_view_renderer.h', 'browser/icon_helper.cc', 'browser/icon_helper.h', 'browser/input_stream.h', diff --git a/android_webview/browser/browser_view_renderer_impl.cc b/android_webview/browser/browser_view_renderer_impl.cc index 67612ac..94a59e1 100644 --- a/android_webview/browser/browser_view_renderer_impl.cc +++ b/android_webview/browser/browser_view_renderer_impl.cc @@ -6,15 +6,19 @@ #include <android/bitmap.h> +#include "android_webview/browser/in_process_renderer/in_process_view_renderer.h" +#include "android_webview/common/aw_switches.h" #include "android_webview/common/renderer_picture_map.h" #include "android_webview/public/browser/draw_gl.h" #include "android_webview/public/browser/draw_sw.h" #include "base/android/jni_android.h" +#include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/logging.h" #include "cc/layers/layer.h" #include "content/public/browser/android/content_view_core.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -117,6 +121,11 @@ class BrowserViewRendererImpl::UserData : public content::WebContents::Data { BrowserViewRendererImpl* BrowserViewRendererImpl::Create( BrowserViewRenderer::Client* client, JavaHelper* java_helper) { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMergeUIAndRendererCompositorThreads)) { + return new InProcessViewRenderer(client, java_helper); + } + return new BrowserViewRendererImpl(client, java_helper); } @@ -126,6 +135,15 @@ BrowserViewRendererImpl* BrowserViewRendererImpl::FromWebContents( return UserData::GetInstance(contents); } +// static +BrowserViewRendererImpl* BrowserViewRendererImpl::FromId(int render_process_id, + int render_view_id) { + const content::RenderViewHost* rvh = + content::RenderViewHost::FromID(render_process_id, render_view_id); + if (!rvh) return NULL; + return FromWebContents(content::WebContents::FromRenderViewHost(rvh)); +} + BrowserViewRendererImpl::BrowserViewRendererImpl( BrowserViewRenderer::Client* client, JavaHelper* java_helper) @@ -164,6 +182,11 @@ BrowserViewRendererImpl::~BrowserViewRendererImpl() { SetContents(NULL); } +void BrowserViewRendererImpl::BindSynchronousCompositor( + content::SynchronousCompositor* compositor) { + NOTREACHED(); // Must be handled by the InProcessViewRenderer +} + // static void BrowserViewRendererImpl::SetAwDrawSWFunctionTable( AwDrawSWFunctionTable* table) { @@ -364,6 +387,8 @@ bool BrowserViewRendererImpl::DrawSW(jobject java_canvas, } ScopedJavaLocalRef<jobject> BrowserViewRendererImpl::CapturePicture() { + // TODO(joth): reimplement this in terms of a call to RenderPicture (vitual + // method) passing in a recordingt canvas, rather than using the picture map. skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); if (!picture || !g_sw_draw_functions) return ScopedJavaLocalRef<jobject>(); diff --git a/android_webview/browser/browser_view_renderer_impl.h b/android_webview/browser/browser_view_renderer_impl.h index d9b0b06..459c7a3 100644 --- a/android_webview/browser/browser_view_renderer_impl.h +++ b/android_webview/browser/browser_view_renderer_impl.h @@ -22,6 +22,7 @@ class SkCanvas; class SkPicture; namespace content { +class SynchronousCompositor; class WebContents; } @@ -40,10 +41,15 @@ class BrowserViewRendererImpl JavaHelper* java_helper); static BrowserViewRendererImpl* FromWebContents( content::WebContents* contents); + static BrowserViewRendererImpl* FromId(int render_process_id, + int render_view_id); static void SetAwDrawSWFunctionTable(AwDrawSWFunctionTable* table); virtual ~BrowserViewRendererImpl(); + virtual void BindSynchronousCompositor( + content::SynchronousCompositor* compositor); + // BrowserViewRenderer implementation. virtual void SetContents( content::ContentViewCore* content_view_core) OVERRIDE; @@ -74,6 +80,8 @@ class BrowserViewRendererImpl BrowserViewRendererImpl(BrowserViewRenderer::Client* client, JavaHelper* java_helper); + virtual bool RenderPicture(SkCanvas* canvas); + private: class UserData; friend class UserData; @@ -88,7 +96,6 @@ class BrowserViewRendererImpl void ResetCompositor(); void Invalidate(); bool RenderSW(SkCanvas* canvas); - bool RenderPicture(SkCanvas* canvas); void OnFrameInfoUpdated(const gfx::SizeF& content_size, const gfx::Vector2dF& scroll_offset, diff --git a/android_webview/browser/in_process_renderer/DEPS b/android_webview/browser/in_process_renderer/DEPS new file mode 100644 index 0000000..51ebf0f --- /dev/null +++ b/android_webview/browser/in_process_renderer/DEPS @@ -0,0 +1,8 @@ +include_rules = [ + # In order to meet synchronous renderer requirements we need to make direct + # calls from android_webview/browser/in_process into some APIs that logically + # live in the renderer side. + "+android_webview/renderer/aw_content_renderer_client.h", + "+content/public/renderer/android", + # Include joth@chromium.org on the review for any additions to this file. +] diff --git a/android_webview/browser/in_process_renderer/in_process_renderer_client.cc b/android_webview/browser/in_process_renderer/in_process_renderer_client.cc new file mode 100644 index 0000000..5f16ae2 --- /dev/null +++ b/android_webview/browser/in_process_renderer/in_process_renderer_client.cc @@ -0,0 +1,55 @@ +// 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 "android_webview/browser/in_process_renderer/in_process_renderer_client.h" + +#include "android_webview/browser/browser_view_renderer_impl.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" + +namespace android_webview { + +namespace { + +int GetInProcessRendererId() { + content::RenderProcessHost::iterator it = + content::RenderProcessHost::AllHostsIterator(); + if (it.IsAtEnd()) { + // There should always be one RPH in single process more. + NOTREACHED(); + return 0; + } + + int id = it.GetCurrentValue()->GetID(); + it.Advance(); + DCHECK(it.IsAtEnd()); // Not multiprocess compatible. + return id; +} + +} + +MessageLoop* InProcessRendererClient::OverrideCompositorMessageLoop() const { + MessageLoop* rv = content::BrowserThread::UnsafeGetMessageLoopForThread( + content::BrowserThread::UI); + DCHECK(rv); + return rv; +} + +void InProcessRendererClient::DidCreateSynchronousCompositor( + int render_view_id, + content::SynchronousCompositor* compositor) { + BrowserViewRendererImpl* view_renderer = + BrowserViewRendererImpl::FromId(GetInProcessRendererId(), render_view_id); + if (view_renderer) + view_renderer->BindSynchronousCompositor(compositor); +} + +bool InProcessRendererClient::ShouldCreateCompositorInputHandler() const { + // Compositor input handling will be performed by the renderer host + // when UI and compositor threads are merged, so we disable client compositor + // input handling in this case. + return false; +} + +} // namespace android_webview diff --git a/android_webview/browser/in_process_renderer/in_process_renderer_client.h b/android_webview/browser/in_process_renderer/in_process_renderer_client.h new file mode 100644 index 0000000..3c597d5 --- /dev/null +++ b/android_webview/browser/in_process_renderer/in_process_renderer_client.h @@ -0,0 +1,27 @@ +// Copyright (c) 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 ANDROID_WEBVIEW_COMMON_IN_PROCESS_RENDERER_CLIENT_ +#define ANDROID_WEBVIEW_COMMON_IN_PROCESS_RENDERER_CLIENT_ + +#include "android_webview/renderer/aw_content_renderer_client.h" + +namespace android_webview { + +// Specialization of the Renderer client used in single process mode, to +// route various factory-like methods to browser/ side code (in general, +// this is only needed / allowed in order to meet synchronous rendering +// requirements). +class InProcessRendererClient : public AwContentRendererClient { + public: + virtual base::MessageLoop* OverrideCompositorMessageLoop() const OVERRIDE; + virtual void DidCreateSynchronousCompositor( + int render_view_id, + content::SynchronousCompositor* compositor) OVERRIDE; + virtual bool ShouldCreateCompositorInputHandler() const OVERRIDE; +}; + +} // android_webview + +#endif // ANDROID_WEBVIEW_COMMON_IN_PROCESS_RENDERER_CLIENT_ diff --git a/android_webview/browser/in_process_renderer/in_process_view_renderer.cc b/android_webview/browser/in_process_renderer/in_process_view_renderer.cc new file mode 100644 index 0000000..63ac223 --- /dev/null +++ b/android_webview/browser/in_process_renderer/in_process_view_renderer.cc @@ -0,0 +1,45 @@ +// Copyright (c) 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 "android_webview/browser/in_process_renderer/in_process_view_renderer.h" + +#include "base/logging.h" +#include "content/public/renderer/android/synchronous_compositor.h" + +namespace android_webview { + +InProcessViewRenderer::InProcessViewRenderer( + BrowserViewRenderer::Client* client, + JavaHelper* java_helper) + : BrowserViewRendererImpl(client, java_helper), + compositor_(NULL) { +} + +InProcessViewRenderer::~InProcessViewRenderer() { + if (compositor_) + compositor_->SetClient(NULL); +} + +void InProcessViewRenderer::BindSynchronousCompositor( + content::SynchronousCompositor* compositor) { + DCHECK(compositor && compositor_ != compositor); + if (compositor_) + compositor_->SetClient(NULL); + compositor_ = compositor; + compositor_->SetClient(this); +} + +bool InProcessViewRenderer::RenderPicture(SkCanvas* canvas) { + return compositor_ && compositor_->DemandDrawSw(canvas); +} + +void InProcessViewRenderer::DidDestroyCompositor( + content::SynchronousCompositor* compositor) { + // Allow for transient hand-over when two compositors may reference + // a single client. + if (compositor_ == compositor) + compositor_ = NULL; +} + +} // namespace android_webview diff --git a/android_webview/browser/in_process_renderer/in_process_view_renderer.h b/android_webview/browser/in_process_renderer/in_process_view_renderer.h new file mode 100644 index 0000000..d2c0c24 --- /dev/null +++ b/android_webview/browser/in_process_renderer/in_process_view_renderer.h @@ -0,0 +1,44 @@ +// Copyright (c) 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 ANDROID_WEBVIEW_BROWSER_IN_PROCESS_IN_PROCESS_VIEW_RENDERER_H_ +#define ANDROID_WEBVIEW_BROWSER_IN_PROCESS_IN_PROCESS_VIEW_RENDERER_H_ + +#include "android_webview/browser/browser_view_renderer_impl.h" + +#include "content/public/renderer/android/synchronous_compositor_client.h" + +namespace content { +class SynchronousCompositor; +} + +namespace android_webview { + +// Provides RenderViewHost wrapper functionality for sending WebView-specific +// IPC messages to the renderer and from there to WebKit. +class InProcessViewRenderer : public BrowserViewRendererImpl, + public content::SynchronousCompositorClient { + public: + InProcessViewRenderer(BrowserViewRenderer::Client* client, + JavaHelper* java_helper); + virtual ~InProcessViewRenderer(); + + // BrowserViewRenderer overrides + virtual void BindSynchronousCompositor( + content::SynchronousCompositor* compositor) OVERRIDE; + virtual bool RenderPicture(SkCanvas* canvas) OVERRIDE; + + // SynchronousCompositorClient overrides + virtual void DidDestroyCompositor( + content::SynchronousCompositor* compositor) OVERRIDE; + + private: + content::SynchronousCompositor* compositor_; + + DISALLOW_COPY_AND_ASSIGN(InProcessViewRenderer); +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_BROWSER_IN_PROCESS_IN_PROCESS_VIEW_RENDERER_H_ diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc index 45207ae..be63a82 100644 --- a/android_webview/lib/main/aw_main_delegate.cc +++ b/android_webview/lib/main/aw_main_delegate.cc @@ -5,6 +5,7 @@ #include "android_webview/lib/main/aw_main_delegate.h" #include "android_webview/browser/aw_content_browser_client.h" +#include "android_webview/browser/in_process_renderer/in_process_renderer_client.h" #include "android_webview/common/aw_switches.h" #include "android_webview/lib/aw_browser_dependency_factory_impl.h" #include "android_webview/native/aw_geolocation_permission_context.h" @@ -29,9 +30,13 @@ AwMainDelegate::~AwMainDelegate() { bool AwMainDelegate::BasicStartupComplete(int* exit_code) { content::SetContentClient(&content_client_); - CommandLine* command_line = CommandLine::ForCurrentProcess(); + CommandLine* cl = CommandLine::ForCurrentProcess(); // Set the command line to enable synchronous API compatibility. - command_line->AppendSwitch(switches::kEnableWebViewSynchronousAPIs); + if (cl->HasSwitch(switches::kMergeUIAndRendererCompositorThreads)) { + cl->AppendSwitch(switches::kEnableSynchronousRendererCompositor); + } else { + cl->AppendSwitch(switches::kEnableWebViewSynchronousAPIs); + } return false; } @@ -75,33 +80,18 @@ content::ContentBrowserClient* return content_browser_client_.get(); } -namespace { -bool UIAndRendererCompositorThreadsMerged() { - return CommandLine::ForCurrentProcess()->HasSwitch( - switches::kMergeUIAndRendererCompositorThreads); -} - -MessageLoop* GetRendererCompositorThreadOverrideLoop() { - if (!UIAndRendererCompositorThreadsMerged()) - return NULL; - - base::MessageLoop* rv = content::BrowserThread::UnsafeGetMessageLoopForThread( - content::BrowserThread::UI); - DCHECK(rv); - return rv; -} -} - content::ContentRendererClient* AwMainDelegate::CreateContentRendererClient() { - // Compositor input handling will be performed by the renderer host - // when UI and compositor threads are merged, so we disable client compositor - // input handling in this case. - const bool enable_client_compositor_input_handling = - !UIAndRendererCompositorThreadsMerged(); + // None of this makes sense for multiprocess. + DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)); + // During transition period allow running in either threading mode; eventually + // only the compositor/UI thread merge mode will be supported. + const bool merge_threads = + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMergeUIAndRendererCompositorThreads); content_renderer_client_.reset( - new AwContentRendererClient(&GetRendererCompositorThreadOverrideLoop, - enable_client_compositor_input_handling)); + merge_threads ? new InProcessRendererClient() : + new AwContentRendererClient()); return content_renderer_client_.get(); } diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc index 9429c96..3d4790f 100644 --- a/android_webview/renderer/aw_content_renderer_client.cc +++ b/android_webview/renderer/aw_content_renderer_client.cc @@ -21,12 +21,7 @@ namespace android_webview { -AwContentRendererClient::AwContentRendererClient( - CompositorMessageLoopGetter* compositor_message_loop_getter, - bool should_create_compositor_input_handler) - : compositor_message_loop_getter_(compositor_message_loop_getter), - should_create_compositor_input_handler_( - should_create_compositor_input_handler) { +AwContentRendererClient::AwContentRendererClient() { } AwContentRendererClient::~AwContentRendererClient() { @@ -100,12 +95,4 @@ void AwContentRendererClient::PrefetchHostName(const char* hostname, // Perhaps componentize chrome implementation or move to content/? } -MessageLoop* AwContentRendererClient::OverrideCompositorMessageLoop() const { - return (*compositor_message_loop_getter_)(); -} - -bool AwContentRendererClient::ShouldCreateCompositorInputHandler() const { - return should_create_compositor_input_handler_; -} - } // namespace android_webview diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h index bcec659..1249c22 100644 --- a/android_webview/renderer/aw_content_renderer_client.h +++ b/android_webview/renderer/aw_content_renderer_client.h @@ -18,11 +18,7 @@ namespace android_webview { class AwContentRendererClient : public content::ContentRendererClient { public: - typedef base::MessageLoop* CompositorMessageLoopGetter(); - - explicit AwContentRendererClient( - CompositorMessageLoopGetter* compositor_message_loop_getter, - bool should_create_compositor_input_handler); + AwContentRendererClient(); virtual ~AwContentRendererClient(); // ContentRendererClient implementation. @@ -41,14 +37,10 @@ class AwContentRendererClient : public content::ContentRendererClient { size_t length) OVERRIDE; virtual bool IsLinkVisited(unsigned long long link_hash) OVERRIDE; virtual void PrefetchHostName(const char* hostname, size_t length) OVERRIDE; - virtual base::MessageLoop* OverrideCompositorMessageLoop() const OVERRIDE; - virtual bool ShouldCreateCompositorInputHandler() const OVERRIDE; private: scoped_ptr<AwRenderProcessObserver> aw_render_process_observer_; scoped_ptr<components::VisitedLinkSlave> visited_link_slave_; - CompositorMessageLoopGetter* compositor_message_loop_getter_; - bool should_create_compositor_input_handler_; }; } // namespace android_webview |