Commit d00f1045 authored by hush's avatar hush Committed by Commit bot

OffscreenPreRaster and its plumbings

If OffscreenPreRaster is enabled, the viewport rect for tile priority
and the tile memory limit calculation will be based on the size of the
webview, instead of the size of visible area of the webview.

Design doc here
https://docs.google.com/document/d/1xOMjvbEIS3dMzpWXWrsl7qV8QOgGEIZL1QxgnfOXmq4/

BUG=460638

Review URL: https://codereview.chromium.org/944053004

Cr-Commit-Position: refs/heads/master@{#318126}
parent 7995ec80
...@@ -68,6 +68,7 @@ BrowserViewRenderer::BrowserViewRenderer( ...@@ -68,6 +68,7 @@ BrowserViewRenderer::BrowserViewRenderer(
page_scale_factor_(1.0), page_scale_factor_(1.0),
on_new_picture_enable_(false), on_new_picture_enable_(false),
clear_view_(false), clear_view_(false),
offscreen_pre_raster_(false),
compositor_needs_continuous_invalidate_(false), compositor_needs_continuous_invalidate_(false),
invalidate_after_composite_(false), invalidate_after_composite_(false),
block_invalidates_(false), block_invalidates_(false),
...@@ -128,8 +129,11 @@ size_t BrowserViewRenderer::CalculateDesiredMemoryPolicy() { ...@@ -128,8 +129,11 @@ size_t BrowserViewRenderer::CalculateDesiredMemoryPolicy() {
if (g_memory_override_in_bytes) if (g_memory_override_in_bytes)
return static_cast<size_t>(g_memory_override_in_bytes); return static_cast<size_t>(g_memory_override_in_bytes);
size_t width = last_on_draw_global_visible_rect_.width(); gfx::Rect interest_rect = offscreen_pre_raster_
size_t height = last_on_draw_global_visible_rect_.height(); ? gfx::Rect(size_)
: last_on_draw_global_visible_rect_;
size_t width = interest_rect.width();
size_t height = interest_rect.height();
size_t bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height; size_t bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
// Round up to a multiple of kMemoryAllocationStep. // Round up to a multiple of kMemoryAllocationStep.
bytes_limit = bytes_limit =
...@@ -178,15 +182,6 @@ bool BrowserViewRenderer::OnDrawHardware() { ...@@ -178,15 +182,6 @@ bool BrowserViewRenderer::OnDrawHardware() {
return false; return false;
} }
if (last_on_draw_global_visible_rect_.IsEmpty() &&
parent_draw_constraints_.surface_rect.IsEmpty()) {
TRACE_EVENT_INSTANT0("android_webview",
"EarlyOut_EmptyVisibleRect",
TRACE_EVENT_SCOPE_THREAD);
shared_renderer_state_.SetForceInvalidateOnNextDrawGLOnUI(true);
return true;
}
ReturnResourceFromParent(); ReturnResourceFromParent();
if (shared_renderer_state_.HasCompositorFrameOnUI()) { if (shared_renderer_state_.HasCompositorFrameOnUI()) {
TRACE_EVENT_INSTANT0("android_webview", TRACE_EVENT_INSTANT0("android_webview",
...@@ -222,11 +217,15 @@ scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { ...@@ -222,11 +217,15 @@ scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() {
// applied onto the layer so global visible rect does not make sense here. // applied onto the layer so global visible rect does not make sense here.
// In this case, just use the surface rect for tiling. // In this case, just use the surface rect for tiling.
gfx::Rect viewport_rect_for_tile_priority; gfx::Rect viewport_rect_for_tile_priority;
if (parent_draw_constraints_.is_layer ||
last_on_draw_global_visible_rect_.IsEmpty()) { // Leave viewport_rect_for_tile_priority empty if offscreen_pre_raster_ is on.
viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect; if (!offscreen_pre_raster_) {
} else { if (parent_draw_constraints_.is_layer ||
viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; last_on_draw_global_visible_rect_.IsEmpty()) {
viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect;
} else {
viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_;
}
} }
scoped_ptr<cc::CompositorFrame> frame = scoped_ptr<cc::CompositorFrame> frame =
...@@ -326,6 +325,11 @@ void BrowserViewRenderer::ClearView() { ...@@ -326,6 +325,11 @@ void BrowserViewRenderer::ClearView() {
EnsureContinuousInvalidation(true, false); EnsureContinuousInvalidation(true, false);
} }
void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) {
// TODO(hush): anything to do when the setting is toggled?
offscreen_pre_raster_ = enable;
}
void BrowserViewRenderer::SetIsPaused(bool paused) { void BrowserViewRenderer::SetIsPaused(bool paused) {
TRACE_EVENT_INSTANT1("android_webview", TRACE_EVENT_INSTANT1("android_webview",
"BrowserViewRenderer::SetIsPaused", "BrowserViewRenderer::SetIsPaused",
......
...@@ -55,6 +55,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { ...@@ -55,6 +55,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
void ClearView(); void ClearView();
void SetOffscreenPreRaster(bool enabled);
// View update notifications. // View update notifications.
void SetIsPaused(bool paused); void SetIsPaused(bool paused);
void SetViewVisibility(bool visible); void SetViewVisibility(bool visible);
...@@ -158,6 +160,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { ...@@ -158,6 +160,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
bool on_new_picture_enable_; bool on_new_picture_enable_;
bool clear_view_; bool clear_view_;
bool offscreen_pre_raster_;
gfx::Vector2d last_on_draw_scroll_offset_; gfx::Vector2d last_on_draw_scroll_offset_;
gfx::Rect last_on_draw_global_visible_rect_; gfx::Rect last_on_draw_global_visible_rect_;
......
...@@ -120,6 +120,7 @@ void FakeWindow::OnDrawHardware() { ...@@ -120,6 +120,7 @@ void FakeWindow::OnDrawHardware() {
on_draw_hardware_pending_ = false; on_draw_hardware_pending_ = false;
hooks_->WillOnDraw(); hooks_->WillOnDraw();
view_->PrepareToDraw(gfx::Vector2d(), location_);
bool success = view_->OnDrawHardware(); bool success = view_->OnDrawHardware();
hooks_->DidOnDraw(success); hooks_->DidOnDraw(success);
if (success) { if (success) {
......
...@@ -88,6 +88,7 @@ public class AwSettings { ...@@ -88,6 +88,7 @@ public class AwSettings {
private boolean mEnableSupportedHardwareAcceleratedFeatures = false; private boolean mEnableSupportedHardwareAcceleratedFeatures = false;
private int mMixedContentMode = MIXED_CONTENT_NEVER_ALLOW; private int mMixedContentMode = MIXED_CONTENT_NEVER_ALLOW;
private boolean mVideoOverlayForEmbeddedVideoEnabled = false; private boolean mVideoOverlayForEmbeddedVideoEnabled = false;
private boolean mOffscreenPreRaster = false;
// Although this bit is stored on AwSettings it is actually controlled via the CookieManager. // Although this bit is stored on AwSettings it is actually controlled via the CookieManager.
private boolean mAcceptThirdPartyCookies = false; private boolean mAcceptThirdPartyCookies = false;
...@@ -1559,6 +1560,45 @@ public class AwSettings { ...@@ -1559,6 +1560,45 @@ public class AwSettings {
|| mMixedContentMode == MIXED_CONTENT_COMPATIBILITY_MODE; || mMixedContentMode == MIXED_CONTENT_COMPATIBILITY_MODE;
} }
public boolean getOffscreenPreRaster() {
synchronized (mAwSettingsLock) {
return getOffscreenPreRasterLocked();
}
}
@CalledByNative
private boolean getOffscreenPreRasterLocked() {
assert Thread.holdsLock(mAwSettingsLock);
return mOffscreenPreRaster;
}
/**
* Sets whether this WebView should raster tiles when it is
* offscreen but attached to window. Turning this on can avoid
* rendering artifacts when animating an offscreen WebView on-screen.
* In particular, insertVisualStateCallback requires this mode to function.
* Offscreen WebViews in this mode uses more memory. Please follow
* these guidelines to limit memory usage:
* - Webview size should be not be larger than the device screen size.
* - Limit simple mode to a small number of webviews. Use it for
*   visible webviews and webviews about to be animated to visible.
*/
public void setOffscreenPreRaster(boolean enabled) {
synchronized (mAwSettingsLock) {
if (enabled != mOffscreenPreRaster) {
mOffscreenPreRaster = enabled;
mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
@Override
public void run() {
if (mNativeAwSettings != 0) {
nativeUpdateOffscreenPreRasterLocked(mNativeAwSettings);
}
}
});
}
}
}
/** /**
* Sets whether to use the video overlay for the embedded video. * Sets whether to use the video overlay for the embedded video.
* @param flag whether to enable the video overlay for the embedded video. * @param flag whether to enable the video overlay for the embedded video.
...@@ -1671,4 +1711,6 @@ public class AwSettings { ...@@ -1671,4 +1711,6 @@ public class AwSettings {
private native void nativeUpdateFormDataPreferencesLocked(long nativeAwSettings); private native void nativeUpdateFormDataPreferencesLocked(long nativeAwSettings);
private native void nativeUpdateRendererPreferencesLocked(long nativeAwSettings); private native void nativeUpdateRendererPreferencesLocked(long nativeAwSettings);
private native void nativeUpdateOffscreenPreRasterLocked(long nativeAwSettings);
} }
...@@ -400,6 +400,11 @@ bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler, ...@@ -400,6 +400,11 @@ bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler,
return true; return true;
} }
void AwContents::SetOffscreenPreRaster(bool enabled) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
browser_view_renderer_.SetOffscreenPreRaster(enabled);
}
void AwContents::AddVisitedLinks(JNIEnv* env, void AwContents::AddVisitedLinks(JNIEnv* env,
jobject obj, jobject obj,
jobjectArray jvisited_links) { jobjectArray jvisited_links) {
......
...@@ -81,6 +81,8 @@ class AwContents : public FindHelper::Listener, ...@@ -81,6 +81,8 @@ class AwContents : public FindHelper::Listener,
const std::string& host, const std::string& host,
const std::string& realm); const std::string& realm);
void SetOffscreenPreRaster(bool enabled);
// Methods called from Java. // Methods called from Java.
void SetJavaPeers(JNIEnv* env, void SetJavaPeers(JNIEnv* env,
jobject obj, jobject obj,
......
...@@ -131,6 +131,7 @@ void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) { ...@@ -131,6 +131,7 @@ void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
ResetScrollAndScaleState(env, obj); ResetScrollAndScaleState(env, obj);
UpdateFormDataPreferencesLocked(env, obj); UpdateFormDataPreferencesLocked(env, obj);
UpdateRendererPreferencesLocked(env, obj); UpdateRendererPreferencesLocked(env, obj);
UpdateOffscreenPreRasterLocked(env, obj);
} }
void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) { void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
...@@ -209,6 +210,14 @@ void AwSettings::UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj) { ...@@ -209,6 +210,14 @@ void AwSettings::UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj) {
host->SyncRendererPrefs(); host->SyncRendererPrefs();
} }
void AwSettings::UpdateOffscreenPreRasterLocked(JNIEnv* env, jobject obj) {
AwContents* contents = AwContents::FromWebContents(web_contents());
if (contents) {
contents->SetOffscreenPreRaster(
Java_AwSettings_getOffscreenPreRasterLocked(env, obj));
}
}
void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) { void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) {
// A single WebContents can normally have 0 to many RenderViewHost instances // A single WebContents can normally have 0 to many RenderViewHost instances
// associated with it. // associated with it.
......
...@@ -38,6 +38,7 @@ class AwSettings : public content::WebContentsObserver { ...@@ -38,6 +38,7 @@ class AwSettings : public content::WebContentsObserver {
void UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj); void UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj);
void UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj); void UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj);
void UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj); void UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj);
void UpdateOffscreenPreRasterLocked(JNIEnv* env, jobject obj);
void PopulateWebPreferences(content::WebPreferences* web_prefs); void PopulateWebPreferences(content::WebPreferences* web_prefs);
......
...@@ -44,7 +44,14 @@ scoped_ptr<cc::CompositorFrame> TestSynchronousCompositor::DemandDrawHw( ...@@ -44,7 +44,14 @@ scoped_ptr<cc::CompositorFrame> TestSynchronousCompositor::DemandDrawHw(
gfx::Rect viewport_rect_for_tile_priority, gfx::Rect viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority) { const gfx::Transform& transform_for_tile_priority) {
DCHECK(hardware_initialized_); DCHECK(hardware_initialized_);
return nullptr; scoped_ptr<cc::CompositorFrame> compositor_frame(new cc::CompositorFrame);
scoped_ptr<cc::DelegatedFrameData> frame(new cc::DelegatedFrameData);
scoped_ptr<cc::RenderPass> root_pass(cc::RenderPass::Create());
root_pass->SetNew(cc::RenderPassId(1, 1), viewport, viewport,
gfx::Transform());
frame->render_pass_list.push_back(root_pass.Pass());
compositor_frame->delegated_frame_data = frame.Pass();
return compositor_frame.Pass();
} }
void TestSynchronousCompositor::ReturnResources( void TestSynchronousCompositor::ReturnResources(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment