Merge revision 739 changes:
- Add the ability to customize the animation frame rate (issue #697). git-svn-id: https://chromiumembedded.googlecode.com/svn/branches/1025@740 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
f0e11cc5df
commit
4a9c00b2e7
|
@ -224,6 +224,13 @@ typedef struct _cef_browser_settings_t {
|
|||
///
|
||||
bool history_disabled;
|
||||
|
||||
///
|
||||
// The number of frames per second (fps) for the requestAnimationFrame timer
|
||||
// and calls to CefRenderHandler::OnPaint(). The value must be between 0 and
|
||||
// 90. Specify zero for the default frame rate of 30 fps.
|
||||
///
|
||||
int animation_frame_rate;
|
||||
|
||||
// The below values map to WebPreferences settings.
|
||||
|
||||
///
|
||||
|
|
|
@ -331,6 +331,7 @@ struct CefBrowserSettingsTraits {
|
|||
target->drag_drop_disabled = src->drag_drop_disabled;
|
||||
target->load_drops_disabled = src->load_drops_disabled;
|
||||
target->history_disabled = src->history_disabled;
|
||||
target->animation_frame_rate = src->animation_frame_rate;
|
||||
|
||||
cef_string_set(src->standard_font_family.str,
|
||||
src->standard_font_family.length, &target->standard_font_family, copy);
|
||||
|
|
|
@ -92,6 +92,8 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) {
|
|||
if (!settings_.developer_tools_disabled)
|
||||
dev_tools_agent_->SetWebView(webviewhost_->webview());
|
||||
|
||||
webviewhost_->SetFrameRate(settings_.animation_frame_rate);
|
||||
|
||||
window_info_.m_Widget = webviewhost_->view_handle();
|
||||
g_signal_connect(G_OBJECT(window_info_.m_Widget), "destroy",
|
||||
G_CALLBACK(window_destroyed), this);
|
||||
|
|
|
@ -108,6 +108,8 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) {
|
|||
if (!settings_.developer_tools_disabled)
|
||||
dev_tools_agent_->SetWebView(webviewhost_->webview());
|
||||
|
||||
webviewhost_->SetFrameRate(settings_.animation_frame_rate);
|
||||
|
||||
BrowserWebView* browserView = (BrowserWebView*)webviewhost_->view_handle();
|
||||
browserView.browser = this;
|
||||
window_info_.m_View = browserView;
|
||||
|
|
|
@ -219,6 +219,8 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) {
|
|||
if (!settings_.developer_tools_disabled)
|
||||
dev_tools_agent_->SetWebView(webviewhost_->webview());
|
||||
|
||||
webviewhost_->SetFrameRate(settings_.animation_frame_rate);
|
||||
|
||||
Unlock();
|
||||
|
||||
if (!window_info_.m_bWindowRenderingDisabled) {
|
||||
|
|
|
@ -14,24 +14,15 @@
|
|||
using webkit::npapi::WebPluginGeometry;
|
||||
using WebKit::WebSize;
|
||||
|
||||
const int WebWidgetHost::kDefaultFrameRate = 30;
|
||||
const int WebWidgetHost::kMaxFrameRate = 90;
|
||||
|
||||
void WebWidgetHost::ScheduleComposite() {
|
||||
if (invalidate_timer_.IsRunning())
|
||||
return;
|
||||
|
||||
// Try to paint at 60fps.
|
||||
static int64 kDesiredRate = 16;
|
||||
|
||||
// Maintain the desired rate.
|
||||
invalidate_timer_.Start(
|
||||
FROM_HERE,
|
||||
base::TimeDelta::FromMilliseconds(kDesiredRate),
|
||||
this,
|
||||
&WebWidgetHost::Invalidate);
|
||||
ScheduleInvalidateTimer();
|
||||
}
|
||||
|
||||
void WebWidgetHost::ScheduleAnimation() {
|
||||
ScheduleComposite();
|
||||
ScheduleInvalidateTimer();
|
||||
}
|
||||
|
||||
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
||||
|
@ -49,6 +40,12 @@ void WebWidgetHost::UpdateRedrawRect(const gfx::Rect& rect) {
|
|||
redraw_rect_ = redraw_rect_.Union(rect);
|
||||
}
|
||||
|
||||
void WebWidgetHost::InvalidateRect(const gfx::Rect& rect) {
|
||||
if (rect.IsEmpty())
|
||||
return;
|
||||
DidInvalidateRect(rect);
|
||||
}
|
||||
|
||||
void WebWidgetHost::SetSize(int width, int height) {
|
||||
webwidget_->resize(WebSize(width, height));
|
||||
DidInvalidateRect(gfx::Rect(0, 0, width, height));
|
||||
|
@ -98,28 +95,69 @@ gfx::PluginWindowHandle WebWidgetHost::GetWindowedPluginAt(int x, int y) {
|
|||
return gfx::kNullPluginWindow;
|
||||
}
|
||||
|
||||
void WebWidgetHost::SetFrameRate(int frames_per_second) {
|
||||
if (frames_per_second <= 0)
|
||||
frames_per_second = kDefaultFrameRate;
|
||||
if (frames_per_second > kMaxFrameRate)
|
||||
frames_per_second = kMaxFrameRate;
|
||||
|
||||
frame_delay_ = 1000 / frames_per_second;
|
||||
}
|
||||
|
||||
void WebWidgetHost::ScheduleInvalidateTimer() {
|
||||
if (invalidate_timer_.IsRunning())
|
||||
return;
|
||||
|
||||
// Maintain the desired rate.
|
||||
base::TimeDelta delta = base::TimeTicks::Now() - last_invalidate_time_;
|
||||
int64 actualRate = delta.InMilliseconds();
|
||||
if (actualRate >= frame_delay_)
|
||||
delta = base::TimeDelta::FromMilliseconds(1);
|
||||
else
|
||||
delta = base::TimeDelta::FromMilliseconds(frame_delay_ - actualRate);
|
||||
|
||||
invalidate_timer_.Start(
|
||||
FROM_HERE,
|
||||
delta,
|
||||
this,
|
||||
&WebWidgetHost::DoInvalidate);
|
||||
}
|
||||
|
||||
void WebWidgetHost::DoInvalidate() {
|
||||
if (!webwidget_)
|
||||
return;
|
||||
WebSize size = webwidget_->size();
|
||||
InvalidateRect(gfx::Rect(0, 0, size.width, size.height));
|
||||
|
||||
last_invalidate_time_ = base::TimeTicks::Now();
|
||||
}
|
||||
|
||||
void WebWidgetHost::SchedulePaintTimer() {
|
||||
if (layouting_ || paint_timer_.IsRunning())
|
||||
return;
|
||||
|
||||
// Maintain the desired rate.
|
||||
base::TimeDelta delta = base::TimeTicks::Now() - last_paint_time_;
|
||||
int64 actualRate = delta.InMilliseconds();
|
||||
if (actualRate >= frame_delay_)
|
||||
delta = base::TimeDelta::FromMilliseconds(1);
|
||||
else
|
||||
delta = base::TimeDelta::FromMilliseconds(frame_delay_ - actualRate);
|
||||
|
||||
paint_timer_.Start(
|
||||
FROM_HERE,
|
||||
base::TimeDelta::FromMilliseconds(0), // Fire immediately.
|
||||
delta,
|
||||
this,
|
||||
&WebWidgetHost::DoPaint);
|
||||
}
|
||||
|
||||
void WebWidgetHost::DoPaint() {
|
||||
if (MessageLoop::current()->IsIdle()) {
|
||||
// Paint to the delegate.
|
||||
#if defined(OS_MACOSX)
|
||||
SkRegion region;
|
||||
Paint(region);
|
||||
SkRegion region;
|
||||
Paint(region);
|
||||
#else
|
||||
Paint();
|
||||
Paint();
|
||||
#endif
|
||||
} else {
|
||||
// Try again later.
|
||||
SchedulePaintTimer();
|
||||
}
|
||||
|
||||
last_paint_time_ = base::TimeTicks::Now();
|
||||
}
|
||||
|
|
|
@ -85,10 +85,6 @@ class WebWidgetHost {
|
|||
// 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
|
||||
|
@ -139,6 +135,8 @@ class WebWidgetHost {
|
|||
void MoveWindowedPlugin(const webkit::npapi::WebPluginGeometry& geometry);
|
||||
gfx::PluginWindowHandle GetWindowedPluginAt(int x, int y);
|
||||
|
||||
void SetFrameRate(int frames_per_second);
|
||||
|
||||
void set_popup(bool popup) { popup_ = popup; }
|
||||
bool popup() { return popup_; }
|
||||
|
||||
|
@ -147,6 +145,10 @@ class WebWidgetHost {
|
|||
protected:
|
||||
WebWidgetHost();
|
||||
|
||||
// Called from the Schedule*() methods.
|
||||
void ScheduleInvalidateTimer();
|
||||
void DoInvalidate();
|
||||
|
||||
// If window rendering is disabled paint messages are generated after all
|
||||
// other pending messages have been processed.
|
||||
void SchedulePaintTimer();
|
||||
|
@ -240,9 +242,13 @@ class WebWidgetHost {
|
|||
// Used to coalesce DidInvalidateRect() events into a single DoPaint() call.
|
||||
// Used when window rendering is disabled.
|
||||
base::OneShotTimer<WebWidgetHost> paint_timer_;
|
||||
base::TimeTicks last_paint_time_;
|
||||
|
||||
// Used to coalesce Schedule*() events into a single Invalidate() call.
|
||||
base::OneShotTimer<WebWidgetHost> invalidate_timer_;
|
||||
base::TimeTicks last_invalidate_time_;
|
||||
|
||||
int64 frame_delay_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Used to call UpdateImeInputState() while IME is active.
|
||||
|
@ -293,6 +299,9 @@ class WebWidgetHost {
|
|||
|
||||
bool painting_;
|
||||
bool layouting_;
|
||||
|
||||
static const int kDefaultFrameRate;
|
||||
static const int kMaxFrameRate;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_WEBWIDGET_HOST_H_
|
||||
|
|
|
@ -290,26 +290,14 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
|||
DidInvalidateRect(clip_rect);
|
||||
}
|
||||
|
||||
void WebWidgetHost::Invalidate() {
|
||||
int width = logical_size_.width();
|
||||
int height = logical_size_.height();
|
||||
GdkRectangle grect = {
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height
|
||||
};
|
||||
GdkWindow* window = view_->window;
|
||||
gdk_window_invalidate_rect(window, &grect, 0);
|
||||
}
|
||||
|
||||
WebWidgetHost::WebWidgetHost()
|
||||
: view_(NULL),
|
||||
paint_delegate_(NULL),
|
||||
webwidget_(NULL),
|
||||
canvas_w_(0),
|
||||
canvas_h_(0),
|
||||
popup_(false) {
|
||||
popup_(false),
|
||||
frame_delay_(1000 / kDefaultFrameRate) {
|
||||
set_painting(false);
|
||||
}
|
||||
|
||||
|
@ -406,11 +394,6 @@ void WebWidgetHost::SetTooltipText(const CefString& tooltip_text) {
|
|||
// TODO(port): Implement this method as part of tooltip support.
|
||||
}
|
||||
|
||||
void WebWidgetHost::InvalidateRect(const gfx::Rect& rect) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
bool WebWidgetHost::GetImage(int width, int height, void* rgba_buffer) {
|
||||
if (!canvas_.get())
|
||||
return false;
|
||||
|
|
|
@ -82,6 +82,7 @@ WebWidgetHost::WebWidgetHost()
|
|||
canvas_w_(0),
|
||||
canvas_h_(0),
|
||||
popup_(false),
|
||||
frame_delay_(1000 / kDefaultFrameRate),
|
||||
mouse_modifiers_(0),
|
||||
painting_(false),
|
||||
layouting_(false) {
|
||||
|
@ -320,25 +321,10 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) {
|
|||
}
|
||||
}
|
||||
|
||||
void WebWidgetHost::Invalidate() {
|
||||
if (!webwidget_)
|
||||
return;
|
||||
|
||||
WebSize size = webwidget_->size();
|
||||
InvalidateRect(gfx::Rect(0, 0, size.width, size.height));
|
||||
}
|
||||
|
||||
void WebWidgetHost::SetTooltipText(const CefString& tooltip_text) {
|
||||
// TODO(port): Implement this method as part of tooltip support.
|
||||
}
|
||||
|
||||
void WebWidgetHost::InvalidateRect(const gfx::Rect& rect) {
|
||||
if (rect.IsEmpty())
|
||||
return;
|
||||
|
||||
DidInvalidateRect(rect);
|
||||
}
|
||||
|
||||
bool WebWidgetHost::GetImage(int width, int height, void* rgba_buffer) {
|
||||
if (!canvas_.get())
|
||||
return false;
|
||||
|
|
|
@ -316,13 +316,6 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
|||
::InvalidateRect(view_, &r, FALSE);
|
||||
}
|
||||
|
||||
void WebWidgetHost::Invalidate() {
|
||||
if (!webwidget_)
|
||||
return;
|
||||
WebSize size = webwidget_->size();
|
||||
InvalidateRect(gfx::Rect(0, 0, size.width, size.height));
|
||||
}
|
||||
|
||||
void WebWidgetHost::SetCursor(HCURSOR cursor) {
|
||||
DCHECK(view_);
|
||||
SetClassLong(view_, GCL_HCURSOR,
|
||||
|
@ -338,6 +331,7 @@ WebWidgetHost::WebWidgetHost()
|
|||
canvas_h_(0),
|
||||
popup_(false),
|
||||
track_mouse_leave_(false),
|
||||
frame_delay_(1000 / kDefaultFrameRate),
|
||||
tooltip_view_(NULL),
|
||||
tooltip_showing_(false),
|
||||
ime_notification_(false),
|
||||
|
@ -530,13 +524,6 @@ void WebWidgetHost::Paint() {
|
|||
}
|
||||
}
|
||||
|
||||
void WebWidgetHost::InvalidateRect(const gfx::Rect& rect) {
|
||||
if (rect.IsEmpty())
|
||||
return;
|
||||
|
||||
DidInvalidateRect(rect);
|
||||
}
|
||||
|
||||
bool WebWidgetHost::GetImage(int width, int height, void* buffer) {
|
||||
const SkBitmap& bitmap = canvas_->getDevice()->accessBitmap(false);
|
||||
DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config);
|
||||
|
|
|
@ -11,11 +11,6 @@ patches = [
|
|||
'name': 'build',
|
||||
'path': '../build/',
|
||||
},
|
||||
{
|
||||
# http://codereview.chromium.org/6730028/
|
||||
'name': 'base',
|
||||
'path': '../base/',
|
||||
},
|
||||
{
|
||||
# http://code.google.com/p/gyp/issues/detail?id=223
|
||||
# http://codereview.chromium.org/10383117/
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
Index: message_loop.cc
|
||||
===================================================================
|
||||
--- message_loop.cc (revision 119867)
|
||||
+++ message_loop.cc (working copy)
|
||||
@@ -362,9 +362,13 @@
|
||||
}
|
||||
|
||||
void MessageLoop::AssertIdle() const {
|
||||
+ DCHECK(IsIdle());
|
||||
+}
|
||||
+
|
||||
+bool MessageLoop::IsIdle() const {
|
||||
// We only check |incoming_queue_|, since we don't want to lock |work_queue_|.
|
||||
base::AutoLock lock(incoming_queue_lock_);
|
||||
- DCHECK(incoming_queue_.empty());
|
||||
+ return incoming_queue_.empty();
|
||||
}
|
||||
|
||||
bool MessageLoop::is_running() const {
|
||||
Index: message_loop.h
|
||||
===================================================================
|
||||
--- message_loop.h (revision 119867)
|
||||
+++ message_loop.h (working copy)
|
||||
@@ -345,6 +345,9 @@
|
||||
// Asserts that the MessageLoop is "idle".
|
||||
void AssertIdle() const;
|
||||
|
||||
+ // Returns true if the MessageLoop is "idle".
|
||||
+ bool IsIdle() const;
|
||||
+
|
||||
#if defined(OS_WIN)
|
||||
void set_os_modal_loop(bool os_modal_loop) {
|
||||
os_modal_loop_ = os_modal_loop;
|
|
@ -297,6 +297,10 @@ void AppGetBrowserSettings(CefBrowserSettings& settings) {
|
|||
g_command_line->HasSwitch(cefclient::kLoadDropsDisabled);
|
||||
settings.history_disabled =
|
||||
g_command_line->HasSwitch(cefclient::kHistoryDisabled);
|
||||
|
||||
settings.animation_frame_rate = GetIntValue(
|
||||
g_command_line->GetSwitchValue(cefclient::kAnimationFrameRate));
|
||||
|
||||
settings.remote_fonts_disabled =
|
||||
g_command_line->HasSwitch(cefclient::kRemoteFontsDisabled);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ const char kPackLoadingDisabled[] = "pack-loading-disabled";
|
|||
const char kDragDropDisabled[] = "drag-drop-disabled";
|
||||
const char kLoadDropsDisabled[] = "load-drops-disabled";
|
||||
const char kHistoryDisabled[] = "history-disabled";
|
||||
const char kAnimationFrameRate[] = "animation-frame-rate";
|
||||
const char kRemoteFontsDisabled[] = "remote-fonts-disabled";
|
||||
const char kDefaultEncoding[] = "default-encoding";
|
||||
const char kEncodingDetectorEnabled[] = "encoding-detector-enabled";
|
||||
|
|
|
@ -40,6 +40,7 @@ extern const char kPackLoadingDisabled[];
|
|||
extern const char kDragDropDisabled[];
|
||||
extern const char kLoadDropsDisabled[];
|
||||
extern const char kHistoryDisabled[];
|
||||
extern const char kAnimationFrameRate[];
|
||||
extern const char kRemoteFontsDisabled[];
|
||||
extern const char kDefaultEncoding[];
|
||||
extern const char kEncodingDetectorEnabled[];
|
||||
|
|
|
@ -64,6 +64,11 @@ class ClientOSRHandler : public CefClient,
|
|||
~ClientOSRHandler() {
|
||||
}
|
||||
|
||||
// Called immediately before the plugin is destroyed.
|
||||
void Detach() {
|
||||
plugin_ = NULL;
|
||||
}
|
||||
|
||||
// CefClient methods
|
||||
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {
|
||||
return this;
|
||||
|
@ -202,6 +207,9 @@ class ClientOSRHandler : public CefClient,
|
|||
CefRect& rect) OVERRIDE {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
if (!plugin_)
|
||||
return false;
|
||||
|
||||
// The simulated screen and view rectangle are the same. This is necessary
|
||||
// for popup menus to be located and sized inside the view.
|
||||
RECT clientRect;
|
||||
|
@ -225,6 +233,9 @@ class ClientOSRHandler : public CefClient,
|
|||
int& screenY) OVERRIDE {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
if (!plugin_)
|
||||
return false;
|
||||
|
||||
// Convert the point from view coordinates to actual screen coordinates.
|
||||
POINT screen_pt = {viewX, viewY};
|
||||
MapWindowPoints(plugin_->hWnd, HWND_DESKTOP, &screen_pt, 1);
|
||||
|
@ -236,12 +247,20 @@ class ClientOSRHandler : public CefClient,
|
|||
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) OVERRIDE {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
if (!plugin_)
|
||||
return;
|
||||
|
||||
plugin_->renderer.OnPopupShow(browser, show);
|
||||
}
|
||||
|
||||
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) OVERRIDE {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
if (!plugin_)
|
||||
return;
|
||||
|
||||
plugin_->renderer.OnPopupSize(browser, rect);
|
||||
}
|
||||
|
||||
|
@ -251,6 +270,9 @@ class ClientOSRHandler : public CefClient,
|
|||
const void* buffer) OVERRIDE {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
if (!plugin_)
|
||||
return;
|
||||
|
||||
wglMakeCurrent(plugin_->hDC, plugin_->hRC);
|
||||
plugin_->renderer.OnPaint(browser, type, dirtyRects, buffer);
|
||||
}
|
||||
|
@ -259,6 +281,9 @@ class ClientOSRHandler : public CefClient,
|
|||
CefCursorHandle cursor) OVERRIDE {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
if (!plugin_)
|
||||
return;
|
||||
|
||||
// Change the plugin window's cursor.
|
||||
SetClassLong(plugin_->hWnd, GCL_HCURSOR,
|
||||
static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
|
||||
|
@ -357,6 +382,11 @@ NPError NPP_DestroyImpl(NPP instance, NPSavedData** save) {
|
|||
ClientPlugin* plugin = reinterpret_cast<ClientPlugin*>(instance->pdata);
|
||||
|
||||
if (plugin) {
|
||||
if (g_offscreenBrowser.get()) {
|
||||
CefRefPtr<ClientOSRHandler> handler =
|
||||
static_cast<ClientOSRHandler*>(g_offscreenBrowser->GetClient().get());
|
||||
handler->Detach();
|
||||
}
|
||||
if (plugin->hWnd) {
|
||||
DestroyWindow(plugin->hWnd);
|
||||
DisableGL(plugin);
|
||||
|
|
Loading…
Reference in New Issue