diff options
author | leandrogracia@chromium.org <leandrogracia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-04 12:20:24 +0000 |
---|---|---|
committer | leandrogracia@chromium.org <leandrogracia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-04 12:20:24 +0000 |
commit | 11b426f286e9d641c2cbe075e28284ae9d952f94 (patch) | |
tree | 4ba31f147c0bbd919e8cbc8d11b4e9163c5f5924 | |
parent | 942f75aad836a8ae3b154289f5db27b58b5c182c (diff) | |
download | chromium_src-11b426f286e9d641c2cbe075e28284ae9d952f94.zip chromium_src-11b426f286e9d641c2cbe075e28284ae9d952f94.tar.gz chromium_src-11b426f286e9d641c2cbe075e28284ae9d952f94.tar.bz2 |
[Android WebView] Prepare to simulate SW rendering with the capture picture API backend.
Introduce the required code to get SW rendering working once RenderView is able
to provide the required picture piles from the compositor.
BUG=167913
Review URL: https://codereview.chromium.org/11727005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175135 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | android_webview/DEPS | 1 | ||||
-rw-r--r-- | android_webview/android_webview.gyp | 3 | ||||
-rw-r--r-- | android_webview/browser/renderer_host/aw_render_view_host_ext.cc | 15 | ||||
-rw-r--r-- | android_webview/browser/renderer_host/aw_render_view_host_ext.h | 16 | ||||
-rw-r--r-- | android_webview/common/render_view_messages.h | 8 | ||||
-rw-r--r-- | android_webview/common/renderer_picture_map.cc | 48 | ||||
-rw-r--r-- | android_webview/common/renderer_picture_map.h | 38 | ||||
-rw-r--r-- | android_webview/lib/DEPS | 1 | ||||
-rw-r--r-- | android_webview/lib/main/aw_main_delegate.cc | 10 | ||||
-rw-r--r-- | android_webview/native/DEPS | 1 | ||||
-rw-r--r-- | android_webview/native/aw_contents.cc | 38 | ||||
-rw-r--r-- | android_webview/native/aw_contents.h | 8 | ||||
-rw-r--r-- | android_webview/renderer/aw_render_view_ext.cc | 27 | ||||
-rw-r--r-- | android_webview/renderer/aw_render_view_ext.h | 6 |
14 files changed, 205 insertions, 15 deletions
diff --git a/android_webview/DEPS b/android_webview/DEPS index 29747ce..64297c3 100644 --- a/android_webview/DEPS +++ b/android_webview/DEPS @@ -8,6 +8,7 @@ include_rules = [ "-android_webview/lib", "!chrome/browser/component", + "+cc", "+content/components", "+content/public/common", "+jni", diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp index b84cf06..5f95e09 100644 --- a/android_webview/android_webview.gyp +++ b/android_webview/android_webview.gyp @@ -103,6 +103,7 @@ '../content/content.gyp:content', '../content/content.gyp:navigation_interception', '../content/content.gyp:web_contents_delegate_android', + '../skia/skia.gyp:skia', 'android_webview_pak', ], 'include_dirs': [ @@ -163,6 +164,8 @@ 'common/aw_resource.h', 'common/render_view_messages.cc', 'common/render_view_messages.h', + 'common/renderer_picture_map.cc', + 'common/renderer_picture_map.h', 'common/url_constants.cc', 'common/url_constants.h', 'lib/aw_browser_dependency_factory_impl.cc', diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc index 4a529f6..73bcad0 100644 --- a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc +++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc @@ -8,14 +8,17 @@ #include "base/android/scoped_java_ref.h" #include "base/callback.h" #include "base/logging.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents.h" namespace android_webview { -AwRenderViewHostExt::AwRenderViewHostExt(content::WebContents* contents) +AwRenderViewHostExt::AwRenderViewHostExt(content::WebContents* contents, + Client* client) : content::WebContentsObserver(contents), - has_new_hit_test_data_(false) { + has_new_hit_test_data_(false), + client_(client) { } AwRenderViewHostExt::~AwRenderViewHostExt() {} @@ -75,6 +78,8 @@ bool AwRenderViewHostExt::OnMessageReceived(const IPC::Message& message) { OnDocumentHasImagesResponse) IPC_MESSAGE_HANDLER(AwViewHostMsg_UpdateHitTestData, OnUpdateHitTestData) + IPC_MESSAGE_HANDLER(AwViewHostMsg_PictureUpdated, + OnPictureUpdated) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -101,4 +106,10 @@ void AwRenderViewHostExt::OnUpdateHitTestData( has_new_hit_test_data_ = true; } +void AwRenderViewHostExt::OnPictureUpdated() { + if (client_) + client_->OnPictureUpdated(web_contents()->GetRenderProcessHost()->GetID(), + routing_id()); +} + } // namespace android_webview diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.h b/android_webview/browser/renderer_host/aw_render_view_host_ext.h index a6d8dde..83bd439 100644 --- a/android_webview/browser/renderer_host/aw_render_view_host_ext.h +++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.h @@ -18,9 +18,17 @@ namespace android_webview { class AwRenderViewHostExt : public content::WebContentsObserver, public base::NonThreadSafe { public: + class Client { + public: + virtual void OnPictureUpdated(int process_id, int render_view_id) = 0; + + protected: + virtual ~Client() {} + }; + // To send receive messages to a RenderView we take the WebContents instance, // as it internally handles RenderViewHost instances changing underneath us. - AwRenderViewHostExt(content::WebContents* contents); + AwRenderViewHostExt(content::WebContents* contents, Client* client); virtual ~AwRenderViewHostExt(); // |result| will be invoked with the outcome of the request. @@ -48,8 +56,8 @@ class AwRenderViewHostExt : public content::WebContentsObserver, virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; void OnDocumentHasImagesResponse(int msg_id, bool has_images); - void OnUpdateHitTestData( - const AwHitTestData& hit_test_data); + void OnUpdateHitTestData(const AwHitTestData& hit_test_data); + void OnPictureUpdated(); std::map<int, DocumentHasImagesResult> pending_document_has_images_requests_; @@ -60,6 +68,8 @@ class AwRenderViewHostExt : public content::WebContentsObserver, bool has_new_hit_test_data_; + Client* client_; + DISALLOW_COPY_AND_ASSIGN(AwRenderViewHostExt); }; diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h index 76f8779..53b23f3 100644 --- a/android_webview/common/render_view_messages.h +++ b/android_webview/common/render_view_messages.h @@ -51,6 +51,10 @@ IPC_MESSAGE_ROUTED2(AwViewMsg_DoHitTest, int /* view_x */, int /* view_y */) +// Enables receiving pictures from the renderer on every new frame. +IPC_MESSAGE_ROUTED1(AwViewMsg_EnableCapturePictureCallback, + bool /* enable */) + //----------------------------------------------------------------------------- // RenderView messages // These are messages sent from the renderer to the browser process. @@ -63,3 +67,7 @@ IPC_MESSAGE_ROUTED2(AwViewHostMsg_DocumentHasImagesResponse, // Response to AwViewMsg_DoHitTest. IPC_MESSAGE_ROUTED1(AwViewHostMsg_UpdateHitTestData, android_webview::AwHitTestData) + +// Notification that a new picture becomes available. It is only sent if +// AwViewMsg_EnableCapturePictureCallback was previously enabled. +IPC_MESSAGE_ROUTED0(AwViewHostMsg_PictureUpdated) diff --git a/android_webview/common/renderer_picture_map.cc b/android_webview/common/renderer_picture_map.cc new file mode 100644 index 0000000..f5e9e03 --- /dev/null +++ b/android_webview/common/renderer_picture_map.cc @@ -0,0 +1,48 @@ +// 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/common/renderer_picture_map.h" + +using base::AutoLock; + +namespace android_webview { + +static RendererPictureMap* g_renderer_picture_map = NULL; + +// static +void RendererPictureMap::CreateInstance() { + if (!g_renderer_picture_map) + g_renderer_picture_map = new RendererPictureMap(); +} + +// static +RendererPictureMap* RendererPictureMap::GetInstance() { + DCHECK(g_renderer_picture_map); + return g_renderer_picture_map; +} + +RendererPictureMap::RendererPictureMap() { +} + +RendererPictureMap::~RendererPictureMap() { +} + +scoped_refptr<cc::PicturePileImpl> RendererPictureMap::GetRendererPicture( + int id) { + AutoLock lock(lock_); + return picture_map_[id]; +} + +void RendererPictureMap::SetRendererPicture(int id, + scoped_refptr<cc::PicturePileImpl> picture) { + AutoLock lock(lock_); + picture_map_[id] = picture; +} + +void RendererPictureMap::ClearRendererPicture(int id) { + AutoLock lock(lock_); + picture_map_.erase(id); +} + +} // android_webview diff --git a/android_webview/common/renderer_picture_map.h b/android_webview/common/renderer_picture_map.h new file mode 100644 index 0000000..5129129 --- /dev/null +++ b/android_webview/common/renderer_picture_map.h @@ -0,0 +1,38 @@ +// 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 ANDROID_WEBVIEW_COMMON_RENDERER_PICTURE_MAP_H_ +#define ANDROID_WEBVIEW_COMMON_RENDERER_PICTURE_MAP_H_ + +#include <map> + +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "cc/picture_pile_impl.h" + +namespace android_webview { + +// Stores picture piles received from diferent renderers and associates them by +// renderer id. Will only work in single process mode. +class RendererPictureMap { + public: + static void CreateInstance(); + static RendererPictureMap* GetInstance(); + + scoped_refptr<cc::PicturePileImpl> GetRendererPicture(int id); + void SetRendererPicture(int id, scoped_refptr<cc::PicturePileImpl> picture); + void ClearRendererPicture(int id); + + private: + RendererPictureMap(); + ~RendererPictureMap(); + + typedef std::map<int, scoped_refptr<cc::PicturePileImpl> > PictureMap; + PictureMap picture_map_; + base::Lock lock_; +}; + +} // android_webview + +#endif // ANDROID_WEBVIEW_COMMON_RENDERER_PICTURE_MAP_H_ diff --git a/android_webview/lib/DEPS b/android_webview/lib/DEPS index fe7bb13..f3505d7 100644 --- a/android_webview/lib/DEPS +++ b/android_webview/lib/DEPS @@ -1,3 +1,4 @@ include_rules = [ + "+cc/switches.h", "+content/public", ] diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc index 8b18910..4ad6937 100644 --- a/android_webview/lib/main/aw_main_delegate.cc +++ b/android_webview/lib/main/aw_main_delegate.cc @@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "cc/switches.h" #include "content/public/browser/browser_main_runner.h" #include "content/public/common/content_switches.h" @@ -29,6 +30,15 @@ bool AwMainDelegate::BasicStartupComplete(int* exit_code) { // Set the command line to enable synchronous API compatibility. command_line->AppendSwitch(switches::kEnableWebViewSynchronousAPIs); + // TODO(leandrogracia): enable with the CapturePicture API support. + if (false) { + // Enable impl-side painting in the compositor. + command_line->AppendSwitch(switches::kForceCompositingMode); + command_line->AppendSwitch(switches::kEnableThreadedCompositing); + command_line->AppendSwitch(switches::kEnableDeferredImageDecoding); + command_line->AppendSwitch(cc::switches::kEnableImplSidePainting); + } + return false; } diff --git a/android_webview/native/DEPS b/android_webview/native/DEPS index 9467ac6..3067d75 100644 --- a/android_webview/native/DEPS +++ b/android_webview/native/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+cc", "+content/public/browser", "+ui/gfx", "+ui/gl", diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index fbdc710..778400e 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -11,6 +11,7 @@ #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h" #include "android_webview/common/aw_hit_test_data.h" +#include "android_webview/common/renderer_picture_map.h" #include "android_webview/native/aw_browser_dependency_factory.h" #include "android_webview/native/aw_contents_io_thread_client_impl.h" #include "android_webview/native/aw_web_contents_delegate.h" @@ -26,6 +27,8 @@ #include "base/pickle.h" #include "base/supports_user_data.h" #include "cc/layer.h" +#include "cc/picture_pile_impl.h" +#include "cc/rendering_stats.h" #include "content/components/navigation_interception/intercept_navigation_delegate.h" #include "content/public/browser/android/content_view_core.h" #include "content/public/browser/browser_thread.h" @@ -159,6 +162,7 @@ AwContents::AwContents(JNIEnv* env, is_composite_pending_(false), last_scroll_x_(0), last_scroll_y_(0), last_frame_context_(NULL) { + RendererPictureMap::CreateInstance(); android_webview::AwBrowserDependencyFactory* dependency_factory = android_webview::AwBrowserDependencyFactory::GetInstance(); @@ -185,7 +189,8 @@ void AwContents::SetWebContents(content::WebContents* web_contents) { new AwContentsUserData(this)); web_contents_->SetDelegate(web_contents_delegate_.get()); - render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents_.get())); + render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents_.get(), + this)); ResetCompositor(); } @@ -417,6 +422,12 @@ void AwContents::DrawGL(AwDrawGLInfo* draw_info) { } bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { + scoped_refptr<cc::PicturePileImpl> picture = + RendererPictureMap::GetInstance()->GetRendererPicture( + web_contents_->GetRoutingID()); + if (!picture) + return false; + AwPixelInfo* pixels; if (!g_draw_sw_functions || (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { @@ -438,15 +449,22 @@ bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { matrix.set(i, pixels->matrix[i]); } canvas.setMatrix(matrix); + SkRegion clip; if (pixels->clip_region_size) { size_t bytes_read = clip.readFromMemory(pixels->clip_region); DCHECK_EQ(pixels->clip_region_size, bytes_read); canvas.setClipRegion(clip); + } else { + clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); } - // TODO(joth): Implement real drawing. For now, fill the view in blue. - canvas.drawARGB(128, 1, 30, 250); + SkIRect sk_clip_rect = clip.getBounds(); + gfx::Rect clip_rect(sk_clip_rect.x(), sk_clip_rect.y(), + sk_clip_rect.width(), sk_clip_rect.height()); + + cc::RenderingStats stats; + picture->Raster(&canvas, clip_rect, 1.0, &stats); } g_draw_sw_functions->release_pixels(pixels); @@ -699,15 +717,15 @@ void AwContents::OnFindResultReceived(int active_ordinal, void AwContents::ScheduleComposite() { TRACE_EVENT0("AwContents", "AwContents::ScheduleComposite"); - Invalidate(); -} -void AwContents::Invalidate() { if (is_composite_pending_) return; is_composite_pending_ = true; + Invalidate(); +} +void AwContents::Invalidate() { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) @@ -866,4 +884,12 @@ jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { return reinterpret_cast<jint>(pending_contents_.release()); } +void AwContents::OnPictureUpdated(int process_id, int render_view_id) { + CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); + if (render_view_id != web_contents_->GetRoutingID()) + return; + + Invalidate(); +} + } // namespace android_webview diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 44da9f2..905240f 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h @@ -9,6 +9,7 @@ #include <string> #include "android_webview/browser/find_helper.h" +#include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" #include "android_webview/public/browser/draw_gl.h" #include "base/android/scoped_java_ref.h" #include "base/android/jni_helper.h" @@ -31,7 +32,6 @@ class WebContents; namespace android_webview { class AwContentsContainer; -class AwRenderViewHostExt; class AwWebContentsDelegate; // Native side of java-class of same name. @@ -39,7 +39,8 @@ class AwWebContentsDelegate; // WebView functionality; analogous to chrome's TabContents, but with a // level of indirection provided by the AwContentsContainer abstraction. class AwContents : public FindHelper::Listener, - public content::Compositor::Client { + public content::Compositor::Client, + public AwRenderViewHostExt::Client { public: // Returns the AwContents instance associated with |web_contents|, or NULL. static AwContents* FromWebContents(content::WebContents* web_contents); @@ -123,6 +124,9 @@ class AwContents : public FindHelper::Listener, void SetPendingWebContentsForPopup(scoped_ptr<content::WebContents> pending); jint ReleasePopupWebContents(JNIEnv* env, jobject obj); + // AwRenderViewHostExt::Client implementation. + virtual void OnPictureUpdated(int process_id, int render_view_id) OVERRIDE; + private: void Invalidate(); void SetWebContents(content::WebContents* web_contents); diff --git a/android_webview/renderer/aw_render_view_ext.cc b/android_webview/renderer/aw_render_view_ext.cc index f9fb960..86f56ac 100644 --- a/android_webview/renderer/aw_render_view_ext.cc +++ b/android_webview/renderer/aw_render_view_ext.cc @@ -8,6 +8,8 @@ #include "android_webview/common/aw_hit_test_data.h" #include "android_webview/common/render_view_messages.h" +#include "android_webview/common/renderer_picture_map.h" +#include "base/bind.h" #include "base/string_piece.h" #include "content/public/common/url_constants.h" #include "content/public/renderer/android_content_detection_prefixes.h" @@ -46,9 +48,17 @@ bool RemovePrefixAndAssignIfMatches(const base::StringPiece& prefix, AwRenderViewExt::AwRenderViewExt(content::RenderView* render_view) : content::RenderViewObserver(render_view) { render_view->GetWebView()->setPermissionClient(this); + // TODO(leandrogracia): enable once the feature is available in RenderView. + //render_view->SetCapturePictureCallback( + // base::Bind(&AwRenderViewExt::OnPictureUpdate, AsWeakPtr())); } -AwRenderViewExt::~AwRenderViewExt() {} +AwRenderViewExt::~AwRenderViewExt() { + // TODO(leandrogracia): enable once the feature is available in RenderView. + //render_view()->SetCapturePictureCallback( + // content::RenderView::CapturePictureCallback()); + RendererPictureMap::GetInstance()->ClearRendererPicture(routing_id()); +} // static void AwRenderViewExt::RenderViewCreated(content::RenderView* render_view) { @@ -60,6 +70,8 @@ bool AwRenderViewExt::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(AwRenderViewExt, message) IPC_MESSAGE_HANDLER(AwViewMsg_DocumentHasImages, OnDocumentHasImagesRequest) IPC_MESSAGE_HANDLER(AwViewMsg_DoHitTest, OnDoHitTest) + IPC_MESSAGE_HANDLER(AwViewMsg_EnableCapturePictureCallback, + OnEnableCapturePictureCallback) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -181,4 +193,17 @@ void AwRenderViewExt::OnDoHitTest(int view_x, int view_y) { Send(new AwViewHostMsg_UpdateHitTestData(routing_id(), data)); } +void AwRenderViewExt::OnEnableCapturePictureCallback(bool enable) { + // TODO(leandrogracia): enable once the feature is available in RenderView. + //render_view()->SetCapturePictureCallback(enable ? + // base::Bind(&AwRenderViewExt::OnPictureUpdate, AsWeakPtr()) : + // content::RenderView::CapturePictureCallback()); +} + +void AwRenderViewExt::OnPictureUpdate( + scoped_refptr<cc::PicturePileImpl> picture) { + RendererPictureMap::GetInstance()->SetRendererPicture(routing_id(), picture); + Send(new AwViewHostMsg_PictureUpdated(routing_id())); +} + } // namespace android_webview diff --git a/android_webview/renderer/aw_render_view_ext.h b/android_webview/renderer/aw_render_view_ext.h index c6d3bba..0959811 100644 --- a/android_webview/renderer/aw_render_view_ext.h +++ b/android_webview/renderer/aw_render_view_ext.h @@ -7,6 +7,8 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "cc/picture_pile_impl.h" #include "content/public/renderer/render_view_observer.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPermissionClient.h" @@ -41,6 +43,10 @@ class AwRenderViewExt : public content::RenderViewObserver, void OnDoHitTest(int view_x, int view_y); + void OnEnableCapturePictureCallback(bool enable); + + void OnPictureUpdate(scoped_refptr<cc::PicturePileImpl> picture); + // WebKit::WebPermissionClient implementation. virtual bool allowImage(WebKit::WebFrame* frame, bool enabledPerSettings, |