From 29652cf5d1121cdc8833106c98f3808a7620fdee Mon Sep 17 00:00:00 2001 From: "victorhsieh@chromium.org" Date: Thu, 27 Sep 2012 20:54:03 +0000 Subject: Fix cpu draining callback in Graphics2D::Flush. Graphics2D::Flush should delay callback when the update is invisible, while the plugin is visible on current tab. Contributed by victorhsieh@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/10933107 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159112 0039d316-1c4b-4281-b951-d872f2087c98 --- webkit/plugins/ppapi/ppb_graphics_2d_impl.cc | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'webkit/plugins/ppapi/ppb_graphics_2d_impl.cc') diff --git a/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc b/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc index a838f1f..ff5c523 100644 --- a/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc +++ b/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc @@ -10,6 +10,7 @@ #include "base/debug/trace_event.h" #include "base/logging.h" #include "base/message_loop.h" +#include "base/time.h" #include "skia/ext/platform_canvas.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_rect.h" @@ -43,6 +44,8 @@ namespace ppapi { namespace { +const int64 kOffscreenCallbackDelayMs = 1000 / 30; // 30 fps + // Converts a rect inside an image of the given dimensions. The rect may be // NULL to indicate it should be the entire image. If the rect is outside of // the image, this will do nothing and return false. @@ -332,7 +335,8 @@ int32_t PPB_Graphics2D_Impl::Flush(scoped_refptr callback, return PP_ERROR_INPROGRESS; bool done_replace_contents = false; - bool nothing_visible = true; + bool no_update_visible = true; + bool is_plugin_visible = true; for (size_t i = 0; i < queued_operations_.size(); i++) { QueuedOperation& operation = queued_operations_[i]; gfx::Rect op_rect; @@ -375,12 +379,14 @@ int32_t PPB_Graphics2D_Impl::Flush(scoped_refptr callback, operation.type = QueuedOperation::PAINT; } - // Set |nothing_visible| to false if the change overlaps the visible area. - gfx::Rect visible_changed_rect = - PP_ToGfxRect(bound_instance_->view_data().clip_rect). - Intersect(op_rect); + gfx::Rect clip = PP_ToGfxRect(bound_instance_->view_data().clip_rect); + is_plugin_visible = !clip.IsEmpty(); + + // Set |no_update_visible| to false if the change overlaps the visible + // area. + gfx::Rect visible_changed_rect = clip.Intersect(op_rect); if (!visible_changed_rect.IsEmpty()) - nothing_visible = false; + no_update_visible = false; // Notify the plugin of the entire change (op_rect), even if it is // partially or completely off-screen. @@ -394,13 +400,18 @@ int32_t PPB_Graphics2D_Impl::Flush(scoped_refptr callback, } queued_operations_.clear(); - if (nothing_visible) { + if (!bound_instance_) { + // As promised in the API, we always schedule callback when unbound. + ScheduleOffscreenCallback(FlushCallbackData(callback)); + } else if (no_update_visible && is_plugin_visible && + bound_instance_->view_data().is_page_visible) { // There's nothing visible to invalidate so just schedule the callback to // execute in the next round of the message loop. ScheduleOffscreenCallback(FlushCallbackData(callback)); } else { unpainted_flush_callback_.Set(callback); } + return PP_OK_COMPLETIONPENDING; } @@ -730,11 +741,12 @@ void PPB_Graphics2D_Impl::ScheduleOffscreenCallback( const FlushCallbackData& callback) { DCHECK(!HasPendingFlush()); offscreen_flush_pending_ = true; - MessageLoop::current()->PostTask( + MessageLoop::current()->PostDelayedTask( FROM_HERE, base::Bind(&PPB_Graphics2D_Impl::ExecuteOffscreenCallback, weak_ptr_factory_.GetWeakPtr(), - callback)); + callback), + base::TimeDelta::FromMilliseconds(kOffscreenCallbackDelayMs)); } void PPB_Graphics2D_Impl::ExecuteOffscreenCallback(FlushCallbackData data) { -- cgit v1.1