Index: chrome/renderer/webplugin_delegate_pepper.cc |
=================================================================== |
--- chrome/renderer/webplugin_delegate_pepper.cc (revision 35153) |
+++ chrome/renderer/webplugin_delegate_pepper.cc (working copy) |
@@ -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 @@ |
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 @@ |
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 @@ |
// 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 @@ |
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::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::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 @@ |
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 @@ |
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 @@ |
} |
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 |
} |