diff options
-rw-r--r-- | o3d/core/cross/client.cc | 19 | ||||
-rw-r--r-- | o3d/core/cross/client.h | 7 | ||||
-rw-r--r-- | o3d/core/cross/message_commands.h | 28 | ||||
-rw-r--r-- | o3d/core/cross/message_queue.cc | 31 | ||||
-rw-r--r-- | o3d/core/cross/message_queue.h | 6 | ||||
-rw-r--r-- | o3d/core/cross/renderer.cc | 3 | ||||
-rw-r--r-- | o3d/core/cross/renderer.h | 17 |
7 files changed, 107 insertions, 4 deletions
diff --git a/o3d/core/cross/client.cc b/o3d/core/cross/client.cc index c63c940..1785d7e1 100644 --- a/o3d/core/cross/client.cc +++ b/o3d/core/cross/client.cc @@ -80,6 +80,9 @@ Client::Client(ServiceLocator* service_locator) evaluation_counter_(service_locator), render_tree_called_(false), render_mode_(RENDERMODE_CONTINUOUS), +#ifdef O3D_PLUGIN_SUPPORT_SET_MAX_FPS + texture_on_hold_(false), +#endif // O3D_PLUGIN_SUPPORT_SET_MAX_FPS event_manager_(), last_tick_time_(0), root_(NULL), @@ -188,10 +191,11 @@ bool Client::Tick() { // Processes any incoming message found in the message queue. Note that this // call does not block if no new messages are found. bool message_check_ok = true; + bool has_new_texture = false; if (message_queue_.get()) { profiler_->ProfileStart("CheckForNewMessages"); - message_check_ok = message_queue_->CheckForNewMessages(); + message_check_ok = message_queue_->CheckForNewMessages(&has_new_texture); profiler_->ProfileStop("CheckForNewMessages"); } @@ -202,6 +206,19 @@ bool Client::Tick() { last_tick_time_ = timer.GetElapsedTimeAndReset(); +#ifdef O3D_PLUGIN_SUPPORT_SET_MAX_FPS + texture_on_hold_ |= has_new_texture; + int max_fps = renderer_->max_fps(); + if (max_fps > 0 && + texture_on_hold_ && + render_mode() == RENDERMODE_ON_DEMAND && + render_elapsed_time_timer_.GetElapsedTimeWithoutClearing() + > 1.0/max_fps) { + renderer_->set_need_to_render(true); + texture_on_hold_ = false; + } +#endif // O3D_PLUGIN_SUPPORT_SET_MAX_FPS + return message_check_ok; } diff --git a/o3d/core/cross/client.h b/o3d/core/cross/client.h index 003c6de..3c4ad76 100644 --- a/o3d/core/cross/client.h +++ b/o3d/core/cross/client.h @@ -66,6 +66,8 @@ #include "core/cross/transform.h" namespace o3d { +//#define O3D_PLUGIN_SUPPORT_SET_MAX_FPS + class MessageQueue; class Profiler; class State; @@ -465,6 +467,11 @@ class Client { // Render mode. RenderMode render_mode_; +#ifdef O3D_PLUGIN_SUPPORT_SET_MAX_FPS + // Used for rendering control + bool texture_on_hold_; +#endif // O3D_PLUGIN_SUPPORT_SET_MAX_FPS + // Render Callbacks. RenderCallbackManager render_callback_manager_; diff --git a/o3d/core/cross/message_commands.h b/o3d/core/cross/message_commands.h index 257ebfb..1eeabc2 100644 --- a/o3d/core/cross/message_commands.h +++ b/o3d/core/cross/message_commands.h @@ -65,6 +65,7 @@ namespace o3d { OP(UPDATE_TEXTURE2D_RECT, MessageUpdateTexture2DRect) \ OP(RENDER, MessageRender) \ OP(GET_VERSION, MessageGetVersion) \ + OP(SET_MAX_FPS, MessageSetMaxFPS) \ namespace imc { @@ -357,6 +358,33 @@ struct MessageRender { Msg msg; }; +// Tell O3D to render on every new texture as long as not exceeding max_fps. +// This is only used when O3D is in Render on demand mode. +struct MessageSetMaxFPS { + // Message Content. + struct Msg { + static const imc::MessageId kMessageId = imc::SET_MAX_FPS; + + imc::MessageId message_id; + + // Maximum frames per second + int32 max_fps; + }; + + MessageSetMaxFPS() { + msg.message_id = Msg::kMessageId; + } + + // Parameters: + // max_fps: The maximum frames per second + explicit MessageSetMaxFPS(int32 max_fps) { + msg.message_id = Msg::kMessageId; + msg.max_fps = max_fps; + } + + Msg msg; +}; + // Get the O3D version. struct MessageGetVersion { // Message Content. diff --git a/o3d/core/cross/message_queue.cc b/o3d/core/cross/message_queue.cc index ae30a58..9d46c8b 100644 --- a/o3d/core/cross/message_queue.cc +++ b/o3d/core/cross/message_queue.cc @@ -189,7 +189,12 @@ String MessageQueue::GetSocketAddress() const { // Checks the message queue for an incoming message. If one is found // then it processes it, otherwise it just returns. -bool MessageQueue::CheckForNewMessages() { +bool MessageQueue::CheckForNewMessages(bool* has_new_texture) { + // The flag will be set to true if we receive a new texture in + // ProcessMessageUpdateTexture2DRect() or + // ProcessMessageUpdateTexture2D() + has_new_texture_ = false; + // NOTE: This code uses reasonable defaults for the max // sizes of the received messages. If a message uses more memory or // transmits more data handles then it will appear as truncated. If @@ -268,6 +273,7 @@ bool MessageQueue::CheckForNewMessages() { ++iter; } + *has_new_texture = has_new_texture_; return true; } @@ -613,6 +619,7 @@ bool MessageQueue::ProcessMessageUpdateTexture2D( } SendBooleanResponse(client->client_handle(), true); + has_new_texture_ = true; return true; } @@ -695,6 +702,7 @@ bool MessageQueue::ProcessMessageUpdateTexture2DRect( message.pitch); SendBooleanResponse(client->client_handle(), true); + has_new_texture_ = true; return true; } @@ -815,6 +823,27 @@ bool MessageQueue::ProcessMessageRender( return true; } +// Processes a request to SetMaxFPS. +bool MessageQueue::ProcessMessageSetMaxFPS( + ConnectedClient* client, + int message_length, + nacl::MessageHeader* header, + nacl::Handle* handles, + const MessageSetMaxFPS::Msg& message) { + if (header->iov_length != 1 || + header->handle_count != 0) { + LOG(ERROR) << "Malformed message for SET_MAX_FPS"; + return false; + } + + Renderer* renderer(service_locator_->GetService<Renderer>()); + if (renderer) { + renderer->set_max_fps(message.max_fps); + } + + return true; +} + // Processes a request to get the O3D version. bool MessageQueue::ProcessMessageGetVersion( ConnectedClient* client, diff --git a/o3d/core/cross/message_queue.h b/o3d/core/cross/message_queue.h index 55643ac..a129e0f 100644 --- a/o3d/core/cross/message_queue.h +++ b/o3d/core/cross/message_queue.h @@ -121,10 +121,12 @@ class MessageQueue { // Checks for new messages on the queue. If messages are found then it // it processes them, otherwise it simply returns. + // Parameters: + // has_new_texture - [out] If a new texture has been received. // Returns: // true if there were no new messages or new messages were succesfully // received. - bool CheckForNewMessages(); + bool CheckForNewMessages(bool* has_new_texture); // Returns the socket address used by the message queue. String GetSocketAddress() const; @@ -214,6 +216,8 @@ class MessageQueue { // address. static int next_message_queue_id_; + bool has_new_texture_; + DISALLOW_COPY_AND_ASSIGN(MessageQueue); }; diff --git a/o3d/core/cross/renderer.cc b/o3d/core/cross/renderer.cc index 1310376..3a71722 100644 --- a/o3d/core/cross/renderer.cc +++ b/o3d/core/cross/renderer.cc @@ -128,7 +128,8 @@ Renderer::Renderer(ServiceLocator* service_locator) dest_y_offset_(0), supports_npot_(false), back_buffer_cleared_(false), - presented_once_(false) { + presented_once_(false), + max_fps_(0) { } Renderer::~Renderer() { diff --git a/o3d/core/cross/renderer.h b/o3d/core/cross/renderer.h index f299886..76f18e2 100644 --- a/o3d/core/cross/renderer.h +++ b/o3d/core/cross/renderer.h @@ -210,6 +210,20 @@ 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. + + // Get max_fps + int max_fps() const { + return max_fps_; + } + + // Set max_fps + void set_max_fps(int max_fps) { + max_fps_ = max_fps; + } + // Handles the plugin resize event. virtual void Resize(int width, int height) = 0; @@ -756,6 +770,9 @@ class Renderer { // Whether we have ever completed a call to Present(). bool presented_once_; + // Maximum frames per second. + int max_fps_; + DISALLOW_COPY_AND_ASSIGN(Renderer); }; |