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(
page_scale_factor_(1.0),
on_new_picture_enable_(false),
clear_view_(false),
offscreen_pre_raster_(false),
compositor_needs_continuous_invalidate_(false),
invalidate_after_composite_(false),
block_invalidates_(false),
......@@ -128,8 +129,11 @@ size_t BrowserViewRenderer::CalculateDesiredMemoryPolicy() {
if (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();
size_t height = last_on_draw_global_visible_rect_.height();
gfx::Rect interest_rect = offscreen_pre_raster_
? 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;
// Round up to a multiple of kMemoryAllocationStep.
bytes_limit =
......@@ -178,15 +182,6 @@ bool BrowserViewRenderer::OnDrawHardware() {
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();
if (shared_renderer_state_.HasCompositorFrameOnUI()) {
TRACE_EVENT_INSTANT0("android_webview",
......@@ -222,11 +217,15 @@ scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() {
// applied onto the layer so global visible rect does not make sense here.
// In this case, just use the surface rect for tiling.
gfx::Rect viewport_rect_for_tile_priority;
if (parent_draw_constraints_.is_layer ||
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_;
// Leave viewport_rect_for_tile_priority empty if offscreen_pre_raster_ is on.
if (!offscreen_pre_raster_) {
if (parent_draw_constraints_.is_layer ||
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 =
......@@ -326,6 +325,11 @@ void BrowserViewRenderer::ClearView() {
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) {
TRACE_EVENT_INSTANT1("android_webview",
"BrowserViewRenderer::SetIsPaused",
......
......@@ -55,6 +55,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
void ClearView();
void SetOffscreenPreRaster(bool enabled);
// View update notifications.
void SetIsPaused(bool paused);
void SetViewVisibility(bool visible);
......@@ -158,6 +160,8 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
bool on_new_picture_enable_;
bool clear_view_;
bool offscreen_pre_raster_;
gfx::Vector2d last_on_draw_scroll_offset_;
gfx::Rect last_on_draw_global_visible_rect_;
......
......@@ -120,6 +120,7 @@ void FakeWindow::OnDrawHardware() {
on_draw_hardware_pending_ = false;
hooks_->WillOnDraw();
view_->PrepareToDraw(gfx::Vector2d(), location_);
bool success = view_->OnDrawHardware();
hooks_->DidOnDraw(success);
if (success) {
......
......@@ -88,6 +88,7 @@ public class AwSettings {
private boolean mEnableSupportedHardwareAcceleratedFeatures = false;
private int mMixedContentMode = MIXED_CONTENT_NEVER_ALLOW;
private boolean mVideoOverlayForEmbeddedVideoEnabled = false;
private boolean mOffscreenPreRaster = false;
// Although this bit is stored on AwSettings it is actually controlled via the CookieManager.
private boolean mAcceptThirdPartyCookies = false;
......@@ -1559,6 +1560,45 @@ public class AwSettings {
|| 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.
* @param flag whether to enable the video overlay for the embedded video.
......@@ -1671,4 +1711,6 @@ public class AwSettings {
private native void nativeUpdateFormDataPreferencesLocked(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,
return true;
}
void AwContents::SetOffscreenPreRaster(bool enabled) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
browser_view_renderer_.SetOffscreenPreRaster(enabled);
}
void AwContents::AddVisitedLinks(JNIEnv* env,
jobject obj,
jobjectArray jvisited_links) {
......
......@@ -81,6 +81,8 @@ class AwContents : public FindHelper::Listener,
const std::string& host,
const std::string& realm);
void SetOffscreenPreRaster(bool enabled);
// Methods called from Java.
void SetJavaPeers(JNIEnv* env,
jobject obj,
......
......@@ -131,6 +131,7 @@ void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
ResetScrollAndScaleState(env, obj);
UpdateFormDataPreferencesLocked(env, obj);
UpdateRendererPreferencesLocked(env, obj);
UpdateOffscreenPreRasterLocked(env, obj);
}
void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
......@@ -209,6 +210,14 @@ void AwSettings::UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj) {
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) {
// A single WebContents can normally have 0 to many RenderViewHost instances
// associated with it.
......
......@@ -38,6 +38,7 @@ class AwSettings : public content::WebContentsObserver {
void UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj);
void UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj);
void UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj);
void UpdateOffscreenPreRasterLocked(JNIEnv* env, jobject obj);
void PopulateWebPreferences(content::WebPreferences* web_prefs);
......
......@@ -44,7 +44,14 @@ scoped_ptr<cc::CompositorFrame> TestSynchronousCompositor::DemandDrawHw(
gfx::Rect viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority) {
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(
......
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