Commit 2d8374c3 authored by boliu@chromium.org's avatar boliu@chromium.org

[Android WebView] Fallback tick

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.

BUG=
NOTRY=true

Review URL: https://chromiumcodereview.appspot.com/17136003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207999 0039d316-1c4b-4281-b951-d872f2087c98
parent 1e5ad60e
...@@ -275,6 +275,8 @@ AwDrawSWFunctionTable* g_sw_draw_functions = NULL; ...@@ -275,6 +275,8 @@ AwDrawSWFunctionTable* g_sw_draw_functions = NULL;
// as a fallback mechanism, which will have an important performance impact. // as a fallback mechanism, which will have an important performance impact.
bool g_is_skia_version_compatible = false; bool g_is_skia_version_compatible = false;
const int64 kFallbackTickTimeoutInMilliseconds = 500;
} // namespace } // namespace
// static // static
...@@ -319,6 +321,7 @@ InProcessViewRenderer::InProcessViewRenderer( ...@@ -319,6 +321,7 @@ InProcessViewRenderer::InProcessViewRenderer(
CHECK(web_contents_); CHECK(web_contents_);
web_contents_->SetUserData(kUserDataKey, new UserData(this)); web_contents_->SetUserData(kUserDataKey, new UserData(this));
content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); content::SynchronousCompositor::SetClientForWebContents(web_contents_, this);
// Currently the logic in this class relies on |compositor_| remaining NULL // Currently the logic in this class relies on |compositor_| remaining NULL
// until the DidInitializeCompositor() call, hence it is not set here. // until the DidInitializeCompositor() call, hence it is not set here.
} }
...@@ -345,6 +348,7 @@ bool InProcessViewRenderer::OnDraw(jobject java_canvas, ...@@ -345,6 +348,7 @@ bool InProcessViewRenderer::OnDraw(jobject java_canvas,
bool is_hardware_canvas, bool is_hardware_canvas,
const gfx::Vector2d& scroll, const gfx::Vector2d& scroll,
const gfx::Rect& clip) { const gfx::Rect& clip) {
fallback_tick_.Cancel();
scroll_at_start_of_frame_ = scroll; scroll_at_start_of_frame_ = scroll;
if (is_hardware_canvas && attached_to_window_ && compositor_ && if (is_hardware_canvas && attached_to_window_ && compositor_ &&
HardwareEnabled() && client_->RequestDrawGL(java_canvas)) { HardwareEnabled() && client_->RequestDrawGL(java_canvas)) {
...@@ -455,7 +459,7 @@ bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas, ...@@ -455,7 +459,7 @@ bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas,
if (!RasterizeIntoBitmap(env, jbitmap, if (!RasterizeIntoBitmap(env, jbitmap,
clip.x() - scroll_at_start_of_frame_.x(), clip.x() - scroll_at_start_of_frame_.x(),
clip.y() - scroll_at_start_of_frame_.y(), clip.y() - scroll_at_start_of_frame_.y(),
base::Bind(&InProcessViewRenderer::RenderSW, base::Bind(&InProcessViewRenderer::CompositeSW,
base::Unretained(this)))) { base::Unretained(this)))) {
TRACE_EVENT_INSTANT0("android_webview", TRACE_EVENT_INSTANT0("android_webview",
"EarlyOut_RasterizeFail", "EarlyOut_RasterizeFail",
...@@ -495,7 +499,7 @@ bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas, ...@@ -495,7 +499,7 @@ bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas,
canvas.translate(scroll_at_start_of_frame_.x(), canvas.translate(scroll_at_start_of_frame_.x(),
scroll_at_start_of_frame_.y()); scroll_at_start_of_frame_.y());
succeeded = RenderSW(&canvas); succeeded = CompositeSW(&canvas);
} }
sw_functions->release_pixels(pixels); sw_functions->release_pixels(pixels);
...@@ -637,7 +641,6 @@ void InProcessViewRenderer::SetContinuousInvalidate(bool invalidate) { ...@@ -637,7 +641,6 @@ void InProcessViewRenderer::SetContinuousInvalidate(bool invalidate) {
"invalidate", "invalidate",
invalidate); invalidate);
continuous_invalidate_ = invalidate; continuous_invalidate_ = invalidate;
// TODO(boliu): Handle if not attached to window case.
EnsureContinuousInvalidation(NULL); EnsureContinuousInvalidation(NULL);
} }
...@@ -698,14 +701,33 @@ void InProcessViewRenderer::EnsureContinuousInvalidation( ...@@ -698,14 +701,33 @@ void InProcessViewRenderer::EnsureContinuousInvalidation(
} else { } else {
client_->PostInvalidate(); client_->PostInvalidate();
} }
// Unretained here is safe because the callback is cancelled when
// |fallback_tick_| is destroyed.
fallback_tick_.Reset(base::Bind(&InProcessViewRenderer::FallbackTickFired,
base::Unretained(this)));
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
fallback_tick_.callback(),
base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
block_invalidates_ = true; block_invalidates_ = true;
} }
} }
bool InProcessViewRenderer::RenderSW(SkCanvas* canvas) { void InProcessViewRenderer::FallbackTickFired() {
// TODO(joth): BrowserViewRendererImpl had a bunch of logic for dpi and page TRACE_EVENT1("android_webview",
// scale here. Determine what if any needs bringing over to this class. "InProcessViewRenderer::FallbackTickFired",
return CompositeSW(canvas); "continuous_invalidate_",
continuous_invalidate_);
if (continuous_invalidate_) {
SkDevice device(SkBitmap::kARGB_8888_Config, 1, 1);
SkCanvas canvas(&device);
block_invalidates_ = true;
CompositeSW(&canvas);
}
block_invalidates_ = false;
EnsureContinuousInvalidation(NULL);
} }
bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) { bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "android_webview/browser/browser_view_renderer.h" #include "android_webview/browser/browser_view_renderer.h"
#include "base/cancelable_callback.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "content/public/browser/android/synchronous_compositor_client.h" #include "content/public/browser/android/synchronous_compositor_client.h"
#include "ui/gfx/vector2d_f.h" #include "ui/gfx/vector2d_f.h"
...@@ -68,9 +69,12 @@ class InProcessViewRenderer : public BrowserViewRenderer, ...@@ -68,9 +69,12 @@ class InProcessViewRenderer : public BrowserViewRenderer,
void EnsureContinuousInvalidation(AwDrawGLInfo* draw_info); void EnsureContinuousInvalidation(AwDrawGLInfo* draw_info);
bool DrawSWInternal(jobject java_canvas, bool DrawSWInternal(jobject java_canvas,
const gfx::Rect& clip_bounds); const gfx::Rect& clip_bounds);
bool RenderSW(SkCanvas* canvas);
bool CompositeSW(SkCanvas* canvas); bool CompositeSW(SkCanvas* canvas);
// 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.
void FallbackTickFired();
BrowserViewRenderer::Client* client_; BrowserViewRenderer::Client* client_;
BrowserViewRenderer::JavaHelper* java_helper_; BrowserViewRenderer::JavaHelper* java_helper_;
content::WebContents* web_contents_; content::WebContents* web_contents_;
...@@ -86,6 +90,8 @@ class InProcessViewRenderer : public BrowserViewRenderer, ...@@ -86,6 +90,8 @@ class InProcessViewRenderer : public BrowserViewRenderer,
// compositor draw which may switch continuous_invalidate on and off in the // compositor draw which may switch continuous_invalidate on and off in the
// process. // process.
bool block_invalidates_; bool block_invalidates_;
// Holds a callback to FallbackTickFired while it is pending.
base::CancelableClosure fallback_tick_;
int width_; int width_;
int height_; int height_;
......
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