- Reduce CPU usage with requestAnimationFrame by maintaining a consistent 60fps frame rate (issue #456).
- (Win) Reduce memory/CPU usage with UpdateInputMethod by restricting tasks to every 100ms (issue #454). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@423 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
10b3b3cc41
commit
87507e875c
|
@ -14,10 +14,31 @@ using webkit::npapi::WebPluginGeometry;
|
|||
using WebKit::WebSize;
|
||||
|
||||
|
||||
void WebWidgetHost::ScheduleAnimation() {
|
||||
void WebWidgetHost::ScheduleComposite() {
|
||||
if (has_invalidate_task_)
|
||||
return;
|
||||
|
||||
has_invalidate_task_ = true;
|
||||
|
||||
// Try to paint at 60fps.
|
||||
static int64 kDesiredRate = 16;
|
||||
|
||||
base::TimeDelta delta = base::TimeTicks::Now() - paint_last_call_;
|
||||
int64 actualRate = delta.InMilliseconds();
|
||||
if (actualRate >= kDesiredRate) {
|
||||
// Can't keep up so run as fast as possible.
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
base::Bind(&WebWidgetHost::Invalidate, weak_factory_.GetWeakPtr()));
|
||||
} else {
|
||||
// Maintain the desired rate.
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE,
|
||||
base::Bind(&WebWidgetHost::ScheduleComposite, weak_factory_.GetWeakPtr()),
|
||||
10);
|
||||
base::Bind(&WebWidgetHost::Invalidate, weak_factory_.GetWeakPtr()),
|
||||
kDesiredRate - actualRate);
|
||||
}
|
||||
}
|
||||
|
||||
void WebWidgetHost::ScheduleAnimation() {
|
||||
ScheduleComposite();
|
||||
}
|
||||
|
||||
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/task.h"
|
||||
#include "base/time.h"
|
||||
#include "skia/ext/platform_canvas.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
|
||||
|
@ -73,8 +74,17 @@ class WebWidgetHost {
|
|||
|
||||
void DidInvalidateRect(const gfx::Rect& rect);
|
||||
void DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect);
|
||||
|
||||
// Called for accelerated content like WebGL.
|
||||
void ScheduleComposite();
|
||||
|
||||
// Called for requestAnimationFrame animations.
|
||||
void ScheduleAnimation();
|
||||
|
||||
// Invalidate the complete client area. This is called at a reasonable frame
|
||||
// rate by the Schedule*() methods.
|
||||
void Invalidate();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void SetCursor(HCURSOR cursor);
|
||||
#endif
|
||||
|
@ -161,7 +171,7 @@ class WebWidgetHost {
|
|||
void OnInputLangChange(DWORD character_set, HKL input_language_id);
|
||||
void ImeUpdateTextInputState(WebKit::WebTextInputType type,
|
||||
const gfx::Rect& caret_rect);
|
||||
static void UpdateInputMethod(HWND view);
|
||||
void UpdateInputMethod();
|
||||
#elif defined(OS_MACOSX)
|
||||
// These need to be called from a non-subclass, so they need to be public.
|
||||
public:
|
||||
|
@ -225,6 +235,17 @@ class WebWidgetHost {
|
|||
// True if an update task is pending when window rendering is disabled.
|
||||
bool has_update_task_;
|
||||
|
||||
// True if an invalidate task is pending due to the Schedule*() methods.
|
||||
bool has_invalidate_task_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// True if an update input method task is pending due to DidInvalidateRect().
|
||||
bool has_update_input_method_task_;
|
||||
#endif
|
||||
|
||||
// When the Paint() method last completed.
|
||||
base::TimeTicks paint_last_call_;
|
||||
|
||||
// Redraw rectangle requested by an explicit call to CefBrowser::Invalidate().
|
||||
gfx::Rect redraw_rect_;
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
|||
DidInvalidateRect(clip_rect);
|
||||
}
|
||||
|
||||
void WebWidgetHost::ScheduleComposite() {
|
||||
void WebWidgetHost::Invalidate() {
|
||||
int width = logical_size_.width();
|
||||
int height = logical_size_.height();
|
||||
GdkRectangle grect = {
|
||||
|
@ -323,6 +323,7 @@ WebWidgetHost::WebWidgetHost()
|
|||
canvas_h_(0),
|
||||
popup_(false),
|
||||
has_update_task_(false),
|
||||
has_invalidate_task_(false),
|
||||
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
||||
set_painting(false);
|
||||
}
|
||||
|
@ -414,6 +415,11 @@ void WebWidgetHost::Paint() {
|
|||
cairo_destroy(cairo_drawable);
|
||||
|
||||
gdk_window_end_paint(window);
|
||||
|
||||
// Used with scheduled invalidation to maintain a consistent frame rate.
|
||||
paint_last_call_ = base::TimeTicks::Now();
|
||||
if (has_invalidate_task_)
|
||||
has_invalidate_task_ = false;
|
||||
}
|
||||
|
||||
void WebWidgetHost::SetTooltipText(const CefString& tooltip_text)
|
||||
|
|
|
@ -67,6 +67,7 @@ WebWidgetHost::WebWidgetHost()
|
|||
canvas_h_(0),
|
||||
popup_(false),
|
||||
has_update_task_(false),
|
||||
has_invalidate_task_(false),
|
||||
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
||||
set_painting(false);
|
||||
}
|
||||
|
@ -177,12 +178,13 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) {
|
|||
paint_rgn_.setRect(convertToSkiaRect(client_rect));
|
||||
}
|
||||
|
||||
// Animate the view and layout any views that have not been laid out yet. The
|
||||
// latter may result in more invalidation. Keep track of the fact that we are
|
||||
// laying out views, because this will sometimes cause ScrollRect to be called
|
||||
// and we don't want to try to scrollRect:by: then.
|
||||
layouting_ = true;
|
||||
webwidget_->animate(0.0);
|
||||
|
||||
// Layout any views that have not been laid out yet. The layout may result in
|
||||
// more invalidation. Keep track of the fact that we are laying out views,
|
||||
// because this will sometimes cause ScrollRect to be called and we don't want
|
||||
// to try to scrollRect:by: then.
|
||||
layouting_ = true;
|
||||
webwidget_->layout();
|
||||
layouting_ = false;
|
||||
|
||||
|
@ -225,9 +227,14 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) {
|
|||
const float y = client_rect.height() - r.bottom();
|
||||
skia::DrawToNativeContext(canvas_.get(), context, x, y, ©_rect);
|
||||
}
|
||||
|
||||
// Used with scheduled invalidation to maintain a consistent frame rate.
|
||||
paint_last_call_ = base::TimeTicks::Now();
|
||||
if (has_invalidate_task_)
|
||||
has_invalidate_task_ = false;
|
||||
}
|
||||
|
||||
void WebWidgetHost::ScheduleComposite() {
|
||||
void WebWidgetHost::Invalidate() {
|
||||
[view_ setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
|
|
|
@ -273,9 +273,15 @@ void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
|
|||
UpdatePaintRect(damaged_rect);
|
||||
InvalidateRect(damaged_rect);
|
||||
|
||||
if (!popup_ && view_) {
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableFunction(
|
||||
&WebWidgetHost::UpdateInputMethod, view_));
|
||||
if (!popup_ && view_ && webwidget_ && input_method_is_active_ &&
|
||||
!has_update_input_method_task_) {
|
||||
has_update_input_method_task_ = true;
|
||||
|
||||
// Call UpdateInputMethod() approximately every 100ms.
|
||||
CefThread::PostDelayedTask(CefThread::UI, FROM_HERE,
|
||||
base::Bind(&WebWidgetHost::UpdateInputMethod,
|
||||
weak_factory_.GetWeakPtr()),
|
||||
100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,7 +314,7 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
|||
InvalidateRect(clip_rect);
|
||||
}
|
||||
|
||||
void WebWidgetHost::ScheduleComposite() {
|
||||
void WebWidgetHost::Invalidate() {
|
||||
if (!webwidget_)
|
||||
return;
|
||||
WebSize size = webwidget_->size();
|
||||
|
@ -331,6 +337,8 @@ WebWidgetHost::WebWidgetHost()
|
|||
popup_(false),
|
||||
track_mouse_leave_(false),
|
||||
has_update_task_(false),
|
||||
has_invalidate_task_(false),
|
||||
has_update_input_method_task_(false),
|
||||
tooltip_view_(NULL),
|
||||
tooltip_showing_(false),
|
||||
ime_notification_(false),
|
||||
|
@ -403,12 +411,11 @@ void WebWidgetHost::Paint() {
|
|||
canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true));
|
||||
}
|
||||
|
||||
layouting_ = true;
|
||||
webwidget_->animate(0.0);
|
||||
|
||||
// This may result in more invalidation.
|
||||
layouting_ = true;
|
||||
webwidget_->layout();
|
||||
|
||||
layouting_ = false;
|
||||
|
||||
// Paint the canvas if necessary. Allow painting to generate extra rects the
|
||||
|
@ -519,6 +526,11 @@ void WebWidgetHost::Paint() {
|
|||
|
||||
paint_delegate_->Paint(popup_, damaged_rects, pixels);
|
||||
}
|
||||
|
||||
// Used with scheduled invalidation to maintain a consistent frame rate.
|
||||
paint_last_call_ = base::TimeTicks::Now();
|
||||
if (has_invalidate_task_)
|
||||
has_invalidate_task_ = false;
|
||||
}
|
||||
|
||||
void WebWidgetHost::InvalidateRect(const gfx::Rect& rect)
|
||||
|
@ -1091,40 +1103,27 @@ void WebWidgetHost::ImeUpdateTextInputState(WebKit::WebTextInputType type,
|
|||
ime_input_.UpdateCaretRect(view_, caret_rect);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void WebWidgetHost::UpdateInputMethod(HWND view)
|
||||
void WebWidgetHost::UpdateInputMethod()
|
||||
{
|
||||
// Since we call this function asynchronously (via PostTask), we
|
||||
// must ensure that we haven't destroyed the window by the time this
|
||||
// function executes
|
||||
if (!::IsWindow(view))
|
||||
REQUIRE_UIT();
|
||||
|
||||
has_update_input_method_task_ = false;
|
||||
|
||||
if (!input_method_is_active_ || !webwidget_)
|
||||
return;
|
||||
|
||||
WebWidgetHost* host = FromWindow(view);
|
||||
|
||||
if (!host || !host->input_method_is_active_)
|
||||
return;
|
||||
|
||||
if (!host->webwidget_ || !CefThread::CurrentlyOn(CefThread::UI))
|
||||
return;
|
||||
|
||||
WebKit::WebTextInputType new_type = WebKit::WebTextInputTypeNone;
|
||||
WebKit::WebTextInputType new_type = webwidget_->textInputType();
|
||||
WebKit::WebRect new_caret_bounds;
|
||||
|
||||
if (host->webwidget_) {
|
||||
new_type = host->webwidget_->textInputType();
|
||||
|
||||
WebKit::WebRect startRect, endRect;
|
||||
if (host->webwidget_->selectionBounds(startRect, endRect))
|
||||
if (webwidget_->selectionBounds(startRect, endRect))
|
||||
new_caret_bounds = endRect;
|
||||
}
|
||||
|
||||
// Only sends text input type and caret bounds to the browser process if they
|
||||
// are changed.
|
||||
if (host->text_input_type_ != new_type ||
|
||||
host->caret_bounds_ != new_caret_bounds) {
|
||||
host->text_input_type_ = new_type;
|
||||
host->caret_bounds_ = new_caret_bounds;
|
||||
host->ImeUpdateTextInputState(new_type, new_caret_bounds);
|
||||
if (text_input_type_ != new_type || caret_bounds_ != new_caret_bounds) {
|
||||
text_input_type_ = new_type;
|
||||
caret_bounds_ = new_caret_bounds;
|
||||
ImeUpdateTextInputState(new_type, new_caret_bounds);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue