summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authortobiasjs <tobiasjs@chromium.org>2015-11-05 14:51:37 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-05 22:52:35 +0000
commit9addff46d3bc49f8d04e43eeb3f55e01a4982a00 (patch)
tree8a1dac7016d82ce693c6bab7dcb5be8f430530cc /android_webview
parent9f14d56493895bf874c7780a7d5e7c2c51ff0f77 (diff)
downloadchromium_src-9addff46d3bc49f8d04e43eeb3f55e01a4982a00.zip
chromium_src-9addff46d3bc49f8d04e43eeb3f55e01a4982a00.tar.gz
chromium_src-9addff46d3bc49f8d04e43eeb3f55e01a4982a00.tar.bz2
Remove fallback tick software draw.
The fallback software draw was needed to allow the scheduler to advance in cases where the WebView is detached or offscreen. Because it is now possible for the pending tree to activate without a draw, the fallback tick is no longer needed in order for VisualStateListener callbacks to fire. BUG=431166 Review URL: https://codereview.chromium.org/1428263003 Cr-Commit-Position: refs/heads/master@{#358156}
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/android_webview_tests.gypi2
-rw-r--r--android_webview/browser/browser_view_renderer.cc90
-rw-r--r--android_webview/browser/browser_view_renderer.h15
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java105
-rw-r--r--android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html19
5 files changed, 72 insertions, 159 deletions
diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi
index 908bce3..14c90ca 100644
--- a/android_webview/android_webview_tests.gypi
+++ b/android_webview/android_webview_tests.gypi
@@ -34,6 +34,7 @@
'<(asset_location)/video.mp4',
'<(asset_location)/visual_state_during_fullscreen_test.html',
'<(asset_location)/visual_state_waits_for_js_test.html',
+ '<(asset_location)/visual_state_waits_for_js_detached_test.html',
'<(asset_location)/visual_state_on_page_commit_visible_test.html',
'<@(snapshot_additional_input_paths)',
],
@@ -61,6 +62,7 @@
'<(java_in_dir)/assets/video.mp4',
'<(java_in_dir)/assets/visual_state_during_fullscreen_test.html',
'<(java_in_dir)/assets/visual_state_waits_for_js_test.html',
+ '<(java_in_dir)/assets/visual_state_waits_for_js_detached_test.html',
'<(java_in_dir)/assets/visual_state_on_page_commit_visible_test.html',
'<@(snapshot_copy_files)',
],
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index fa9ea17..c61f2e1 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -30,8 +30,6 @@ namespace {
const double kEpsilon = 1e-8;
-const int64 kFallbackTickTimeoutInMilliseconds = 100;
-
// Used to calculate memory allocation. Determined experimentally.
const size_t kMemoryMultiplier = 20;
const size_t kBytesPerPixel = 4;
@@ -103,8 +101,7 @@ BrowserViewRenderer::BrowserViewRenderer(
max_page_scale_factor_(0.f),
on_new_picture_enable_(false),
clear_view_(false),
- offscreen_pre_raster_(false),
- fallback_tick_pending_(false) {}
+ offscreen_pre_raster_(false) {}
BrowserViewRenderer::~BrowserViewRenderer() {
}
@@ -225,12 +222,6 @@ bool BrowserViewRenderer::OnDrawHardware() {
shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_);
hardware_enabled_ = true;
- return CompositeHw();
-}
-
-bool BrowserViewRenderer::CompositeHw() {
- CancelFallbackTick();
-
ReturnResourceFromParent();
UpdateMemoryPolicy();
@@ -270,14 +261,16 @@ bool BrowserViewRenderer::CompositeHw() {
transform_for_tile_priority, offscreen_pre_raster_,
parent_draw_constraints.is_layer));
- // Uncommitted frame can happen with consecutive fallback ticks.
+ // If we haven't received a kModeSync functor call since the last
+ // CompositeHw then we need to discard the resources that are being
+ // held onto by the previously prepared frame.
ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI());
shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass());
return true;
}
void BrowserViewRenderer::UpdateParentDrawConstraints() {
- PostInvalidateWithFallback();
+ PostInvalidate();
ParentCompositorDrawConstraints parent_draw_constraints =
shared_renderer_state_.GetParentDrawConstraintsOnUI();
client_->ParentDrawConstraintsUpdated(parent_draw_constraints);
@@ -351,7 +344,7 @@ void BrowserViewRenderer::ClearView() {
clear_view_ = true;
// Always invalidate ignoring the compositor to actually clear the webview.
- PostInvalidateWithFallback();
+ PostInvalidate();
}
void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) {
@@ -649,80 +642,11 @@ void BrowserViewRenderer::DidOverscroll(
void BrowserViewRenderer::PostInvalidate() {
TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate",
TRACE_EVENT_SCOPE_THREAD);
- PostInvalidateWithFallback();
-}
-
-void BrowserViewRenderer::PostInvalidateWithFallback() {
- // Always call view invalidate. We rely the Android framework to ignore the
- // invalidate when it's not needed such as when view is not visible.
client_->PostInvalidate();
-
- // Stop fallback ticks when one of these is true.
- // 1) Webview is paused. Also need to check we are not in clear view since
- // paused, offscreen still expect clear view to recover.
- // 2) If we are attached to window and the window is not visible (eg when
- // app is in the background). We are sure in this case the webview is used
- // "on-screen" but that updates are not needed when in the background.
- bool throttle_fallback_tick =
- (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_);
-
- if (throttle_fallback_tick || fallback_tick_pending_)
- return;
-
- DCHECK(post_fallback_tick_.IsCancelled());
- DCHECK(fallback_tick_fired_.IsCancelled());
-
- post_fallback_tick_.Reset(base::Bind(&BrowserViewRenderer::PostFallbackTick,
- base::Unretained(this)));
- ui_task_runner_->PostTask(FROM_HERE, post_fallback_tick_.callback());
- fallback_tick_pending_ = true;
-}
-
-void BrowserViewRenderer::CancelFallbackTick() {
- post_fallback_tick_.Cancel();
- fallback_tick_fired_.Cancel();
- fallback_tick_pending_ = false;
-}
-
-void BrowserViewRenderer::PostFallbackTick() {
- DCHECK(fallback_tick_fired_.IsCancelled());
- TRACE_EVENT0("android_webview", "BrowserViewRenderer::PostFallbackTick");
- post_fallback_tick_.Cancel();
- fallback_tick_fired_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired,
- base::Unretained(this)));
- ui_task_runner_->PostDelayedTask(
- FROM_HERE, fallback_tick_fired_.callback(),
- base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
-}
-
-void BrowserViewRenderer::FallbackTickFired() {
- TRACE_EVENT0("android_webview", "BrowserViewRenderer::FallbackTickFired");
- // This should only be called if OnDraw or DrawGL did not come in time, which
- // means fallback_tick_pending_ must still be true.
- DCHECK(fallback_tick_pending_);
- fallback_tick_fired_.Cancel();
- fallback_tick_pending_ = false;
- if (compositor_) {
- if (hardware_enabled_ && !size_.IsEmpty()) {
- CompositeHw();
- } else {
- ForceFakeCompositeSW();
- }
- }
-}
-
-void BrowserViewRenderer::ForceFakeCompositeSW() {
- DCHECK(compositor_);
- SkBitmap bitmap;
- bitmap.allocN32Pixels(1, 1);
- bitmap.eraseColor(0);
- SkCanvas canvas(bitmap);
- CompositeSW(&canvas);
}
bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) {
DCHECK(compositor_);
- CancelFallbackTick();
ReturnResourceFromParent();
return compositor_->DemandDrawSw(canvas);
}
@@ -744,8 +668,6 @@ std::string BrowserViewRenderer::ToString() const {
base::StringAppendF(&str, "window_visible: %d ", window_visible_);
base::StringAppendF(&str, "dip_scale: %f ", dip_scale_);
base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_);
- base::StringAppendF(&str, "fallback_tick_pending: %d ",
- fallback_tick_pending_);
base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str());
base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_);
base::StringAppendF(&str,
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index 21c28c8..4d31689 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -120,18 +120,12 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
private:
void SetTotalRootLayerScrollOffset(const gfx::Vector2dF& new_value_dip);
bool CanOnDraw();
- // Posts an invalidate with fallback tick. All invalidates posted while an
- // invalidate is pending will be posted as a single invalidate after the
- // pending invalidate is done.
- void PostInvalidateWithFallback();
- void CancelFallbackTick();
void UpdateCompositorIsActive();
bool CompositeSW(SkCanvas* canvas);
scoped_refptr<base::trace_event::ConvertableToTraceFormat>
RootLayerStateAsValue(const gfx::Vector2dF& total_scroll_offset_dip,
const gfx::SizeF& scrollable_size_dip);
- bool CompositeHw();
void ReturnUnusedResource(scoped_ptr<ChildFrame> frame);
void ReturnResourceFromParent();
@@ -142,11 +136,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
void PostFallbackTick();
void FallbackTickFired();
- // Force invoke the compositor to run produce a 1x1 software frame that is
- // immediately discarded. This is a hack to force invoke parts of the
- // compositor that are not directly exposed here.
- void ForceFakeCompositeSW();
-
gfx::Vector2d max_scroll_offset() const;
void UpdateMemoryPolicy();
@@ -179,10 +168,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient {
gfx::Vector2d last_on_draw_scroll_offset_;
gfx::Rect last_on_draw_global_visible_rect_;
- base::CancelableClosure post_fallback_tick_;
- base::CancelableClosure fallback_tick_fired_;
- bool fallback_tick_pending_;
-
gfx::Size size_;
gfx::SizeF scrollable_size_dip_;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
index 2ae84a6..8af193f 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
@@ -9,13 +9,12 @@ import android.graphics.Color;
import android.graphics.Rect;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
-import android.view.View;
-import android.webkit.WebChromeClient;
import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContents.VisualStateCallback;
+import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwWebResourceResponse;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.GraphicsTestUtils;
@@ -32,6 +31,7 @@ import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -42,6 +42,8 @@ import java.util.concurrent.atomic.AtomicReference;
public class VisualStateTest extends AwTestBase {
private static final String WAIT_FOR_JS_TEST_URL =
"file:///android_asset/visual_state_waits_for_js_test.html";
+ private static final String WAIT_FOR_JS_DETACHED_TEST_URL =
+ "file:///android_asset/visual_state_waits_for_js_detached_test.html";
private static final String ON_PAGE_COMMIT_VISIBLE_TEST_URL =
"file:///android_asset/visual_state_on_page_commit_visible_test.html";
private static final String FULLSCREEN_TEST_URL =
@@ -403,77 +405,60 @@ public class VisualStateTest extends AwTestBase {
assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
}
+ private AwTestContainerView createDetachedTestContainerViewOnMainSync(
+ final AwContentsClient awContentsClient) {
+ return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<AwTestContainerView>() {
+ @Override
+ public AwTestContainerView call() {
+ AwTestContainerView detachedView =
+ createDetachedAwTestContainerView(awContentsClient);
+ detachedView.setClipBounds(new Rect(0, 0, 100, 100));
+ detachedView.measure(100, 100);
+ detachedView.layout(0, 0, 100, 100);
+ return detachedView;
+ }
+ });
+ }
+
@Feature({"AndroidWebView"})
@SmallTest
- public void testVisualStateCallbackWhenContainerViewDetached()
- throws Throwable {
- final CountDownLatch readyToEnterFullscreenSignal = new CountDownLatch(1);
- final CountDownLatch hasCustomViewSignal = new CountDownLatch(1);
+ public void testVisualStateCallbackWhenContainerViewDetached() throws Throwable {
final CountDownLatch testFinishedSignal = new CountDownLatch(1);
- final AtomicReference<AwContents> awContentsRef = new AtomicReference<>();
- final AtomicReference<View> customViewRef = new AtomicReference<>();
-
- final TestAwContentsClient awContentsClient = new TestAwContentsClient() {
- @Override
- public void onPageFinished(String url) {
- super.onPageFinished(url);
- readyToEnterFullscreenSignal.countDown();
- }
-
- @Override
- public void onShowCustomView(
- final View customView, WebChromeClient.CustomViewCallback callback) {
- // Please note that we don't attach the custom view to the window here
- // (awContentsClient is an instance of TestAwContentsClient, not
- // FullScreenVideoTestAwContentsClient).
- customView.setClipBounds(new Rect(0, 0, 100, 100));
- customView.measure(100, 100);
- customView.layout(0, 0, 100, 100);
- customViewRef.set(customView);
- hasCustomViewSignal.countDown();
- }
- };
- final AwTestContainerView testView = createAwTestContainerViewOnMainSync(awContentsClient);
+ final TestAwContentsClient awContentsClient = new TestAwContentsClient();
+ final AwTestContainerView testView =
+ createDetachedTestContainerViewOnMainSync(awContentsClient);
final AwContents awContents = testView.getAwContents();
- awContentsRef.set(awContents);
final ContentViewCore contentViewCore = testView.getContentViewCore();
+
enableJavaScriptOnUiThread(awContents);
- awContents.getSettings().setFullscreenSupported(true);
- // JS will notify this observer once it has entered fullscreen.
- final JavascriptEventObserver jsObserver = new JavascriptEventObserver();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- jsObserver.register(contentViewCore, "jsObserver");
+ // JS will notify this observer once it has changed the background color of the page.
+ final Object pageChangeNotifier = new Object() {
+ public void onPageChanged() {
+ ThreadUtils.postOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ awContents.insertVisualStateCallback(20, new VisualStateCallback() {
+ @Override
+ public void onComplete(long id) {
+ Bitmap redScreenshot =
+ GraphicsTestUtils.drawAwContents(awContents, 100, 100);
+ assertEquals(Color.RED, redScreenshot.getPixel(50, 50));
+ testFinishedSignal.countDown();
+ }
+ });
+ }
+ });
}
- });
-
- loadUrlSync(awContents, awContentsClient.getOnPageFinishedHelper(), FULLSCREEN_TEST_URL);
-
- assertTrue(readyToEnterFullscreenSignal.await(
- AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
- DOMUtils.clickNode(VisualStateTest.this, contentViewCore, ENTER_FULLSCREEN_CONTROL_ID);
-
- assertTrue(hasCustomViewSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS));
+ };
runTestOnUiThread(new Runnable() {
@Override
public void run() {
- awContents.insertVisualStateCallback(20, new VisualStateCallback() {
- @Override
- public void onComplete(long id) {
- assertFalse(customViewRef.get().isAttachedToWindow());
- // NOTE: We cannot use drawAwContents here because the web contents
- // are rendered into the custom view while in fullscreen.
- Bitmap redScreenshot = GraphicsTestUtils.drawView(
- customViewRef.get(), 100, 100);
- assertEquals(Color.RED, redScreenshot.getPixel(50, 50));
- testFinishedSignal.countDown();
- }
- });
+ contentViewCore.addPossiblyUnsafeJavascriptInterface(
+ pageChangeNotifier, "pageChangeNotifier", null);
+ awContents.loadUrl(WAIT_FOR_JS_DETACHED_TEST_URL);
}
});
diff --git a/android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html b/android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html
new file mode 100644
index 0000000..6bbf102
--- /dev/null
+++ b/android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+ <script>
+ function updateColor() {
+ document.body.style.backgroundColor = "red";
+ pageChangeNotifier.onPageChanged();
+ }
+ </script>
+ <style>
+ body {
+ margin: 0px;
+ padding: 0px;
+ background-color: blue;
+ }
+ </style>
+</head>
+<body onload="javascript:updateColor()">
+</body>
+</html>