summaryrefslogtreecommitdiffstats
path: root/o3d/plugin/cross
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/plugin/cross')
-rw-r--r--o3d/plugin/cross/main_thread_task_poster.cc64
-rw-r--r--o3d/plugin/cross/main_thread_task_poster.h57
-rw-r--r--o3d/plugin/cross/o3d_glue.cc61
-rw-r--r--o3d/plugin/cross/o3d_glue.h3
4 files changed, 155 insertions, 30 deletions
diff --git a/o3d/plugin/cross/main_thread_task_poster.cc b/o3d/plugin/cross/main_thread_task_poster.cc
new file mode 100644
index 0000000..24a42e2
--- /dev/null
+++ b/o3d/plugin/cross/main_thread_task_poster.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <npapi.h>
+#include "plugin/cross/main_thread_task_poster.h"
+
+namespace o3d {
+
+MainThreadTaskPoster::MainThreadTaskPoster(ServiceLocator* service_locator,
+ NPP npp)
+ : service_(service_locator, this),
+ npp_(npp) {
+}
+
+MainThreadTaskPoster::~MainThreadTaskPoster() {
+}
+
+bool MainThreadTaskPoster::IsSupported() {
+ int plugin_major, plugin_minor, browser_major, browser_minor;
+ NPN_Version(&plugin_major, &plugin_minor, &browser_major, &browser_minor);
+ return browser_major > 0 ||
+ browser_minor >= NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL;
+}
+
+void MainThreadTaskPoster::PostTask(Task* task) {
+ DCHECK(IsSupported());
+ NPN_PluginThreadAsyncCall(npp_, &MainThreadTaskPoster::RunTask, task);
+}
+
+void MainThreadTaskPoster::RunTask(void* data) {
+ Task* task = static_cast<Task*>(data);
+ task->Run();
+ delete task;
+}
+} // namespace o3d
diff --git a/o3d/plugin/cross/main_thread_task_poster.h b/o3d/plugin/cross/main_thread_task_poster.h
new file mode 100644
index 0000000..e322af1
--- /dev/null
+++ b/o3d/plugin/cross/main_thread_task_poster.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_PLUGIN_CROSS_MAIN_THREAD_TASK_POSTER_H
+#define O3D_PLUGIN_CROSS_MAIN_THREAD_TASK_POSTER_H
+
+#include <npapi.h>
+#include "core/cross/imain_thread_task_poster.h"
+#include "core/cross/service_implementation.h"
+
+namespace o3d {
+
+class MainThreadTaskPoster : public IMainThreadTaskPoster {
+ public:
+ MainThreadTaskPoster(ServiceLocator* service_locator, NPP npp);
+ virtual ~MainThreadTaskPoster();
+ virtual bool IsSupported();
+ virtual void PostTask(Task* task);
+ private:
+ static void RunTask(void* data);
+ ServiceImplementation<IMainThreadTaskPoster> service_;
+ NPP npp_;
+ DISALLOW_COPY_AND_ASSIGN(MainThreadTaskPoster);
+};
+
+} // namespace o3d
+
+#endif // O3D_PLUGIN_CROSS_MAIN_THREAD_TASK_POSTER_H
diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc
index 9d6c24e..9053255 100644
--- a/o3d/plugin/cross/o3d_glue.cc
+++ b/o3d/plugin/cross/o3d_glue.cc
@@ -101,6 +101,7 @@ PluginObject::PluginObject(NPP npp)
client_info_manager_(&service_locator_),
object_manager_(&service_locator_),
profiler_(&service_locator_),
+ main_thread_task_poster_(&service_locator_, npp),
fullscreen_(false),
renderer_(NULL),
features_(NULL),
@@ -822,52 +823,52 @@ void PluginObject::PlatformSpecificSetCursor() {
#endif // OS_LINUX
-void PluginObject::AsyncTick() {
- if (pending_ticks_ >= 1)
+namespace {
+void TickPluginObject(void* data) {
+ PluginObject* plugin_object = static_cast<PluginObject*>(data);
+
+ // Check the plugin has not been destroyed already. Chrome sometimes invokes
+ // async callbacks after destruction.
+ if (!plugin_object->client())
return;
- class TickCallback : public StreamManager::FinishedCallback {
- public:
- explicit TickCallback(PluginObject* plugin_object)
- : plugin_object_(plugin_object) {
- }
+ // Don't allow reentrancy through asynchronous ticks. Chrome sometimes does
+ // this. It is also possible for the asyncronous call to be invoked while
+ // a message is being handled. This prevents that.
+ Client::ScopedIncrement reentrance_count(plugin_object->client());
+ if (reentrance_count.get() > 1)
+ return;
- virtual void Run(DownloadStream*,
- bool,
- const std::string&,
- const std::string&) {
- plugin_object_->Tick();
- }
+ plugin_object->Tick();
+}
+}
- private:
- PluginObject* plugin_object_;
- };
+void PluginObject::AsyncTick() {
+ if (pending_ticks_ >= 1)
+ return;
++pending_ticks_;
- // Invoke Client::Tick and Client::RenderClient in a way that is asynchronous
- // in Chrome. This avoids issues with making calls into the browser from a
- // message handler.
- // If NPN_PluginThreadAsyncCall worked in more browsers, it would be simpler
- // to use that.
- // We're calling LoadURL here with a URL that will return 0 bytes on browsers
- // that support the "data:" protocol and fail in browsers that don't like IE.
- // On browsers that support it, the side effect is to call the TickCallback.
- if (!stream_manager_->LoadURL("data:,", NULL, NULL, NULL,
- new TickCallback(this), NP_NORMAL)) {
- // Fallback on synchronous call if asynchronous load fails.
+ // Invoke Tick asynchronously if NPN_PluginThreadAsyncCall is supported.
+ // Otherwise invoke it synchronously.
+ int plugin_major, plugin_minor, browser_major, browser_minor;
+ NPN_Version(&plugin_major, &plugin_minor, &browser_major, &browser_minor);
+ if (browser_major > 0 ||
+ browser_minor >= NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) {
+ NPN_PluginThreadAsyncCall(npp_, TickPluginObject, this);
+ } else {
Tick();
}
}
void PluginObject::Tick() {
+ DCHECK(pending_ticks_ > 0);
+ --pending_ticks_;
+
client_->Tick();
if (renderer_ && renderer_->need_to_render()) {
client_->RenderClient(true);
}
-
- DCHECK(pending_ticks_ > 0);
- --pending_ticks_;
}
} // namespace _o3d
diff --git a/o3d/plugin/cross/o3d_glue.h b/o3d/plugin/cross/o3d_glue.h
index c61d1d9..c318ea5 100644
--- a/o3d/plugin/cross/o3d_glue.h
+++ b/o3d/plugin/cross/o3d_glue.h
@@ -64,6 +64,7 @@
#include "core/cross/object_manager.h"
#include "core/cross/error.h"
#include "core/cross/profiler.h"
+#include "plugin/cross/main_thread_task_poster.h"
#include "plugin/cross/np_v8_bridge.h"
#include "client_glue.h"
#include "third_party/nixysa/static_glue/npapi/common.h"
@@ -85,6 +86,7 @@ using o3d::ClientInfoManager;
using o3d::EvaluationCounter;
using o3d::Features;
using o3d::EvaluationCounter;
+using o3d::MainThreadTaskPoster;
using o3d::ObjectManager;
using o3d::Profiler;
using o3d::Renderer;
@@ -129,6 +131,7 @@ class PluginObject: public NPObject {
ClientInfoManager client_info_manager_;
ObjectManager object_manager_;
Profiler profiler_;
+ MainThreadTaskPoster main_thread_task_poster_;
bool fullscreen_; // Are we rendered fullscreen or in the plugin region?
Renderer *renderer_;
Client *client_;