summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-09 17:23:57 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-09 17:23:57 +0000
commit53e7aab17f5d57ef3419ba70632caf65de52cda3 (patch)
tree90f5f3dfb8687b7671a62ea7b9a83f4e12a2b25c
parent0ec5ff993e5b3f90d84e8dee2d5b90590482737a (diff)
downloadchromium_src-53e7aab17f5d57ef3419ba70632caf65de52cda3.zip
chromium_src-53e7aab17f5d57ef3419ba70632caf65de52cda3.tar.gz
chromium_src-53e7aab17f5d57ef3419ba70632caf65de52cda3.tar.bz2
Implemented shared memory as an NPObject. Using NPObject method to expose mapping function rather than NPAPI change.
Note that shared memory objects currently lose identity when they cross a process boundary. If an object is sent across a boundary and back, there are now two objects representing the same handle in a single process. This can be fixed. TEST=none BUG=none Review URL: http://codereview.chromium.org/194049 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25749 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--o3d/gpu_plugin/command_buffer.cc26
-rw-r--r--o3d/gpu_plugin/command_buffer.h8
-rw-r--r--o3d/gpu_plugin/command_buffer_unittest.cc42
-rw-r--r--o3d/gpu_plugin/gpu_plugin.gyp118
-rw-r--r--o3d/gpu_plugin/gpu_plugin_object.cc7
-rw-r--r--o3d/gpu_plugin/gpu_plugin_object.h3
-rw-r--r--o3d/gpu_plugin/np_utils/np_browser.cc22
-rw-r--r--o3d/gpu_plugin/np_utils/np_browser.h11
-rw-r--r--o3d/gpu_plugin/np_utils/np_browser_mock.h2
-rw-r--r--o3d/gpu_plugin/np_utils/np_browser_stub.cc12
-rw-r--r--o3d/gpu_plugin/np_utils/np_browser_stub.h9
-rw-r--r--o3d/gpu_plugin/np_utils/np_object_mock.h3
-rw-r--r--o3d/gpu_plugin/np_utils/webkit_browser.h112
-rw-r--r--o3d/gpu_plugin/system_services/shared_memory.cc65
-rw-r--r--o3d/gpu_plugin/system_services/shared_memory.h55
-rw-r--r--o3d/gpu_plugin/system_services/shared_memory_mock.h30
-rw-r--r--o3d/gpu_plugin/system_services/shared_memory_public.h33
-rw-r--r--o3d/gpu_plugin/system_services/shared_memory_unittest.cc112
18 files changed, 546 insertions, 124 deletions
diff --git a/o3d/gpu_plugin/command_buffer.cc b/o3d/gpu_plugin/command_buffer.cc
index ca2d691..5f520dc 100644
--- a/o3d/gpu_plugin/command_buffer.cc
+++ b/o3d/gpu_plugin/command_buffer.cc
@@ -11,13 +11,10 @@ CommandBuffer::CommandBuffer(NPP npp) : npp_(npp) {
}
CommandBuffer::~CommandBuffer() {
- if (shared_memory_) {
- NPBrowser::get()->UnmapSharedMemory(npp_, shared_memory_);
- }
}
bool CommandBuffer::Initialize(int32 size) {
- if (buffer_object_.Get())
+ if (shared_memory_.Get())
return false;
NPObjectPointer<NPObject> window = NPObjectPointer<NPObject>::FromReturned(
@@ -35,23 +32,30 @@ bool CommandBuffer::Initialize(int32 size) {
return false;
}
+ NPObjectPointer<NPObject> result;
if (!NPInvoke(npp_, system, "createSharedMemory", size,
- &buffer_object_)) {
+ &result)) {
return false;
}
- shared_memory_ = NPBrowser::get()->MapSharedMemory(
- npp_, buffer_object_.Get(), size, false);
- if (!shared_memory_) {
- buffer_object_ = NPObjectPointer<NPObject>();
+ // TODO(spatrick): validate NPClass before assuming a CHRSHaredMemory is
+ // returned.
+ shared_memory_ = NPObjectPointer<CHRSharedMemory>(
+ static_cast<CHRSharedMemory*>(result.Get()));
+ if (!shared_memory_.Get())
+ return false;
+
+ bool mapped;
+ if (!NPInvoke(npp_, shared_memory_, "map", &mapped) || !mapped) {
+ shared_memory_ = NPObjectPointer<CHRSharedMemory>();
return false;
}
return true;
}
-NPObjectPointer<NPObject> CommandBuffer::GetBuffer() {
- return buffer_object_;
+NPObjectPointer<NPObject> CommandBuffer::GetSharedMemory() {
+ return shared_memory_;
}
void CommandBuffer::SetPutOffset(int32 offset) {
diff --git a/o3d/gpu_plugin/command_buffer.h b/o3d/gpu_plugin/command_buffer.h
index 1fdc299..d7be196 100644
--- a/o3d/gpu_plugin/command_buffer.h
+++ b/o3d/gpu_plugin/command_buffer.h
@@ -7,6 +7,7 @@
#include "o3d/gpu_plugin/np_utils/default_np_object.h"
#include "o3d/gpu_plugin/np_utils/np_dispatcher.h"
+#include "o3d/gpu_plugin/system_services/shared_memory_public.h"
namespace o3d {
namespace gpu_plugin {
@@ -22,7 +23,7 @@ class CommandBuffer : public DefaultNPObject<NPObject> {
virtual bool Initialize(int32 size);
// Gets the shared memory object for the command buffer.
- virtual NPObjectPointer<NPObject> GetBuffer();
+ virtual NPObjectPointer<NPObject> GetSharedMemory();
// The client calls this to update its put offset.
virtual void SetPutOffset(int32 offset);
@@ -34,13 +35,12 @@ class CommandBuffer : public DefaultNPObject<NPObject> {
NP_UTILS_DISPATCHER(Initialize, bool(int32))
NP_UTILS_DISPATCHER(SetPutOffset, void(int32))
NP_UTILS_DISPATCHER(GetGetOffset, int32())
- NP_UTILS_DISPATCHER(GetBuffer, NPObjectPointer<NPObject>())
+ NP_UTILS_DISPATCHER(GetSharedMemory, NPObjectPointer<NPObject>())
NP_UTILS_END_DISPATCHER_CHAIN
private:
NPP npp_;
- NPObjectPointer<NPObject> buffer_object_;
- NPSharedMemory* shared_memory_;
+ NPObjectPointer<CHRSharedMemory> shared_memory_;
};
} // namespace gpu_plugin
diff --git a/o3d/gpu_plugin/command_buffer_unittest.cc b/o3d/gpu_plugin/command_buffer_unittest.cc
index 5931081..acc5970 100644
--- a/o3d/gpu_plugin/command_buffer_unittest.cc
+++ b/o3d/gpu_plugin/command_buffer_unittest.cc
@@ -7,6 +7,7 @@
#include "o3d/gpu_plugin/np_utils/np_browser_mock.h"
#include "o3d/gpu_plugin/np_utils/np_object_mock.h"
#include "o3d/gpu_plugin/np_utils/np_object_pointer.h"
+#include "o3d/gpu_plugin/system_services/shared_memory_mock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -56,7 +57,8 @@ class CommandBufferTest : public testing::Test {
};
TEST_F(CommandBufferTest, TestBehaviorWhileUninitialized) {
- EXPECT_EQ(NPObjectPointer<NPObject>(), command_buffer_object_->GetBuffer());
+ EXPECT_EQ(NPObjectPointer<NPObject>(),
+ command_buffer_object_->GetSharedMemory());
EXPECT_EQ(0, command_buffer_object_->GetGetOffset());
}
@@ -64,26 +66,21 @@ TEST_F(CommandBufferTest, InitializesCommandBuffer) {
EXPECT_CALL(mock_browser_, GetWindowNPObject(NULL))
.WillOnce(Return(window_object_.ToReturned()));
- NPObjectPointer<NPObject> expected_buffer =
- NPCreateObject<MockNPObject>(NULL);
+ NPObjectPointer<MockSharedMemory> expected_shared_memory =
+ NPCreateObject<StrictMock<MockSharedMemory> >(NULL);
EXPECT_CALL(*system_object_.Get(), CreateSharedMemory(1024))
- .WillOnce(Return(expected_buffer));
+ .WillOnce(Return(expected_shared_memory));
- NPSharedMemory shared_memory;
-
- EXPECT_CALL(mock_browser_, MapSharedMemory(NULL,
- expected_buffer.Get(),
- 1024,
- false))
- .WillOnce(Return(&shared_memory));
+ EXPECT_CALL(*expected_shared_memory.Get(), Map())
+ .WillOnce(Return(true));
EXPECT_TRUE(command_buffer_object_->Initialize(1024));
- EXPECT_EQ(expected_buffer, command_buffer_object_->GetBuffer());
+ EXPECT_EQ(expected_shared_memory, command_buffer_object_->GetSharedMemory());
// Cannot reinitialize.
EXPECT_FALSE(command_buffer_object_->Initialize(1024));
- EXPECT_EQ(expected_buffer, command_buffer_object_->GetBuffer());
+ EXPECT_EQ(expected_shared_memory, command_buffer_object_->GetSharedMemory());
}
TEST_F(CommandBufferTest, InitializeFailsIfCannotCreateSharedMemory) {
@@ -94,27 +91,26 @@ TEST_F(CommandBufferTest, InitializeFailsIfCannotCreateSharedMemory) {
.WillOnce(Return(NPObjectPointer<NPObject>()));
EXPECT_FALSE(command_buffer_object_->Initialize(1024));
- EXPECT_EQ(NPObjectPointer<NPObject>(), command_buffer_object_->GetBuffer());
+ EXPECT_EQ(NPObjectPointer<NPObject>(),
+ command_buffer_object_->GetSharedMemory());
}
TEST_F(CommandBufferTest, InitializeFailsIfCannotMapSharedMemory) {
EXPECT_CALL(mock_browser_, GetWindowNPObject(NULL))
.WillOnce(Return(window_object_.ToReturned()));
- NPObjectPointer<NPObject> expected_buffer =
- NPCreateObject<MockNPObject>(NULL);
+ NPObjectPointer<MockSharedMemory> expected_shared_memory =
+ NPCreateObject<StrictMock<MockSharedMemory> >(NULL);
EXPECT_CALL(*system_object_.Get(), CreateSharedMemory(1024))
- .WillOnce(Return(expected_buffer));
+ .WillOnce(Return(expected_shared_memory));
- EXPECT_CALL(mock_browser_, MapSharedMemory(NULL,
- expected_buffer.Get(),
- 1024,
- false))
- .WillOnce(Return(static_cast<NPSharedMemory*>(NULL)));
+ EXPECT_CALL(*expected_shared_memory.Get(), Map())
+ .WillOnce(Return(false));
EXPECT_FALSE(command_buffer_object_->Initialize(1024));
- EXPECT_EQ(NPObjectPointer<NPObject>(), command_buffer_object_->GetBuffer());
+ EXPECT_EQ(NPObjectPointer<NPObject>(),
+ command_buffer_object_->GetSharedMemory());
}
} // namespace gpu_plugin
} // namespace o3d
diff --git a/o3d/gpu_plugin/gpu_plugin.gyp b/o3d/gpu_plugin/gpu_plugin.gyp
index a466e12..908cc99 100644
--- a/o3d/gpu_plugin/gpu_plugin.gyp
+++ b/o3d/gpu_plugin/gpu_plugin.gyp
@@ -8,7 +8,7 @@
],
'targets': [
{
- 'target_name': 'gpu_plugin',
+ 'target_name': 'np_utils',
'type': '<(library)',
'dependencies': [
'../../base/base.gyp:base',
@@ -18,30 +18,115 @@
'../../third_party/npapi',
],
'sources': [
- 'command_buffer.cc',
- 'command_buffer.h',
- 'gpu_plugin.cc',
- 'gpu_plugin.h',
- 'gpu_plugin_object.cc',
- 'gpu_plugin_object.h',
- 'gpu_plugin_object_win.cc',
- 'gpu_plugin_object_factory.cc',
- 'gpu_plugin_object_factory.h',
'np_utils/default_np_object.h',
'np_utils/dynamic_np_object.cc',
'np_utils/dynamic_np_object.h',
'np_utils/np_browser.cc',
'np_utils/np_browser.h',
+ 'np_utils/np_browser_mock.h',
+ 'np_utils/np_browser_stub.cc',
+ 'np_utils/np_browser_stub.h',
'np_utils/np_class.h',
'np_utils/np_dispatcher.cc',
'np_utils/np_dispatcher.h',
'np_utils/np_dispatcher_specializations.h',
+ 'np_utils/np_object_mock.h',
'np_utils/np_object_pointer.h',
'np_utils/np_plugin_object.h',
'np_utils/np_plugin_object_factory.cc',
'np_utils/np_plugin_object_factory.h',
+ 'np_utils/np_plugin_object_factory_mock.h',
+ 'np_utils/np_plugin_object_mock.h',
'np_utils/np_utils.cc',
'np_utils/np_utils.h',
+ 'np_utils/webkit_browser.h',
+ ],
+ },
+
+ # This is a standalone executable until O3D is fully moved over to using
+ # gyp. At that point these can become part of the regular O3D unit tests.
+ {
+ 'target_name': 'np_utils_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ 'gpu_plugin',
+ '../../testing/gmock.gyp:gmock',
+ '../../testing/gmock.gyp:gmockmain',
+ '../../testing/gtest.gyp:gtest',
+ ],
+ 'include_dirs': [
+ '../..',
+ '../../third_party/npapi',
+ ],
+ 'sources': [
+ 'np_utils/dispatched_np_object_unittest.cc',
+ 'np_utils/dynamic_np_object_unittest.cc',
+ 'np_utils/np_class_unittest.cc',
+ 'np_utils/np_object_pointer_unittest.cc',
+ 'np_utils/np_utils_unittest.cc',
+ ],
+ },
+
+ {
+ 'target_name': 'system_services',
+ 'type': '<(library)',
+ 'dependencies': [
+ '../../base/base.gyp:base',
+ 'np_utils',
+ ],
+ 'include_dirs': [
+ '../..',
+ '../../third_party/npapi',
+ ],
+ 'sources': [
+ 'system_services/shared_memory.cc',
+ 'system_services/shared_memory.h',
+ 'system_services/shared_memory_mock.h',
+ 'system_services/shared_memory_public.h',
+ ],
+ },
+
+ # This is a standalone executable until O3D is fully moved over to using
+ # gyp. At that point these can become part of the regular O3D unit tests.
+ {
+ 'target_name': 'system_services_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ 'system_services',
+ '../../testing/gmock.gyp:gmock',
+ '../../testing/gmock.gyp:gmockmain',
+ '../../testing/gtest.gyp:gtest',
+ ],
+ 'include_dirs': [
+ '../..',
+ '../../third_party/npapi',
+ ],
+ 'sources': [
+ 'system_services/shared_memory_unittest.cc',
+ ],
+ },
+
+ {
+ 'target_name': 'gpu_plugin',
+ 'type': '<(library)',
+ 'dependencies': [
+ '../../base/base.gyp:base',
+ 'np_utils',
+ ],
+ 'include_dirs': [
+ '../..',
+ '../../third_party/npapi',
+ ],
+ 'sources': [
+ 'command_buffer.cc',
+ 'command_buffer.h',
+ 'gpu_plugin.cc',
+ 'gpu_plugin.h',
+ 'gpu_plugin_object.cc',
+ 'gpu_plugin_object.h',
+ 'gpu_plugin_object_win.cc',
+ 'gpu_plugin_object_factory.cc',
+ 'gpu_plugin_object_factory.h',
],
},
@@ -52,6 +137,8 @@
'type': 'executable',
'dependencies': [
'gpu_plugin',
+ 'np_utils',
+ 'system_services',
'../../testing/gmock.gyp:gmock',
'../../testing/gmock.gyp:gmockmain',
'../../testing/gtest.gyp:gtest',
@@ -66,17 +153,6 @@
'gpu_plugin_unittest.cc',
'gpu_plugin_object_unittest.cc',
'gpu_plugin_object_factory_unittest.cc',
- 'np_utils/dispatched_np_object_unittest.cc',
- 'np_utils/dynamic_np_object_unittest.cc',
- 'np_utils/np_browser_mock.h',
- 'np_utils/np_browser_stub.cc',
- 'np_utils/np_browser_stub.h',
- 'np_utils/np_class_unittest.cc',
- 'np_utils/np_object_mock.h',
- 'np_utils/np_object_pointer_unittest.cc',
- 'np_utils/np_plugin_object_factory_mock.h',
- 'np_utils/np_plugin_object_mock.h',
- 'np_utils/np_utils_unittest.cc',
],
},
]
diff --git a/o3d/gpu_plugin/gpu_plugin_object.cc b/o3d/gpu_plugin/gpu_plugin_object.cc
index 329cd58..de67c8a4 100644
--- a/o3d/gpu_plugin/gpu_plugin_object.cc
+++ b/o3d/gpu_plugin/gpu_plugin_object.cc
@@ -20,8 +20,7 @@ const NPUTF8 GPUPluginObject::kPluginType[] =
GPUPluginObject::GPUPluginObject(NPP npp)
: npp_(npp),
- status_(CREATED),
- shared_memory_(NULL) {
+ status_(CREATED) {
memset(&window_, 0, sizeof(window_));
}
@@ -60,10 +59,6 @@ NPError GPUPluginObject::Destroy(NPSavedData** saved) {
if (status_ != INITIALIZED)
return NPERR_GENERIC_ERROR;
- if (shared_memory_) {
- NPBrowser::get()->UnmapSharedMemory(npp_, shared_memory_);
- }
-
command_buffer_object_ = NPObjectPointer<CommandBuffer>();
status_ = DESTROYED;
diff --git a/o3d/gpu_plugin/gpu_plugin_object.h b/o3d/gpu_plugin/gpu_plugin_object.h
index 38b684b..0ca11e3 100644
--- a/o3d/gpu_plugin/gpu_plugin_object.h
+++ b/o3d/gpu_plugin/gpu_plugin_object.h
@@ -8,7 +8,7 @@
#include <string>
#include "o3d/gpu_plugin/command_buffer.h"
-#include "o3d/gpu_plugin/np_utils/dispatched_np_object.h"
+#include "o3d/gpu_plugin/np_utils/default_np_object.h"
#include "o3d/gpu_plugin/np_utils/np_dispatcher.h"
#include "o3d/gpu_plugin/np_utils/np_plugin_object.h"
#include "o3d/gpu_plugin/np_utils/np_utils.h"
@@ -63,7 +63,6 @@ class GPUPluginObject : public DefaultNPObject<NPObject>,
Status status_;
NPWindow window_;
NPObjectPointer<CommandBuffer> command_buffer_object_;
- NPSharedMemory* shared_memory_;
};
} // namespace gpu_plugin
diff --git a/o3d/gpu_plugin/np_utils/np_browser.cc b/o3d/gpu_plugin/np_utils/np_browser.cc
index d0c50c8..ac25c1e 100644
--- a/o3d/gpu_plugin/np_utils/np_browser.cc
+++ b/o3d/gpu_plugin/np_utils/np_browser.cc
@@ -12,13 +12,7 @@ namespace gpu_plugin {
NPBrowser* NPBrowser::browser_;
NPBrowser::NPBrowser(NPNetscapeFuncs* funcs)
- : netscape_funcs_(funcs),
- chromium_funcs_(NULL) {
- // Attempt to get the Chromium functions.
- if (netscape_funcs_ && netscape_funcs_->getvalue) {
- netscape_funcs_->getvalue(NULL, NPNVchromiumFuncs, &chromium_funcs_);
- }
-
+ : netscape_funcs_(funcs) {
// Make this the first browser in the linked list.
previous_browser_ = browser_;
browser_ = this;
@@ -109,19 +103,5 @@ NPObject* NPBrowser::GetWindowNPObject(NPP npp) {
return NULL;
}
}
-
-NPSharedMemory* NPBrowser::MapSharedMemory(NPP id,
- NPObject* object,
- size_t size,
- bool read_only) {
- DCHECK(chromium_funcs_);
- return chromium_funcs_->mapsharedmemory(id, object, size, read_only);
-}
-
-void NPBrowser::UnmapSharedMemory(NPP id,
- NPSharedMemory* shared_memory) {
- DCHECK(chromium_funcs_);
- chromium_funcs_->unmapsharedmemory(id, shared_memory);
-}
} // namespace gpu_plugin
} // namespace o3d
diff --git a/o3d/gpu_plugin/np_utils/np_browser.h b/o3d/gpu_plugin/np_utils/np_browser.h
index dd5e675..21b6133 100644
--- a/o3d/gpu_plugin/np_utils/np_browser.h
+++ b/o3d/gpu_plugin/np_utils/np_browser.h
@@ -9,7 +9,6 @@
#include "third_party/npapi/bindings/npruntime.h"
typedef struct _NPNetscapeFuncs NPNetscapeFuncs;
-typedef struct _NPChromiumFuncs NPChromiumFuncs;
namespace o3d {
namespace gpu_plugin {
@@ -72,20 +71,10 @@ class NPBrowser {
virtual NPObject* GetWindowNPObject(NPP npp);
- // Chromium specific additions.
- virtual NPSharedMemory* MapSharedMemory(NPP id,
- NPObject* object,
- size_t size,
- bool read_only);
-
- virtual void UnmapSharedMemory(NPP id,
- NPSharedMemory* shared_memory);
-
private:
static NPBrowser* browser_;
NPBrowser* previous_browser_;
NPNetscapeFuncs* netscape_funcs_;
- NPChromiumFuncs* chromium_funcs_;
DISALLOW_COPY_AND_ASSIGN(NPBrowser);
};
diff --git a/o3d/gpu_plugin/np_utils/np_browser_mock.h b/o3d/gpu_plugin/np_utils/np_browser_mock.h
index dbbf548..9db951e 100644
--- a/o3d/gpu_plugin/np_utils/np_browser_mock.h
+++ b/o3d/gpu_plugin/np_utils/np_browser_mock.h
@@ -31,8 +31,6 @@ class MockNPBrowser : public StubNPBrowser {
MOCK_METHOD2(CreateObject, NPObject*(NPP, const NPClass*));
MOCK_METHOD1(GetWindowNPObject, NPObject*(NPP));
- MOCK_METHOD4(MapSharedMemory, NPSharedMemory*(NPP, NPObject*, size_t, bool));
- MOCK_METHOD2(UnmapSharedMemory, void(NPP, NPSharedMemory*));
};
} // namespace gpu_plugin
diff --git a/o3d/gpu_plugin/np_utils/np_browser_stub.cc b/o3d/gpu_plugin/np_utils/np_browser_stub.cc
index e1c8edf..5c673ac 100644
--- a/o3d/gpu_plugin/np_utils/np_browser_stub.cc
+++ b/o3d/gpu_plugin/np_utils/np_browser_stub.cc
@@ -103,17 +103,5 @@ bool StubNPBrowser::Invoke(NPP npp,
NPObject* StubNPBrowser::GetWindowNPObject(NPP npp) {
return NULL;
}
-
-
-NPSharedMemory* StubNPBrowser::MapSharedMemory(NPP id,
- NPObject* object,
- size_t size,
- bool read_only) {
- return NULL;
-}
-
-void StubNPBrowser::UnmapSharedMemory(NPP id,
- NPSharedMemory* shared_memory) {
-}
} // namespace gpu_plugin
} // namespace o3d
diff --git a/o3d/gpu_plugin/np_utils/np_browser_stub.h b/o3d/gpu_plugin/np_utils/np_browser_stub.h
index e431c1b..3e1288c 100644
--- a/o3d/gpu_plugin/np_utils/np_browser_stub.h
+++ b/o3d/gpu_plugin/np_utils/np_browser_stub.h
@@ -67,15 +67,6 @@ class StubNPBrowser : public NPBrowser {
virtual NPObject* GetWindowNPObject(NPP npp);
- // Chromium specific additions.
- virtual NPSharedMemory* MapSharedMemory(NPP id,
- NPObject* object,
- size_t size,
- bool read_only);
-
- virtual void UnmapSharedMemory(NPP id,
- NPSharedMemory* shared_memory);
-
private:
DISALLOW_COPY_AND_ASSIGN(StubNPBrowser);
};
diff --git a/o3d/gpu_plugin/np_utils/np_object_mock.h b/o3d/gpu_plugin/np_utils/np_object_mock.h
index 7e53262..552df62e 100644
--- a/o3d/gpu_plugin/np_utils/np_object_mock.h
+++ b/o3d/gpu_plugin/np_utils/np_object_mock.h
@@ -5,8 +5,7 @@
#ifndef O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_MOCK_H_
#define O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_MOCK_H_
-#include "third_party/npapi/bindings/npapi.h"
-#include "third_party/npapi/bindings/npruntime.h"
+#include "o3d/gpu_plugin/np_utils/np_browser.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace o3d {
diff --git a/o3d/gpu_plugin/np_utils/webkit_browser.h b/o3d/gpu_plugin/np_utils/webkit_browser.h
new file mode 100644
index 0000000..70e0782
--- /dev/null
+++ b/o3d/gpu_plugin/np_utils/webkit_browser.h
@@ -0,0 +1,112 @@
+// 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 O3D_GPU_PLUGIN_NP_UTILS_WEBKIT_BROWSER_H_
+#define O3D_GPU_PLUGIN_NP_UTILS_WEBKIT_BROWSER_H_
+
+// TODO(apatrick): This does not belong in np_utils. np_utils should not be
+// dependent on WebKit (and it isn't - that's why the member functions are
+// inline).
+
+#include <stdlib.h>
+
+#include "o3d/gpu_plugin/np_utils/np_browser.h"
+#include "WebKit/api/public/WebBindings.h"
+
+typedef struct _NPNetscapeFuncs NPNetscapeFuncs;
+typedef struct _NPChromiumFuncs NPChromiumFuncs;
+
+namespace o3d {
+namespace gpu_plugin {
+
+// This class implements NPBrowser for the WebKit WebBindings.
+class WebKitBrowser : public NPBrowser {
+ public:
+ WebKitBrowser(): NPBrowser(NULL) {
+ }
+
+ // Standard functions from NPNetscapeFuncs.
+
+ virtual NPIdentifier GetStringIdentifier(const NPUTF8* name) {
+ return WebKit::WebBindings::getStringIdentifier(name);
+ }
+
+ virtual void* MemAlloc(size_t size) {
+ return malloc(size);
+ }
+
+ virtual void MemFree(void* p) {
+ free(p);
+ }
+
+ virtual NPObject* CreateObject(NPP npp, const NPClass* cl) {
+ return WebKit::WebBindings::createObject(npp, const_cast<NPClass*>(cl));
+ }
+
+ virtual NPObject* RetainObject(NPObject* object) {
+ return WebKit::WebBindings::retainObject(object);
+ }
+
+ virtual void ReleaseObject(NPObject* object) {
+ WebKit::WebBindings::releaseObject(object);
+ }
+
+ virtual void ReleaseVariantValue(NPVariant* variant) {
+ WebKit::WebBindings::releaseVariantValue(variant);
+ }
+
+ virtual bool HasProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return WebKit::WebBindings::hasProperty(npp, object, name);
+ }
+
+ virtual bool GetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ NPVariant* result) {
+ return WebKit::WebBindings::getProperty(npp, object, name, result);
+ }
+
+ virtual bool SetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* result) {
+ return WebKit::WebBindings::setProperty(npp, object, name, result);
+ }
+
+ virtual bool RemoveProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return WebKit::WebBindings::removeProperty(npp, object, name);
+ }
+
+ virtual bool HasMethod(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return WebKit::WebBindings::hasMethod(npp, object, name);
+ }
+
+ virtual bool Invoke(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return WebKit::WebBindings::invoke(npp, object, name, args, num_args,
+ result);
+ }
+
+ virtual NPObject* GetWindowNPObject(NPP npp) {
+ return NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebKitBrowser);
+};
+
+} // namespace gpu_plugin
+} // namespace o3d
+
+#endif // O3D_GPU_PLUGIN_NP_UTILS_WEBKIT_BROWSER_H_
diff --git a/o3d/gpu_plugin/system_services/shared_memory.cc b/o3d/gpu_plugin/system_services/shared_memory.cc
new file mode 100644
index 0000000..2246d30
--- /dev/null
+++ b/o3d/gpu_plugin/system_services/shared_memory.cc
@@ -0,0 +1,65 @@
+// 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 "o3d/gpu_plugin/system_services/shared_memory.h"
+
+namespace o3d {
+namespace gpu_plugin {
+
+SharedMemory::SharedMemory(NPP npp)
+ : npp_(npp),
+ shared_memory_(NULL) {
+ handle = NULL;
+ ptr = NULL;
+ size = 0;
+}
+
+SharedMemory::~SharedMemory() {
+ if (shared_memory_) {
+ delete shared_memory_;
+ }
+}
+
+void SharedMemory::Initialize(base::SharedMemory* shared_memory, int32 size) {
+ DCHECK(shared_memory);
+ shared_memory_ = shared_memory;
+ this->handle = shared_memory->handle();
+ this->size = size;
+}
+
+bool SharedMemory::Initialize(int32 size) {
+ if (size < 0)
+ return false;
+
+ if (shared_memory_)
+ return false;
+
+ shared_memory_ = new base::SharedMemory();
+ if (!shared_memory_->Create(std::wstring(), false, false, size)) {
+ delete shared_memory_;
+ shared_memory_ = NULL;
+ return false;
+ }
+
+ handle = shared_memory_->handle();
+ this->size = size;
+ return true;
+}
+
+bool SharedMemory::Map() {
+ if (!shared_memory_)
+ return false;
+
+ if (!shared_memory_->memory()) {
+ if (!shared_memory_->Map(shared_memory_->max_size()))
+ return false;
+
+ ptr = shared_memory_->memory();
+ }
+
+ return true;
+}
+
+} // namespace gpu_plugin
+} // namespace o3d
diff --git a/o3d/gpu_plugin/system_services/shared_memory.h b/o3d/gpu_plugin/system_services/shared_memory.h
new file mode 100644
index 0000000..eb45a96
--- /dev/null
+++ b/o3d/gpu_plugin/system_services/shared_memory.h
@@ -0,0 +1,55 @@
+// 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 O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_H_
+#define O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_H_
+
+#include "base/shared_memory.h"
+#include "o3d/gpu_plugin/np_utils/default_np_object.h"
+#include "o3d/gpu_plugin/np_utils/np_dispatcher.h"
+#include "o3d/gpu_plugin/np_utils/np_object_pointer.h"
+#include "o3d/gpu_plugin/system_services/shared_memory_public.h"
+#include "third_party/npapi/bindings/npruntime.h"
+
+namespace o3d {
+namespace gpu_plugin {
+
+// An NPObject holding a shared memory handle.
+class SharedMemory : public DefaultNPObject<CHRSharedMemory> {
+ public:
+ explicit SharedMemory(NPP npp);
+ ~SharedMemory();
+
+ // Initialize from an existing base::SharedMemory. Takes ownership of the
+ // base::SharedMemory.
+ void Initialize(base::SharedMemory* shared_memory, int32 size);
+
+ virtual bool Initialize(int32 size);
+
+ virtual int32 GetSize() {
+ return size;
+ }
+
+ virtual bool Map();
+
+ base::SharedMemory* shared_memory() const {
+ return shared_memory_;
+ }
+
+ NP_UTILS_BEGIN_DISPATCHER_CHAIN(SharedMemory, DefaultNPObject<NPObject>)
+ NP_UTILS_DISPATCHER(Initialize, bool(int32));
+ NP_UTILS_DISPATCHER(GetSize, int32())
+ NP_UTILS_DISPATCHER(Map, bool())
+ NP_UTILS_END_DISPATCHER_CHAIN
+
+ private:
+ NPP npp_;
+ base::SharedMemory* shared_memory_;
+ DISALLOW_COPY_AND_ASSIGN(SharedMemory);
+};
+
+} // namespace gpu_plugin
+} // namespace o3d
+
+#endif // O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_H_
diff --git a/o3d/gpu_plugin/system_services/shared_memory_mock.h b/o3d/gpu_plugin/system_services/shared_memory_mock.h
new file mode 100644
index 0000000..de3f93d
--- /dev/null
+++ b/o3d/gpu_plugin/system_services/shared_memory_mock.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 O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_MOCK_H_
+#define O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_MOCK_H_
+
+#include "o3d/gpu_plugin/system_services/shared_memory.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace o3d {
+namespace gpu_plugin {
+
+class MockSharedMemory : public SharedMemory {
+ public:
+ explicit MockSharedMemory(NPP npp) : SharedMemory(npp) {
+ }
+
+ MOCK_METHOD1(Initialize, bool(int32));
+ MOCK_METHOD0(GetSize, int32());
+ MOCK_METHOD0(Map, bool());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockSharedMemory);
+};
+
+} // namespace gpu_plugin
+} // namespace o3d
+
+#endif // O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_MOCK_H_
diff --git a/o3d/gpu_plugin/system_services/shared_memory_public.h b/o3d/gpu_plugin/system_services/shared_memory_public.h
new file mode 100644
index 0000000..af994ef2
--- /dev/null
+++ b/o3d/gpu_plugin/system_services/shared_memory_public.h
@@ -0,0 +1,33 @@
+// 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 O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_PUBLIC_H_
+#define O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_PUBLIC_H_
+
+// Mapped memory range. Size is zero and pointer is null until object is
+// mapped. Each process needs to separately map the object. It is safe to
+// map an already mapped object.
+
+#include "third_party/npapi/bindings/npruntime.h"
+
+#if defined(__cplusplus)
+
+struct CHRSharedMemory : NPObject {
+ size_t size;
+ void* ptr;
+ void* handle;
+};
+
+#else
+
+typedef struct _CHRSharedMemory {
+ NPObject object;
+ size_t size;
+ void* ptr;
+ void* handle;
+} CHRSharedMemory;
+
+#endif
+
+#endif // O3D_GPU_PLUGIN_SYSTEM_SERVICES_SHARED_MEMORY_PUBLIC_H_
diff --git a/o3d/gpu_plugin/system_services/shared_memory_unittest.cc b/o3d/gpu_plugin/system_services/shared_memory_unittest.cc
new file mode 100644
index 0000000..9998b19
--- /dev/null
+++ b/o3d/gpu_plugin/system_services/shared_memory_unittest.cc
@@ -0,0 +1,112 @@
+// 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 "base/process_util.h"
+#include "o3d/gpu_plugin/np_utils/np_browser_stub.h"
+#include "o3d/gpu_plugin/system_services/shared_memory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Return;
+using testing::SetArgumentPointee;
+using testing::StrictMock;
+
+namespace o3d {
+namespace gpu_plugin {
+
+class SharedMemoryTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ shared_memory_ = NPCreateObject<SharedMemory>(NULL);
+ }
+
+ StubNPBrowser stub_browser_;
+ NPObjectPointer<SharedMemory> shared_memory_;
+};
+
+TEST_F(SharedMemoryTest, MemoryIsNotMappedBeforeInitialization) {
+ EXPECT_TRUE(NULL == shared_memory_->handle);
+ EXPECT_TRUE(NULL == shared_memory_->ptr);
+ EXPECT_EQ(0, shared_memory_->size);
+ EXPECT_EQ(0, shared_memory_->GetSize());
+}
+
+TEST_F(SharedMemoryTest, InitializesAndReturnsMappedMemory) {
+ EXPECT_TRUE(shared_memory_->Initialize(65536));
+ EXPECT_TRUE(NULL != shared_memory_->handle);
+ EXPECT_TRUE(NULL == shared_memory_->ptr);
+ EXPECT_EQ(65536, shared_memory_->size);
+ EXPECT_EQ(65536, shared_memory_->GetSize());
+
+ EXPECT_TRUE(shared_memory_->Map());
+ ASSERT_TRUE(NULL != shared_memory_->ptr);
+ EXPECT_EQ(65536, shared_memory_->size);
+
+ // Test that memory can be written to.
+ int8* ptr = static_cast<int8*>(shared_memory_->ptr);
+ for (int i = 0; i < 65536; ++i) {
+ ptr[i] = 7;
+ }
+}
+
+TEST_F(SharedMemoryTest, MapFailsBeforeInitialization) {
+ EXPECT_FALSE(shared_memory_->Map());
+}
+
+TEST_F(SharedMemoryTest, InitializeFailsForNegativeSize) {
+ EXPECT_FALSE(shared_memory_->Initialize(-1));
+}
+
+TEST_F(SharedMemoryTest, SecondCallToInitializeFails) {
+ EXPECT_TRUE(shared_memory_->Initialize(65536));
+ EXPECT_FALSE(shared_memory_->Initialize(65536));
+}
+
+TEST_F(SharedMemoryTest, InitializeRoundsUpToPageSizeButReportsRequestedSize) {
+ EXPECT_TRUE(shared_memory_->Initialize(7));
+
+ EXPECT_TRUE(shared_memory_->Map());
+ EXPECT_EQ(7, shared_memory_->size);
+
+ // Test that memory can be written to.
+ int8* ptr = static_cast<int8*>(shared_memory_->ptr);
+ for (int i = 0; i < 7; ++i) {
+ ptr[i] = 7;
+ }
+}
+
+TEST_F(SharedMemoryTest, SecondMapDoesNothing) {
+ EXPECT_TRUE(shared_memory_->Initialize(65536));
+
+ EXPECT_TRUE(shared_memory_->Map());
+ ASSERT_TRUE(NULL != shared_memory_->handle);
+ ASSERT_TRUE(NULL != shared_memory_->ptr);
+ EXPECT_EQ(65536, shared_memory_->size);
+
+ void* handle = shared_memory_->handle;
+ void* ptr = shared_memory_->ptr;
+ EXPECT_TRUE(shared_memory_->Map());
+ ASSERT_EQ(ptr, shared_memory_->ptr);
+ EXPECT_EQ(65536, shared_memory_->size);
+}
+
+TEST_F(SharedMemoryTest, CanInitializeWithHandle) {
+ base::SharedMemory* temp_shared_memory = new base::SharedMemory;
+ EXPECT_TRUE(temp_shared_memory->Create(std::wstring(), false, false, 65536));
+
+ shared_memory_->Initialize(temp_shared_memory, 65536);
+ EXPECT_TRUE(NULL != shared_memory_->handle);
+ EXPECT_TRUE(NULL == shared_memory_->ptr);
+ EXPECT_EQ(65536, shared_memory_->size);
+
+ EXPECT_TRUE(shared_memory_->Map());
+ EXPECT_TRUE(NULL != shared_memory_->handle);
+ EXPECT_TRUE(NULL != shared_memory_->ptr);
+ EXPECT_EQ(65536, shared_memory_->size);
+}
+
+} // namespace gpu_plugin
+} // namespace o3d