summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorzhurunz@google.com <zhurunz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-09 17:59:25 +0000
committerzhurunz@google.com <zhurunz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-09 17:59:25 +0000
commit7d1d235e5730527a50caf787550055118c164fa0 (patch)
treef6ed5f10ff26c150d82ba791054fa14c71c72236 /o3d
parent7ac575734caffdb73ec426bb3296a38a11249ce0 (diff)
downloadchromium_src-7d1d235e5730527a50caf787550055118c164fa0.zip
chromium_src-7d1d235e5730527a50caf787550055118c164fa0.tar.gz
chromium_src-7d1d235e5730527a50caf787550055118c164fa0.tar.bz2
Some changes in RENDERMODE_CONTINUOUS mode when max_fps has been set.
If Renderer::max_fps has been set, rendering is driven by incoming new textures. We draw on each new texture as long as not exceeding max_fps. If we are in RENDERMODE_ON_DEMAND mode, Client::Render() can still set dirty specifically. If we are in ENDERMODE_CONTINUOUS mode, we do NOT set dirty on each tick any more (since it is already driven by new textures.). There is one problem here: what if new texture don't come in for some reason? If that happened, no rendering callback will be invoked and this can cause problem sometimes. For example, some UI may depend on the rendering callback to work correctly. So, in RENDERMODE_CONTINUOUS mode, if we have set max_fps but haven't received any new texture for a while, we draw anyway to trigger the rendering callback. Review URL: http://codereview.chromium.org/2899008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51982 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/core/cross/client.cc43
-rw-r--r--o3d/core/cross/client.h8
-rw-r--r--o3d/core/cross/renderer.h5
-rw-r--r--o3d/plugin/linux/main_linux.cc10
-rw-r--r--o3d/plugin/mac/plugin_mac.mm2
-rw-r--r--o3d/plugin/win/main_win.cc2
6 files changed, 60 insertions, 10 deletions
diff --git a/o3d/core/cross/client.cc b/o3d/core/cross/client.cc
index 271df8e42..f534ef3 100644
--- a/o3d/core/cross/client.cc
+++ b/o3d/core/cross/client.cc
@@ -65,6 +65,25 @@ using std::vector;
using std::make_pair;
namespace o3d {
+// If Renderer::max_fps has been set, rendering is driven by incoming new
+// textures. We draw on each new texture as long as not exceeding max_fps.
+//
+// If we are in RENDERMODE_ON_DEMAND mode, Client::Render() can still set dirty
+// specifically.
+//
+// If we are in RENDERMODE_CONTINUOUS mode, we do NOT set dirty on each tick any
+// more (since it is already driven by new textures.).
+// There is one problem here: what if new texture don't come in for some reason?
+// If that happened, no rendering callback will be invoked and this can cause
+// problem sometimes. For example, some UI may depend on the rendering callback
+// to work correctly.
+// So, in RENDERMODE_CONTINUOUS mode, if we have set max_fps but haven't
+// received any new texture for a while, we draw anyway to trigger the rendering
+// callback.
+// This value defines the minimum number of draws per seconds in
+// RENDERMODE_CONTINUOUS mode.
+static const float kContinuousModeMinDrawPerSecond = 15;
+// TODO(zhurunz) Tuning this value.
// Client constructor. Creates the default root node for the scenegraph
Client::Client(ServiceLocator* service_locator)
@@ -356,6 +375,30 @@ bool Client::IsRendering() {
return (renderer_.IsAvailable() && renderer_->rendering());
}
+bool Client::NeedsContinuousRender() {
+ // Sanity check
+ if (!renderer_.IsAvailable()) {
+ return false;
+ }
+
+ bool needRender = false;
+ // Only may happen in RENDERMODE_CONTINUOUS mode.
+ if (render_mode() == RENDERMODE_CONTINUOUS) {
+ // Always need a draw in normal RENDERMODE_CONTINUOUS mode.
+ needRender = true;
+
+ // If max_fps has been set, only need a draw when "long time no draw".
+ int max_fps = renderer_->max_fps();
+ if (max_fps > 0 &&
+ render_elapsed_time_timer_.GetElapsedTimeWithoutClearing() <
+ 1.0/kContinuousModeMinDrawPerSecond)
+ {
+ needRender = false;
+ }
+ }
+ return needRender;
+}
+
// Executes draw calls for all visible shapes in a subtree
void Client::RenderTree(RenderNode *tree_root) {
if (!renderer_.IsAvailable())
diff --git a/o3d/core/cross/client.h b/o3d/core/cross/client.h
index 1dcb36d..4affeb2 100644
--- a/o3d/core/cross/client.h
+++ b/o3d/core/cross/client.h
@@ -264,6 +264,14 @@ class Client {
// the plugin to become reentrant. Detect this at a higher level.
bool IsRendering();
+ // If Renderer::max_fps has been set in RENDERMODE_CONTINUOUS mode, we don't
+ // draw on each tick but just let new textures drive the rendering. There is
+ // only one exception: if we haven't received any new textures for a while, we
+ // still need to draw in order to trigger rendering callback. Since there
+ // might be some UI depends on rendering callback.
+ // This function determines if this has happened and if we need a draw.
+ bool NeedsContinuousRender();
+
// Sets the texture to use when a Texture or Sampler is missing while
// rendering. If you set it to NULL you'll get an error if you try to render
// something that is missing a needed Texture, Sampler or ParamSampler
diff --git a/o3d/core/cross/renderer.h b/o3d/core/cross/renderer.h
index 76f18e2..3be95f4 100644
--- a/o3d/core/cross/renderer.h
+++ b/o3d/core/cross/renderer.h
@@ -210,9 +210,8 @@ class Renderer {
need_to_render_ = need_to_render;
}
- // We only respect max_fps in RENDERMODE_ON_DEMAND.
- // When max_fps is set to positive value in RENDERMODE_ON_DEMAND,
- // we render on every new texture without exceeding max_fps.
+ // When max_fps is set to positive value, we render on every new texture as
+ // long as not exceeding max_fps.
// Get max_fps
int max_fps() const {
diff --git a/o3d/plugin/linux/main_linux.cc b/o3d/plugin/linux/main_linux.cc
index 7e3ffb3..d2d79af 100644
--- a/o3d/plugin/linux/main_linux.cc
+++ b/o3d/plugin/linux/main_linux.cc
@@ -83,7 +83,7 @@ void LinuxTimer(XtPointer data, XtIntervalId* id) {
obj->client()->Tick();
obj->draw_ = true;
if (obj->renderer()) {
- if (obj->client()->render_mode() == o3d::Client::RENDERMODE_CONTINUOUS ||
+ if (obj->client()->NeedsContinuousRender() ||
obj->renderer()->need_to_render()) {
// NOTE: this draws no matter what instead of just invalidating the
@@ -93,7 +93,7 @@ void LinuxTimer(XtPointer data, XtIntervalId* id) {
}
}
obj->xt_interval_ =
- XtAppAddTimeOut(obj->xt_app_context_, 10, LinuxTimer, obj);
+ XtAppAddTimeOut(obj->xt_app_context_, 8, LinuxTimer, obj);
}
void LinuxExposeHandler(Widget w,
@@ -606,7 +606,7 @@ static gboolean GtkTimeoutCallback(gpointer user_data) {
obj->draw_ = true;
obj->client()->Tick();
if (obj->renderer()) {
- if (obj->client()->render_mode() == o3d::Client::RENDERMODE_CONTINUOUS ||
+ if (obj->client()->NeedsContinuousRender() ||
obj->renderer()->need_to_render()) {
GtkWidget *widget;
@@ -802,7 +802,7 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window) {
}
gtk_widget_show(obj->gtk_container_);
drawable = GDK_WINDOW_XID(obj->gtk_container_->window);
- obj->timeout_id_ = g_timeout_add(10, GtkTimeoutCallback, obj);
+ obj->timeout_id_ = g_timeout_add(8, GtkTimeoutCallback, obj);
} else {
// No XEmbed support, the xwindow is a Xt Widget.
Widget widget = XtWindowToWidget(display, xwindow);
@@ -822,7 +822,7 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window) {
LinuxEnterLeaveHandler, obj);
obj->xt_app_context_ = XtWidgetToApplicationContext(widget);
obj->xt_interval_ =
- XtAppAddTimeOut(obj->xt_app_context_, 10, LinuxTimer, obj);
+ XtAppAddTimeOut(obj->xt_app_context_, 8, LinuxTimer, obj);
}
// Create and assign the graphics context.
diff --git a/o3d/plugin/mac/plugin_mac.mm b/o3d/plugin/mac/plugin_mac.mm
index 26c8f7c..66b8ba6 100644
--- a/o3d/plugin/mac/plugin_mac.mm
+++ b/o3d/plugin/mac/plugin_mac.mm
@@ -280,7 +280,7 @@ void RenderTimer::TimerCallback(CFRunLoopTimerRef timer, void* info) {
obj->IsOffscreenRenderingEnabled();
if (plugin_visible && obj->renderer()) {
- if (obj->client()->render_mode() == o3d::Client::RENDERMODE_CONTINUOUS ||
+ if (obj->client()->NeedsContinuousRender() ||
obj->renderer()->need_to_render()) {
// Force a sync to the VBL (once per timer callback)
// to avoid tearing
diff --git a/o3d/plugin/win/main_win.cc b/o3d/plugin/win/main_win.cc
index 3f8a465..3042306 100644
--- a/o3d/plugin/win/main_win.cc
+++ b/o3d/plugin/win/main_win.cc
@@ -488,7 +488,7 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
// If rendering continuously, invalidate the window and force a paint if
// it is visible. The paint invalidates the renderer and Tick will later
// repaint the window.
- if (obj->client()->render_mode() == o3d::Client::RENDERMODE_CONTINUOUS) {
+ if (obj->client()->NeedsContinuousRender()) {
InvalidateRect(obj->GetHWnd(), NULL, FALSE);
UpdateWindow(obj->GetHWnd());
}