diff options
Diffstat (limited to 'android_webview/browser/browser_view_renderer.cc')
-rw-r--r-- | android_webview/browser/browser_view_renderer.cc | 127 |
1 files changed, 113 insertions, 14 deletions
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index 32cb906..7944934 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc @@ -13,7 +13,6 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "content/public/browser/android/synchronous_compositor.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -23,7 +22,6 @@ using base::android::AttachCurrentThread; using base::android::JavaRef; using base::android::ScopedJavaLocalRef; -using content::BrowserThread; namespace android_webview { @@ -31,15 +29,44 @@ namespace { const int64 kFallbackTickTimeoutInMilliseconds = 20; +class AutoResetWithLock { + public: + AutoResetWithLock(gfx::Vector2dF* scoped_variable, + gfx::Vector2dF new_value, + base::Lock& lock) + : scoped_variable_(scoped_variable), + original_value_(*scoped_variable), + lock_(lock) { + base::AutoLock auto_lock(lock_); + *scoped_variable_ = new_value; + } + + ~AutoResetWithLock() { + base::AutoLock auto_lock(lock_); + *scoped_variable_ = original_value_; + } + + private: + gfx::Vector2dF* scoped_variable_; + gfx::Vector2dF original_value_; + base::Lock& lock_; + + DISALLOW_COPY_AND_ASSIGN(AutoResetWithLock); +}; + } // namespace BrowserViewRenderer::BrowserViewRenderer( BrowserViewRendererClient* client, SharedRendererState* shared_renderer_state, - content::WebContents* web_contents) + content::WebContents* web_contents, + const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) : client_(client), shared_renderer_state_(shared_renderer_state), web_contents_(web_contents), + weak_factory_on_ui_thread_(this), + ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), + ui_task_runner_(ui_task_runner), has_compositor_(false), is_paused_(false), view_visible_(false), @@ -124,8 +151,8 @@ skia::RefPtr<SkPicture> BrowserViewRenderer::CapturePicture(int width, // Reset scroll back to the origin, will go back to the old // value when scroll_reset is out of scope. - base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_dip_, - gfx::Vector2d()); + AutoResetWithLock scroll_reset( + &scroll_offset_dip_, gfx::Vector2dF(), scroll_offset_dip_lock_); SkCanvas* rec_canvas = picture->beginRecording(width, height, 0); if (has_compositor_) @@ -227,6 +254,7 @@ void BrowserViewRenderer::DidInitializeCompositor( "BrowserViewRenderer::DidInitializeCompositor"); DCHECK(compositor); DCHECK(!has_compositor_); + DCHECK(ui_task_runner_->BelongsToCurrentThread()); has_compositor_ = true; shared_renderer_state_->SetCompositorOnUiThread(compositor); } @@ -235,11 +263,20 @@ void BrowserViewRenderer::DidDestroyCompositor( content::SynchronousCompositor* compositor) { TRACE_EVENT0("android_webview", "BrowserViewRenderer::DidDestroyCompositor"); DCHECK(has_compositor_); + DCHECK(ui_task_runner_->BelongsToCurrentThread()); has_compositor_ = false; shared_renderer_state_->SetCompositorOnUiThread(NULL); } void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) { + if (!ui_task_runner_->BelongsToCurrentThread()) { + ui_task_runner_->PostTask( + FROM_HERE, + base::Bind(&BrowserViewRenderer::SetContinuousInvalidate, + ui_thread_weak_ptr_, + invalidate)); + return; + } if (compositor_needs_continuous_invalidate_ == invalidate) return; @@ -284,16 +321,25 @@ void BrowserViewRenderer::ScrollTo(gfx::Vector2d scroll_offset) { DCHECK_LE(scroll_offset_dip.x(), max_scroll_offset_dip_.x()); DCHECK_LE(scroll_offset_dip.y(), max_scroll_offset_dip_.y()); - if (scroll_offset_dip_ == scroll_offset_dip) - return; + { + base::AutoLock lock(scroll_offset_dip_lock_); + if (scroll_offset_dip_ == scroll_offset_dip) + return; - scroll_offset_dip_ = scroll_offset_dip; + scroll_offset_dip_ = scroll_offset_dip; + } if (has_compositor_) shared_renderer_state_->CompositorDidChangeRootLayerScrollOffset(); } void BrowserViewRenderer::DidUpdateContent() { + if (!ui_task_runner_->BelongsToCurrentThread()) { + ui_task_runner_->PostTask(FROM_HERE, + base::Bind(&BrowserViewRenderer::DidUpdateContent, + ui_thread_weak_ptr_)); + return; + } TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::DidUpdateContent", TRACE_EVENT_SCOPE_THREAD); @@ -304,6 +350,14 @@ void BrowserViewRenderer::DidUpdateContent() { 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; @@ -315,12 +369,24 @@ void BrowserViewRenderer::SetMaxRootLayerScrollOffset( void BrowserViewRenderer::SetTotalRootLayerScrollOffset( gfx::Vector2dF scroll_offset_dip) { - // TOOD(mkosiba): Add a DCHECK to say that this does _not_ get called during - // DrawGl when http://crbug.com/249972 is fixed. - if (scroll_offset_dip_ == 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; + } - scroll_offset_dip_ = scroll_offset_dip; + { + base::AutoLock lock(scroll_offset_dip_lock_); + // TOOD(mkosiba): Add a DCHECK to say that this does _not_ get called during + // DrawGl when http://crbug.com/249972 is fixed. + if (scroll_offset_dip_ == scroll_offset_dip) + return; + + scroll_offset_dip_ = scroll_offset_dip; + } gfx::Vector2d max_offset = max_scroll_offset(); gfx::Vector2d scroll_offset; @@ -347,10 +413,16 @@ void BrowserViewRenderer::SetTotalRootLayerScrollOffset( } gfx::Vector2dF BrowserViewRenderer::GetTotalRootLayerScrollOffset() { + base::AutoLock lock(scroll_offset_dip_lock_); return scroll_offset_dip_; } bool BrowserViewRenderer::IsExternalFlingActive() const { + if (!ui_task_runner_->BelongsToCurrentThread()) { + // TODO(boliu): This is short term hack since we cannot call into + // view system on non-UI thread. + return false; + } return client_->IsFlingActive(); } @@ -358,6 +430,16 @@ void BrowserViewRenderer::SetRootLayerPageScaleFactorAndLimits( 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, + ui_thread_weak_ptr_, + page_scale_factor, + min_page_scale_factor, + max_page_scale_factor)); + return; + } page_scale_factor_ = page_scale_factor; DCHECK_GT(page_scale_factor_, 0); client_->SetPageScaleFactorAndLimits( @@ -366,12 +448,30 @@ void BrowserViewRenderer::SetRootLayerPageScaleFactorAndLimits( 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); } void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll, gfx::Vector2dF latest_overscroll_delta, gfx::Vector2dF current_fling_velocity) { + if (!ui_task_runner_->BelongsToCurrentThread()) { + ui_task_runner_->PostTask( + FROM_HERE, + base::Bind(&BrowserViewRenderer::DidOverscroll, + ui_thread_weak_ptr_, + accumulated_overscroll, + latest_overscroll_delta, + current_fling_velocity)); + return; + } const float physical_pixel_scale = dip_scale_ * page_scale_factor_; if (accumulated_overscroll == latest_overscroll_delta) overscroll_rounding_error_ = gfx::Vector2dF(); @@ -417,8 +517,7 @@ void BrowserViewRenderer::EnsureContinuousInvalidation(bool force_invalidate) { // ticked. This can happen if this is reached because force_invalidate is // true. if (compositor_needs_continuous_invalidate_) { - BrowserThread::PostDelayedTask( - BrowserThread::UI, + ui_task_runner_->PostDelayedTask( FROM_HERE, fallback_tick_.callback(), base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); |