summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-22 23:28:15 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-22 23:28:15 +0000
commit7477ea6f6a173b586622fd276433a346760ffbf4 (patch)
tree678229a49ae5c4bb1a54a61374466cdddf57db59 /chrome
parente4f7cec0a45a803faf00875a070090b165ff1fc5 (diff)
downloadchromium_src-7477ea6f6a173b586622fd276433a346760ffbf4.zip
chromium_src-7477ea6f6a173b586622fd276433a346760ffbf4.tar.gz
chromium_src-7477ea6f6a173b586622fd276433a346760ffbf4.tar.bz2
Added Pepper 3D device that instantiates the GPU plugin and sends GLES2 commands to it via a command buffer.
Added API for managing buffers to Pepper 3D device. Removed DCHECK from WebPluginImpl::SetWindow that checks against a windowless plugin being given a window handle. Please check this! Now an initially windowless plugin instance gets a handle when it requests a Pepper 3D context. Perhaps the window handle should be concealed from the underlying plugin isntance. Removed enable_gpu gyp variable and C macro. GPU code is always built on windows but not mac or linux. It is enabled at runtime with the --enable-gpu-plugin switch. Redesigned CommandBuffer interface so it exposes shared memory through a Buffer. This was necessary because Pepper has no notion of shared memory handles. The Buffer exposes the shared memory as both a handle (through base::SharedMemory) and the mapped address and size. Refactored CommandBufferEngine so mapped shared memory addresses and sizes are returned with a single call rather than two separate calls. Added 3D demo to pepper test plugin. TEST=try servers BUG=none Review URL: http://codereview.chromium.org/367002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35185 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/DEPS2
-rw-r--r--chrome/browser/plugin_process_host.cc1
-rw-r--r--chrome/browser/plugin_service.cc3
-rwxr-xr-xchrome/chrome.gyp7
-rwxr-xr-xchrome/chrome_renderer.gypi13
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/command_buffer_messages_internal.h5
-rw-r--r--chrome/common/gpu_plugin.cc43
-rw-r--r--chrome/common/gpu_plugin.h15
-rw-r--r--chrome/plugin/command_buffer_stub.cc44
-rw-r--r--chrome/plugin/command_buffer_stub.h3
-rw-r--r--chrome/plugin/plugin_main.cc3
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc2
-rw-r--r--chrome/plugin/webplugin_delegate_stub.h2
-rw-r--r--chrome/renderer/command_buffer_proxy.cc70
-rw-r--r--chrome/renderer/command_buffer_proxy.h8
-rw-r--r--chrome/renderer/render_view.cc5
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc178
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h41
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc2
21 files changed, 359 insertions, 92 deletions
diff --git a/chrome/DEPS b/chrome/DEPS
index e96251a..c24006e 100644
--- a/chrome/DEPS
+++ b/chrome/DEPS
@@ -1,6 +1,6 @@
include_rules = [
"+app",
- "+gpu/command_buffer",
+ "+gpu",
"+net",
"+printing",
"+views",
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index f187b8c..5ae3715 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -373,6 +373,7 @@ bool PluginProcessHost::Init(const WebPluginInfo& info,
switches::kMemoryProfiling,
switches::kUseLowFragHeapCrt,
switches::kEnableStatsTable,
+ switches::kEnableGPUPlugin,
#if defined(OS_CHROMEOS)
switches::kProfile,
#endif
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index ba5821e..9c75d5c 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -19,6 +19,7 @@
#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/gpu_plugin.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/notification_service.h"
@@ -71,6 +72,8 @@ PluginService::PluginService()
RegisterInternalNaClPlugin();
#endif
+ chrome::RegisterInternalGPUPlugin();
+
#if defined(OS_WIN)
hkcu_key_.Create(
HKEY_CURRENT_USER, kRegistryMozillaPlugins, KEY_NOTIFY);
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index f231743..989cd4a 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -508,6 +508,8 @@
'common/dom_storage_type.h',
'common/filter_policy.h',
'common/gears_api.h',
+ 'common/gpu_plugin.cc',
+ 'common/gpu_plugin.h',
'common/gtk_tree.cc',
'common/gtk_tree.h',
'common/gtk_util.cc',
@@ -772,6 +774,9 @@
# end up using this module as well.
'conditions': [
['OS=="win"', {
+ 'dependencies': [
+ '../gpu/gpu.gyp:command_buffer_service',
+ ],
'defines': [
'__STD_C',
'_CRT_SECURE_NO_DEPRECATE',
@@ -780,8 +785,6 @@
'include_dirs': [
'third_party/wtl/include',
],
- },],
- ['enable_gpu==1', {
'sources': [
'plugin/command_buffer_stub.cc',
'plugin/command_buffer_stub.h',
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index a0c8e09..d9cc809 100755
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -148,15 +148,6 @@
],
},
'conditions': [
- ['enable_gpu==1', {
- 'dependencies': [
- '../gpu/gpu.gyp:gpu_plugin',
- ],
- 'sources': [
- 'renderer/command_buffer_proxy.cc',
- 'renderer/command_buffer_proxy.h',
- ],
- }],
['disable_nacl!=1', {
'dependencies': [
'nacl',
@@ -174,6 +165,10 @@
'include_dirs': [
'third_party/wtl/include',
],
+ 'sources': [
+ 'renderer/command_buffer_proxy.cc',
+ 'renderer/command_buffer_proxy.h',
+ ],
'conditions': [
['win_use_allocator_shim==1', {
'dependencies': [
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index ea5208d..5ce3111 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -204,6 +204,9 @@ const char kEnableFileCookies[] = "enable-file-cookies";
// Enable Geolocation support.
const char kEnableGeolocation[] = "enable-geolocation";
+// Enable the GPU plugin and Pepper 3D rendering.
+const char kEnableGPUPlugin[] = "enable-gpu-plugin";
+
// Disable LocalStorage.
const char kDisableLocalStorage[] = "disable-local-storage";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index bb9ffc9..0622455 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -74,6 +74,7 @@ extern const char kEnableExtensionToolstrips[];
extern const char kEnableFastback[];
extern const char kEnableFileCookies[];
extern const char kEnableGeolocation[];
+extern const char kEnableGPUPlugin[];
extern const char kDisableLocalStorage[];
extern const char kEnableLogging[];
extern const char kEnableMonitorProfile[];
diff --git a/chrome/common/command_buffer_messages_internal.h b/chrome/common/command_buffer_messages_internal.h
index ae28ecc..cbcda79 100644
--- a/chrome/common/command_buffer_messages_internal.h
+++ b/chrome/common/command_buffer_messages_internal.h
@@ -43,9 +43,10 @@ IPC_BEGIN_MESSAGES(CommandBuffer)
// Get the shared memory handle for a transfer buffer mapped to the callers
// process.
- IPC_SYNC_MESSAGE_ROUTED1_1(CommandBufferMsg_GetTransferBuffer,
+ IPC_SYNC_MESSAGE_ROUTED1_2(CommandBufferMsg_GetTransferBuffer,
int32 /* id */,
- base::SharedMemoryHandle /* transfer_buffer */)
+ base::SharedMemoryHandle /* transfer_buffer */,
+ size_t /* size */)
// Get the most recently processed token. Used for implementing fences.
IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetToken,
diff --git a/chrome/common/gpu_plugin.cc b/chrome/common/gpu_plugin.cc
new file mode 100644
index 0000000..fc79cbb
--- /dev/null
+++ b/chrome/common/gpu_plugin.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2009 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/command_line.h"
+#include "base/string_util.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/gpu_plugin.h"
+#include "gpu/gpu_plugin/gpu_plugin.h"
+#include "webkit/glue/plugins/plugin_list.h"
+
+#if defined(ENABLE_GPU)
+#include "webkit/glue/plugins/plugin_constants_win.h"
+#endif
+
+namespace chrome {
+
+void RegisterInternalGPUPlugin() {
+#if defined(ENABLE_GPU)
+ static const std::wstring kWideMimeType = ASCIIToWide(kGPUPluginMimeType);
+ static const NPAPI::PluginVersionInfo kGPUPluginInfo = {
+ FilePath(FILE_PATH_LITERAL("gpu-plugin")),
+ L"GPU Plug-in",
+ L"GPU Rendering Plug-in",
+ L"1",
+ kWideMimeType.c_str(),
+ L"",
+ L"",
+ {
+#if !defined(OS_LINUX)
+ gpu_plugin::NP_GetEntryPoints,
+#endif
+ gpu_plugin::NP_Initialize,
+ gpu_plugin::NP_Shutdown
+ }
+ };
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableGPUPlugin))
+ NPAPI::PluginList::Singleton()->RegisterInternalPlugin(kGPUPluginInfo);
+#endif // ENABLE_GPU
+}
+
+} // namespace chrome
diff --git a/chrome/common/gpu_plugin.h b/chrome/common/gpu_plugin.h
new file mode 100644
index 0000000..3fd609e
--- /dev/null
+++ b/chrome/common/gpu_plugin.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2009 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 CHROME_COMMON_GPU_PLUGIN_H_
+#define CHROME_COMMON_GPU_PLUGIN_H_
+
+namespace chrome {
+
+// Register the GPU plugin as an internal plugin in the PluginList.
+void RegisterInternalGPUPlugin();
+
+} // namespace chrome
+
+#endif // CHROME_COMMON_GPU_PLUGIN_H_
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index 632e868..d7dbf9f 100644
--- a/chrome/plugin/command_buffer_stub.cc
+++ b/chrome/plugin/command_buffer_stub.cc
@@ -8,6 +8,8 @@
#include "chrome/plugin/command_buffer_stub.h"
#include "chrome/plugin/plugin_channel.h"
+using gpu::Buffer;
+
CommandBufferStub::CommandBufferStub(PluginChannel* channel,
gfx::NativeView view)
: channel_(channel),
@@ -42,23 +44,25 @@ void CommandBufferStub::OnInitialize(int32 size,
// Assume service is responsible for duplicating the handle from the calling
// process.
base::ProcessHandle peer_handle;
- if (base::OpenProcessHandle(channel_->peer_pid(), &peer_handle))
+ if (!base::OpenProcessHandle(channel_->peer_pid(), &peer_handle))
return;
command_buffer_.reset(new gpu::CommandBufferService);
// Initialize the CommandBufferService and GPUProcessor.
- base::SharedMemory* shared_memory = command_buffer_->Initialize(size);
- if (shared_memory) {
- processor_ = new gpu::GPUProcessor(command_buffer_.get());
- if (processor_->Initialize(view_)) {
- command_buffer_->SetPutOffsetChangeCallback(
- NewCallback(processor_.get(),
- &gpu::GPUProcessor::ProcessCommands));
- shared_memory->ShareToProcess(peer_handle, ring_buffer);
- } else {
- processor_ = NULL;
- command_buffer_.reset();
+ if (command_buffer_->Initialize(size)) {
+ Buffer buffer = command_buffer_->GetRingBuffer();
+ if (buffer.shared_memory) {
+ processor_ = new gpu::GPUProcessor(command_buffer_.get());
+ if (processor_->Initialize(view_)) {
+ command_buffer_->SetPutOffsetChangeCallback(
+ NewCallback(processor_.get(),
+ &gpu::GPUProcessor::ProcessCommands));
+ buffer.shared_memory->ShareToProcess(peer_handle, ring_buffer);
+ } else {
+ processor_ = NULL;
+ command_buffer_.reset();
+ }
}
}
@@ -85,19 +89,23 @@ void CommandBufferStub::OnDestroyTransferBuffer(int32 id) {
command_buffer_->DestroyTransferBuffer(id);
}
-void CommandBufferStub::OnGetTransferBuffer(int32 id,
- base::SharedMemoryHandle* transfer_buffer) {
+void CommandBufferStub::OnGetTransferBuffer(
+ int32 id,
+ base::SharedMemoryHandle* transfer_buffer,
+ size_t* size) {
*transfer_buffer = 0;
+ *size = 0;
// Assume service is responsible for duplicating the handle to the calling
// process.
base::ProcessHandle peer_handle;
- if (base::OpenProcessHandle(channel_->peer_pid(), &peer_handle))
+ if (!base::OpenProcessHandle(channel_->peer_pid(), &peer_handle))
return;
- base::SharedMemory* shared_memory = command_buffer_->GetTransferBuffer(id);
- if (shared_memory) {
- shared_memory->ShareToProcess(peer_handle, transfer_buffer);
+ Buffer buffer = command_buffer_->GetTransferBuffer(id);
+ if (buffer.shared_memory) {
+ buffer.shared_memory->ShareToProcess(peer_handle, transfer_buffer);
+ *size = buffer.shared_memory->max_size();
}
base::CloseProcessHandle(peer_handle);
diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h
index 2a167c3..c7d765e 100644
--- a/chrome/plugin/command_buffer_stub.h
+++ b/chrome/plugin/command_buffer_stub.h
@@ -43,7 +43,8 @@ class CommandBufferStub : public IPC::Channel::Listener,
void OnCreateTransferBuffer(int32 size, int32* id);
void OnDestroyTransferBuffer(int32 id);
void OnGetTransferBuffer(int32 id,
- base::SharedMemoryHandle* transfer_buffer);
+ base::SharedMemoryHandle* transfer_buffer,
+ size_t* size);
void OnGetToken(int32* token);
void OnResetParseError(int32* parse_error);
void OnGetErrorStatus(bool* error_status);
diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc
index 5863621..319ccce 100644
--- a/chrome/plugin/plugin_main.cc
+++ b/chrome/plugin/plugin_main.cc
@@ -15,6 +15,7 @@
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/gpu_plugin.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/main_function_params.h"
#include "chrome/plugin/plugin_thread.h"
@@ -112,6 +113,8 @@ int PluginMain(const MainFunctionParams& parameters) {
}
#endif
+ chrome::RegisterInternalGPUPlugin();
+
MessageLoop::current()->Run();
}
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index b2b4b33..49c535c 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -369,7 +369,7 @@ void WebPluginDelegateStub::OnCreateCommandBuffer(int* route_id) {
*route_id = command_buffer_stub_->route_id();
#else
*route_id = 0;
-#endif
+#endif // ENABLE_GPU
}
void WebPluginDelegateStub::CreateSharedBuffer(
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index d5d3ab0..34358fa 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -6,6 +6,8 @@
#define CHROME_PLUGIN_WEBPLUGIN_DELEGATE_STUB_H_
#include <queue>
+#include <string>
+#include <vector>
#include "base/gfx/rect.h"
#include "base/ref_counted.h"
diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc
index 262bb8e..b78fa84 100644
--- a/chrome/renderer/command_buffer_proxy.cc
+++ b/chrome/renderer/command_buffer_proxy.cc
@@ -8,6 +8,9 @@
#include "chrome/common/plugin_messages.h"
#include "chrome/renderer/command_buffer_proxy.h"
#include "chrome/renderer/plugin_channel_host.h"
+#include "gpu/command_buffer/common/cmd_buffer_common.h"
+
+using gpu::Buffer;
CommandBufferProxy::CommandBufferProxy(
PluginChannelHost* channel,
@@ -18,6 +21,14 @@ CommandBufferProxy::CommandBufferProxy(
}
CommandBufferProxy::~CommandBufferProxy() {
+ // Delete all the locally cached shared memory objects, closing the handle
+ // in this process.
+ for (TransferBufferMap::iterator it = transfer_buffers_.begin();
+ it != transfer_buffers_.end();
+ ++it) {
+ delete it->second.shared_memory;
+ it->second.shared_memory = NULL;
+ }
}
bool CommandBufferProxy::Send(IPC::Message* msg) {
@@ -30,10 +41,10 @@ bool CommandBufferProxy::Send(IPC::Message* msg) {
return false;
}
-base::SharedMemory* CommandBufferProxy::Initialize(int32 size) {
+bool CommandBufferProxy::Initialize(int32 size) {
DCHECK(!ring_buffer_.get());
- // Initialize the service. Assuming we are in the renderer process, the GPU
+ // Initialize the service. Assuming we are sandboxed, the GPU
// process is responsible for duplicating the handle. This might not be true
// for NaCl.
base::SharedMemoryHandle handle;
@@ -42,18 +53,22 @@ base::SharedMemory* CommandBufferProxy::Initialize(int32 size) {
ring_buffer_.reset(new base::SharedMemory(handle, false));
if (ring_buffer_->Map(size * sizeof(int32))) {
size_ = size;
- return ring_buffer_.get();
+ return true;
}
ring_buffer_.reset();
}
- return NULL;
+ return false;
}
-base::SharedMemory* CommandBufferProxy::GetRingBuffer() {
+Buffer CommandBufferProxy::GetRingBuffer() {
// Return locally cached ring buffer.
- return ring_buffer_.get();
+ Buffer buffer;
+ buffer.ptr = ring_buffer_->memory();
+ buffer.size = size_ * sizeof(gpu::CommandBufferEntry);
+ buffer.shared_memory = ring_buffer_.get();
+ return buffer;
}
int32 CommandBufferProxy::GetSize() {
@@ -107,30 +122,55 @@ int32 CommandBufferProxy::CreateTransferBuffer(size_t size) {
void CommandBufferProxy::DestroyTransferBuffer(int32 id) {
// Remove the transfer buffer from the client side4 cache.
- transfer_buffers_.erase(id);
+ TransferBufferMap::iterator it = transfer_buffers_.find(id);
+ DCHECK(it != transfer_buffers_.end());
+
+ // Delete the shared memory object, closing the handle in this process.
+ delete it->second.shared_memory;
+
+ transfer_buffers_.erase(it);
Send(new CommandBufferMsg_DestroyTransferBuffer(route_id_, id));
}
-base::SharedMemory* CommandBufferProxy::GetTransferBuffer(int32 id) {
+Buffer CommandBufferProxy::GetTransferBuffer(int32 id) {
// Check local cache to see if there is already a client side shared memory
// object for this id.
TransferBufferMap::iterator it = transfer_buffers_.find(id);
- if (it != transfer_buffers_.end())
- return it->second.get();
+ if (it != transfer_buffers_.end()) {
+ return it->second;
+ }
// Assuming we are in the renderer process, the service is responsible for
// duplicating the handle. This might not be true for NaCl.
base::SharedMemoryHandle handle;
- if (!Send(new CommandBufferMsg_GetTransferBuffer(route_id_, id, &handle)))
- return NULL;
+ size_t size;
+ if (!Send(new CommandBufferMsg_GetTransferBuffer(route_id_,
+ id,
+ &handle,
+ &size))) {
+ return Buffer();
+ }
// Cache the transfer buffer shared memory object client side.
- base::SharedMemory* transfer_buffer =
+ base::SharedMemory* shared_memory =
new base::SharedMemory(handle, false, base::GetCurrentProcessHandle());
- transfer_buffers_[id].reset(transfer_buffer);
- return transfer_buffer;
+ // Map the shared memory on demand.
+ if (!shared_memory->memory()) {
+ if (!shared_memory->Map(shared_memory->max_size())) {
+ delete shared_memory;
+ return Buffer();
+ }
+ }
+
+ Buffer buffer;
+ buffer.ptr = shared_memory->memory();
+ buffer.size = size;
+ buffer.shared_memory = shared_memory;
+ transfer_buffers_[id] = buffer;
+
+ return buffer;
}
int32 CommandBufferProxy::GetToken() {
diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h
index 5abfead..7453988 100644
--- a/chrome/renderer/command_buffer_proxy.h
+++ b/chrome/renderer/command_buffer_proxy.h
@@ -33,8 +33,8 @@ class CommandBufferProxy : public gpu::CommandBuffer,
virtual bool Send(IPC::Message* msg);
// CommandBuffer implementation:
- virtual base::SharedMemory* Initialize(int32 size);
- virtual base::SharedMemory* GetRingBuffer();
+ virtual bool Initialize(int32 size);
+ virtual gpu::Buffer GetRingBuffer();
virtual int32 GetSize();
virtual int32 SyncOffsets(int32 put_offset);
virtual int32 GetGetOffset();
@@ -43,7 +43,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
virtual void SetPutOffsetChangeCallback(Callback0::Type* callback);
virtual int32 CreateTransferBuffer(size_t size);
virtual void DestroyTransferBuffer(int32 id);
- virtual base::SharedMemory* GetTransferBuffer(int32 handle);
+ virtual gpu::Buffer GetTransferBuffer(int32 handle);
virtual int32 GetToken();
virtual void SetToken(int32 token);
virtual int32 ResetParseError();
@@ -57,7 +57,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
scoped_ptr<base::SharedMemory> ring_buffer_;
// Local cache of id to transfer buffer mapping.
- typedef std::map<int32, linked_ptr<base::SharedMemory> > TransferBufferMap;
+ typedef std::map<int32, gpu::Buffer> TransferBufferMap;
TransferBufferMap transfer_buffers_;
scoped_refptr<PluginChannelHost> channel_;
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index c4f7483..6313755 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -2671,7 +2671,10 @@ webkit_glue::WebPluginDelegate* RenderView::CreatePluginDelegate(
#if defined(OS_WIN) // In-proc plugins aren't supported on Linux or Mac.
if (use_pepper_host) {
return WebPluginDelegatePepper::Create(
- path, *mime_type_to_use, gfx::NativeViewFromId(host_window_));
+ path,
+ *mime_type_to_use,
+ AsWeakPtr(),
+ gfx::NativeViewFromId(host_window_));
} else {
return WebPluginDelegateImpl::Create(
path, *mime_type_to_use, gfx::NativeViewFromId(host_window_));
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 5fc549c..4c32b7b 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -18,6 +18,7 @@
#include "base/string_util.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/webplugin_delegate_proxy.h"
#include "third_party/npapi/bindings/npapi_extensions.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "webkit/glue/glue_util.h"
@@ -28,6 +29,11 @@
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/webkit_glue.h"
+#if defined(ENABLE_GPU)
+#include "webkit/glue/plugins/plugin_constants_win.h"
+#endif
+
+using gpu::Buffer;
using webkit_glue::WebPlugin;
using webkit_glue::WebPluginDelegate;
using webkit_glue::WebPluginResourceClient;
@@ -53,6 +59,7 @@ uint32 WebPluginDelegatePepper::next_buffer_id = 0;
WebPluginDelegatePepper* WebPluginDelegatePepper::Create(
const FilePath& filename,
const std::string& mime_type,
+ const base::WeakPtr<RenderView>& render_view,
gfx::PluginWindowHandle containing_view) {
scoped_refptr<NPAPI::PluginLib> plugin_lib =
NPAPI::PluginLib::CreatePluginLib(filename);
@@ -65,7 +72,9 @@ WebPluginDelegatePepper* WebPluginDelegatePepper::Create(
scoped_refptr<NPAPI::PluginInstance> instance =
plugin_lib->CreateInstance(mime_type);
- return new WebPluginDelegatePepper(containing_view, instance.get());
+ return new WebPluginDelegatePepper(render_view,
+ containing_view,
+ instance.get());
}
bool WebPluginDelegatePepper::Initialize(
@@ -98,9 +107,6 @@ bool WebPluginDelegatePepper::Initialize(
// retreived via NPN_GetValue of NPNVnetscapeWindow.
instance_->set_window_handle(parent_);
- // This is a windowless plugin, so set it to have a NULL handle.
- plugin_->SetWindow(NULL);
-
plugin_url_ = url.spec();
return true;
@@ -147,6 +153,10 @@ void WebPluginDelegatePepper::UpdateGeometry(
new_committed.allocPixels();
committed_bitmap_ = new_committed;
+ // Forward the new geometry to the nested plugin instance.
+ if (nested_delegate_)
+ nested_delegate_->UpdateGeometry(window_rect, clip_rect);
+
if (!instance())
return;
@@ -247,6 +257,11 @@ NPError WebPluginDelegatePepper::Device2DQueryConfig(
NPError WebPluginDelegatePepper::Device2DInitializeContext(
const NPDeviceContext2DConfig* config,
NPDeviceContext2D* context) {
+ // This is a windowless plugin, so set it to have a NULL handle. Defer this
+ // until we know the plugin will use the 2D device. If it uses the 3D device
+ // it will have a window handle.
+ plugin_->SetWindow(NULL);
+
int width = window_rect_.width();
int height = window_rect_.height();
uint32 buffer_size = width * height * kBytesPerPixel;
@@ -392,6 +407,49 @@ NPError WebPluginDelegatePepper::Device3DQueryConfig(
NPError WebPluginDelegatePepper::Device3DInitializeContext(
const NPDeviceContext3DConfig* config,
NPDeviceContext3D* context) {
+#if defined(ENABLE_GPU)
+ // Check to see if the GPU plugin is already initialized and fail if so.
+ if (nested_delegate_)
+ return NPERR_GENERIC_ERROR;
+
+ // Create an instance of the GPU plugin that is responsible for 3D
+ // rendering.
+ nested_delegate_ = new WebPluginDelegateProxy(kGPUPluginMimeType,
+ render_view_);
+
+ // TODO(apatrick): should the GPU plugin be attached to plugin_?
+ if (nested_delegate_->Initialize(GURL(),
+ std::vector<std::string>(),
+ std::vector<std::string>(),
+ plugin_,
+ false)) {
+ // Ask the GPU plugin to create a command buffer and return a proxy.
+ command_buffer_.reset(nested_delegate_->CreateCommandBuffer());
+ if (command_buffer_.get()) {
+ // Initialize the proxy command buffer.
+ if (command_buffer_->Initialize(config->commandBufferEntries)) {
+ // Initialize the 3D context.
+ context->reserved = NULL;
+ Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ context->commandBuffer = ring_buffer.ptr;
+ context->commandBufferEntries = command_buffer_->GetSize();
+ context->getOffset = command_buffer_->GetGetOffset();
+ context->putOffset = command_buffer_->GetPutOffset();
+
+ // Ensure the service knows the window size before rendering anything.
+ nested_delegate_->UpdateGeometry(window_rect_, clip_rect_);
+
+ return NPERR_NO_ERROR;
+ }
+ }
+
+ command_buffer_.reset();
+ }
+
+ nested_delegate_->PluginDestroyed();
+ nested_delegate_ = NULL;
+#endif // ENABLE_GPU
+
return NPERR_GENERIC_ERROR;
}
@@ -406,7 +464,32 @@ NPError WebPluginDelegatePepper::Device3DGetStateContext(
NPDeviceContext3D* context,
int32 state,
int32* value) {
- return NPERR_GENERIC_ERROR;
+#if defined(ENABLE_GPU)
+ if (!command_buffer_.get())
+ return NPERR_GENERIC_ERROR;
+
+ switch (state) {
+ case NPDeviceContext3DState_GetOffset:
+ context->getOffset = *value = command_buffer_->GetGetOffset();
+ break;
+ case NPDeviceContext3DState_PutOffset:
+ *value = command_buffer_->GetPutOffset();
+ break;
+ case NPDeviceContext3DState_Token:
+ *value = command_buffer_->GetToken();
+ break;
+ case NPDeviceContext3DState_ParseError:
+ *value = command_buffer_->ResetParseError();
+ break;
+ case NPDeviceContext3DState_ErrorStatus:
+ *value = command_buffer_->GetErrorStatus() ? 1 : 0;
+ break;
+ default:
+ return NPERR_GENERIC_ERROR;
+ };
+#endif // ENABLE_GPU
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DFlushContext(
@@ -414,37 +497,75 @@ NPError WebPluginDelegatePepper::Device3DFlushContext(
NPDeviceContext3D* context,
NPDeviceFlushContextCallbackPtr callback,
void* user_data) {
- return NPERR_GENERIC_ERROR;
+#if defined(ENABLE_GPU)
+ DCHECK(callback == NULL);
+ context->getOffset = command_buffer_->SyncOffsets(context->putOffset);
+#endif // ENABLE_GPU
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DDestroyContext(
NPDeviceContext3D* context) {
- return NPERR_GENERIC_ERROR;
+#if defined(ENABLE_GPU)
+ command_buffer_.reset();
+
+ if (nested_delegate_) {
+ nested_delegate_->PluginDestroyed();
+ nested_delegate_ = NULL;
+ }
+#endif // ENABLE_GPU
+
+ return NPERR_NO_ERROR;
}
-bool WebPluginDelegatePepper::IsPluginDelegateWindow(
- gfx::NativeWindow window) {
- return false;
+NPError WebPluginDelegatePepper::Device3DCreateBuffer(
+ NPDeviceContext3D* context,
+ size_t size,
+ int32* id) {
+#if defined(ENABLE_GPU)
+ *id = command_buffer_->CreateTransferBuffer(size);
+ if (*id < 0)
+ return NPERR_GENERIC_ERROR;
+#endif // ENABLE_GPU
+
+ return NPERR_NO_ERROR;
}
-bool WebPluginDelegatePepper::GetPluginNameFromWindow(
- gfx::NativeWindow window, std::wstring *plugin_name) {
- return false;
+NPError WebPluginDelegatePepper::Device3DDestroyBuffer(
+ NPDeviceContext3D* context,
+ int32 id) {
+#if defined(ENABLE_GPU)
+ command_buffer_->DestroyTransferBuffer(id);
+#endif // ENABLE_GPU
+ return NPERR_NO_ERROR;
}
-bool WebPluginDelegatePepper::IsDummyActivationWindow(
- gfx::NativeWindow window) {
- return false;
+NPError WebPluginDelegatePepper::Device3DMapBuffer(
+ NPDeviceContext3D* context,
+ int32 id,
+ NPDeviceBuffer* np_buffer) {
+#if defined(ENABLE_GPU)
+ Buffer gpu_buffer = command_buffer_->GetTransferBuffer(id);
+ np_buffer->ptr = gpu_buffer.ptr;
+ np_buffer->size = gpu_buffer.size;
+ if (!np_buffer->ptr)
+ return NPERR_GENERIC_ERROR;
+#endif // ENABLE_GPU
+
+ return NPERR_NO_ERROR;
}
WebPluginDelegatePepper::WebPluginDelegatePepper(
+ const base::WeakPtr<RenderView>& render_view,
gfx::PluginWindowHandle containing_view,
NPAPI::PluginInstance *instance)
- : plugin_(NULL),
+ : render_view_(render_view),
+ plugin_(NULL),
instance_(instance),
parent_(containing_view),
buffer_size_(0),
- plugin_buffer_(0) {
+ plugin_buffer_(0),
+ nested_delegate_(NULL) {
// For now we keep a window struct, although it isn't used.
memset(&window_, 0, sizeof(window_));
// All Pepper plugins are windowless and transparent.
@@ -458,18 +579,27 @@ WebPluginDelegatePepper::~WebPluginDelegatePepper() {
}
void WebPluginDelegatePepper::PluginDestroyed() {
+ if (nested_delegate_) {
+ nested_delegate_->PluginDestroyed();
+ nested_delegate_ = NULL;
+ }
delete this;
}
void WebPluginDelegatePepper::Paint(WebKit::WebCanvas* canvas,
const gfx::Rect& rect) {
#if defined(OS_WIN)
- // Blit from background_context to context.
- if (!committed_bitmap_.isNull()) {
- gfx::Point origin(window_rect_.origin().x(), window_rect_.origin().y());
- canvas->drawBitmap(committed_bitmap_,
- SkIntToScalar(window_rect_.origin().x()),
- SkIntToScalar(window_rect_.origin().y()));
+ if (nested_delegate_) {
+ // TODO(apatrick): The GPU plugin will render to an offscreen render target.
+ // Need to copy it to the screen here.
+ } else {
+ // Blit from background_context to context.
+ if (!committed_bitmap_.isNull()) {
+ gfx::Point origin(window_rect_.origin().x(), window_rect_.origin().y());
+ canvas->drawBitmap(committed_bitmap_,
+ SkIntToScalar(window_rect_.origin().x()),
+ SkIntToScalar(window_rect_.origin().y()));
+ }
}
#endif
}
diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h
index aa798d7..2e78500 100644
--- a/chrome/renderer/webplugin_delegate_pepper.h
+++ b/chrome/renderer/webplugin_delegate_pepper.h
@@ -18,7 +18,10 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
+#include "base/weak_ptr.h"
#include "chrome/common/transport_dib.h"
+#include "chrome/renderer/render_view.h"
+#include "chrome/renderer/command_buffer_proxy.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npapi_extensions.h"
@@ -32,16 +35,11 @@ class PluginInstance;
// An implementation of WebPluginDelegate for Pepper in-process plugins.
class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
public:
- static WebPluginDelegatePepper* Create(const FilePath& filename,
- const std::string& mime_type, gfx::PluginWindowHandle containing_view);
-
- static bool IsPluginDelegateWindow(gfx::NativeWindow window);
- static bool GetPluginNameFromWindow(gfx::NativeWindow window,
- std::wstring *plugin_name);
-
- // Returns true if the window handle passed in is that of the dummy
- // activation window for windowless plugins.
- static bool IsDummyActivationWindow(gfx::NativeWindow window);
+ static WebPluginDelegatePepper* Create(
+ const FilePath& filename,
+ const std::string& mime_type,
+ const base::WeakPtr<RenderView>& render_view,
+ gfx::PluginWindowHandle containing_view);
// WebPluginDelegate implementation
virtual bool Initialize(const GURL& url,
@@ -118,9 +116,16 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
NPDeviceFlushContextCallbackPtr callback,
void* user_data);
virtual NPError Device3DDestroyContext(NPDeviceContext3D* context);
+ virtual NPError Device3DCreateBuffer(NPDeviceContext3D* context,
+ size_t size,
+ int32* id);
+ virtual NPError Device3DDestroyBuffer(NPDeviceContext3D* context,
+ int32 id);
+ virtual NPError Device3DMapBuffer(NPDeviceContext3D* context,
+ int32 id,
+ NPDeviceBuffer* buffer);
// End of WebPluginDelegate implementation.
- bool IsWindowless() const { return true; }
gfx::Rect GetRect() const { return window_rect_; }
gfx::Rect GetClipRect() const { return clip_rect_; }
@@ -128,8 +133,10 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
FilePath GetPluginPath();
private:
- WebPluginDelegatePepper(gfx::PluginWindowHandle containing_view,
- NPAPI::PluginInstance *instance);
+ WebPluginDelegatePepper(
+ const base::WeakPtr<RenderView>& render_view,
+ gfx::PluginWindowHandle containing_view,
+ NPAPI::PluginInstance *instance);
~WebPluginDelegatePepper();
// Tells the plugin about the current state of the window.
@@ -144,6 +151,8 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
// Closes down and destroys our plugin instance.
void DestroyInstance();
+ base::WeakPtr<RenderView> render_view_;
+
webkit_glue::WebPlugin* plugin_;
scoped_refptr<NPAPI::PluginInstance> instance_;
@@ -176,6 +185,12 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
// The url with which the plugin was instantiated.
std::string plugin_url_;
+ // The nested GPU plugin and its command buffer proxy.
+ WebPluginDelegateProxy* nested_delegate_;
+#if defined(ENABLE_GPU)
+ scoped_ptr<CommandBufferProxy> command_buffer_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(WebPluginDelegatePepper);
};
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 78f3dfe..f459b51 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -1153,7 +1153,7 @@ CommandBufferProxy* WebPluginDelegateProxy::CreateCommandBuffer() {
return new CommandBufferProxy(channel_host_, command_buffer_id);
#else
return NULL;
-#endif
+#endif // ENABLE_GPU
}
void WebPluginDelegateProxy::OnCancelDocumentLoad() {