- 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;
|
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,
|
MessageLoop::current()->PostDelayedTask(FROM_HERE,
|
||||||
base::Bind(&WebWidgetHost::ScheduleComposite, weak_factory_.GetWeakPtr()),
|
base::Bind(&WebWidgetHost::Invalidate, weak_factory_.GetWeakPtr()),
|
||||||
10);
|
kDesiredRate - actualRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::ScheduleAnimation() {
|
||||||
|
ScheduleComposite();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/task.h"
|
#include "base/task.h"
|
||||||
|
#include "base/time.h"
|
||||||
#include "skia/ext/platform_canvas.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/WebInputEvent.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
|
||||||
|
@ -73,8 +74,17 @@ class WebWidgetHost {
|
||||||
|
|
||||||
void DidInvalidateRect(const gfx::Rect& rect);
|
void DidInvalidateRect(const gfx::Rect& rect);
|
||||||
void DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect);
|
void DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect);
|
||||||
|
|
||||||
|
// Called for accelerated content like WebGL.
|
||||||
void ScheduleComposite();
|
void ScheduleComposite();
|
||||||
|
|
||||||
|
// Called for requestAnimationFrame animations.
|
||||||
void ScheduleAnimation();
|
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)
|
#if defined(OS_WIN)
|
||||||
void SetCursor(HCURSOR cursor);
|
void SetCursor(HCURSOR cursor);
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,7 +171,7 @@ class WebWidgetHost {
|
||||||
void OnInputLangChange(DWORD character_set, HKL input_language_id);
|
void OnInputLangChange(DWORD character_set, HKL input_language_id);
|
||||||
void ImeUpdateTextInputState(WebKit::WebTextInputType type,
|
void ImeUpdateTextInputState(WebKit::WebTextInputType type,
|
||||||
const gfx::Rect& caret_rect);
|
const gfx::Rect& caret_rect);
|
||||||
static void UpdateInputMethod(HWND view);
|
void UpdateInputMethod();
|
||||||
#elif defined(OS_MACOSX)
|
#elif defined(OS_MACOSX)
|
||||||
// These need to be called from a non-subclass, so they need to be public.
|
// These need to be called from a non-subclass, so they need to be public.
|
||||||
public:
|
public:
|
||||||
|
@ -225,6 +235,17 @@ class WebWidgetHost {
|
||||||
// True if an update task is pending when window rendering is disabled.
|
// True if an update task is pending when window rendering is disabled.
|
||||||
bool has_update_task_;
|
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().
|
// Redraw rectangle requested by an explicit call to CefBrowser::Invalidate().
|
||||||
gfx::Rect redraw_rect_;
|
gfx::Rect redraw_rect_;
|
||||||
|
|
||||||
|
|
|
@ -302,7 +302,7 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
||||||
DidInvalidateRect(clip_rect);
|
DidInvalidateRect(clip_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::ScheduleComposite() {
|
void WebWidgetHost::Invalidate() {
|
||||||
int width = logical_size_.width();
|
int width = logical_size_.width();
|
||||||
int height = logical_size_.height();
|
int height = logical_size_.height();
|
||||||
GdkRectangle grect = {
|
GdkRectangle grect = {
|
||||||
|
@ -323,6 +323,7 @@ WebWidgetHost::WebWidgetHost()
|
||||||
canvas_h_(0),
|
canvas_h_(0),
|
||||||
popup_(false),
|
popup_(false),
|
||||||
has_update_task_(false),
|
has_update_task_(false),
|
||||||
|
has_invalidate_task_(false),
|
||||||
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
||||||
set_painting(false);
|
set_painting(false);
|
||||||
}
|
}
|
||||||
|
@ -414,6 +415,11 @@ void WebWidgetHost::Paint() {
|
||||||
cairo_destroy(cairo_drawable);
|
cairo_destroy(cairo_drawable);
|
||||||
|
|
||||||
gdk_window_end_paint(window);
|
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)
|
void WebWidgetHost::SetTooltipText(const CefString& tooltip_text)
|
||||||
|
|
|
@ -67,6 +67,7 @@ WebWidgetHost::WebWidgetHost()
|
||||||
canvas_h_(0),
|
canvas_h_(0),
|
||||||
popup_(false),
|
popup_(false),
|
||||||
has_update_task_(false),
|
has_update_task_(false),
|
||||||
|
has_invalidate_task_(false),
|
||||||
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
||||||
set_painting(false);
|
set_painting(false);
|
||||||
}
|
}
|
||||||
|
@ -177,12 +178,13 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) {
|
||||||
paint_rgn_.setRect(convertToSkiaRect(client_rect));
|
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);
|
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();
|
webwidget_->layout();
|
||||||
layouting_ = false;
|
layouting_ = false;
|
||||||
|
|
||||||
|
@ -225,9 +227,14 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) {
|
||||||
const float y = client_rect.height() - r.bottom();
|
const float y = client_rect.height() - r.bottom();
|
||||||
skia::DrawToNativeContext(canvas_.get(), context, x, y, ©_rect);
|
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];
|
[view_ setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -273,9 +273,15 @@ void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
|
||||||
UpdatePaintRect(damaged_rect);
|
UpdatePaintRect(damaged_rect);
|
||||||
InvalidateRect(damaged_rect);
|
InvalidateRect(damaged_rect);
|
||||||
|
|
||||||
if (!popup_ && view_) {
|
if (!popup_ && view_ && webwidget_ && input_method_is_active_ &&
|
||||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableFunction(
|
!has_update_input_method_task_) {
|
||||||
&WebWidgetHost::UpdateInputMethod, view_));
|
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);
|
InvalidateRect(clip_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::ScheduleComposite() {
|
void WebWidgetHost::Invalidate() {
|
||||||
if (!webwidget_)
|
if (!webwidget_)
|
||||||
return;
|
return;
|
||||||
WebSize size = webwidget_->size();
|
WebSize size = webwidget_->size();
|
||||||
|
@ -331,6 +337,8 @@ WebWidgetHost::WebWidgetHost()
|
||||||
popup_(false),
|
popup_(false),
|
||||||
track_mouse_leave_(false),
|
track_mouse_leave_(false),
|
||||||
has_update_task_(false),
|
has_update_task_(false),
|
||||||
|
has_invalidate_task_(false),
|
||||||
|
has_update_input_method_task_(false),
|
||||||
tooltip_view_(NULL),
|
tooltip_view_(NULL),
|
||||||
tooltip_showing_(false),
|
tooltip_showing_(false),
|
||||||
ime_notification_(false),
|
ime_notification_(false),
|
||||||
|
@ -403,12 +411,11 @@ void WebWidgetHost::Paint() {
|
||||||
canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true));
|
canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
layouting_ = true;
|
|
||||||
webwidget_->animate(0.0);
|
webwidget_->animate(0.0);
|
||||||
|
|
||||||
// This may result in more invalidation.
|
// This may result in more invalidation.
|
||||||
|
layouting_ = true;
|
||||||
webwidget_->layout();
|
webwidget_->layout();
|
||||||
|
|
||||||
layouting_ = false;
|
layouting_ = false;
|
||||||
|
|
||||||
// Paint the canvas if necessary. Allow painting to generate extra rects the
|
// 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);
|
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)
|
void WebWidgetHost::InvalidateRect(const gfx::Rect& rect)
|
||||||
|
@ -1091,40 +1103,27 @@ void WebWidgetHost::ImeUpdateTextInputState(WebKit::WebTextInputType type,
|
||||||
ime_input_.UpdateCaretRect(view_, caret_rect);
|
ime_input_.UpdateCaretRect(view_, caret_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
void WebWidgetHost::UpdateInputMethod()
|
||||||
void WebWidgetHost::UpdateInputMethod(HWND view)
|
|
||||||
{
|
{
|
||||||
// Since we call this function asynchronously (via PostTask), we
|
REQUIRE_UIT();
|
||||||
// must ensure that we haven't destroyed the window by the time this
|
|
||||||
// function executes
|
has_update_input_method_task_ = false;
|
||||||
if (!::IsWindow(view))
|
|
||||||
|
if (!input_method_is_active_ || !webwidget_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WebWidgetHost* host = FromWindow(view);
|
WebKit::WebTextInputType new_type = webwidget_->textInputType();
|
||||||
|
|
||||||
if (!host || !host->input_method_is_active_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!host->webwidget_ || !CefThread::CurrentlyOn(CefThread::UI))
|
|
||||||
return;
|
|
||||||
|
|
||||||
WebKit::WebTextInputType new_type = WebKit::WebTextInputTypeNone;
|
|
||||||
WebKit::WebRect new_caret_bounds;
|
WebKit::WebRect new_caret_bounds;
|
||||||
|
|
||||||
if (host->webwidget_) {
|
|
||||||
new_type = host->webwidget_->textInputType();
|
|
||||||
|
|
||||||
WebKit::WebRect startRect, endRect;
|
WebKit::WebRect startRect, endRect;
|
||||||
if (host->webwidget_->selectionBounds(startRect, endRect))
|
if (webwidget_->selectionBounds(startRect, endRect))
|
||||||
new_caret_bounds = endRect;
|
new_caret_bounds = endRect;
|
||||||
}
|
|
||||||
|
|
||||||
// Only sends text input type and caret bounds to the browser process if they
|
// Only sends text input type and caret bounds to the browser process if they
|
||||||
// are changed.
|
// are changed.
|
||||||
if (host->text_input_type_ != new_type ||
|
if (text_input_type_ != new_type || caret_bounds_ != new_caret_bounds) {
|
||||||
host->caret_bounds_ != new_caret_bounds) {
|
text_input_type_ = new_type;
|
||||||
host->text_input_type_ = new_type;
|
caret_bounds_ = new_caret_bounds;
|
||||||
host->caret_bounds_ = new_caret_bounds;
|
ImeUpdateTextInputState(new_type, new_caret_bounds);
|
||||||
host->ImeUpdateTextInputState(new_type, new_caret_bounds);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue