summaryrefslogtreecommitdiff
path: root/android_webview/browser
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2014-06-03 10:58:34 +0100
committerTorne (Richard Coles) <torne@google.com>2014-06-03 10:58:34 +0100
commitcedac228d2dd51db4b79ea1e72c7f249408ee061 (patch)
treeaa4ff43d7fe316e95d12721ce5e17653a768a0dd /android_webview/browser
parent6a869ecff032b5bed299d661b078b0555034598b (diff)
downloadchromium_org-cedac228d2dd51db4b79ea1e72c7f249408ee061.tar.gz
Merge from Chromium at DEPS revision 273901
This commit was generated by merge_to_master.py. Change-Id: I45745444894df927ffc1045ab8de88b9e52636a3
Diffstat (limited to 'android_webview/browser')
-rw-r--r--android_webview/browser/aw_browser_context.cc35
-rw-r--r--android_webview/browser/aw_browser_context.h17
-rw-r--r--android_webview/browser/aw_browser_main_parts.cc11
-rw-r--r--android_webview/browser/aw_content_browser_client.cc27
-rw-r--r--android_webview/browser/aw_content_browser_client.h6
-rw-r--r--android_webview/browser/aw_contents_io_thread_client.h3
-rw-r--r--android_webview/browser/aw_cookie_access_policy.cc84
-rw-r--r--android_webview/browser/aw_cookie_access_policy.h59
-rw-r--r--android_webview/browser/aw_cookie_access_policy_unittest.cc151
-rw-r--r--android_webview/browser/aw_login_delegate.cc3
-rw-r--r--android_webview/browser/aw_request_interceptor.cc2
-rw-r--r--android_webview/browser/aw_request_interceptor.h8
-rw-r--r--android_webview/browser/aw_static_cookie_policy_unittest.cc66
-rw-r--r--android_webview/browser/browser_view_renderer.cc313
-rw-r--r--android_webview/browser/browser_view_renderer.h33
-rw-r--r--android_webview/browser/browser_view_renderer_client.h19
-rw-r--r--android_webview/browser/deferred_gpu_command_service.cc59
-rw-r--r--android_webview/browser/deferred_gpu_command_service.h4
-rw-r--r--android_webview/browser/gl_view_renderer_manager.cc5
-rw-r--r--android_webview/browser/gl_view_renderer_manager.h4
-rw-r--r--android_webview/browser/hardware_renderer.cc220
-rw-r--r--android_webview/browser/hardware_renderer.h89
-rw-r--r--android_webview/browser/hardware_renderer_interface.h26
-rw-r--r--android_webview/browser/hardware_renderer_legacy.cc106
-rw-r--r--android_webview/browser/hardware_renderer_legacy.h46
-rw-r--r--android_webview/browser/net/aw_url_request_context_getter.cc68
-rw-r--r--android_webview/browser/net/init_native_callback.h10
-rw-r--r--android_webview/browser/parent_output_surface.cc35
-rw-r--r--android_webview/browser/parent_output_surface.h30
-rw-r--r--android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc4
-rw-r--r--android_webview/browser/scoped_app_gl_state_restore.cc19
-rw-r--r--android_webview/browser/shared_renderer_state.cc79
-rw-r--r--android_webview/browser/shared_renderer_state.h43
33 files changed, 1197 insertions, 487 deletions
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index e4a2a1d08a..c6c020c5a4 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -41,6 +41,9 @@ AwBrowserContext* g_browser_context = NULL;
} // namespace
+// Data reduction proxy is disabled by default.
+bool AwBrowserContext::data_reduction_proxy_enabled_ = false;
+
AwBrowserContext::AwBrowserContext(
const FilePath path,
JniDependencyFactory* native_factory)
@@ -73,6 +76,22 @@ AwBrowserContext* AwBrowserContext::FromWebContents(
return static_cast<AwBrowserContext*>(web_contents->GetBrowserContext());
}
+// static
+void AwBrowserContext::SetDataReductionProxyEnabled(bool enabled) {
+ // Cache the setting value. It is possible that data reduction proxy is
+ // not created yet.
+ data_reduction_proxy_enabled_ = enabled;
+ AwBrowserContext* context = AwBrowserContext::GetDefault();
+ // Can't enable Data reduction proxy if user pref service is not ready.
+ if (context == NULL || context->user_pref_service_.get() == NULL)
+ return;
+ DataReductionProxySettings* proxy_settings =
+ context->GetDataReductionProxySettings();
+ if (proxy_settings == NULL)
+ return;
+ proxy_settings->SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
+}
+
void AwBrowserContext::PreMainMessageLoopRun() {
cookie_store_ = CreateCookieStore(this);
DataReductionProxySettings::SetAllowed(true);
@@ -169,9 +188,8 @@ void AwBrowserContext::CreateUserPrefServiceIfNecessary() {
user_pref_service_.get(),
GetRequestContext());
- //TODO(sgurun): Attach this to the API. It is currently hard coded in a
- // disabled state.
- data_reduction_proxy_settings_->SetDataReductionProxyEnabled(false);
+ data_reduction_proxy_settings_->SetDataReductionProxyEnabled(
+ data_reduction_proxy_enabled_);
}
base::FilePath AwBrowserContext::GetPath() const {
@@ -219,16 +237,16 @@ void AwBrowserContext::CancelMidiSysExPermissionRequest(
void AwBrowserContext::RequestProtectedMediaIdentifierPermission(
int render_process_id,
int render_view_id,
- int bridge_id,
- int group_id,
- const GURL& requesting_frame,
+ const GURL& origin,
const ProtectedMediaIdentifierPermissionCallback& callback) {
NOTIMPLEMENTED();
callback.Run(false);
}
void AwBrowserContext::CancelProtectedMediaIdentifierPermissionRequests(
- int group_id) {
+ int render_process_id,
+ int render_view_id,
+ const GURL& origin) {
NOTIMPLEMENTED();
}
@@ -268,8 +286,7 @@ AwBrowserContext::GetGeolocationPermissionContext() {
return geolocation_permission_context_.get();
}
-content::BrowserPluginGuestManagerDelegate*
-AwBrowserContext::GetGuestManagerDelegate() {
+content::BrowserPluginGuestManager* AwBrowserContext::GetGuestManager() {
return NULL;
}
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index 94bbf4ac2f..8b0c068af9 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -64,6 +64,8 @@ class AwBrowserContext : public content::BrowserContext,
static AwBrowserContext* FromWebContents(
content::WebContents* web_contents);
+ static void SetDataReductionProxyEnabled(bool enabled);
+
// Maps to BrowserMainParts::PreMainMessageLoopRun.
void PreMainMessageLoopRun();
@@ -112,19 +114,18 @@ class AwBrowserContext : public content::BrowserContext,
virtual void RequestProtectedMediaIdentifierPermission(
int render_process_id,
int render_view_id,
- int bridge_id,
- int group_id,
- const GURL& requesting_frame,
+ const GURL& origin,
const ProtectedMediaIdentifierPermissionCallback& callback) OVERRIDE;
- virtual void CancelProtectedMediaIdentifierPermissionRequests(int group_id)
- OVERRIDE;
+ virtual void CancelProtectedMediaIdentifierPermissionRequests(
+ int render_process_id,
+ int render_view_id,
+ const GURL& origin) OVERRIDE;
virtual content::ResourceContext* GetResourceContext() OVERRIDE;
virtual content::DownloadManagerDelegate*
GetDownloadManagerDelegate() OVERRIDE;
virtual content::GeolocationPermissionContext*
GetGeolocationPermissionContext() OVERRIDE;
- virtual content::BrowserPluginGuestManagerDelegate*
- GetGuestManagerDelegate() OVERRIDE;
+ virtual content::BrowserPluginGuestManager* GetGuestManager() OVERRIDE;
virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
// visitedlink::VisitedLinkDelegate implementation.
@@ -132,6 +133,8 @@ class AwBrowserContext : public content::BrowserContext,
const scoped_refptr<URLEnumerator>& enumerator) OVERRIDE;
private:
+ static bool data_reduction_proxy_enabled_;
+
// The file path where data for this context is persisted.
base::FilePath context_storage_path_;
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
index 653f8c5f90..0b04715432 100644
--- a/android_webview/browser/aw_browser_main_parts.cc
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -6,6 +6,7 @@
#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_result_codes.h"
+#include "android_webview/common/aw_switches.h"
#include "base/android/build_info.h"
#include "base/android/memory_pressure_listener_android.h"
#include "base/command_line.h"
@@ -62,9 +63,13 @@ int AwBrowserMainParts::PreCreateThreads() {
}
void AwBrowserMainParts::PreMainMessageLoopRun() {
- if (!gpu::gles2::MailboxSynchronizer::Initialize()) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kDisableAccelerated2dCanvas);
+ // TODO(boliu): Can't support accelerated 2d canvas and WebGL with ubercomp
+ // yet: crbug.com/352424.
+ if (!switches::UbercompEnabled() &&
+ !gpu::gles2::MailboxSynchronizer::Initialize()) {
+ CommandLine* cl = CommandLine::ForCurrentProcess();
+ cl->AppendSwitch(switches::kDisableAccelerated2dCanvas);
+ cl->AppendSwitch(switches::kDisableExperimentalWebGL);
}
browser_context_->PreMainMessageLoopRun();
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 1ba73c75ef..62aff355d1 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -52,8 +52,7 @@ public:
const IPC::Message& message,
BrowserThread::ID* thread) OVERRIDE;
virtual bool OnMessageReceived(
- const IPC::Message& message,
- bool* message_was_ok) OVERRIDE;
+ const IPC::Message& message) OVERRIDE;
void OnShouldOverrideUrlLoading(int routing_id,
const base::string16& url,
@@ -83,14 +82,13 @@ void AwContentsMessageFilter::OverrideThreadForMessage(
}
}
-bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message,
- bool* message_was_ok) {
+bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(AwContentsMessageFilter, message, *message_was_ok)
- IPC_MESSAGE_HANDLER(AwViewHostMsg_ShouldOverrideUrlLoading,
- OnShouldOverrideUrlLoading)
- IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated)
- IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_BEGIN_MESSAGE_MAP(AwContentsMessageFilter, message)
+ IPC_MESSAGE_HANDLER(AwViewHostMsg_ShouldOverrideUrlLoading,
+ OnShouldOverrideUrlLoading)
+ IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated)
+ IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
@@ -205,7 +203,7 @@ void AwContentBrowserClient::RenderProcessWillLaunch(
content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
host->GetID(), android_webview::kContentScheme);
content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
- host->GetID(), content::kFileScheme);
+ host->GetID(), url::kFileScheme);
host->AddFilter(new AwContentsMessageFilter(host->GetID()));
host->AddFilter(new cdm::CdmMessageFilterAndroid());
@@ -214,9 +212,9 @@ void AwContentBrowserClient::RenderProcessWillLaunch(
net::URLRequestContextGetter* AwContentBrowserClient::CreateRequestContext(
content::BrowserContext* browser_context,
content::ProtocolHandlerMap* protocol_handlers,
- content::ProtocolHandlerScopedVector protocol_interceptors) {
+ content::URLRequestInterceptorScopedVector request_interceptors) {
DCHECK(browser_context_.get() == browser_context);
- // TODO(mkosiba,kinuko): protocol_interceptors should be hooked up in the
+ // TODO(mkosiba,kinuko): request_interceptors should be hooked up in the
// downstream. (crbug.com/350286)
return browser_context_->CreateRequestContext(protocol_handlers);
}
@@ -227,8 +225,10 @@ AwContentBrowserClient::CreateRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
- content::ProtocolHandlerScopedVector protocol_interceptors) {
+ content::URLRequestInterceptorScopedVector request_interceptors) {
DCHECK(browser_context_.get() == browser_context);
+ // TODO(mkosiba,kinuko): request_interceptors should be hooked up in the
+ // downstream. (crbug.com/350286)
return browser_context_->CreateRequestContextForStoragePartition(
partition_path, in_memory, protocol_handlers);
}
@@ -400,7 +400,6 @@ bool AwContentBrowserClient::CanCreateWindow(
bool opener_suppressed,
content::ResourceContext* context,
int render_process_id,
- bool is_guest,
int opener_id,
bool* no_javascript_access) {
// We unconditionally allow popup windows at this stage and will give
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 9e4f5f3086..b313e58ebf 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -10,7 +10,6 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/content_browser_client.h"
-#include "net/url_request/url_request_job_factory.h"
struct WebPreferences;
@@ -46,13 +45,13 @@ class AwContentBrowserClient : public content::ContentBrowserClient {
virtual net::URLRequestContextGetter* CreateRequestContext(
content::BrowserContext* browser_context,
content::ProtocolHandlerMap* protocol_handlers,
- content::ProtocolHandlerScopedVector protocol_interceptors) OVERRIDE;
+ content::URLRequestInterceptorScopedVector request_interceptors) OVERRIDE;
virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
content::BrowserContext* browser_context,
const base::FilePath& partition_path,
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
- content::ProtocolHandlerScopedVector protocol_interceptors) OVERRIDE;
+ content::URLRequestInterceptorScopedVector request_interceptors) OVERRIDE;
virtual std::string GetCanonicalEncodingNameByAliasName(
const std::string& alias_name) OVERRIDE;
virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
@@ -133,7 +132,6 @@ class AwContentBrowserClient : public content::ContentBrowserClient {
bool opener_suppressed,
content::ResourceContext* context,
int render_process_id,
- bool is_guest,
int opener_id,
bool* no_javascript_access) OVERRIDE;
virtual std::string GetWorkerProcessTitle(
diff --git a/android_webview/browser/aw_contents_io_thread_client.h b/android_webview/browser/aw_contents_io_thread_client.h
index 8186739f1a..0ac29fcb46 100644
--- a/android_webview/browser/aw_contents_io_thread_client.h
+++ b/android_webview/browser/aw_contents_io_thread_client.h
@@ -84,6 +84,9 @@ class AwContentsIoThreadClient {
// This method is called on the IO thread only.
virtual bool ShouldBlockNetworkLoads() const = 0;
+ // Retrieve the AcceptThirdPartyCookies setting value of this AwContents.
+ virtual bool ShouldAcceptThirdPartyCookies() const = 0;
+
// Called when ResourceDispathcerHost detects a download request.
// The download is already cancelled when this is called, since
// relevant for DownloadListener is already extracted.
diff --git a/android_webview/browser/aw_cookie_access_policy.cc b/android_webview/browser/aw_cookie_access_policy.cc
index 06e3060530..e07db11b96 100644
--- a/android_webview/browser/aw_cookie_access_policy.cc
+++ b/android_webview/browser/aw_cookie_access_policy.cc
@@ -4,13 +4,17 @@
#include "android_webview/browser/aw_cookie_access_policy.h"
+#include "android_webview/browser/aw_contents_io_thread_client.h"
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_request_info.h"
#include "net/base/net_errors.h"
using base::AutoLock;
using content::BrowserThread;
+using content::ResourceRequestInfo;
using net::StaticCookiePolicy;
namespace android_webview {
@@ -23,43 +27,59 @@ AwCookieAccessPolicy::~AwCookieAccessPolicy() {
}
AwCookieAccessPolicy::AwCookieAccessPolicy()
- : allow_access_(true),
- allow_third_party_access_(true) {
+ : accept_cookies_(true) {
}
AwCookieAccessPolicy* AwCookieAccessPolicy::GetInstance() {
return g_lazy_instance.Pointer();
}
-bool AwCookieAccessPolicy::GetGlobalAllowAccess() {
+bool AwCookieAccessPolicy::GetShouldAcceptCookies() {
AutoLock lock(lock_);
- return allow_access_;
+ return accept_cookies_;
}
-void AwCookieAccessPolicy::SetGlobalAllowAccess(bool allow) {
+void AwCookieAccessPolicy::SetShouldAcceptCookies(bool allow) {
AutoLock lock(lock_);
- allow_access_ = allow;
+ accept_cookies_ = allow;
}
-bool AwCookieAccessPolicy::GetThirdPartyAllowAccess() {
- AutoLock lock(lock_);
- return allow_third_party_access_;
+bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies(
+ int render_process_id,
+ int render_frame_id) {
+ scoped_ptr<AwContentsIoThreadClient> io_thread_client =
+ AwContentsIoThreadClient::FromID(render_process_id, render_frame_id);
+ if (!io_thread_client) {
+ return false;
+ }
+ return io_thread_client->ShouldAcceptThirdPartyCookies();
}
-void AwCookieAccessPolicy::SetThirdPartyAllowAccess(bool allow) {
- AutoLock lock(lock_);
- allow_third_party_access_ = allow;
+bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies(
+ const net::URLRequest& request) {
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
+ if (!info) {
+ return false;
+ }
+ return GetShouldAcceptThirdPartyCookies(info->GetChildID(),
+ info->GetRenderFrameID());
}
bool AwCookieAccessPolicy::OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) {
- return AllowGet(request.url(), request.first_party_for_cookies());
+ bool global = GetShouldAcceptCookies();
+ bool thirdParty = GetShouldAcceptThirdPartyCookies(request);
+ return AwStaticCookiePolicy(global, thirdParty)
+ .AllowGet(request.url(), request.first_party_for_cookies());
}
bool AwCookieAccessPolicy::OnCanSetCookie(const net::URLRequest& request,
const std::string& cookie_line,
net::CookieOptions* options) {
- return AllowSet(request.url(), request.first_party_for_cookies());
+ bool global = GetShouldAcceptCookies();
+ bool thirdParty = GetShouldAcceptThirdPartyCookies(request);
+ return AwStaticCookiePolicy(global, thirdParty)
+ .AllowSet(request.url(), request.first_party_for_cookies());
}
bool AwCookieAccessPolicy::AllowGetCookie(const GURL& url,
@@ -68,7 +88,10 @@ bool AwCookieAccessPolicy::AllowGetCookie(const GURL& url,
content::ResourceContext* context,
int render_process_id,
int render_frame_id) {
- return AllowGet(url, first_party);
+ bool global = GetShouldAcceptCookies();
+ bool thirdParty =
+ GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id);
+ return AwStaticCookiePolicy(global, thirdParty).AllowGet(url, first_party);
}
bool AwCookieAccessPolicy::AllowSetCookie(const GURL& url,
@@ -78,26 +101,37 @@ bool AwCookieAccessPolicy::AllowSetCookie(const GURL& url,
int render_process_id,
int render_frame_id,
net::CookieOptions* options) {
- return AllowSet(url, first_party);
+ bool global = GetShouldAcceptCookies();
+ bool thirdParty =
+ GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id);
+ return AwStaticCookiePolicy(global, thirdParty).AllowSet(url, first_party);
+}
+
+AwStaticCookiePolicy::AwStaticCookiePolicy(bool accept_cookies,
+ bool accept_third_party_cookies)
+ : accept_cookies_(accept_cookies),
+ accept_third_party_cookies_(accept_third_party_cookies) {
}
-StaticCookiePolicy::Type AwCookieAccessPolicy::GetPolicy() {
- if (!GetGlobalAllowAccess()) {
+StaticCookiePolicy::Type AwStaticCookiePolicy::GetPolicy() const {
+ if (!accept_cookies()) {
return StaticCookiePolicy::BLOCK_ALL_COOKIES;
- } else if (!GetThirdPartyAllowAccess()) {
+ } else if (!accept_third_party_cookies()) {
return StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES;
}
return StaticCookiePolicy::ALLOW_ALL_COOKIES;
}
-bool AwCookieAccessPolicy::AllowSet(const GURL& url, const GURL& first_party) {
- return StaticCookiePolicy(GetPolicy()).CanSetCookie(url, first_party)
- == net::OK;
+bool AwStaticCookiePolicy::AllowSet(const GURL& url,
+ const GURL& first_party) const {
+ return StaticCookiePolicy(GetPolicy()).CanSetCookie(url, first_party) ==
+ net::OK;
}
-bool AwCookieAccessPolicy::AllowGet(const GURL& url, const GURL& first_party) {
- return StaticCookiePolicy(GetPolicy()).CanGetCookies(url, first_party)
- == net::OK;
+bool AwStaticCookiePolicy::AllowGet(const GURL& url,
+ const GURL& first_party) const {
+ return StaticCookiePolicy(GetPolicy()).CanGetCookies(url, first_party) ==
+ net::OK;
}
} // namespace android_webview
diff --git a/android_webview/browser/aw_cookie_access_policy.h b/android_webview/browser/aw_cookie_access_policy.h
index 7fd7b59b3a..480eddd2d4 100644
--- a/android_webview/browser/aw_cookie_access_policy.h
+++ b/android_webview/browser/aw_cookie_access_policy.h
@@ -25,19 +25,20 @@ class GURL;
namespace android_webview {
// Manages the cookie access (both setting and getting) policy for WebView.
+// Currently we don't distinguish between sources (i.e. network vs. JavaScript)
+// or between reading vs. writing cookies.
class AwCookieAccessPolicy {
public:
static AwCookieAccessPolicy* GetInstance();
- // These manage the global access state shared across requests regardless of
- // source (i.e. network or JavaScript).
- bool GetGlobalAllowAccess();
- void SetGlobalAllowAccess(bool allow);
+ // Can we read/write any cookies?
+ bool GetShouldAcceptCookies();
+ void SetShouldAcceptCookies(bool allow);
- // These allow more fine grained control over requests depending on whether
- // the cookie is third party or not.
- bool GetThirdPartyAllowAccess();
- void SetThirdPartyAllowAccess(bool allow);
+ // Can we read/write third party cookies?
+ bool GetShouldAcceptThirdPartyCookies(int render_process_id,
+ int render_frame_id);
+ bool GetShouldAcceptThirdPartyCookies(const net::URLRequest& request);
// These are the functions called when operating over cookies from the
// network. See NetworkDelegate for further descriptions.
@@ -68,20 +69,42 @@ class AwCookieAccessPolicy {
AwCookieAccessPolicy();
~AwCookieAccessPolicy();
- bool allow_access_;
- bool allow_third_party_access_;
+ bool accept_cookies_;
base::Lock lock_;
- // We have two bits of state but only three different cases:
- // If !GlobalAllowAccess then reject all cookies.
- // If GlobalAllowAccess and !ThirdPartyAllowAccess then reject third party.
- // If GlobalAllowAccess and ThirdPartyAllowAccess then allow all cookies.
- net::StaticCookiePolicy::Type GetPolicy(void);
+ DISALLOW_COPY_AND_ASSIGN(AwCookieAccessPolicy);
+};
- bool AllowGet(const GURL& url, const GURL& first_party);
- bool AllowSet(const GURL& url, const GURL& first_party);
+class AwStaticCookiePolicy {
+ public:
+ AwStaticCookiePolicy(bool allow_global_access,
+ bool allow_third_party_access);
- DISALLOW_COPY_AND_ASSIGN(AwCookieAccessPolicy);
+ bool accept_cookies() const {
+ return accept_cookies_;
+ }
+
+ bool accept_third_party_cookies() const {
+ return accept_third_party_cookies_;
+ }
+
+ bool AllowGet(const GURL& url, const GURL& first_party) const;
+ bool AllowSet(const GURL& url, const GURL& first_party) const;
+
+ private:
+ const bool accept_cookies_;
+ const bool accept_third_party_cookies_;
+
+ // We have two bits of state but only three different cases:
+ // If !ShouldAcceptCookies
+ // then reject all cookies.
+ // If ShouldAcceptCookies and !ShouldAcceptThirdPartyCookies
+ // then reject third party.
+ // If ShouldAcceptCookies and ShouldAcceptThirdPartyCookies
+ // then allow all cookies.
+ net::StaticCookiePolicy::Type GetPolicy() const;
+
+ DISALLOW_COPY_AND_ASSIGN(AwStaticCookiePolicy);
};
} // namespace android_webview
diff --git a/android_webview/browser/aw_cookie_access_policy_unittest.cc b/android_webview/browser/aw_cookie_access_policy_unittest.cc
deleted file mode 100644
index 6f8a1f1c85..0000000000
--- a/android_webview/browser/aw_cookie_access_policy_unittest.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2014 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/aw_cookie_access_policy.h"
-
-#include "base/run_loop.h"
-#include "net/base/request_priority.h"
-#include "net/cookies/canonical_cookie.h"
-#include "net/url_request/url_request_test_util.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-class ResourceContext;
-}
-
-namespace net {
-class CookieOptions;
-}
-
-class GURL;
-
-using android_webview::AwCookieAccessPolicy;
-using net::CookieList;
-using net::TestDelegate;
-using net::TestJobInterceptor;
-using net::TestNetworkDelegate;
-using net::TestURLRequestContext;
-using net::TestURLRequest;
-using testing::Test;
-
-class AwCookieAccessPolicyTest : public Test {
- public:
- static const GURL kUrlFirstParty;
- static const GURL kUrlThirdParty;
-
- AwCookieAccessPolicyTest()
- : loop_(),
- context_(),
- url_request_delegate_(),
- network_delegate_(),
- first_party_request_() {}
-
- virtual void SetUp() {
- context_.set_network_delegate(&network_delegate_);
- first_party_request_.reset(new TestURLRequest(kUrlFirstParty,
- net::DEFAULT_PRIORITY,
- &url_request_delegate_,
- &context_));
- first_party_request_->set_method("GET");
-
- third_party_request_.reset(new TestURLRequest(kUrlThirdParty,
- net::DEFAULT_PRIORITY,
- &url_request_delegate_,
- &context_));
- third_party_request_->set_method("GET");
- third_party_request_->set_first_party_for_cookies(kUrlFirstParty);
- }
-
- AwCookieAccessPolicy* policy() {
- return AwCookieAccessPolicy::GetInstance();
- }
-
- bool GetGlobalAllowAccess() {
- return policy()->GetGlobalAllowAccess();
- }
-
- void SetGlobalAllowAccess(bool allow) {
- policy()->SetGlobalAllowAccess(allow);
- }
-
- bool GetThirdPartyAllowAccess() {
- return policy()->GetThirdPartyAllowAccess();
- }
-
- void SetThirdPartyAllowAccess(bool allow) {
- policy()->SetThirdPartyAllowAccess(allow);
- }
-
- bool OnCanGetCookies(const net::URLRequest& request) {
- return policy()->OnCanGetCookies(request, CookieList());
- }
-
- bool OnCanSetCookie(const net::URLRequest& request) {
- return policy()->OnCanSetCookie(request, "", NULL);
- }
-
- bool AllowGetCookie(const GURL& url, const GURL& first_party) {
- return policy()->AllowGetCookie(url, first_party, CookieList(), NULL, 0, 0);
- }
-
- bool AllowSetCookie(const GURL& url, const GURL& first_party) {
- return policy()->AllowSetCookie(url, first_party, "", NULL, 0, 0, NULL);
- }
-
- void expectFirstPartyAccess(bool expectedResult) {
- EXPECT_EQ(expectedResult, AllowSetCookie(kUrlFirstParty, kUrlFirstParty));
- EXPECT_EQ(expectedResult, AllowGetCookie(kUrlFirstParty, kUrlFirstParty));
- EXPECT_EQ(expectedResult, OnCanGetCookies(*first_party_request_));
- EXPECT_EQ(expectedResult, OnCanSetCookie(*first_party_request_));
- }
-
- void expectThirdPartyAccess(bool expectedResult) {
- EXPECT_EQ(expectedResult, AllowSetCookie(kUrlFirstParty, kUrlThirdParty));
- EXPECT_EQ(expectedResult, AllowGetCookie(kUrlFirstParty, kUrlThirdParty));
- EXPECT_EQ(expectedResult, OnCanGetCookies(*third_party_request_));
- EXPECT_EQ(expectedResult, OnCanSetCookie(*third_party_request_));
- }
-
- protected:
- base::MessageLoopForIO loop_;
- TestURLRequestContext context_;
- TestDelegate url_request_delegate_;
- TestNetworkDelegate network_delegate_;
- scoped_ptr<TestURLRequest> first_party_request_;
- scoped_ptr<TestURLRequest> third_party_request_;
-};
-
-const GURL AwCookieAccessPolicyTest::kUrlFirstParty =
- GURL("http://first.example");
-const GURL AwCookieAccessPolicyTest::kUrlThirdParty =
- GURL("http://third.example");
-
-TEST_F(AwCookieAccessPolicyTest, BlockAllCookies) {
- SetGlobalAllowAccess(false);
- SetThirdPartyAllowAccess(false);
- expectFirstPartyAccess(false);
- expectThirdPartyAccess(false);
-}
-
-TEST_F(AwCookieAccessPolicyTest, BlockAllCookiesWithThirdPartySet) {
- SetGlobalAllowAccess(false);
- SetThirdPartyAllowAccess(true);
- expectFirstPartyAccess(false);
- expectThirdPartyAccess(false);
-}
-
-TEST_F(AwCookieAccessPolicyTest, FirstPartyCookiesOnly) {
- SetGlobalAllowAccess(true);
- SetThirdPartyAllowAccess(false);
- expectFirstPartyAccess(true);
- expectThirdPartyAccess(false);
-}
-
-TEST_F(AwCookieAccessPolicyTest, AllowAllCookies) {
- SetGlobalAllowAccess(true);
- SetThirdPartyAllowAccess(true);
- expectFirstPartyAccess(true);
- expectThirdPartyAccess(true);
-}
diff --git a/android_webview/browser/aw_login_delegate.cc b/android_webview/browser/aw_login_delegate.cc
index d8d894bbe1..9c8a7c15ea 100644
--- a/android_webview/browser/aw_login_delegate.cc
+++ b/android_webview/browser/aw_login_delegate.cc
@@ -105,7 +105,8 @@ void AwLoginDelegate::HandleHttpAuthRequestOnUIThread(
// auth attempt, because it maintains internal state to cancel if there have
// been too many attempts.
if (!drp_auth_handler_.get()) {
- drp_auth_handler_.reset(new DataReductionProxyAuthRequestHandler());
+ drp_auth_handler_.reset(new DataReductionProxyAuthRequestHandler(
+ drp_settings));
}
DCHECK(drp_auth_handler_.get());
base::string16 user, password;
diff --git a/android_webview/browser/aw_request_interceptor.cc b/android_webview/browser/aw_request_interceptor.cc
index e61d04b5d4..a53061b684 100644
--- a/android_webview/browser/aw_request_interceptor.cc
+++ b/android_webview/browser/aw_request_interceptor.cc
@@ -53,7 +53,7 @@ AwRequestInterceptor::QueryForInterceptedRequestData(
return io_thread_client->ShouldInterceptRequest(location, request).Pass();
}
-net::URLRequestJob* AwRequestInterceptor::MaybeCreateJob(
+net::URLRequestJob* AwRequestInterceptor::MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/android_webview/browser/aw_request_interceptor.h b/android_webview/browser/aw_request_interceptor.h
index 51a7af84e6..b83ab32e23 100644
--- a/android_webview/browser/aw_request_interceptor.h
+++ b/android_webview/browser/aw_request_interceptor.h
@@ -6,7 +6,7 @@
#define ANDROID_WEBVIEW_BROWSER_AW_REQUEST_INTERCEPTOR_H_
#include "base/memory/scoped_ptr.h"
-#include "net/url_request/url_request_job_factory.h"
+#include "net/url_request/url_request_interceptor.h"
class GURL;
@@ -24,13 +24,13 @@ class InterceptedRequestData;
// This class allows the Java-side embedder to substitute the default
// URLRequest of a given request for an alternative job that will read data
// from a Java stream.
-class AwRequestInterceptor : public net::URLRequestJobFactory::ProtocolHandler {
+class AwRequestInterceptor : public net::URLRequestInterceptor {
public:
AwRequestInterceptor();
virtual ~AwRequestInterceptor();
- // net::URLRequestJobFactory::ProtocolHandler override -----------------------
- virtual net::URLRequestJob* MaybeCreateJob(
+ // net::URLRequestInterceptor override --------------------------------------
+ virtual net::URLRequestJob* MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const OVERRIDE;
diff --git a/android_webview/browser/aw_static_cookie_policy_unittest.cc b/android_webview/browser/aw_static_cookie_policy_unittest.cc
new file mode 100644
index 0000000000..edeb315806
--- /dev/null
+++ b/android_webview/browser/aw_static_cookie_policy_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 2014 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/aw_cookie_access_policy.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+class GURL;
+
+using android_webview::AwStaticCookiePolicy;
+using testing::Test;
+
+class AwStaticCookiePolicyTest : public Test {
+ public:
+ static const GURL kUrlFirstParty;
+ static const GURL kUrlThirdParty;
+
+ AwStaticCookiePolicyTest() {}
+
+ void expectFirstPartyAccess(const AwStaticCookiePolicy& policy,
+ bool expectedResult) {
+ EXPECT_EQ(expectedResult, policy.AllowSet(kUrlFirstParty, kUrlFirstParty));
+ EXPECT_EQ(expectedResult, policy.AllowGet(kUrlFirstParty, kUrlFirstParty));
+ }
+
+ void expectThirdPartyAccess(const AwStaticCookiePolicy& policy,
+ bool expectedResult) {
+ EXPECT_EQ(expectedResult, policy.AllowSet(kUrlFirstParty, kUrlThirdParty));
+ EXPECT_EQ(expectedResult, policy.AllowGet(kUrlFirstParty, kUrlThirdParty));
+ }
+};
+
+const GURL AwStaticCookiePolicyTest::kUrlFirstParty =
+ GURL("http://first.example");
+const GURL AwStaticCookiePolicyTest::kUrlThirdParty =
+ GURL("http://third.example");
+
+TEST_F(AwStaticCookiePolicyTest, BlockAllCookies) {
+ AwStaticCookiePolicy policy(false /* allow_cookies */,
+ false /* allow_third_party_cookies */);
+ expectFirstPartyAccess(policy, false);
+ expectThirdPartyAccess(policy, false);
+}
+
+TEST_F(AwStaticCookiePolicyTest, BlockAllCookiesWithThirdPartySet) {
+ AwStaticCookiePolicy policy(false /* allow_cookies */,
+ true /* allow_third_party_cookies */);
+ expectFirstPartyAccess(policy, false);
+ expectThirdPartyAccess(policy, false);
+}
+
+TEST_F(AwStaticCookiePolicyTest, FirstPartyCookiesOnly) {
+ AwStaticCookiePolicy policy(true /* allow_cookies */,
+ false /* allow_third_party_cookies */);
+ expectFirstPartyAccess(policy, true);
+ expectThirdPartyAccess(policy, false);
+}
+
+TEST_F(AwStaticCookiePolicyTest, AllowAllCookies) {
+ AwStaticCookiePolicy policy(true /* allow_cookies */,
+ true /* allow_third_party_cookies */);
+ expectFirstPartyAccess(policy, true);
+ expectThirdPartyAccess(policy, true);
+}
+
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index 2fc80229d6..3c1ceb42be 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -6,14 +6,17 @@
#include "android_webview/browser/browser_view_renderer_client.h"
#include "android_webview/browser/shared_renderer_state.h"
+#include "android_webview/common/aw_switches.h"
#include "android_webview/public/browser/draw_gl.h"
#include "base/android/jni_android.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
+#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "cc/output/compositor_frame.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
@@ -73,6 +76,27 @@ class AutoResetWithLock {
DISALLOW_COPY_AND_ASSIGN(AutoResetWithLock);
};
+class TracedValue : public base::debug::ConvertableToTraceFormat {
+ public:
+ explicit TracedValue(base::Value* value) : value_(value) {}
+ static scoped_refptr<base::debug::ConvertableToTraceFormat> FromValue(
+ base::Value* value) {
+ return scoped_refptr<base::debug::ConvertableToTraceFormat>(
+ new TracedValue(value));
+ }
+ virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
+ std::string tmp;
+ base::JSONWriter::Write(value_.get(), &tmp);
+ *out += tmp;
+ }
+
+ private:
+ virtual ~TracedValue() {}
+ scoped_ptr<base::Value> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(TracedValue);
+};
+
} // namespace
// static
@@ -107,6 +131,7 @@ BrowserViewRenderer::BrowserViewRenderer(
view_visible_(false),
window_visible_(false),
attached_to_window_(false),
+ hardware_enabled_(false),
dip_scale_(0.0),
page_scale_factor_(1.0),
on_new_picture_enable_(false),
@@ -166,8 +191,8 @@ void BrowserViewRenderer::TrimMemory(const int level, const bool visible) {
SynchronousCompositorMemoryPolicy
BrowserViewRenderer::CalculateDesiredMemoryPolicy() {
SynchronousCompositorMemoryPolicy policy;
- size_t width = draw_gl_input_.global_visible_rect.width();
- size_t height = draw_gl_input_.global_visible_rect.height();
+ size_t width = last_on_draw_global_visible_rect_.width();
+ size_t height = last_on_draw_global_visible_rect_.height();
policy.bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
// Round up to a multiple of kMemoryAllocationStep.
policy.bytes_limit =
@@ -225,39 +250,132 @@ bool BrowserViewRenderer::OnDraw(jobject java_canvas,
const gfx::Vector2d& scroll,
const gfx::Rect& global_visible_rect,
const gfx::Rect& clip) {
- draw_gl_input_.frame_id++;
- draw_gl_input_.scroll_offset = scroll;
- draw_gl_input_.global_visible_rect = global_visible_rect;
- draw_gl_input_.width = width_;
- draw_gl_input_.height = height_;
+ last_on_draw_scroll_offset_ = scroll;
+ last_on_draw_global_visible_rect_ = global_visible_rect;
+
if (clear_view_)
return false;
+
if (is_hardware_canvas && attached_to_window_) {
- shared_renderer_state_->SetDrawGLInput(draw_gl_input_);
-
- SynchronousCompositorMemoryPolicy old_policy =
- shared_renderer_state_->GetMemoryPolicy();
- SynchronousCompositorMemoryPolicy new_policy =
- CalculateDesiredMemoryPolicy();
- RequestMemoryPolicy(new_policy);
- // We should be performing a hardware draw here. If we don't have the
- // compositor yet or if RequestDrawGL fails, it means we failed this draw
- // and thus return false here to clear to background color for this draw.
- bool did_draw_gl =
- has_compositor_ && client_->RequestDrawGL(java_canvas, false);
- if (did_draw_gl)
- GlobalTileManager::GetInstance()->DidUse(tile_manager_key_);
- else
- RequestMemoryPolicy(old_policy);
-
- return did_draw_gl;
+ if (switches::UbercompEnabled()) {
+ return OnDrawHardware(java_canvas);
+ } else {
+ return OnDrawHardwareLegacy(java_canvas);
+ }
}
// Perform a software draw
return DrawSWInternal(java_canvas, clip);
}
-void BrowserViewRenderer::DidDrawGL(const DrawGLResult& result) {
- DidComposite(!result.clip_contains_visible_rect);
+bool BrowserViewRenderer::OnDrawHardwareLegacy(jobject java_canvas) {
+ scoped_ptr<DrawGLInput> draw_gl_input(new DrawGLInput);
+ draw_gl_input->scroll_offset = last_on_draw_scroll_offset_;
+ draw_gl_input->global_visible_rect = last_on_draw_global_visible_rect_;
+ draw_gl_input->width = width_;
+ draw_gl_input->height = height_;
+
+ SynchronousCompositorMemoryPolicy old_policy =
+ shared_renderer_state_->GetMemoryPolicy();
+ SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy();
+ RequestMemoryPolicy(new_policy);
+ // We should be performing a hardware draw here. If we don't have the
+ // compositor yet or if RequestDrawGL fails, it means we failed this draw
+ // and thus return false here to clear to background color for this draw.
+ bool did_draw_gl =
+ has_compositor_ && client_->RequestDrawGL(java_canvas, false);
+ if (did_draw_gl) {
+ GlobalTileManager::GetInstance()->DidUse(tile_manager_key_);
+ shared_renderer_state_->SetDrawGLInput(draw_gl_input.Pass());
+ } else {
+ RequestMemoryPolicy(old_policy);
+ }
+
+ return did_draw_gl;
+}
+
+void BrowserViewRenderer::DidDrawGL(scoped_ptr<DrawGLResult> result) {
+ DidComposite(!result->clip_contains_visible_rect);
+}
+
+bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) {
+ if (!has_compositor_)
+ return false;
+
+ if (!hardware_enabled_) {
+ hardware_enabled_ =
+ shared_renderer_state_->GetCompositor()->InitializeHwDraw(NULL);
+ if (hardware_enabled_) {
+ gpu::GLInProcessContext* share_context =
+ shared_renderer_state_->GetCompositor()->GetShareContext();
+ DCHECK(share_context);
+ shared_renderer_state_->SetSharedContext(share_context);
+ }
+ }
+ if (!hardware_enabled_)
+ return false;
+
+ ReturnResources();
+ SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy();
+ RequestMemoryPolicy(new_policy);
+ shared_renderer_state_->GetCompositor()->SetMemoryPolicy(
+ shared_renderer_state_->GetMemoryPolicy());
+
+ scoped_ptr<DrawGLInput> draw_gl_input(new DrawGLInput);
+ draw_gl_input->scroll_offset = last_on_draw_scroll_offset_;
+ draw_gl_input->global_visible_rect = last_on_draw_global_visible_rect_;
+ draw_gl_input->width = width_;
+ draw_gl_input->height = height_;
+
+ gfx::Transform transform;
+ gfx::Size surface_size(width_, height_);
+ gfx::Rect viewport(surface_size);
+ // TODO(boliu): Should really be |last_on_draw_global_visible_rect_|.
+ // See crbug.com/372073.
+ gfx::Rect clip = viewport;
+ bool stencil_enabled = false;
+ scoped_ptr<cc::CompositorFrame> frame =
+ shared_renderer_state_->GetCompositor()->DemandDrawHw(
+ surface_size, transform, viewport, clip, stencil_enabled);
+ if (!frame.get())
+ return false;
+
+ GlobalTileManager::GetInstance()->DidUse(tile_manager_key_);
+
+ frame->AssignTo(&draw_gl_input->frame);
+ scoped_ptr<DrawGLInput> old_input = shared_renderer_state_->PassDrawGLInput();
+ if (old_input.get()) {
+ shared_renderer_state_->ReturnResources(
+ old_input->frame.delegated_frame_data->resource_list);
+ }
+ shared_renderer_state_->SetDrawGLInput(draw_gl_input.Pass());
+
+ DidComposite(false);
+ bool did_request = client_->RequestDrawGL(java_canvas, false);
+ if (did_request)
+ return true;
+
+ ReturnResources();
+ return false;
+}
+
+void BrowserViewRenderer::DidDrawDelegated(scoped_ptr<DrawGLResult> result) {
+ if (!ui_task_runner_->BelongsToCurrentThread()) {
+ // TODO(boliu): This should be a cancelable callback.
+ ui_task_runner_->PostTask(FROM_HERE,
+ base::Bind(&BrowserViewRenderer::DidDrawDelegated,
+ ui_thread_weak_ptr_,
+ base::Passed(&result)));
+ return;
+ }
+ ReturnResources();
+}
+
+void BrowserViewRenderer::ReturnResources() {
+ cc::CompositorFrameAck frame_ack;
+ shared_renderer_state_->SwapReturnedResources(&frame_ack.resources);
+ if (!frame_ack.resources.empty()) {
+ shared_renderer_state_->GetCompositor()->ReturnResources(frame_ack);
+ }
}
bool BrowserViewRenderer::DrawSWInternal(jobject java_canvas,
@@ -277,7 +395,7 @@ bool BrowserViewRenderer::DrawSWInternal(jobject java_canvas,
return BrowserViewRendererJavaHelper::GetInstance()
->RenderViaAuxilaryBitmapIfNeeded(
java_canvas,
- draw_gl_input_.scroll_offset,
+ last_on_draw_scroll_offset_,
clip,
base::Bind(&BrowserViewRenderer::CompositeSW,
base::Unretained(this)));
@@ -377,6 +495,20 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) {
void BrowserViewRenderer::OnDetachedFromWindow() {
TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
attached_to_window_ = false;
+ if (hardware_enabled_) {
+ scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput();
+ if (input.get()) {
+ shared_renderer_state_->ReturnResources(
+ input->frame.delegated_frame_data->resource_list);
+ }
+ ReturnResources();
+ DCHECK(shared_renderer_state_->ReturnedResourcesEmpty());
+
+ if (switches::UbercompEnabled())
+ shared_renderer_state_->GetCompositor()->ReleaseHwDraw();
+ shared_renderer_state_->SetSharedContext(NULL);
+ hardware_enabled_ = false;
+ }
SynchronousCompositorMemoryPolicy zero_policy;
RequestMemoryPolicy(zero_policy);
GlobalTileManager::GetInstance()->Remove(tile_manager_key_);
@@ -485,6 +617,14 @@ void BrowserViewRenderer::ScrollTo(gfx::Vector2d scroll_offset) {
scroll_offset_dip_ = scroll_offset_dip;
}
+ TRACE_EVENT_INSTANT2("android_webview",
+ "BrowserViewRenderer::ScrollTo",
+ TRACE_EVENT_SCOPE_THREAD,
+ "x",
+ scroll_offset_dip.x(),
+ "y",
+ scroll_offset_dip.y());
+
if (has_compositor_)
shared_renderer_state_->GetCompositor()->
DidChangeRootLayerScrollOffset();
@@ -505,35 +645,8 @@ void BrowserViewRenderer::DidUpdateContent() {
client_->OnNewPicture();
}
-void BrowserViewRenderer::SetMaxRootLayerScrollOffset(
- gfx::Vector2dF new_value_dip) {
- if (!ui_task_runner_->BelongsToCurrentThread()) {
- ui_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&BrowserViewRenderer::SetMaxRootLayerScrollOffset,
- ui_thread_weak_ptr_,
- new_value_dip));
- return;
- }
- DCHECK_GT(dip_scale_, 0);
-
- max_scroll_offset_dip_ = new_value_dip;
- DCHECK_LE(0, max_scroll_offset_dip_.x());
- DCHECK_LE(0, max_scroll_offset_dip_.y());
-
- client_->SetMaxContainerViewScrollOffset(max_scroll_offset());
-}
-
void BrowserViewRenderer::SetTotalRootLayerScrollOffset(
gfx::Vector2dF scroll_offset_dip) {
- if (!ui_task_runner_->BelongsToCurrentThread()) {
- ui_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&BrowserViewRenderer::SetTotalRootLayerScrollOffset,
- ui_thread_weak_ptr_,
- scroll_offset_dip));
- return;
- }
{
base::AutoLock lock(render_thread_lock_);
@@ -561,10 +674,8 @@ void BrowserViewRenderer::SetTotalRootLayerScrollOffset(
DCHECK(0 <= scroll_offset.x());
DCHECK(0 <= scroll_offset.y());
- // Disabled because the conditions are being violated while running
- // AwZoomTest.testMagnification, see http://crbug.com/340648
- // DCHECK(scroll_offset.x() <= max_offset.x());
- // DCHECK(scroll_offset.y() <= max_offset.y());
+ DCHECK(scroll_offset.x() <= max_offset.x());
+ DCHECK(scroll_offset.y() <= max_offset.y());
client_->ScrollContainerViewTo(scroll_offset);
}
@@ -583,38 +694,68 @@ bool BrowserViewRenderer::IsExternalFlingActive() const {
return client_->IsFlingActive();
}
-void BrowserViewRenderer::SetRootLayerPageScaleFactorAndLimits(
+void BrowserViewRenderer::UpdateRootLayerState(
+ const gfx::Vector2dF& total_scroll_offset_dip,
+ const gfx::Vector2dF& max_scroll_offset_dip,
+ const gfx::SizeF& scrollable_size_dip,
float page_scale_factor,
float min_page_scale_factor,
float max_page_scale_factor) {
if (!ui_task_runner_->BelongsToCurrentThread()) {
ui_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&BrowserViewRenderer::SetRootLayerPageScaleFactorAndLimits,
+ base::Bind(&BrowserViewRenderer::UpdateRootLayerState,
ui_thread_weak_ptr_,
+ total_scroll_offset_dip,
+ max_scroll_offset_dip,
+ scrollable_size_dip,
page_scale_factor,
min_page_scale_factor,
max_page_scale_factor));
return;
}
+ TRACE_EVENT_INSTANT1(
+ "android_webview",
+ "BrowserViewRenderer::UpdateRootLayerState",
+ TRACE_EVENT_SCOPE_THREAD,
+ "state",
+ TracedValue::FromValue(
+ RootLayerStateAsValue(total_scroll_offset_dip, scrollable_size_dip)
+ .release()));
+
+ DCHECK_GT(dip_scale_, 0);
+
+ max_scroll_offset_dip_ = max_scroll_offset_dip;
+ DCHECK_LE(0, max_scroll_offset_dip_.x());
+ DCHECK_LE(0, max_scroll_offset_dip_.y());
+
page_scale_factor_ = page_scale_factor;
DCHECK_GT(page_scale_factor_, 0);
- client_->SetPageScaleFactorAndLimits(
- page_scale_factor, min_page_scale_factor, max_page_scale_factor);
- client_->SetMaxContainerViewScrollOffset(max_scroll_offset());
+
+ client_->UpdateScrollState(max_scroll_offset(),
+ scrollable_size_dip,
+ page_scale_factor,
+ min_page_scale_factor,
+ max_page_scale_factor);
+ SetTotalRootLayerScrollOffset(total_scroll_offset_dip);
}
-void BrowserViewRenderer::SetRootLayerScrollableSize(
- gfx::SizeF scrollable_size) {
- if (!ui_task_runner_->BelongsToCurrentThread()) {
- ui_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&BrowserViewRenderer::SetRootLayerScrollableSize,
- ui_thread_weak_ptr_,
- scrollable_size));
- return;
- }
- client_->SetContentsSize(scrollable_size);
+scoped_ptr<base::Value> BrowserViewRenderer::RootLayerStateAsValue(
+ const gfx::Vector2dF& total_scroll_offset_dip,
+ const gfx::SizeF& scrollable_size_dip) {
+ scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
+
+ state->SetDouble("total_scroll_offset_dip.x", total_scroll_offset_dip.x());
+ state->SetDouble("total_scroll_offset_dip.y", total_scroll_offset_dip.y());
+
+ state->SetDouble("max_scroll_offset_dip.x", max_scroll_offset_dip_.x());
+ state->SetDouble("max_scroll_offset_dip.y", max_scroll_offset_dip_.y());
+
+ state->SetDouble("scrollable_size_dip.width", scrollable_size_dip.width());
+ state->SetDouble("scrollable_size_dip.height", scrollable_size_dip.height());
+
+ state->SetDouble("page_scale_factor", page_scale_factor_);
+ return state.PassAs<base::Value>();
}
void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll,
@@ -664,7 +805,10 @@ void BrowserViewRenderer::EnsureContinuousInvalidation(bool force_invalidate) {
if (throttle_fallback_tick)
return;
- block_invalidates_ = compositor_needs_continuous_invalidate_;
+ {
+ base::AutoLock lock(render_thread_lock_);
+ block_invalidates_ = compositor_needs_continuous_invalidate_;
+ }
// Unretained here is safe because the callback is cancelled when
// |fallback_tick_| is destroyed.
@@ -713,8 +857,21 @@ bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) {
}
void BrowserViewRenderer::DidComposite(bool force_invalidate) {
+ {
+ base::AutoLock lock(render_thread_lock_);
+ block_invalidates_ = false;
+ }
+
+ if (!ui_task_runner_->BelongsToCurrentThread()) {
+ ui_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&BrowserViewRenderer::EnsureContinuousInvalidation,
+ ui_thread_weak_ptr_,
+ force_invalidate));
+ return;
+ }
+
fallback_tick_.Cancel();
- block_invalidates_ = false;
EnsureContinuousInvalidation(force_invalidate);
}
@@ -733,7 +890,7 @@ std::string BrowserViewRenderer::ToString(AwDrawGLInfo* draw_info) const {
base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_);
base::StringAppendF(&str,
"global visible rect: %s ",
- draw_gl_input_.global_visible_rect.ToString().c_str());
+ last_on_draw_global_visible_rect_.ToString().c_str());
base::StringAppendF(
&str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str());
base::StringAppendF(&str,
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index 991075f3ac..7195ad3adb 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -11,6 +11,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/cancelable_callback.h"
+#include "base/values.h"
#include "content/public/browser/android/synchronous_compositor_client.h"
#include "skia/ext/refptr.h"
#include "ui/gfx/rect.h"
@@ -80,7 +81,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
const gfx::Vector2d& scroll,
const gfx::Rect& global_visible_rect,
const gfx::Rect& clip);
- void DidDrawGL(const DrawGLResult& result);
+ void DidDrawGL(scoped_ptr<DrawGLResult> result);
+ void DidDrawDelegated(scoped_ptr<DrawGLResult> result);
// CapturePicture API methods.
skia::RefPtr<SkPicture> CapturePicture(int width, int height);
@@ -120,17 +122,16 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
virtual void DidDestroyCompositor(content::SynchronousCompositor* compositor)
OVERRIDE;
virtual void SetContinuousInvalidate(bool invalidate) OVERRIDE;
- virtual void SetMaxRootLayerScrollOffset(gfx::Vector2dF new_value) OVERRIDE;
- virtual void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value_css)
- OVERRIDE;
virtual void DidUpdateContent() OVERRIDE;
virtual gfx::Vector2dF GetTotalRootLayerScrollOffset() OVERRIDE;
+ virtual void UpdateRootLayerState(
+ const gfx::Vector2dF& total_scroll_offset_dip,
+ const gfx::Vector2dF& max_scroll_offset_dip,
+ const gfx::SizeF& scrollable_size_dip,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) OVERRIDE;
virtual bool IsExternalFlingActive() const OVERRIDE;
- virtual void SetRootLayerPageScaleFactorAndLimits(float page_scale_factor,
- float min_page_scale_factor,
- float max_page_scale_factor)
- OVERRIDE;
- virtual void SetRootLayerScrollableSize(gfx::SizeF scrollable_size) OVERRIDE;
virtual void DidOverscroll(gfx::Vector2dF accumulated_overscroll,
gfx::Vector2dF latest_overscroll_delta,
gfx::Vector2dF current_fling_velocity) OVERRIDE;
@@ -141,6 +142,7 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
bool effective_immediately) OVERRIDE;
private:
+ void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value_dip);
// Checks the continuous invalidate and block invalidate state, and schedule
// invalidates appropriately. If |force_invalidate| is true, then send a view
// invalidate regardless of compositor expectation.
@@ -148,6 +150,13 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
bool DrawSWInternal(jobject java_canvas, const gfx::Rect& clip_bounds);
bool CompositeSW(SkCanvas* canvas);
void DidComposite(bool force_invalidate);
+ scoped_ptr<base::Value> RootLayerStateAsValue(
+ const gfx::Vector2dF& total_scroll_offset_dip,
+ const gfx::SizeF& scrollable_size_dip);
+
+ bool OnDrawHardwareLegacy(jobject java_canvas);
+ bool OnDrawHardware(jobject java_canvas);
+ void ReturnResources();
// If we call up view invalidate and OnDraw is not called before a deadline,
// then we keep ticking the SynchronousCompositor so it can make progress.
@@ -185,11 +194,15 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
bool view_visible_;
bool window_visible_; // Only applicable if |attached_to_window_| is true.
bool attached_to_window_;
+ bool hardware_enabled_;
float dip_scale_;
float page_scale_factor_;
bool on_new_picture_enable_;
bool clear_view_;
+ gfx::Vector2d last_on_draw_scroll_offset_;
+ gfx::Rect last_on_draw_global_visible_rect_;
+
// When true, we should continuously invalidate and keep drawing, for example
// to drive animation. This value is set by the compositor and should always
// reflect the expectation of the compositor and not be reused for other
@@ -205,8 +218,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
int width_;
int height_;
- DrawGLInput draw_gl_input_;
-
// Current scroll offset in CSS pixels.
gfx::Vector2dF scroll_offset_dip_;
diff --git a/android_webview/browser/browser_view_renderer_client.h b/android_webview/browser/browser_view_renderer_client.h
index fce1c80332..41fbf5a4b3 100644
--- a/android_webview/browser/browser_view_renderer_client.h
+++ b/android_webview/browser/browser_view_renderer_client.h
@@ -34,20 +34,19 @@ class BrowserViewRendererClient {
// Try to set the view's scroll offset to |new_value|.
virtual void ScrollContainerViewTo(gfx::Vector2d new_value) = 0;
- // Set the view's scroll offset cap to |new_value|.
- virtual void SetMaxContainerViewScrollOffset(gfx::Vector2d new_value) = 0;
-
// Is a Android view system managed fling in progress?
virtual bool IsFlingActive() const = 0;
- // Set the current page scale to |page_scale_factor| and page scale limits
+ // Sets the following:
+ // view's scroll offset cap to |max_scroll_offset|,
+ // current contents_size to |contents_size_dip|,
+ // the current page scale to |page_scale_factor| and page scale limits
// to |min_page_scale_factor|..|max_page_scale_factor|.
- virtual void SetPageScaleFactorAndLimits(float page_scale_factor,
- float min_page_scale_factor,
- float max_page_scale_factor) = 0;
-
- // Set the current contents_size to |contents_size_dip|.
- virtual void SetContentsSize(gfx::SizeF contents_size_dip) = 0;
+ virtual void UpdateScrollState(gfx::Vector2d max_scroll_offset,
+ gfx::SizeF contents_size_dip,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) = 0;
// Handle overscroll.
virtual void DidOverscroll(gfx::Vector2d overscroll_delta) = 0;
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc
index 601334ae7f..cb31954c18 100644
--- a/android_webview/browser/deferred_gpu_command_service.cc
+++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -6,12 +6,43 @@
#include "android_webview/browser/gl_view_renderer_manager.h"
#include "android_webview/browser/shared_renderer_state.h"
+#include "base/synchronization/lock.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "gpu/command_buffer/service/shader_translator_cache.h"
namespace android_webview {
namespace {
+
+// TODO(boliu): Consider using base/atomicops.h.
+class ThreadSafeBool {
+ public:
+ ThreadSafeBool();
+ void Set(bool boolean);
+ bool Get();
+
+ private:
+ base::Lock lock_;
+ bool boolean_;
+ DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool);
+};
+
+ThreadSafeBool::ThreadSafeBool() : boolean_(false) {
+}
+
+void ThreadSafeBool::Set(bool boolean) {
+ base::AutoLock lock(lock_);
+ boolean_ = boolean;
+}
+
+bool ThreadSafeBool::Get() {
+ base::AutoLock lock(lock_);
+ return boolean_;
+}
+
+base::LazyInstance<ThreadSafeBool> g_request_pending =
+ LAZY_INSTANCE_INITIALIZER;
+
base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
g_service = LAZY_INSTANCE_INITIALIZER;
} // namespace
@@ -31,16 +62,31 @@ ScopedAllowGL::ScopedAllowGL() {
g_service.Get()->RunTasks();
}
-ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); }
+ScopedAllowGL::~ScopedAllowGL() {
+ allow_gl.Get().Set(false);
+ g_request_pending.Get().Set(false);
+
+ if (g_service.Get())
+ g_service.Get()->RunTasks();
+}
// static
void DeferredGpuCommandService::SetInstance() {
if (!g_service.Get()) {
g_service.Get() = new DeferredGpuCommandService;
content::SynchronousCompositor::SetGpuService(g_service.Get());
+
+ // Initialize global booleans.
+ g_request_pending.Get().Set(false);
}
}
+// static
+DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() {
+ DCHECK(g_service.Get().get());
+ return g_service.Get().get();
+}
+
DeferredGpuCommandService::DeferredGpuCommandService() {}
DeferredGpuCommandService::~DeferredGpuCommandService() {
@@ -48,15 +94,20 @@ DeferredGpuCommandService::~DeferredGpuCommandService() {
DCHECK(tasks_.empty());
}
+// This method can be called on any thread.
// static
-void DeferredGpuCommandService::RequestProcessGLOnUIThread() {
+void DeferredGpuCommandService::RequestProcessGL() {
SharedRendererState* renderer_state =
GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
if (!renderer_state) {
LOG(ERROR) << "No hardware renderer. Deadlock likely";
return;
}
- renderer_state->ClientRequestDrawGL();
+
+ if (!g_request_pending.Get().Get()) {
+ g_request_pending.Get().Set(true);
+ renderer_state->ClientRequestDrawGL();
+ }
}
// Called from different threads!
@@ -68,7 +119,7 @@ void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
if (ScopedAllowGL::IsAllowed()) {
RunTasks();
} else {
- RequestProcessGLOnUIThread();
+ RequestProcessGL();
}
}
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/deferred_gpu_command_service.h
index bbfe9475da..696854db99 100644
--- a/android_webview/browser/deferred_gpu_command_service.h
+++ b/android_webview/browser/deferred_gpu_command_service.h
@@ -27,12 +27,12 @@ class ScopedAllowGL {
DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL);
};
-// TODO(boliu): Teach this class about RT.
class DeferredGpuCommandService
: public gpu::InProcessCommandBuffer::Service,
public base::RefCountedThreadSafe<DeferredGpuCommandService> {
public:
static void SetInstance();
+ static DeferredGpuCommandService* GetInstance();
virtual void ScheduleTask(const base::Closure& task) OVERRIDE;
virtual void ScheduleIdleWork(const base::Closure& task) OVERRIDE;
@@ -50,7 +50,7 @@ class DeferredGpuCommandService
friend class base::RefCountedThreadSafe<DeferredGpuCommandService>;
private:
- static void RequestProcessGLOnUIThread();
+ static void RequestProcessGL();
DeferredGpuCommandService();
diff --git a/android_webview/browser/gl_view_renderer_manager.cc b/android_webview/browser/gl_view_renderer_manager.cc
index b9d1a83fe1..204239c8af 100644
--- a/android_webview/browser/gl_view_renderer_manager.cc
+++ b/android_webview/browser/gl_view_renderer_manager.cc
@@ -25,6 +25,11 @@ GLViewRendererManager::GLViewRendererManager() {}
GLViewRendererManager::~GLViewRendererManager() {}
+GLViewRendererManager::Key GLViewRendererManager::NullKey() {
+ AutoLock auto_lock(lock_);
+ return mru_list_.end();
+}
+
GLViewRendererManager::Key GLViewRendererManager::PushBack(RendererType view) {
AutoLock auto_lock(lock_);
DCHECK(mru_list_.end() ==
diff --git a/android_webview/browser/gl_view_renderer_manager.h b/android_webview/browser/gl_view_renderer_manager.h
index 5d6cb8da4f..f34d9cb261 100644
--- a/android_webview/browser/gl_view_renderer_manager.h
+++ b/android_webview/browser/gl_view_renderer_manager.h
@@ -28,9 +28,7 @@ class GLViewRendererManager {
static GLViewRendererManager* GetInstance();
- Key NullKey() {
- return mru_list_.end();
- }
+ Key NullKey();
Key PushBack(RendererType view);
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index f2cf8e90b1..d1d2253101 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -5,35 +5,125 @@
#include "android_webview/browser/hardware_renderer.h"
#include "android_webview/browser/aw_gl_surface.h"
-#include "android_webview/browser/browser_view_renderer_client.h"
+#include "android_webview/browser/deferred_gpu_command_service.h"
+#include "android_webview/browser/parent_output_surface.h"
+#include "android_webview/browser/shared_renderer_state.h"
#include "android_webview/public/browser/draw_gl.h"
+#include "base/auto_reset.h"
#include "base/debug/trace_event.h"
#include "base/strings/string_number_conversions.h"
-#include "content/public/browser/android/synchronous_compositor.h"
-#include "content/public/browser/browser_thread.h"
-#include "gpu/command_buffer/service/shader_translator_cache.h"
+#include "cc/layers/delegated_frame_provider.h"
+#include "cc/layers/delegated_renderer_layer.h"
+#include "cc/layers/layer.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/output_surface.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_settings.h"
+#include "gpu/command_buffer/client/gl_in_process_context.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/transform.h"
#include "ui/gl/gl_bindings.h"
+#include "webkit/common/gpu/context_provider_in_process.h"
+#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
namespace android_webview {
+namespace {
+
+using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
+
+scoped_refptr<cc::ContextProvider> CreateContext(
+ scoped_refptr<gfx::GLSurface> surface,
+ scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
+ gpu::GLInProcessContext* share_context) {
+ const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+
+ blink::WebGraphicsContext3D::Attributes attributes;
+ attributes.antialias = false;
+ attributes.depth = false;
+ attributes.stencil = false;
+ attributes.shareResources = true;
+ attributes.noAutomaticFlushes = true;
+ gpu::GLInProcessContextAttribs in_process_attribs;
+ WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
+ attributes, &in_process_attribs);
+ in_process_attribs.lose_context_when_out_of_memory = 1;
+
+ scoped_ptr<gpu::GLInProcessContext> context(
+ gpu::GLInProcessContext::Create(service,
+ surface,
+ surface->IsOffscreen(),
+ gfx::kNullAcceleratedWidget,
+ surface->GetSize(),
+ share_context,
+ false /* share_resources */,
+ in_process_attribs,
+ gpu_preference));
+ DCHECK(context.get());
+
+ return webkit::gpu::ContextProviderInProcess::Create(
+ WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
+ context.Pass(), attributes),
+ "Parent-Compositor");
+}
+
+} // namespace
+
HardwareRenderer::HardwareRenderer(SharedRendererState* state)
: shared_renderer_state_(state),
- last_egl_context_(eglGetCurrentContext()) {
+ last_egl_context_(eglGetCurrentContext()),
+ view_width_(-1),
+ view_height_(-1),
+ viewport_clip_valid_for_dcheck_(false),
+ root_layer_(cc::Layer::Create()),
+ output_surface_(NULL) {
DCHECK(last_egl_context_);
gl_surface_ = new AwGLSurface;
- bool success =
- shared_renderer_state_->GetCompositor()->
- InitializeHwDraw(gl_surface_);
- DCHECK(success);
+
+ cc::LayerTreeSettings settings;
+
+ // Should be kept in sync with compositor_impl_android.cc.
+ settings.allow_antialiasing = false;
+ settings.highp_threshold_min = 2048;
+
+ // Webview does not own the surface so should not clear it.
+ settings.should_clear_root_render_pass = false;
+
+ layer_tree_host_ =
+ cc::LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings);
+ layer_tree_host_->SetRootLayer(root_layer_);
+ layer_tree_host_->SetLayerTreeHostClientReady();
}
HardwareRenderer::~HardwareRenderer() {
- shared_renderer_state_->GetCompositor()->ReleaseHwDraw();
- gl_surface_ = NULL;
+ // Must reset everything before |resource_collection_| to ensure all
+ // resources are returned before resetting |resource_collection_| client.
+ layer_tree_host_.reset();
+ root_layer_ = NULL;
+ delegated_layer_ = NULL;
+ frame_provider_ = NULL;
+ if (resource_collection_.get()) {
+#if DCHECK_IS_ON
+ // Check collection is empty.
+ cc::ReturnedResourceArray returned_resources;
+ resource_collection_->TakeUnusedResourcesForChildCompositor(
+ &returned_resources);
+ DCHECK_EQ(0u, returned_resources.size());
+#endif // DCHECK_IS_ON
+
+ resource_collection_->SetClient(NULL);
+ }
+}
+
+void HardwareRenderer::DidBeginMainFrame() {
+ // This is called after OutputSurface is created, but before the impl frame
+ // starts. We set the draw constraints here.
+ DCHECK(output_surface_);
+ DCHECK(viewport_clip_valid_for_dcheck_);
+ output_surface_->SetDrawConstraints(viewport_, clip_);
}
bool HardwareRenderer::DrawGL(bool stencil_enabled,
@@ -54,54 +144,84 @@ bool HardwareRenderer::DrawGL(bool stencil_enabled,
if (last_egl_context_ != current_context)
DLOG(WARNING) << "EGLContextChanged";
- if (draw_info->mode != AwDrawGLInfo::kModeDraw)
- return false;
+ scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput();
+ if (!resource_collection_.get()) {
+ resource_collection_ = new cc::DelegatedFrameResourceCollection;
+ resource_collection_->SetClient(this);
+ }
- // Should only need to access SharedRendererState in kModeDraw and kModeSync.
- const DrawGLInput input = shared_renderer_state_->GetDrawGLInput();
- SetCompositorMemoryPolicy();
+ if (input.get()) {
+ DCHECK(!input->frame.gl_frame_data);
+ DCHECK(!input->frame.software_frame_data);
+
+ bool size_changed =
+ input->width != view_width_ || input->height != view_height_;
+ view_width_ = input->width;
+ view_height_ = input->height;
+ scroll_offset_ = input->scroll_offset;
+
+ if (!frame_provider_ || size_changed) {
+ if (delegated_layer_) {
+ delegated_layer_->RemoveFromParent();
+ }
+
+ frame_provider_ = new cc::DelegatedFrameProvider(
+ resource_collection_.get(), input->frame.delegated_frame_data.Pass());
+
+ delegated_layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
+ delegated_layer_->SetBounds(gfx::Size(view_width_, view_height_));
+ delegated_layer_->SetIsDrawable(true);
+ delegated_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
+
+ root_layer_->AddChild(delegated_layer_);
+ } else {
+ frame_provider_->SetFrameData(input->frame.delegated_frame_data.Pass());
+ }
+ }
- gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
+ viewport_.SetSize(draw_info->width, draw_info->height);
+ layer_tree_host_->SetViewportSize(viewport_);
+ clip_.SetRect(draw_info->clip_left,
+ draw_info->clip_top,
+ draw_info->clip_right - draw_info->clip_left,
+ draw_info->clip_bottom - draw_info->clip_top);
- gfx::Transform transform;
+ gfx::Transform transform(gfx::Transform::kSkipInitialization);
transform.matrix().setColMajorf(draw_info->transform);
- transform.Translate(input.scroll_offset.x(), input.scroll_offset.y());
- gfx::Rect clip_rect(draw_info->clip_left,
- draw_info->clip_top,
- draw_info->clip_right - draw_info->clip_left,
- draw_info->clip_bottom - draw_info->clip_top);
-
- gfx::Rect viewport(draw_info->width, draw_info->height);
- if (!draw_info->is_layer) {
- gfx::RectF view_rect(input.width, input.height);
- transform.TransformRect(&view_rect);
- viewport.Intersect(gfx::ToEnclosingRect(view_rect));
- }
+ transform.Translate(scroll_offset_.x(), scroll_offset_.y());
+ delegated_layer_->SetTransform(transform);
- bool did_draw = shared_renderer_state_->GetCompositor()->DemandDrawHw(
- gfx::Size(draw_info->width, draw_info->height),
- transform,
- viewport,
- clip_rect,
- stencil_enabled);
+ gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
+ {
+ base::AutoReset<bool> frame_resetter(&viewport_clip_valid_for_dcheck_,
+ true);
+ layer_tree_host_->SetNeedsRedrawRect(clip_);
+ layer_tree_host_->Composite(gfx::FrameTime::Now());
+ }
gl_surface_->ResetBackingFrameBufferObject();
- if (did_draw) {
- result->frame_id = input.frame_id;
- result->clip_contains_visible_rect =
- clip_rect.Contains(input.global_visible_rect);
- }
- return did_draw;
+ return true;
}
-void HardwareRenderer::SetCompositorMemoryPolicy() {
- if (shared_renderer_state_->IsMemoryPolicyDirty()) {
- content::SynchronousCompositorMemoryPolicy policy =
- shared_renderer_state_->GetMemoryPolicy();
- // Memory policy is set by BrowserViewRenderer on UI thread.
- shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy);
- shared_renderer_state_->SetMemoryPolicyDirty(false);
- }
+scoped_ptr<cc::OutputSurface> HardwareRenderer::CreateOutputSurface(
+ bool fallback) {
+ // Android webview does not support losing output surface.
+ DCHECK(!fallback);
+ scoped_refptr<cc::ContextProvider> context_provider =
+ CreateContext(gl_surface_,
+ DeferredGpuCommandService::GetInstance(),
+ shared_renderer_state_->GetSharedContext());
+ scoped_ptr<ParentOutputSurface> output_surface_holder(
+ new ParentOutputSurface(context_provider));
+ output_surface_ = output_surface_holder.get();
+ return output_surface_holder.PassAs<cc::OutputSurface>();
+}
+
+void HardwareRenderer::UnusedResourcesAreAvailable() {
+ cc::ReturnedResourceArray returned_resources;
+ resource_collection_->TakeUnusedResourcesForChildCompositor(
+ &returned_resources);
+ shared_renderer_state_->InsertReturnedResources(returned_resources);
}
} // namespace android_webview
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h
index 169bbd3a5c..8adbf0e9e3 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/hardware_renderer.h
@@ -5,46 +5,93 @@
#ifndef ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_
#define ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_
-#include <queue>
-
+#include "android_webview/browser/hardware_renderer_interface.h"
#include "android_webview/browser/shared_renderer_state.h"
-#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/thread_local.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
+#include "cc/trees/layer_tree_host_client.h"
+#include "cc/trees/layer_tree_host_single_thread_client.h"
struct AwDrawGLInfo;
+namespace cc {
+class DelegatedFrameProvider;
+class DelegatedRendererLayer;
+class Layer;
+class LayerTreeHost;
+}
+
namespace android_webview {
class AwGLSurface;
-class BrowserViewRendererClient;
-
-namespace internal {
-class DeferredGpuCommandService;
-} // namespace internal
+class ParentOutputSurface;
-class HardwareRenderer {
+class HardwareRenderer : public HardwareRendererInterface,
+ public cc::LayerTreeHostClient,
+ public cc::LayerTreeHostSingleThreadClient,
+ public cc::DelegatedFrameResourceCollectionClient {
public:
explicit HardwareRenderer(SharedRendererState* state);
- ~HardwareRenderer();
-
- bool DrawGL(bool stencil_enabled,
- int framebuffer_binding_ext,
- AwDrawGLInfo* draw_info,
- DrawGLResult* result);
+ virtual ~HardwareRenderer();
+
+ // HardwareRendererInterface overrides.
+ virtual bool DrawGL(bool stencil_enabled,
+ int framebuffer_binding_ext,
+ AwDrawGLInfo* draw_info,
+ DrawGLResult* result) OVERRIDE;
+
+ // cc::LayerTreeHostClient overrides.
+ virtual void WillBeginMainFrame(int frame_id) OVERRIDE {}
+ virtual void DidBeginMainFrame() OVERRIDE;
+ virtual void Animate(base::TimeTicks frame_begin_time) OVERRIDE {}
+ virtual void Layout() OVERRIDE {}
+ virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
+ float page_scale) OVERRIDE {}
+ virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
+ bool fallback) OVERRIDE;
+ virtual void DidInitializeOutputSurface() OVERRIDE {}
+ virtual void WillCommit() OVERRIDE {}
+ virtual void DidCommit() OVERRIDE {}
+ virtual void DidCommitAndDrawFrame() OVERRIDE {}
+ virtual void DidCompleteSwapBuffers() OVERRIDE {}
+
+ // cc::LayerTreeHostSingleThreadClient overrides.
+ virtual void ScheduleComposite() OVERRIDE {}
+ virtual void ScheduleAnimation() OVERRIDE {}
+ virtual void DidPostSwapBuffers() OVERRIDE {}
+ virtual void DidAbortSwapBuffers() OVERRIDE {}
+
+ // cc::DelegatedFrameResourceCollectionClient overrides.
+ virtual void UnusedResourcesAreAvailable() OVERRIDE;
private:
- friend class internal::DeferredGpuCommandService;
-
- void SetCompositorMemoryPolicy();
-
SharedRendererState* shared_renderer_state_;
typedef void* EGLContext;
EGLContext last_egl_context_;
+ // Information about last delegated frame.
+ int view_width_;
+ int view_height_;
+ gfx::Vector2d scroll_offset_;
+
+ // Information from draw.
+ gfx::Size viewport_;
+ gfx::Rect clip_;
+ bool viewport_clip_valid_for_dcheck_;
+
scoped_refptr<AwGLSurface> gl_surface_;
+ scoped_ptr<cc::LayerTreeHost> layer_tree_host_;
+ scoped_refptr<cc::Layer> root_layer_;
+
+ scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
+ scoped_refptr<cc::DelegatedRendererLayer> delegated_layer_;
+
+ // This is owned indirectly by |layer_tree_host_|.
+ ParentOutputSurface* output_surface_;
+
DISALLOW_COPY_AND_ASSIGN(HardwareRenderer);
};
diff --git a/android_webview/browser/hardware_renderer_interface.h b/android_webview/browser/hardware_renderer_interface.h
new file mode 100644
index 0000000000..c827243a1f
--- /dev/null
+++ b/android_webview/browser/hardware_renderer_interface.h
@@ -0,0 +1,26 @@
+// Copyright 2014 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_HARDWARE_RENDERER_INTERFACE_H_
+#define ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_INTERFACE_H_
+
+struct AwDrawGLInfo;
+
+namespace android_webview {
+
+struct DrawGLResult;
+
+class HardwareRendererInterface {
+ public:
+ virtual ~HardwareRendererInterface() {}
+
+ virtual bool DrawGL(bool stencil_enabled,
+ int framebuffer_binding_ext,
+ AwDrawGLInfo* draw_info,
+ DrawGLResult* result) = 0;
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_INTERFACE_H_
diff --git a/android_webview/browser/hardware_renderer_legacy.cc b/android_webview/browser/hardware_renderer_legacy.cc
new file mode 100644
index 0000000000..ade6be94fa
--- /dev/null
+++ b/android_webview/browser/hardware_renderer_legacy.cc
@@ -0,0 +1,106 @@
+// Copyright 2014 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/hardware_renderer_legacy.h"
+
+#include "android_webview/browser/aw_gl_surface.h"
+#include "android_webview/browser/shared_renderer_state.h"
+#include "android_webview/public/browser/draw_gl.h"
+#include "base/debug/trace_event.h"
+#include "base/strings/string_number_conversions.h"
+#include "cc/output/compositor_frame.h"
+#include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/browser/browser_thread.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/transform.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace android_webview {
+
+HardwareRendererLegacy::HardwareRendererLegacy(SharedRendererState* state)
+ : shared_renderer_state_(state), last_egl_context_(eglGetCurrentContext()) {
+ DCHECK(last_egl_context_);
+
+ gl_surface_ = new AwGLSurface;
+ bool success =
+ shared_renderer_state_->GetCompositor()->InitializeHwDraw(gl_surface_);
+ DCHECK(success);
+}
+
+HardwareRendererLegacy::~HardwareRendererLegacy() {
+ draw_gl_input_ = shared_renderer_state_->PassDrawGLInput();
+ shared_renderer_state_->GetCompositor()->ReleaseHwDraw();
+ gl_surface_ = NULL;
+}
+
+bool HardwareRendererLegacy::DrawGL(bool stencil_enabled,
+ int framebuffer_binding_ext,
+ AwDrawGLInfo* draw_info,
+ DrawGLResult* result) {
+ TRACE_EVENT0("android_webview", "HardwareRendererLegacy::DrawGL");
+
+ // We need to watch if the current Android context has changed and enforce
+ // a clean-up in the compositor.
+ EGLContext current_context = eglGetCurrentContext();
+ if (!current_context) {
+ DLOG(ERROR) << "DrawGL called without EGLContext";
+ return false;
+ }
+
+ // TODO(boliu): Handle context loss.
+ if (last_egl_context_ != current_context)
+ DLOG(WARNING) << "EGLContextChanged";
+
+ // Should only need to access SharedRendererState in kModeDraw and kModeSync.
+ scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput();
+ if (input.get())
+ draw_gl_input_ = input.Pass();
+ SetCompositorMemoryPolicy();
+
+ gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
+
+ gfx::Transform transform;
+ transform.matrix().setColMajorf(draw_info->transform);
+ transform.Translate(draw_gl_input_->scroll_offset.x(),
+ draw_gl_input_->scroll_offset.y());
+ gfx::Rect clip_rect(draw_info->clip_left,
+ draw_info->clip_top,
+ draw_info->clip_right - draw_info->clip_left,
+ draw_info->clip_bottom - draw_info->clip_top);
+
+ gfx::Rect viewport(draw_info->width, draw_info->height);
+ if (!draw_info->is_layer) {
+ gfx::RectF view_rect(draw_gl_input_->width, draw_gl_input_->height);
+ transform.TransformRect(&view_rect);
+ viewport.Intersect(gfx::ToEnclosingRect(view_rect));
+ }
+
+ scoped_ptr<cc::CompositorFrame> frame =
+ shared_renderer_state_->GetCompositor()->DemandDrawHw(
+ gfx::Size(draw_info->width, draw_info->height),
+ transform,
+ viewport,
+ clip_rect,
+ framebuffer_binding_ext);
+ gl_surface_->ResetBackingFrameBufferObject();
+
+ if (frame.get()) {
+ result->clip_contains_visible_rect =
+ clip_rect.Contains(draw_gl_input_->global_visible_rect);
+ }
+ return !!frame.get();
+}
+
+void HardwareRendererLegacy::SetCompositorMemoryPolicy() {
+ if (shared_renderer_state_->IsMemoryPolicyDirty()) {
+ content::SynchronousCompositorMemoryPolicy policy =
+ shared_renderer_state_->GetMemoryPolicy();
+ // Memory policy is set by BrowserViewRenderer on UI thread.
+ shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy);
+ shared_renderer_state_->SetMemoryPolicyDirty(false);
+ }
+}
+
+} // namespace android_webview
diff --git a/android_webview/browser/hardware_renderer_legacy.h b/android_webview/browser/hardware_renderer_legacy.h
new file mode 100644
index 0000000000..a92fe9b32a
--- /dev/null
+++ b/android_webview/browser/hardware_renderer_legacy.h
@@ -0,0 +1,46 @@
+// Copyright 2014 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_HARDWARE_RENDERER_LEGACY_H_
+#define ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_LEGACY_H_
+
+#include "android_webview/browser/hardware_renderer_interface.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+
+struct AwDrawGLInfo;
+
+namespace android_webview {
+
+class AwGLSurface;
+class SharedRendererState;
+struct DrawGLInput;
+
+class HardwareRendererLegacy : public HardwareRendererInterface {
+ public:
+ explicit HardwareRendererLegacy(SharedRendererState* state);
+ virtual ~HardwareRendererLegacy();
+
+ virtual bool DrawGL(bool stencil_enabled,
+ int framebuffer_binding_ext,
+ AwDrawGLInfo* draw_info,
+ DrawGLResult* result) OVERRIDE;
+
+ private:
+ void SetCompositorMemoryPolicy();
+
+ SharedRendererState* shared_renderer_state_;
+ scoped_ptr<DrawGLInput> draw_gl_input_;
+
+ typedef void* EGLContext;
+ EGLContext last_egl_context_;
+
+ scoped_refptr<AwGLSurface> gl_surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(HardwareRendererLegacy);
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_LEGACY_H_
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index 2850b4459d..d456af2ef1 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/aw_request_interceptor.h"
#include "android_webview/browser/net/aw_network_delegate.h"
@@ -30,11 +31,13 @@
#include "net/http/http_cache.h"
#include "net/http/http_stream_factory.h"
#include "net/proxy/proxy_service.h"
+#include "net/socket/next_proto.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
-#include "net/url_request/protocol_intercept_job_factory.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_intercepting_job_factory.h"
+#include "net/url_request/url_request_interceptor.h"
using content::BrowserThread;
using data_reduction_proxy::DataReductionProxySettings;
@@ -89,6 +92,11 @@ void PopulateNetworkSessionParams(
params->network_delegate = context->network_delegate();
params->http_server_properties = context->http_server_properties();
params->net_log = context->net_log();
+
+ // TODO(sgurun) remove once crbug.com/329681 is fixed.
+ params->next_protos = net::NextProtosSpdy31();
+ params->use_alternate_protocols = true;
+
ApplyCmdlineOverridesToNetworkSessionParams(params);
}
@@ -96,22 +104,22 @@ scoped_ptr<net::URLRequestJobFactory> CreateJobFactory(
content::ProtocolHandlerMap* protocol_handlers) {
scoped_ptr<AwURLRequestJobFactory> aw_job_factory(new AwURLRequestJobFactory);
bool set_protocol = aw_job_factory->SetProtocolHandler(
- content::kFileScheme,
+ url::kFileScheme,
new net::FileProtocolHandler(
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
DCHECK(set_protocol);
set_protocol = aw_job_factory->SetProtocolHandler(
- content::kDataScheme, new net::DataProtocolHandler());
+ url::kDataScheme, new net::DataProtocolHandler());
DCHECK(set_protocol);
set_protocol = aw_job_factory->SetProtocolHandler(
- content::kBlobScheme,
- (*protocol_handlers)[content::kBlobScheme].release());
+ url::kBlobScheme,
+ (*protocol_handlers)[url::kBlobScheme].release());
DCHECK(set_protocol);
set_protocol = aw_job_factory->SetProtocolHandler(
- content::kFileSystemScheme,
- (*protocol_handlers)[content::kFileSystemScheme].release());
+ url::kFileSystemScheme,
+ (*protocol_handlers)[url::kFileSystemScheme].release());
DCHECK(set_protocol);
set_protocol = aw_job_factory->SetProtocolHandler(
content::kChromeUIScheme,
@@ -124,36 +132,36 @@ scoped_ptr<net::URLRequestJobFactory> CreateJobFactory(
protocol_handlers->clear();
// Create a chain of URLRequestJobFactories. The handlers will be invoked
- // in the order in which they appear in the protocol_handlers vector.
- typedef std::vector<net::URLRequestJobFactory::ProtocolHandler*>
- ProtocolHandlerVector;
- ProtocolHandlerVector protocol_interceptors;
+ // in the order in which they appear in the |request_interceptors| vector.
+ typedef std::vector<net::URLRequestInterceptor*>
+ URLRequestInterceptorVector;
+ URLRequestInterceptorVector request_interceptors;
// Note that even though the content:// scheme handler is created here,
// it cannot be used by child processes until access to it is granted via
// ChildProcessSecurityPolicy::GrantScheme(). This is done in
// AwContentBrowserClient.
- protocol_interceptors.push_back(
- CreateAndroidContentProtocolHandler().release());
- protocol_interceptors.push_back(
- CreateAndroidAssetFileProtocolHandler().release());
+ request_interceptors.push_back(
+ CreateAndroidContentRequestInterceptor().release());
+ request_interceptors.push_back(
+ CreateAndroidAssetFileRequestInterceptor().release());
// The AwRequestInterceptor must come after the content and asset file job
// factories. This for WebViewClassic compatibility where it was not
// possible to intercept resource loads to resolvable content:// and
// file:// URIs.
// This logical dependency is also the reason why the Content
- // ProtocolHandler has to be added as a ProtocolInterceptJobFactory rather
- // than via SetProtocolHandler.
- protocol_interceptors.push_back(new AwRequestInterceptor());
+ // URLRequestInterceptor has to be added as an interceptor rather than as a
+ // ProtocolHandler.
+ request_interceptors.push_back(new AwRequestInterceptor());
// The chain of responsibility will execute the handlers in reverse to the
// order in which the elements of the chain are created.
scoped_ptr<net::URLRequestJobFactory> job_factory(aw_job_factory.Pass());
- for (ProtocolHandlerVector::reverse_iterator
- i = protocol_interceptors.rbegin();
- i != protocol_interceptors.rend();
+ for (URLRequestInterceptorVector::reverse_iterator
+ i = request_interceptors.rbegin();
+ i != request_interceptors.rend();
++i) {
- job_factory.reset(new net::ProtocolInterceptJobFactory(
+ job_factory.reset(new net::URLRequestInterceptingJobFactory(
job_factory.Pass(), make_scoped_ptr(*i)));
}
@@ -215,8 +223,18 @@ void AwURLRequestContextGetter::InitializeURLRequestContext() {
20 * 1024 * 1024, // 20M
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)));
+ AwBrowserContext* browser_context = AwBrowserContext::GetDefault();
+ DCHECK(browser_context);
+ DataReductionProxySettings* drp_settings =
+ browser_context->GetDataReductionProxySettings();
+ DCHECK(drp_settings);
+ std::string drp_key = drp_settings->key();
+ // Only precache credentials if a key is available at URLRequestContext
+ // initialization.
+ if (!drp_key.empty()) {
DataReductionProxySettings::InitDataReductionProxySession(
- main_cache->GetSession());
+ main_cache->GetSession(), drp_settings->key());
+ }
main_http_factory_.reset(main_cache);
url_request_context_->set_http_transaction_factory(main_cache);
@@ -224,10 +242,6 @@ void AwURLRequestContextGetter::InitializeURLRequestContext() {
job_factory_ = CreateJobFactory(&protocol_handlers_);
url_request_context_->set_job_factory(job_factory_.get());
-
- // TODO(sgurun) remove once crbug.com/329681 is fixed. Should be
- // called only once.
- net::HttpStreamFactory::EnableNpnSpdy31();
}
net::URLRequestContext* AwURLRequestContextGetter::GetURLRequestContext() {
diff --git a/android_webview/browser/net/init_native_callback.h b/android_webview/browser/net/init_native_callback.h
index 5f48e4cb83..d98867cff4 100644
--- a/android_webview/browser/net/init_native_callback.h
+++ b/android_webview/browser/net/init_native_callback.h
@@ -7,10 +7,10 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "net/url_request/url_request_job_factory.h"
namespace net {
class CookieStore;
+class URLRequestInterceptor;
} // namespace net
namespace android_webview {
@@ -21,12 +21,12 @@ scoped_refptr<net::CookieStore> CreateCookieStore(
AwBrowserContext* browser_context);
// Called lazily when the job factory is being constructed.
-scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
- CreateAndroidAssetFileProtocolHandler();
+scoped_ptr<net::URLRequestInterceptor>
+ CreateAndroidAssetFileRequestInterceptor();
// Called lazily when the job factory is being constructed.
-scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
- CreateAndroidContentProtocolHandler();
+scoped_ptr<net::URLRequestInterceptor>
+ CreateAndroidContentRequestInterceptor();
} // namespace android_webview
diff --git a/android_webview/browser/parent_output_surface.cc b/android_webview/browser/parent_output_surface.cc
new file mode 100644
index 0000000000..0150eaa555
--- /dev/null
+++ b/android_webview/browser/parent_output_surface.cc
@@ -0,0 +1,35 @@
+// Copyright 2014 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/parent_output_surface.h"
+
+#include "cc/output/output_surface_client.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+
+namespace android_webview {
+
+ParentOutputSurface::ParentOutputSurface(
+ scoped_refptr<cc::ContextProvider> context_provider)
+ : cc::OutputSurface(context_provider) {
+ capabilities_.draw_and_swap_full_viewport_every_frame = true;
+}
+
+ParentOutputSurface::~ParentOutputSurface() {
+}
+
+void ParentOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
+ context_provider_->ContextGL()->ShallowFlushCHROMIUM();
+ client_->DidSwapBuffers();
+}
+
+void ParentOutputSurface::SetDrawConstraints(const gfx::Size& surface_size,
+ const gfx::Rect& clip) {
+ DCHECK(client_);
+ surface_size_ = surface_size;
+ gfx::Transform identity;
+ gfx::Rect empty;
+ SetExternalDrawConstraints(identity, empty, clip, true);
+}
+
+} // namespace android_webview
diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/parent_output_surface.h
new file mode 100644
index 0000000000..88dabae040
--- /dev/null
+++ b/android_webview/browser/parent_output_surface.h
@@ -0,0 +1,30 @@
+// Copyright 2014 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_PARENT_OUTPUT_SURFACE_H_
+#define ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_
+
+#include "cc/output/output_surface.h"
+
+namespace android_webview {
+
+class ParentOutputSurface : NON_EXPORTED_BASE(public cc::OutputSurface) {
+ public:
+ explicit ParentOutputSurface(
+ scoped_refptr<cc::ContextProvider> context_provider);
+ virtual ~ParentOutputSurface();
+
+ // OutputSurface overrides.
+ virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {}
+ virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE;
+
+ void SetDrawConstraints(const gfx::Size& surface_size, const gfx::Rect& clip);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ParentOutputSurface);
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
index 05eb520945..8872dd776d 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -20,11 +20,11 @@
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/resource_throttle.h"
-#include "content/public/common/url_constants.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
+#include "url/url_constants.h"
using android_webview::AwContentsIoThreadClient;
using content::BrowserThread;
@@ -170,7 +170,7 @@ bool IoThreadClientThrottle::ShouldBlockRequest() {
}
if (io_client->ShouldBlockNetworkLoads()) {
- if (request_->url().SchemeIs(content::kFtpScheme)) {
+ if (request_->url().SchemeIs(url::kFtpScheme)) {
return true;
}
SetCacheControlFlag(request_, net::LOAD_ONLY_FROM_CACHE);
diff --git a/android_webview/browser/scoped_app_gl_state_restore.cc b/android_webview/browser/scoped_app_gl_state_restore.cc
index 71a5711a26..399b36aaf0 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.cc
+++ b/android_webview/browser/scoped_app_gl_state_restore.cc
@@ -51,6 +51,17 @@ void GLEnableDisable(GLenum cap, bool enable) {
glDisable(cap);
}
+bool ClearGLErrors(bool warn, const char* msg) {
+ bool no_error = true;
+ GLenum error;
+ while ((error = glGetError()) != GL_NO_ERROR) {
+ DLOG_IF(WARNING, warn) << error << " " << msg;
+ no_error = false;
+ }
+
+ return no_error;
+}
+
bool g_globals_initialized = false;
GLint g_gl_max_texture_units = 0;
bool g_supports_oes_vertex_array_object = false;
@@ -148,6 +159,8 @@ ScopedAppGLStateRestoreImpl::ScopedAppGLStateRestoreImpl(
TRACE_EVENT0("android_webview", "AppGLStateSave");
MakeAppContextCurrent();
+ ClearGLErrors(true, "Incoming GLError");
+
if (!g_globals_initialized) {
g_globals_initialized = true;
@@ -251,12 +264,15 @@ ScopedAppGLStateRestoreImpl::ScopedAppGLStateRestoreImpl(
glGetVertexAttribfv(
i, GL_CURRENT_VERTEX_ATTRIB, vertex_attrib_[i].current_vertex_attrib);
}
+ DCHECK(ClearGLErrors(false, NULL));
}
ScopedAppGLStateRestoreImpl::~ScopedAppGLStateRestoreImpl() {
TRACE_EVENT0("android_webview", "AppGLStateRestore");
MakeAppContextCurrent();
+ DCHECK(ClearGLErrors(false, NULL));
+
glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_);
@@ -347,6 +363,9 @@ ScopedAppGLStateRestoreImpl::~ScopedAppGLStateRestoreImpl() {
GLEnableDisable(GL_STENCIL_TEST, stencil_test_);
glStencilFunc(stencil_func_, stencil_mask_, stencil_ref_);
+
+ // Do not leak GLError out of chromium.
+ ClearGLErrors(true, "Chromium GLError");
}
} // namespace internal
diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc
index 3483d630e7..42a42450ac 100644
--- a/android_webview/browser/shared_renderer_state.cc
+++ b/android_webview/browser/shared_renderer_state.cc
@@ -10,9 +10,14 @@
namespace android_webview {
-DrawGLInput::DrawGLInput() : frame_id(0), width(0), height(0) {}
+DrawGLInput::DrawGLInput() : width(0), height(0) {
+}
+
+DrawGLInput::~DrawGLInput() {
+}
-DrawGLResult::DrawGLResult() : frame_id(0), clip_contains_visible_rect(false) {}
+DrawGLResult::DrawGLResult() : clip_contains_visible_rect(false) {
+}
SharedRendererState::SharedRendererState(
scoped_refptr<base::MessageLoopProxy> ui_loop,
@@ -23,7 +28,9 @@ SharedRendererState::SharedRendererState(
ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()),
compositor_(NULL),
memory_policy_dirty_(false),
- hardware_initialized_(false) {
+ hardware_allowed_(false),
+ hardware_initialized_(false),
+ share_context_(NULL) {
DCHECK(ui_loop_->BelongsToCurrentThread());
DCHECK(client_on_ui_);
}
@@ -76,37 +83,25 @@ SharedRendererState::GetMemoryPolicy() const {
return memory_policy_;
}
-void SharedRendererState::SetDrawGLInput(const DrawGLInput& input) {
- base::AutoLock lock(lock_);
- draw_gl_input_ = input;
-}
-
-DrawGLInput SharedRendererState::GetDrawGLInput() const {
+void SharedRendererState::SetDrawGLInput(scoped_ptr<DrawGLInput> input) {
base::AutoLock lock(lock_);
- return draw_gl_input_;
+ DCHECK(!draw_gl_input_.get());
+ draw_gl_input_ = input.Pass();
}
-void SharedRendererState::ClearClosureQueue() {
+scoped_ptr<DrawGLInput> SharedRendererState::PassDrawGLInput() {
base::AutoLock lock(lock_);
- std::queue<base::Closure> empty;
- std::swap(closure_queue_, empty);
+ return draw_gl_input_.Pass();
}
-void SharedRendererState::AppendClosure(const base::Closure& closure) {
+void SharedRendererState::SetHardwareAllowed(bool allowed) {
base::AutoLock lock(lock_);
- closure_queue_.push(closure);
+ hardware_allowed_ = allowed;
}
-base::Closure SharedRendererState::PopFrontClosure() {
- base::Closure closure;
-
+bool SharedRendererState::IsHardwareAllowed() const {
base::AutoLock lock(lock_);
- if (!closure_queue_.empty()) {
- closure = closure_queue_.front();
- closure_queue_.pop();
- }
-
- return closure;
+ return hardware_allowed_;
}
void SharedRendererState::SetHardwareInitialized(bool initialized) {
@@ -119,6 +114,18 @@ bool SharedRendererState::IsHardwareInitialized() const {
return hardware_initialized_;
}
+void SharedRendererState::SetSharedContext(gpu::GLInProcessContext* context) {
+ base::AutoLock lock(lock_);
+ DCHECK(!share_context_ || !context);
+ share_context_ = context;
+}
+
+gpu::GLInProcessContext* SharedRendererState::GetSharedContext() const {
+ base::AutoLock lock(lock_);
+ DCHECK(share_context_);
+ return share_context_;
+}
+
void SharedRendererState::SetMemoryPolicyDirty(bool is_dirty) {
base::AutoLock lock(lock_);
memory_policy_dirty_ = is_dirty;
@@ -129,4 +136,28 @@ bool SharedRendererState::IsMemoryPolicyDirty() const {
return memory_policy_dirty_;
}
+void SharedRendererState::ReturnResources(
+ const cc::TransferableResourceArray& input) {
+ base::AutoLock lock(lock_);
+ cc::TransferableResource::ReturnResources(input, &returned_resources_);
+}
+
+void SharedRendererState::InsertReturnedResources(
+ const cc::ReturnedResourceArray& resources) {
+ base::AutoLock lock(lock_);
+ returned_resources_.insert(
+ returned_resources_.end(), resources.begin(), resources.end());
+}
+
+void SharedRendererState::SwapReturnedResources(
+ cc::ReturnedResourceArray* resources) {
+ base::AutoLock lock(lock_);
+ resources->swap(returned_resources_);
+}
+
+bool SharedRendererState::ReturnedResourcesEmpty() const {
+ base::AutoLock lock(lock_);
+ return returned_resources_.empty();
+}
+
} // namespace android_webview
diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h
index 9c90731d7a..8350c9dfc3 100644
--- a/android_webview/browser/shared_renderer_state.h
+++ b/android_webview/browser/shared_renderer_state.h
@@ -5,33 +5,40 @@
#ifndef ANDROID_WEBVIEW_BROWSER_SHARED_RENDERER_STATE_H_
#define ANDROID_WEBVIEW_BROWSER_SHARED_RENDERER_STATE_H_
-#include <queue>
-
-#include "base/callback.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/synchronization/lock.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/compositor_frame_ack.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
+namespace cc {
+class CompositorFrameAck;
+}
+
+namespace gpu {
+class GLInProcessContext;
+}
+
namespace android_webview {
class BrowserViewRendererClient;
// Set by BrowserViewRenderer and read by HardwareRenderer.
struct DrawGLInput {
- unsigned int frame_id;
gfx::Rect global_visible_rect;
gfx::Vector2d scroll_offset;
int width;
int height;
+ cc::CompositorFrame frame;
DrawGLInput();
+ ~DrawGLInput();
};
// Set by HardwareRenderer and read by BrowserViewRenderer.
struct DrawGLResult {
- unsigned int frame_id;
bool clip_contains_visible_rect;
DrawGLResult();
@@ -61,17 +68,25 @@ class SharedRendererState {
void SetMemoryPolicyDirty(bool is_dirty);
bool IsMemoryPolicyDirty() const;
- void SetDrawGLInput(const DrawGLInput& input);
- DrawGLInput GetDrawGLInput() const;
+ void SetDrawGLInput(scoped_ptr<DrawGLInput> input);
+ scoped_ptr<DrawGLInput> PassDrawGLInput();
- void ClearClosureQueue();
- void AppendClosure(const base::Closure& closure);
- // Will return empty closure if queue empty.
- base::Closure PopFrontClosure();
+ // Set by UI and read by RT.
+ void SetHardwareAllowed(bool allowed);
+ bool IsHardwareAllowed() const;
+ // Set by RT and read by UI.
void SetHardwareInitialized(bool initialized);
bool IsHardwareInitialized() const;
+ void SetSharedContext(gpu::GLInProcessContext* context);
+ gpu::GLInProcessContext* GetSharedContext() const;
+
+ void ReturnResources(const cc::TransferableResourceArray& input);
+ void InsertReturnedResources(const cc::ReturnedResourceArray& resources);
+ void SwapReturnedResources(cc::ReturnedResourceArray* resources);
+ bool ReturnedResourcesEmpty() const;
+
private:
void ClientRequestDrawGLOnUIThread();
@@ -88,9 +103,11 @@ class SharedRendererState {
// Set to true when SetMemoryPolicy called with a different memory policy.
// Set to false when memory policy is read and enforced to compositor.
bool memory_policy_dirty_;
- DrawGLInput draw_gl_input_;
- std::queue<base::Closure> closure_queue_;
+ scoped_ptr<DrawGLInput> draw_gl_input_;
+ bool hardware_allowed_;
bool hardware_initialized_;
+ gpu::GLInProcessContext* share_context_;
+ cc::ReturnedResourceArray returned_resources_;
};
} // namespace android_webview