summaryrefslogtreecommitdiffstats
path: root/gpu/gpu_plugin
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-25 00:01:32 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-25 00:01:32 +0000
commit96449d2cf2f37ffcab09ad8e15d9d6f3534271cb (patch)
tree7d603b2bc43bea75362248d27e54c5ce51017fdf /gpu/gpu_plugin
parentfd50fb2b7e19a6589270a02a28fb4dea5b6f38d3 (diff)
downloadchromium_src-96449d2cf2f37ffcab09ad8e15d9d6f3534271cb.zip
chromium_src-96449d2cf2f37ffcab09ad8e15d9d6f3534271cb.tar.gz
chromium_src-96449d2cf2f37ffcab09ad8e15d9d6f3534271cb.tar.bz2
Landing the GPU process and command buffer code again, this time with a DEPS file with the necessary include rules.
TEST=none BUG=none git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33006 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/gpu_plugin')
-rw-r--r--gpu/gpu_plugin/gpu_plugin.cc135
-rw-r--r--gpu/gpu_plugin/gpu_plugin.h30
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object.cc123
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object.h133
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object_factory.cc27
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object_factory.h27
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc41
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object_unittest.cc319
-rw-r--r--gpu/gpu_plugin/gpu_plugin_object_win.cc62
-rw-r--r--gpu/gpu_plugin/gpu_plugin_unittest.cc302
10 files changed, 1199 insertions, 0 deletions
diff --git a/gpu/gpu_plugin/gpu_plugin.cc b/gpu/gpu_plugin/gpu_plugin.cc
new file mode 100644
index 0000000..35771fd
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/gpu_plugin/gpu_plugin.h"
+#include "gpu/gpu_plugin/gpu_plugin_object_factory.h"
+#include "gpu/np_utils/np_browser.h"
+#include "gpu/np_utils/np_plugin_object.h"
+#include "gpu/np_utils/np_plugin_object_factory.h"
+#include "webkit/glue/plugins/nphostapi.h"
+
+using np_utils::NPBrowser;
+using np_utils::NPPluginObjectFactory;
+using np_utils::PluginObject;
+
+namespace gpu_plugin {
+
+// Definitions of NPAPI plugin entry points.
+
+namespace {
+NPBrowser* g_browser;
+GPUPluginObjectFactory g_plugin_object_factory;
+
+NPError NPP_New(NPMIMEType plugin_type, NPP instance,
+ uint16 mode, int16 argc, char* argn[],
+ char* argv[], NPSavedData* saved) {
+ if (!instance)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ PluginObject* plugin_object =
+ NPPluginObjectFactory::get()->CreatePluginObject(instance, plugin_type);
+ if (!plugin_object)
+ return NPERR_GENERIC_ERROR;
+
+ instance->pdata = plugin_object;
+
+ NPError error = plugin_object->New(plugin_type, argc, argn, argv, saved);
+ if (error != NPERR_NO_ERROR) {
+ plugin_object->Release();
+ }
+
+ return error;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData** saved) {
+ if (!instance)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata);
+ NPError error = plugin_object->Destroy(saved);
+
+ if (error == NPERR_NO_ERROR) {
+ plugin_object->Release();
+ }
+
+ return error;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow* window) {
+ if (!instance)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata);
+ return plugin_object->SetWindow(window);
+}
+
+int16 NPP_HandleEvent(NPP instance, void* event) {
+ if (!instance)
+ return 0;
+
+ PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata);
+ return plugin_object->HandleEvent(static_cast<NPEvent*>(event));
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
+ if (!instance)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata);
+ switch (variable) {
+ case NPPVpluginScriptableNPObject:
+ *reinterpret_cast<NPObject**>(value) =
+ plugin_object->GetScriptableNPObject();
+ return NPERR_NO_ERROR;
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) {
+ return NPERR_NO_ERROR;
+}
+}
+
+NPError NP_GetEntryPoints(NPPluginFuncs* funcs) {
+ funcs->newp = NPP_New;
+ funcs->destroy = NPP_Destroy;
+ funcs->setwindow = NPP_SetWindow;
+ funcs->event = NPP_HandleEvent;
+ funcs->getvalue = NPP_GetValue;
+ funcs->setvalue = NPP_SetValue;
+ return NPERR_NO_ERROR;
+}
+
+#if defined(OS_LINUX)
+NPError API_CALL NP_Initialize(NPNetscapeFuncs *browser_funcs,
+ NPPluginFuncs* plugin_funcs) {
+#else
+NPError NP_Initialize(NPNetscapeFuncs *browser_funcs) {
+#endif
+ if (!browser_funcs)
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+
+ if (g_browser)
+ return NPERR_GENERIC_ERROR;
+
+#if defined(OS_LINUX)
+ NP_GetEntryPoints(plugin_funcs);
+#endif
+
+ g_browser = new NPBrowser(browser_funcs);
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NP_Shutdown() {
+ if (!g_browser)
+ return NPERR_GENERIC_ERROR;
+
+ delete g_browser;
+ g_browser = NULL;
+
+ return NPERR_NO_ERROR;
+}
+} // namespace gpu_plugin
diff --git a/gpu/gpu_plugin/gpu_plugin.h b/gpu/gpu_plugin/gpu_plugin.h
new file mode 100644
index 0000000..0f90f77
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_GPU_PLUGIN_GPU_PLUGIN_H_
+#define GPU_GPU_PLUGIN_GPU_PLUGIN_H_
+
+#include "gpu/np_utils/np_headers.h"
+
+typedef struct _NPPluginFuncs NPPluginFuncs;
+typedef struct _NPNetscapeFuncs NPNetscapeFuncs;
+
+namespace gpu_plugin {
+
+// Declarations of NPAPI plugin entry points.
+
+NPError NP_GetEntryPoints(NPPluginFuncs* funcs);
+
+#if defined(OS_LINUX)
+NPError NP_Initialize(NPNetscapeFuncs *browser_funcs,
+ NPPluginFuncs* plugin_funcs);
+#else
+NPError NP_Initialize(NPNetscapeFuncs* browser_funcs);
+#endif
+
+NPError NP_Shutdown();
+
+} // namespace gpu_plugin
+
+#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_H_
diff --git a/gpu/gpu_plugin/gpu_plugin_object.cc b/gpu/gpu_plugin/gpu_plugin_object.cc
new file mode 100644
index 0000000..d4ea9150
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+
+#include "base/logging.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
+#include "gpu/command_buffer/service/gpu_processor.h"
+#include "gpu/np_utils/np_utils.h"
+#include "gpu/gpu_plugin/gpu_plugin_object.h"
+
+using ::base::SharedMemory;
+using command_buffer::CommandBuffer;
+using command_buffer::CommandBufferService;
+using command_buffer::GPUProcessor;
+using np_utils::NPBrowser;
+using np_utils::NPObjectPointer;
+
+namespace gpu_plugin {
+
+const NPUTF8 GPUPluginObject::kPluginType[] =
+ "application/vnd.google.chrome.gpu-plugin";
+
+GPUPluginObject::GPUPluginObject(NPP npp)
+ : npp_(npp),
+ status_(kWaitingForNew),
+ command_buffer_(new CommandBufferService),
+ processor_(new GPUProcessor(npp, command_buffer_.get())) {
+ memset(&window_, 0, sizeof(window_));
+}
+
+NPError GPUPluginObject::New(NPMIMEType plugin_type,
+ int16 argc,
+ char* argn[],
+ char* argv[],
+ NPSavedData* saved) {
+ if (status_ != kWaitingForNew)
+ return NPERR_GENERIC_ERROR;
+
+ status_ = kWaitingForSetWindow;
+
+ return NPERR_NO_ERROR;
+}
+
+NPError GPUPluginObject::SetWindow(NPWindow* new_window) {
+ if (status_ == kWaitingForNew || status_ == kDestroyed)
+ return NPERR_GENERIC_ERROR;
+
+ // PlatformSpecificSetWindow advances the status depending on what happens.
+ NPError error = PlatformSpecificSetWindow(new_window);
+ if (error == NPERR_NO_ERROR) {
+ window_ = *new_window;
+
+ if (event_sync_.Get()) {
+ NPInvokeVoid(npp_,
+ event_sync_,
+ "resize",
+ static_cast<int32>(window_.width),
+ static_cast<int32>(window_.height));
+ }
+ } else {
+ memset(&window_, 0, sizeof(window_));
+ }
+
+ return error;
+}
+
+int16 GPUPluginObject::HandleEvent(NPEvent* event) {
+ return 0;
+}
+
+NPError GPUPluginObject::Destroy(NPSavedData** saved) {
+ if (status_ == kWaitingForNew || status_ == kDestroyed)
+ return NPERR_GENERIC_ERROR;
+
+ if (command_buffer_.get()) {
+ command_buffer_->SetPutOffsetChangeCallback(NULL);
+ }
+
+ status_ = kDestroyed;
+
+ return NPERR_NO_ERROR;
+}
+
+void GPUPluginObject::Release() {
+ DCHECK(status_ == kWaitingForNew || status_ == kDestroyed);
+ NPBrowser::get()->ReleaseObject(this);
+}
+
+NPObject*GPUPluginObject::GetScriptableNPObject() {
+ NPBrowser::get()->RetainObject(this);
+ return this;
+}
+
+CommandBuffer* GPUPluginObject::OpenCommandBuffer() {
+ if (status_ == kInitializationSuccessful)
+ return command_buffer_.get();
+
+ // SetWindow must have been called before OpenCommandBuffer.
+ // PlatformSpecificSetWindow advances the status to
+ // kWaitingForOpenCommandBuffer.
+ if (status_ != kWaitingForOpenCommandBuffer)
+ return NULL;
+
+ scoped_ptr<SharedMemory> ring_buffer(new SharedMemory);
+ if (!ring_buffer->Create(std::wstring(), false, false, kCommandBufferSize))
+ return NULL;
+
+ if (command_buffer_->Initialize(ring_buffer.release())) {
+ if (processor_->Initialize(static_cast<HWND>(window_.window))) {
+ command_buffer_->SetPutOffsetChangeCallback(
+ NewCallback(processor_.get(),
+ &GPUProcessor::ProcessCommands));
+ status_ = kInitializationSuccessful;
+ return command_buffer_.get();
+ }
+ }
+
+ return NULL;
+}
+
+} // namespace gpu_plugin
diff --git a/gpu/gpu_plugin/gpu_plugin_object.h b/gpu/gpu_plugin/gpu_plugin_object.h
new file mode 100644
index 0000000..0602aa9
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object.h
@@ -0,0 +1,133 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_
+#define GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_
+
+#include <string>
+
+#include "base/ref_counted.h"
+#include "base/thread.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/service/gpu_processor.h"
+#include "gpu/np_utils/default_np_object.h"
+#include "gpu/np_utils/np_dispatcher.h"
+#include "gpu/np_utils/np_headers.h"
+#include "gpu/np_utils/np_plugin_object.h"
+#include "gpu/np_utils/np_utils.h"
+
+namespace gpu_plugin {
+
+// The scriptable object for the GPU plugin.
+class GPUPluginObject : public np_utils::DefaultNPObject<NPObject>,
+ public np_utils::PluginObject {
+ public:
+ static const int32 kCommandBufferSize = 1024 * 1024;
+
+ enum Status {
+ // In the state of waiting for the named function to be called to continue
+ // the initialization sequence.
+ kWaitingForNew,
+ kWaitingForSetWindow,
+ kWaitingForOpenCommandBuffer,
+
+ // Initialization either succeeded or failed.
+ kInitializationSuccessful,
+ kInitializationFailed,
+
+ // Destroy has now been called and the plugin object cannot be used.
+ kDestroyed,
+ };
+
+ static const NPUTF8 kPluginType[];
+
+ explicit GPUPluginObject(NPP npp);
+
+ virtual NPError New(NPMIMEType plugin_type,
+ int16 argc,
+ char* argn[],
+ char* argv[],
+ NPSavedData* saved);
+
+ virtual NPError SetWindow(NPWindow* new_window);
+ const NPWindow& GetWindow() { return window_; }
+
+ virtual int16 HandleEvent(NPEvent* event);
+
+ virtual NPError Destroy(NPSavedData** saved);
+
+ virtual void Release();
+
+ virtual NPObject* GetScriptableNPObject();
+
+ // Returns the current initialization status. See Status enum.
+ int32 GetStatus() {
+ return status_;
+ }
+
+ // Get the width of the plugin window.
+ int32 GetWidth() {
+ return window_.width;
+ }
+
+ // Get the height of the plugin window.
+ int32 GetHeight() {
+ return window_.height;
+ }
+
+ // Set the object that receives notifications of GPU plugin object events
+ // such as resize and keyboard and mouse input.
+ void SetEventSync(np_utils::NPObjectPointer<NPObject> event_sync) {
+ event_sync_ = event_sync;
+ }
+
+ np_utils::NPObjectPointer<NPObject> GetEventSync() {
+ return event_sync_;
+ }
+
+ // Initializes and returns the command buffer object. Returns NULL if the
+ // command buffer cannot be initialized, for example if the plugin does not
+ // yet have a window handle.
+ command_buffer::CommandBuffer* OpenCommandBuffer();
+
+ // Set the status for testing.
+ void set_status(Status status) {
+ status_ = status;
+ }
+
+ // Replace the default command buffer for testing. Takes ownership.
+ void set_command_buffer(command_buffer::CommandBuffer*
+ command_buffer) {
+ command_buffer_.reset(command_buffer);
+ }
+
+ // Replace the default GPU processor for testing.
+ void set_gpu_processor(
+ const scoped_refptr<command_buffer::GPUProcessor>& processor) {
+ processor_ = processor;
+ }
+
+ NP_UTILS_BEGIN_DISPATCHER_CHAIN(GPUPluginObject, DefaultNPObject<NPObject>)
+ NP_UTILS_DISPATCHER(GetStatus, int32())
+ NP_UTILS_DISPATCHER(GetWidth, int32())
+ NP_UTILS_DISPATCHER(GetHeight, int32())
+ NP_UTILS_DISPATCHER(SetEventSync,
+ void(np_utils::NPObjectPointer<NPObject> sync))
+ NP_UTILS_DISPATCHER(GetEventSync, np_utils::NPObjectPointer<NPObject>())
+ NP_UTILS_END_DISPATCHER_CHAIN
+
+ private:
+ NPError PlatformSpecificSetWindow(NPWindow* new_window);
+
+ NPP npp_;
+ Status status_;
+ NPWindow window_;
+ scoped_ptr<command_buffer::CommandBuffer> command_buffer_;
+ scoped_refptr<command_buffer::GPUProcessor> processor_;
+ np_utils::NPObjectPointer<NPObject> event_sync_;
+};
+
+} // namespace gpu_plugin
+
+#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_
diff --git a/gpu/gpu_plugin/gpu_plugin_object_factory.cc b/gpu/gpu_plugin/gpu_plugin_object_factory.cc
new file mode 100644
index 0000000..da9e17a
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object_factory.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/gpu_plugin/gpu_plugin_object.h"
+#include "gpu/gpu_plugin/gpu_plugin_object_factory.h"
+#include "gpu/np_utils/np_utils.h"
+
+namespace gpu_plugin {
+
+GPUPluginObjectFactory::GPUPluginObjectFactory() {
+}
+
+GPUPluginObjectFactory::~GPUPluginObjectFactory() {
+}
+
+np_utils::PluginObject* GPUPluginObjectFactory::CreatePluginObject(
+ NPP npp,
+ NPMIMEType plugin_type) {
+ if (strcmp(plugin_type, GPUPluginObject::kPluginType) == 0) {
+ return np_utils::NPCreateObject<GPUPluginObject>(npp).ToReturned();
+ }
+
+ return NULL;
+}
+
+} // namespace gpu_plugin
diff --git a/gpu/gpu_plugin/gpu_plugin_object_factory.h b/gpu/gpu_plugin/gpu_plugin_object_factory.h
new file mode 100644
index 0000000..0d1d80e
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object_factory.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_
+#define GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_
+
+#include "gpu/np_utils/np_plugin_object_factory.h"
+
+namespace gpu_plugin {
+
+// Plugin object factory for creating the GPUPluginObject.
+class GPUPluginObjectFactory : public np_utils::NPPluginObjectFactory {
+ public:
+ GPUPluginObjectFactory();
+ virtual ~GPUPluginObjectFactory();
+
+ virtual np_utils::PluginObject* CreatePluginObject(NPP npp,
+ NPMIMEType plugin_type);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GPUPluginObjectFactory);
+};
+
+} // namespace gpu_plugin
+
+#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_
diff --git a/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc b/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc
new file mode 100644
index 0000000..298a8c5
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/gpu_plugin/gpu_plugin_object.h"
+#include "gpu/gpu_plugin/gpu_plugin_object_factory.h"
+#include "gpu/np_utils/np_browser_stub.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using np_utils::PluginObject;
+
+namespace gpu_plugin {
+
+class PluginObjectFactoryTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ factory_ = new GPUPluginObjectFactory;
+ }
+
+ virtual void TearDown() {
+ delete factory_;
+ }
+
+ np_utils::StubNPBrowser stub_browser_;
+ GPUPluginObjectFactory* factory_;
+};
+
+TEST_F(PluginObjectFactoryTest, ReturnsNullForUnknownMimeType) {
+ PluginObject* plugin_object = factory_->CreatePluginObject(
+ NULL, "application/unknown");
+ EXPECT_TRUE(NULL == plugin_object);
+}
+
+TEST_F(PluginObjectFactoryTest, CreatesGPUPlugin) {
+ PluginObject* plugin_object = factory_->CreatePluginObject(
+ NULL, const_cast<NPMIMEType>(GPUPluginObject::kPluginType));
+ EXPECT_TRUE(NULL != plugin_object);
+}
+
+} // namespace gpu_plugin
diff --git a/gpu/gpu_plugin/gpu_plugin_object_unittest.cc b/gpu/gpu_plugin/gpu_plugin_object_unittest.cc
new file mode 100644
index 0000000..b032aa0
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object_unittest.cc
@@ -0,0 +1,319 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/common/command_buffer_mock.h"
+#include "gpu/gpu_plugin/gpu_plugin_object.h"
+#include "gpu/command_buffer/service/gpu_processor_mock.h"
+#include "gpu/np_utils/np_browser_mock.h"
+#include "gpu/np_utils/dynamic_np_object.h"
+#include "gpu/np_utils/np_object_mock.h"
+#include "gpu/np_utils/np_object_pointer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webkit/glue/plugins/nphostapi.h"
+
+using ::base::SharedMemory;
+using command_buffer::GPUProcessor;
+using command_buffer::MockCommandBuffer;
+using command_buffer::MockGPUProcessor;
+using np_utils::MockNPBrowser;
+using np_utils::NPBrowser;
+using np_utils::NPObjectPointer;
+using testing::_;
+using testing::DoAll;
+using testing::Invoke;
+using testing::NotNull;
+using testing::Return;
+using testing::SetArgumentPointee;
+using testing::StrictMock;
+
+namespace gpu_plugin {
+
+class GPUPluginObjectTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ plugin_object_ = np_utils::NPCreateObject<GPUPluginObject>(NULL);
+
+ command_buffer_ = new MockCommandBuffer;
+
+ // Takes ownership.
+ plugin_object_->set_command_buffer(command_buffer_);
+
+ processor_ = new MockGPUProcessor(command_buffer_);
+ plugin_object_->set_gpu_processor(processor_.get());
+ }
+
+ MockNPBrowser mock_browser_;
+ NPObjectPointer<GPUPluginObject> plugin_object_;
+ MockCommandBuffer* command_buffer_;
+ scoped_refptr<MockGPUProcessor> processor_;
+};
+
+namespace {
+template <typename T>
+void DeleteObject(T* object) {
+ delete object;
+}
+} // namespace anonymous
+
+
+TEST_F(GPUPluginObjectTest, CanInstantiateAndDestroyPluginObject) {
+ EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+
+ EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus());
+}
+
+TEST_F(GPUPluginObjectTest, DestroyFailsIfNotInitialized) {
+ EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->Destroy(NULL));
+}
+
+TEST_F(GPUPluginObjectTest, NewFailsIfAlreadyInitialized) {
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+
+ EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus());
+}
+
+TEST_F(GPUPluginObjectTest, NewFailsIfObjectHasPreviouslyBeenDestroyed) {
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+
+ EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus());
+}
+
+TEST_F(GPUPluginObjectTest, WindowIsNullBeforeSetWindowCalled) {
+ NPWindow window = plugin_object_->GetWindow();
+ EXPECT_EQ(NULL, window.window);
+}
+
+TEST_F(GPUPluginObjectTest, CanSetWindow) {
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ NPWindow window = {0};
+ window.window = &window;
+ window.x = 7;
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window));
+ EXPECT_EQ(0, memcmp(&window, &plugin_object_->GetWindow(), sizeof(window)));
+ EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer,
+ plugin_object_->GetStatus());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+}
+
+TEST_F(GPUPluginObjectTest, CanGetWindowSize) {
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ NPWindow window = {0};
+ window.window = &window;
+ window.x = 10;
+ window.y = 10;
+ window.width = 100;
+ window.height = 200;
+
+ EXPECT_EQ(0, plugin_object_->GetWidth());
+ EXPECT_EQ(0, plugin_object_->GetHeight());
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window));
+ EXPECT_EQ(100, plugin_object_->GetWidth());
+ EXPECT_EQ(200, plugin_object_->GetHeight());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+}
+
+TEST_F(GPUPluginObjectTest, SetWindowFailsIfNotInitialized) {
+ NPWindow window = {0};
+ EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->SetWindow(&window));
+ EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus());
+}
+
+TEST_F(GPUPluginObjectTest, CanGetScriptableNPObject) {
+ NPObject* scriptable_object = plugin_object_->GetScriptableNPObject();
+ EXPECT_EQ(plugin_object_.Get(), scriptable_object);
+ NPBrowser::get()->ReleaseObject(scriptable_object);
+}
+
+TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsInitializedCommandBuffer) {
+ EXPECT_CALL(*command_buffer_, Initialize(NotNull()))
+ .WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>),
+ Return(true)));
+
+ EXPECT_CALL(*processor_.get(), Initialize(NULL))
+ .WillOnce(Return(true));
+
+ EXPECT_CALL(*command_buffer_, SetPutOffsetChangeCallback(NotNull()))
+ .WillOnce(Invoke(DeleteObject<Callback0::Type>));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ // Set status as though SetWindow has been called. Avoids having to create a
+ // valid window handle to pass to SetWindow in tests.
+ plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer);
+
+ EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer());
+
+ // Calling OpenCommandBuffer again just returns the existing command buffer.
+ EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer());
+
+ EXPECT_EQ(GPUPluginObject::kInitializationSuccessful,
+ plugin_object_->GetStatus());
+
+ EXPECT_CALL(*command_buffer_, SetPutOffsetChangeCallback(NULL));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+}
+
+TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsNullIfWindowNotReady) {
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ // Set status as though SetWindow has not been called.
+ plugin_object_->set_status(GPUPluginObject::kWaitingForSetWindow);
+
+ EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer());
+
+ EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus());
+}
+
+
+TEST_F(GPUPluginObjectTest,
+ OpenCommandBufferReturnsNullIfCommandBufferCannotInitialize) {
+ EXPECT_CALL(*command_buffer_, Initialize(NotNull()))
+ .WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>),
+ Return(false)));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ // Set status as though SetWindow has been called. Avoids having to create a
+ // valid window handle to pass to SetWindow in tests.
+ plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer);
+
+ EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer());
+
+ EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer,
+ plugin_object_->GetStatus());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+}
+
+TEST_F(GPUPluginObjectTest,
+ OpenCommandBufferReturnsNullIGPUProcessorCannotInitialize) {
+ EXPECT_CALL(*command_buffer_, Initialize(NotNull()))
+ .WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>),
+ Return(true)));
+
+ EXPECT_CALL(*processor_.get(), Initialize(NULL))
+ .WillOnce(Return(false));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ // Set status as though SetWindow has been called. Avoids having to create a
+ // valid window handle to pass to SetWindow in tests.
+ plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer);
+
+ EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer());
+
+ EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer,
+ plugin_object_->GetStatus());
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+}
+
+class MockEventSync : public np_utils::DefaultNPObject<NPObject> {
+ public:
+ explicit MockEventSync(NPP npp) {
+ }
+
+ MOCK_METHOD2(Resize, void(int32 width, int32 height));
+
+ NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockEventSync, DefaultNPObject<NPObject>)
+ NP_UTILS_DISPATCHER(Resize, void(int32 width, int32 height))
+ NP_UTILS_END_DISPATCHER_CHAIN
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockEventSync);
+};
+
+TEST_F(GPUPluginObjectTest, SendsResizeEventOnSetWindow) {
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
+ 0,
+ NULL,
+ NULL,
+ NULL));
+
+ NPObjectPointer<MockEventSync> event_sync =
+ np_utils::NPCreateObject<MockEventSync>(NULL);
+ plugin_object_->SetEventSync(event_sync);
+
+ EXPECT_CALL(*event_sync.Get(), Resize(100, 200));
+
+ NPWindow window = {0};
+ window.window = &window;
+ window.x = 10;
+ window.y = 10;
+ window.width = 100;
+ window.height = 200;
+
+ plugin_object_->SetWindow(&window);
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
+}
+
+} // namespace gpu_plugin
diff --git a/gpu/gpu_plugin/gpu_plugin_object_win.cc b/gpu/gpu_plugin/gpu_plugin_object_win.cc
new file mode 100644
index 0000000..31c6393
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_object_win.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <windows.h>
+
+#include "gpu/command_buffer/service/gpu_processor.h"
+#include "gpu/gpu_plugin/gpu_plugin_object.h"
+
+namespace gpu_plugin {
+
+namespace {
+const LPCTSTR kPluginObjectProperty = TEXT("GPUPluginObject");
+const LPCTSTR kOriginalWindowProc = TEXT("GPUPluginObjectOriginalWindowProc");
+
+LRESULT CALLBACK WindowProc(HWND handle,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ return ::DefWindowProc(handle, message, w_param, l_param);
+}
+} // namespace anonymous
+
+NPError GPUPluginObject::PlatformSpecificSetWindow(NPWindow* new_window) {
+ // Detach properties from old window and restore the original window proc.
+ if (window_.window) {
+ HWND handle = reinterpret_cast<HWND>(window_.window);
+ ::RemoveProp(handle, kPluginObjectProperty);
+
+ LONG original_window_proc = reinterpret_cast<LONG>(
+ ::GetProp(handle, kOriginalWindowProc));
+ ::SetWindowLong(handle, GWL_WNDPROC,
+ original_window_proc);
+ ::RemoveProp(handle, kOriginalWindowProc);
+ }
+
+ // Attach properties to new window and set a new window proc.
+ if (new_window->window) {
+ HWND handle = reinterpret_cast<HWND>(new_window->window);
+ ::SetProp(handle,
+ kPluginObjectProperty,
+ reinterpret_cast<HANDLE>(this));
+
+ LONG original_window_proc = ::GetWindowLong(handle, GWL_WNDPROC);
+ ::SetProp(handle,
+ kOriginalWindowProc,
+ reinterpret_cast<HANDLE>(original_window_proc));
+ ::SetWindowLong(handle, GWL_WNDPROC,
+ reinterpret_cast<LONG>(WindowProc));
+
+ status_ = kWaitingForOpenCommandBuffer;
+ } else {
+ status_ = kWaitingForSetWindow;
+ if (processor_) {
+ processor_->Destroy();
+ }
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+} // namespace gpu_plugin
diff --git a/gpu/gpu_plugin/gpu_plugin_unittest.cc b/gpu/gpu_plugin/gpu_plugin_unittest.cc
new file mode 100644
index 0000000..ea1bb5f
--- /dev/null
+++ b/gpu/gpu_plugin/gpu_plugin_unittest.cc
@@ -0,0 +1,302 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/gpu_plugin/gpu_plugin.h"
+#include "gpu/gpu_plugin/gpu_plugin_object.h"
+#include "gpu/np_utils/np_object_mock.h"
+#include "gpu/np_utils/np_plugin_object_factory_mock.h"
+#include "gpu/np_utils/np_plugin_object_mock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/glue/plugins/nphostapi.h"
+
+#if defined(OS_LINUX)
+#define INITIALIZE_PLUGIN_FUNCS , &plugin_funcs_
+#else
+#define INITIALIZE_PLUGIN_FUNCS
+#endif
+
+using np_utils::MockPluginObject;
+using np_utils::PluginObject;
+using testing::_;
+using testing::DoAll;
+using testing::NiceMock;
+using testing::Return;
+using testing::SetArgumentPointee;
+using testing::StrictMock;
+
+namespace gpu_plugin {
+
+class GPUPluginTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ memset(&npp_, 0, sizeof(npp_));
+ memset(&browser_funcs_, 0, sizeof(browser_funcs_));
+ memset(&plugin_funcs_, 0, sizeof(plugin_funcs_));
+
+ plugin_object_factory_ = new StrictMock<np_utils::MockPluginObjectFactory>;
+
+ np_class_ = np_utils::NPGetClass<StrictMock<np_utils::MockNPObject> >();
+ }
+
+ virtual void TearDown() {
+ delete plugin_object_factory_;
+ }
+
+ NPP_t npp_;
+ NPNetscapeFuncs browser_funcs_;
+ NPPluginFuncs plugin_funcs_;
+ np_utils::MockPluginObjectFactory* plugin_object_factory_;
+ const NPClass* np_class_;
+};
+
+TEST_F(GPUPluginTest, GetEntryPointsSetsNeededFunctionPointers) {
+#if defined(OS_LINUX)
+ NPError error = gpu_plugin::NP_Initialize(&browser_funcs_,
+ &plugin_funcs_);
+ gpu_plugin::NP_Shutdown();
+#else
+ NPError error = gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+#endif
+
+ EXPECT_EQ(NPERR_NO_ERROR, error);
+ EXPECT_TRUE(NULL != plugin_funcs_.newp);
+ EXPECT_TRUE(NULL != plugin_funcs_.destroy);
+ EXPECT_TRUE(NULL != plugin_funcs_.setwindow);
+ EXPECT_TRUE(NULL != plugin_funcs_.event);
+ EXPECT_TRUE(NULL != plugin_funcs_.getvalue);
+ EXPECT_TRUE(NULL != plugin_funcs_.setvalue);
+}
+
+TEST_F(GPUPluginTest, CanInitializeAndShutdownPlugin) {
+ EXPECT_EQ(NPERR_NO_ERROR,
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS));
+ EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown());
+}
+
+TEST_F(GPUPluginTest, InitializeFailsIfBrowserFuncsIsNull) {
+ EXPECT_EQ(NPERR_INVALID_FUNCTABLE_ERROR,
+ gpu_plugin::NP_Initialize(NULL INITIALIZE_PLUGIN_FUNCS));
+}
+
+TEST_F(GPUPluginTest, InitializeFailsIfAlreadyInitialized) {
+ EXPECT_EQ(NPERR_NO_ERROR,
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS));
+ EXPECT_EQ(NPERR_GENERIC_ERROR,
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS));
+ EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown());
+}
+
+TEST_F(GPUPluginTest, ShutdownFailsIfNotInitialized) {
+ EXPECT_EQ(NPERR_GENERIC_ERROR, gpu_plugin::NP_Shutdown());
+}
+
+TEST_F(GPUPluginTest, NewReturnsErrorForInvalidInstance) {
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.newp(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ NULL, 0, 0, NULL, NULL, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, GetValueReturnsErrorForInvalidInstance) {
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ int* result = NULL;
+ EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.getvalue(
+ NULL, NPPVjavaClass, &result));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, DestroyReturnsErrorForInvalidInstance) {
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.destroy(NULL, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, SetWindowReturnsErrorForInvalidInstance) {
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.setwindow(NULL, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, HandleEventReturnsFalseForInvalidInstance) {
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(0, plugin_funcs_.event(NULL, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, NewCreatesAPluginObjectAndInitializesIt) {
+ StrictMock<np_utils::MockPluginObject> plugin_object;
+
+ EXPECT_CALL(*plugin_object_factory_, CreatePluginObject(
+ &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType)))
+ .WillOnce(Return(&plugin_object));
+
+ NPObject scriptable_object;
+
+ EXPECT_CALL(plugin_object, New(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ 0, NULL, NULL, NULL))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, GetScriptableNPObject())
+ .WillOnce(Return(&scriptable_object));
+
+ EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL)))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, Release());
+
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ &npp_, 0, 0, NULL, NULL, NULL));
+
+ NPObject* result;
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.getvalue(
+ &npp_, NPPVpluginScriptableNPObject, &result));
+ EXPECT_EQ(&scriptable_object, result);
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, NewFailsIfPluginObjectFactoryFails) {
+ EXPECT_CALL(*plugin_object_factory_, CreatePluginObject(
+ &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType)))
+ .WillOnce(Return(static_cast<PluginObject*>(NULL)));
+
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.newp(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ &npp_, 0, 0, NULL, NULL, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, SetWindowForwardsToPluginObject) {
+ StrictMock<MockPluginObject> plugin_object;
+
+ EXPECT_CALL(*plugin_object_factory_, CreatePluginObject(
+ &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType)))
+ .WillOnce(Return(&plugin_object));
+
+ EXPECT_CALL(plugin_object, New(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ 0, NULL, NULL, NULL))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ NPWindow window = {0};
+
+ EXPECT_CALL(plugin_object, SetWindow(&window))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL)))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, Release());
+
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ &npp_, 0, 0, NULL, NULL, NULL));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.setwindow(&npp_, &window));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, HandleEventForwardsToPluginObject) {
+ StrictMock<MockPluginObject> plugin_object;
+
+ EXPECT_CALL(*plugin_object_factory_, CreatePluginObject(
+ &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType)))
+ .WillOnce(Return(&plugin_object));
+
+ EXPECT_CALL(plugin_object, New(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ 0, NULL, NULL, NULL))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ NPEvent event = {0};
+
+ EXPECT_CALL(plugin_object, HandleEvent(&event))
+ .WillOnce(Return(7));
+
+ EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL)))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, Release());
+
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ &npp_, 0, 0, NULL, NULL, NULL));
+
+ EXPECT_EQ(7, plugin_funcs_.event(&npp_, &event));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+TEST_F(GPUPluginTest, GetValueReturnsErrorForUnknownVariable) {
+ StrictMock<MockPluginObject> plugin_object;
+
+ EXPECT_CALL(*plugin_object_factory_, CreatePluginObject(
+ &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType)))
+ .WillOnce(Return(&plugin_object));
+
+ EXPECT_CALL(plugin_object, New(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ 0, NULL, NULL, NULL))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL)))
+ .WillOnce(Return(NPERR_NO_ERROR));
+
+ EXPECT_CALL(plugin_object, Release());
+
+ gpu_plugin::NP_GetEntryPoints(&plugin_funcs_);
+ gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS);
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp(
+ const_cast<NPMIMEType>(GPUPluginObject::kPluginType),
+ &npp_, 0, 0, NULL, NULL, NULL));
+
+ int* result = NULL;
+ EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.getvalue(
+ &npp_, NPPVjavaClass, &result));
+
+ EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL));
+
+ gpu_plugin::NP_Shutdown();
+}
+
+} // namespace gpu_plugin