diff options
author | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 00:01:32 +0000 |
---|---|---|
committer | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 00:01:32 +0000 |
commit | 96449d2cf2f37ffcab09ad8e15d9d6f3534271cb (patch) | |
tree | 7d603b2bc43bea75362248d27e54c5ce51017fdf /gpu/gpu_plugin | |
parent | fd50fb2b7e19a6589270a02a28fb4dea5b6f38d3 (diff) | |
download | chromium_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.cc | 135 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin.h | 30 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object.cc | 123 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object.h | 133 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object_factory.cc | 27 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object_factory.h | 27 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc | 41 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object_unittest.cc | 319 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_object_win.cc | 62 | ||||
-rw-r--r-- | gpu/gpu_plugin/gpu_plugin_unittest.cc | 302 |
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 |