X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fandroid_webview%2Fbrowser%2Fin_process_view_renderer.cc;h=26eaa2f04e0a04162be0f3a9b96d71329dd88901;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=4496f2b1b310adcc6809a69d31702044a6e8ebbc;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/android_webview/browser/in_process_view_renderer.cc b/src/android_webview/browser/in_process_view_renderer.cc index 4496f2b..26eaa2f 100644 --- a/src/android_webview/browser/in_process_view_renderer.cc +++ b/src/android_webview/browser/in_process_view_renderer.cc @@ -173,7 +173,8 @@ ScopedAllowGL::~ScopedAllowGL() { bool ScopedAllowGL::allow_gl = false; -base::LazyInstance::Leaky g_view_renderer_manager; +base::LazyInstance::Leaky g_view_renderer_manager = + LAZY_INSTANCE_INITIALIZER; void RequestProcessGLOnUIThread() { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { @@ -190,23 +191,94 @@ void RequestProcessGLOnUIThread() { } } -} // namespace +class DeferredGpuCommandService + : public gpu::InProcessCommandBuffer::Service, + public base::RefCountedThreadSafe { + public: + DeferredGpuCommandService(); + + virtual void ScheduleTask(const base::Closure& task) OVERRIDE; + virtual void ScheduleIdleWork(const base::Closure& task) OVERRIDE; + virtual bool UseVirtualizedGLContexts() OVERRIDE; + + void RunTasks(); + + virtual void AddRef() const OVERRIDE { + base::RefCountedThreadSafe::AddRef(); + } + virtual void Release() const OVERRIDE { + base::RefCountedThreadSafe::Release(); + } + + protected: + virtual ~DeferredGpuCommandService(); + friend class base::RefCountedThreadSafe; + + private: + base::Lock tasks_lock_; + std::queue tasks_; + DISALLOW_COPY_AND_ASSIGN(DeferredGpuCommandService); +}; + +DeferredGpuCommandService::DeferredGpuCommandService() {} + +DeferredGpuCommandService::~DeferredGpuCommandService() { + base::AutoLock lock(tasks_lock_); + DCHECK(tasks_.empty()); +} // Called from different threads! -static void ScheduleGpuWork() { +void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) { + { + base::AutoLock lock(tasks_lock_); + tasks_.push(task); + } if (ScopedAllowGL::IsAllowed()) { - gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); + RunTasks(); } else { RequestProcessGLOnUIThread(); } } +void DeferredGpuCommandService::ScheduleIdleWork( + const base::Closure& callback) { + // TODO(sievers): Should this do anything? +} + +bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; } + +void DeferredGpuCommandService::RunTasks() { + bool has_more_tasks; + { + base::AutoLock lock(tasks_lock_); + has_more_tasks = tasks_.size() > 0; + } + + while (has_more_tasks) { + base::Closure task; + { + base::AutoLock lock(tasks_lock_); + task = tasks_.front(); + tasks_.pop(); + } + task.Run(); + { + base::AutoLock lock(tasks_lock_); + has_more_tasks = tasks_.size() > 0; + } + + } +} + +base::LazyInstance > g_service = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + // static void BrowserViewRenderer::SetAwDrawSWFunctionTable( AwDrawSWFunctionTable* table) { g_sw_draw_functions = table; - gpu::InProcessCommandBuffer::SetScheduleCallback( - base::Bind(&ScheduleGpuWork)); } // static @@ -229,6 +301,7 @@ InProcessViewRenderer::InProcessViewRenderer( dip_scale_(0.0), page_scale_factor_(1.0), on_new_picture_enable_(false), + clear_view_(false), compositor_needs_continuous_invalidate_(false), block_invalidates_(false), width_(0), @@ -350,7 +423,7 @@ void InProcessViewRenderer::TrimMemory(int level) { TRACE_EVENT0("android_webview", "InProcessViewRenderer::TrimMemory"); ScopedAppGLStateRestore state_restore( ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); - gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); + g_service.Get()->RunTasks(); ScopedAllowGL allow_gl; SetMemoryPolicy(policy); @@ -375,6 +448,8 @@ bool InProcessViewRenderer::OnDraw(jobject java_canvas, const gfx::Vector2d& scroll, const gfx::Rect& clip) { scroll_at_start_of_frame_ = scroll; + if (clear_view_) + return false; if (is_hardware_canvas && attached_to_window_ && HardwareEnabled()) { // We should be performing a hardware draw here. If we don't have the // comositor yet or if RequestDrawGL fails, it means we failed this draw and @@ -388,7 +463,11 @@ bool InProcessViewRenderer::OnDraw(jobject java_canvas, bool InProcessViewRenderer::InitializeHwDraw() { TRACE_EVENT0("android_webview", "InitializeHwDraw"); DCHECK(!gl_surface_); - gl_surface_ = new AwGLSurface; + gl_surface_ = new AwGLSurface; + if (!g_service.Get()) { + g_service.Get() = new DeferredGpuCommandService; + content::SynchronousCompositor::SetGpuService(g_service.Get()); + } hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_); hardware_initialized_ = true; @@ -413,7 +492,8 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { } ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); - gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); + if (g_service.Get()) + g_service.Get()->RunTasks(); ScopedAllowGL allow_gl; if (!attached_to_window_) { @@ -627,6 +707,18 @@ void InProcessViewRenderer::EnableOnNewPicture(bool enabled) { EnsureContinuousInvalidation(NULL, false); } +void InProcessViewRenderer::ClearView() { + TRACE_EVENT_INSTANT0("android_webview", + "InProcessViewRenderer::ClearView", + TRACE_EVENT_SCOPE_THREAD); + if (clear_view_) + return; + + clear_view_ = true; + // Always invalidate ignoring the compositor to actually clear the webview. + EnsureContinuousInvalidation(NULL, true); +} + void InProcessViewRenderer::SetIsPaused(bool paused) { TRACE_EVENT_INSTANT1("android_webview", "InProcessViewRenderer::SetIsPaused", @@ -690,7 +782,7 @@ void InProcessViewRenderer::OnDetachedFromWindow() { ScopedAppGLStateRestore state_restore( ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); - gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); + g_service.Get()->RunTasks(); ScopedAllowGL allow_gl; compositor_->ReleaseHwDraw(); hardware_initialized_ = false; @@ -792,6 +884,11 @@ void InProcessViewRenderer::ScrollTo(gfx::Vector2d scroll_offset) { } void InProcessViewRenderer::DidUpdateContent() { + TRACE_EVENT_INSTANT0("android_webview", + "InProcessViewRenderer::DidUpdateContent", + TRACE_EVENT_SCOPE_THREAD); + clear_view_ = false; + EnsureContinuousInvalidation(NULL, false); if (on_new_picture_enable_) client_->OnNewPicture(); } @@ -832,8 +929,10 @@ void InProcessViewRenderer::SetTotalRootLayerScrollOffset( DCHECK(0 <= scroll_offset.x()); DCHECK(0 <= scroll_offset.y()); - DCHECK(scroll_offset.x() <= max_offset.x()); - DCHECK(scroll_offset.y() <= max_offset.y()); + // Disabled because the conditions are being violated while running + // AwZoomTest.testMagnification, see http://crbug.com/340648 + // DCHECK(scroll_offset.x() <= max_offset.x()); + // DCHECK(scroll_offset.y() <= max_offset.y()); client_->ScrollContainerViewTo(scroll_offset); } @@ -846,11 +945,14 @@ bool InProcessViewRenderer::IsExternalFlingActive() const { return client_->IsFlingActive(); } -void InProcessViewRenderer::SetRootLayerPageScaleFactor( - float page_scale_factor) { +void InProcessViewRenderer::SetRootLayerPageScaleFactorAndLimits( + float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor) { page_scale_factor_ = page_scale_factor; DCHECK_GT(page_scale_factor_, 0); - client_->SetPageScaleFactor(page_scale_factor); + client_->SetPageScaleFactorAndLimits( + page_scale_factor, min_page_scale_factor, max_page_scale_factor); } void InProcessViewRenderer::SetRootLayerScrollableSize( @@ -862,7 +964,6 @@ void InProcessViewRenderer::DidOverscroll( gfx::Vector2dF accumulated_overscroll, gfx::Vector2dF latest_overscroll_delta, gfx::Vector2dF current_fling_velocity) { - DCHECK(current_fling_velocity.IsZero()); const float physical_pixel_scale = dip_scale_ * page_scale_factor_; if (accumulated_overscroll == latest_overscroll_delta) overscroll_rounding_error_ = gfx::Vector2dF(); @@ -884,6 +985,8 @@ void InProcessViewRenderer::EnsureContinuousInvalidation( if (!need_invalidate || block_invalidates_) return; + // 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. if (draw_info) { draw_info->dirty_left = cached_global_visible_rect_.x(); draw_info->dirty_top = cached_global_visible_rect_.y(); @@ -894,8 +997,14 @@ void InProcessViewRenderer::EnsureContinuousInvalidation( client_->PostInvalidate(); } - bool throttle_fallback_tick = (is_paused_ && !on_new_picture_enable_) || - (attached_to_window_ && !window_visible_); + // 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) return; @@ -978,6 +1087,7 @@ std::string InProcessViewRenderer::ToString(AwDrawGLInfo* draw_info) const { overscroll_rounding_error_.ToString().c_str()); base::StringAppendF( &str, "on_new_picture_enable: %d ", on_new_picture_enable_); + base::StringAppendF(&str, "clear_view: %d ", clear_view_); if (draw_info) { base::StringAppendF(&str, "clip left top right bottom: [%d %d %d %d] ",