Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3442)

Unified Diff: chrome/renderer/webplugin_delegate_pepper.cc

Issue 6614030: Revert 76840 - Removed GPU plugin.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/renderer/webplugin_delegate_pepper.h ('k') | chrome/renderer/webplugin_delegate_proxy.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/webplugin_delegate_pepper.cc
===================================================================
--- chrome/renderer/webplugin_delegate_pepper.cc (revision 76844)
+++ chrome/renderer/webplugin_delegate_pepper.cc (working copy)
@@ -63,6 +63,14 @@
#include "ui/gfx/gdi_util.h"
#endif
+#if defined(ENABLE_GPU)
+#include "webkit/plugins/npapi/plugin_constants_win.h"
+#endif
+
+#if defined(ENABLE_GPU)
+using gpu::Buffer;
+#endif
+
using webkit::npapi::WebPlugin;
using webkit::npapi::WebPluginDelegate;
using webkit::npapi::WebPluginResourceClient;
@@ -79,6 +87,15 @@
TransportDIB* dib;
};
+struct Device3DImpl {
+#if defined(ENABLE_GPU)
+ gpu::CommandBuffer* command_buffer;
+#endif
+ bool dynamically_created;
+};
+
+const int32 kDefaultCommandBufferSize = 1024 * 1024;
+
} // namespace
static const float kPointsPerInch = 72.0;
@@ -180,6 +197,22 @@
instance_ = 0;
}
+
+ // Destroy the nested GPU plugin only after first destroying the underlying
+ // Pepper plugin. This is so the Pepper plugin does not attempt to issue
+ // rendering commands after the GPU plugin has stopped processing them and
+ // responding to them.
+ if (nested_delegate_) {
+#if defined(ENABLE_GPU)
+ if (command_buffer_) {
+ nested_delegate_->DestroyCommandBuffer(command_buffer_);
+ command_buffer_ = NULL;
+ }
+#endif
+
+ nested_delegate_->PluginDestroyed();
+ nested_delegate_ = NULL;
+ }
}
void WebPluginDelegatePepper::UpdateGeometry(
@@ -204,6 +237,21 @@
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 defined(ENABLE_GPU)
+#if defined(OS_MACOSX)
+ // Send the new window size to the command buffer service code so it
+ // can allocate a new backing store. The handle to the new backing
+ // store is sent back to the browser asynchronously.
+ if (command_buffer_) {
+ command_buffer_->SetWindowSize(window_rect_.size());
+ }
+#endif // OS_MACOSX
+#endif // ENABLE_GPU
+
if (!instance())
return;
@@ -519,7 +567,8 @@
}
// This is a windowless plugin, so set it to have no handle. Defer this
- // until we know the plugin will use the 2D device.
+ // until we know the plugin will use the 2D device. If it uses the 3D device
+ // it will have a window handle.
plugin_->SetWindow(gfx::kNullPluginWindow);
scoped_ptr<Graphics2DDeviceContext> g2d(new Graphics2DDeviceContext(this));
@@ -620,6 +669,76 @@
NPError WebPluginDelegatePepper::Device3DInitializeContext(
const NPDeviceContext3DConfig* config,
NPDeviceContext3D* context) {
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+#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(
+ "application/vnd.google.chrome.gpu-plugin", 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)) {
+ plugin_->SetAcceptsInputEvents(true);
+
+ // Ensure the window has the correct size before initializing the
+ // command buffer.
+ nested_delegate_->UpdateGeometry(window_rect_, clip_rect_);
+
+ // Ask the GPU plugin to create a command buffer and return a proxy.
+ command_buffer_ = nested_delegate_->CreateCommandBuffer();
+ if (command_buffer_) {
+ // Initialize the proxy command buffer.
+ if (command_buffer_->Initialize(config->commandBufferSize)) {
+ // Get the initial command buffer state.
+ gpu::CommandBuffer::State state = command_buffer_->GetState();
+
+ // Initialize the 3D context.
+ context->reserved = NULL;
+ context->waitForProgress = true;
+ Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ context->commandBuffer = ring_buffer.ptr;
+ context->commandBufferSize = state.num_entries;
+ context->repaintCallback = NULL;
+ Synchronize3DContext(context, state);
+
+ ScheduleHandleRepaint(instance_->npp(), context);
+
+#if defined(OS_MACOSX)
+ command_buffer_->SetWindowSize(window_rect_.size());
+#endif // OS_MACOSX
+
+ // Make sure the nested delegate shows up in the right place
+ // on the page.
+ SendNestedDelegateGeometryToBrowser(window_rect_, clip_rect_);
+
+ // Save the implementation information (the CommandBuffer).
+ Device3DImpl* impl = new Device3DImpl;
+ impl->command_buffer = command_buffer_;
+ impl->dynamically_created = false;
+ context->reserved = impl;
+
+ return NPERR_NO_ERROR;
+ }
+
+ nested_delegate_->DestroyCommandBuffer(command_buffer_);
+ command_buffer_ = NULL;
+ }
+ }
+
+ nested_delegate_->PluginDestroyed();
+ nested_delegate_ = NULL;
+#endif // ENABLE_GPU
+
return NPERR_GENERIC_ERROR;
}
@@ -642,49 +761,212 @@
NPDeviceContext3D* context,
NPDeviceFlushContextCallbackPtr callback,
void* user_data) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+#if defined(ENABLE_GPU)
+ gpu::CommandBuffer::State state;
+
+ if (context->waitForProgress) {
+ if (callback) {
+ command_buffer_->AsyncFlush(
+ context->putOffset,
+ method_factory3d_.NewRunnableMethod(
+ &WebPluginDelegatePepper::Device3DUpdateState,
+ id,
+ context,
+ callback,
+ user_data));
+ } else {
+ state = command_buffer_->FlushSync(context->putOffset);
+ Synchronize3DContext(context, state);
+ }
+ } else {
+ if (callback) {
+ command_buffer_->AsyncGetState(
+ method_factory3d_.NewRunnableMethod(
+ &WebPluginDelegatePepper::Device3DUpdateState,
+ id,
+ context,
+ callback,
+ user_data));
+ } else {
+ state = command_buffer_->GetState();
+ Synchronize3DContext(context, state);
+ }
+ }
+#endif // ENABLE_GPU
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DDestroyContext(
NPDeviceContext3D* context) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+#if defined(ENABLE_GPU)
+ // Prevent any async flush callbacks from being invoked after the context
+ // has been destroyed.
+ method_factory3d_.RevokeAll();
+
+ // TODO(apatrick): this will be much simpler when we switch to the new device
+ // API. There should be no need for the Device3DImpl and the context will
+ // always be destroyed dynamically.
+ Device3DImpl* impl = static_cast<Device3DImpl*>(context->reserved);
+ bool dynamically_created = impl->dynamically_created;
+ delete impl;
+ context->reserved = NULL;
+ if (dynamically_created) {
+ delete context;
+ }
+
+ if (nested_delegate_) {
+ if (command_buffer_) {
+ nested_delegate_->DestroyCommandBuffer(command_buffer_);
+ command_buffer_ = NULL;
+ }
+
+ nested_delegate_->PluginDestroyed();
+ nested_delegate_ = NULL;
+ }
+#endif // ENABLE_GPU
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DCreateBuffer(
NPDeviceContext3D* context,
size_t size,
int32* id) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+#if defined(ENABLE_GPU)
+ *id = command_buffer_->CreateTransferBuffer(size);
+ if (*id < 0)
+ return NPERR_GENERIC_ERROR;
+#endif // ENABLE_GPU
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DDestroyBuffer(
NPDeviceContext3D* context,
int32 id) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+#if defined(ENABLE_GPU)
+ command_buffer_->DestroyTransferBuffer(id);
+#endif // ENABLE_GPU
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DMapBuffer(
NPDeviceContext3D* context,
int32 id,
NPDeviceBuffer* np_buffer) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+#if defined(ENABLE_GPU)
+ Buffer gpu_buffer;
+ if (id == NP3DCommandBufferId) {
+ gpu_buffer = command_buffer_->GetRingBuffer();
+ } else {
+ 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;
}
NPError WebPluginDelegatePepper::Device3DGetNumConfigs(int32* num_configs) {
- return NPERR_GENERIC_ERROR;
+ if (!num_configs)
+ return NPERR_GENERIC_ERROR;
+
+ *num_configs = 1;
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DGetConfigAttribs(
int32 config,
int32* attrib_list) {
- return NPERR_GENERIC_ERROR;
+ // Only one config available currently.
+ if (config != 0)
+ return NPERR_GENERIC_ERROR;
+
+ if (attrib_list) {
+ for (int32* attrib_pair = attrib_list; *attrib_pair; attrib_pair += 2) {
+ switch (attrib_pair[0]) {
+ case NP3DAttrib_BufferSize:
+ attrib_pair[1] = 32;
+ break;
+ case NP3DAttrib_AlphaSize:
+ case NP3DAttrib_BlueSize:
+ case NP3DAttrib_GreenSize:
+ case NP3DAttrib_RedSize:
+ attrib_pair[1] = 8;
+ break;
+ case NP3DAttrib_DepthSize:
+ attrib_pair[1] = 24;
+ break;
+ case NP3DAttrib_StencilSize:
+ attrib_pair[1] = 8;
+ break;
+ case NP3DAttrib_SurfaceType:
+ attrib_pair[1] = 0;
+ break;
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DCreateContext(
int32 config,
const int32* attrib_list,
NPDeviceContext3D** context) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+ // Only one config available currently.
+ if (config != 0)
+ return NPERR_GENERIC_ERROR;
+
+ // For now, just use the old API to initialize the context.
+ NPDeviceContext3DConfig old_config;
+ old_config.commandBufferSize = kDefaultCommandBufferSize;
+ if (attrib_list) {
+ for (const int32* attrib_pair = attrib_list; *attrib_pair;
+ attrib_pair += 2) {
+ switch (attrib_pair[0]) {
+ case NP3DAttrib_CommandBufferSize:
+ old_config.commandBufferSize = attrib_pair[1];
+ break;
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ *context = new NPDeviceContext3D;
+ Device3DInitializeContext(&old_config, *context);
+
+ // Flag the context as dynamically created by the browser. TODO(apatrick):
+ // take this out when all contexts are dynamically created.
+ Device3DImpl* impl = static_cast<Device3DImpl*>((*context)->reserved);
+ impl->dynamically_created = true;
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DRegisterCallback(
@@ -693,7 +975,19 @@
int32 callback_type,
NPDeviceGenericCallbackPtr callback,
void* callback_data) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+ switch (callback_type) {
+ case NP3DCallback_Repaint:
+ context->repaintCallback = reinterpret_cast<NPDeviceContext3DRepaintPtr>(
+ callback);
+ break;
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::Device3DSynchronizeContext(
@@ -704,7 +998,58 @@
int32* output_attrib_list,
NPDeviceSynchronizeContextCallbackPtr callback,
void* callback_data) {
- return NPERR_GENERIC_ERROR;
+ if (!context)
+ return NPERR_GENERIC_ERROR;
+
+ // Copy input attributes into context.
+ if (input_attrib_list) {
+ for (const int32* attrib_pair = input_attrib_list;
+ *attrib_pair;
+ attrib_pair += 2) {
+ switch (attrib_pair[0]) {
+ case NP3DAttrib_PutOffset:
+ context->putOffset = attrib_pair[1];
+ break;
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ // Use existing flush mechanism for now.
+ if (mode != NPDeviceSynchronizationMode_Cached) {
+ context->waitForProgress = mode == NPDeviceSynchronizationMode_Flush;
+ Device3DFlushContext(id, context, callback, callback_data);
+ }
+
+ // Copy most recent output attributes from context.
+ // To read output attributes after the completion of an asynchronous flush,
+ // invoke SynchronizeContext again with mode
+ // NPDeviceSynchronizationMode_Cached from the callback function.
+ if (output_attrib_list) {
+ for (int32* attrib_pair = output_attrib_list;
+ *attrib_pair;
+ attrib_pair += 2) {
+ switch (attrib_pair[0]) {
+ case NP3DAttrib_CommandBufferSize:
+ attrib_pair[1] = context->commandBufferSize;
+ break;
+ case NP3DAttrib_GetOffset:
+ attrib_pair[1] = context->getOffset;
+ break;
+ case NP3DAttrib_PutOffset:
+ attrib_pair[1] = context->putOffset;
+ break;
+ case NP3DAttrib_Token:
+ attrib_pair[1] = context->token;
+ break;
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ return NPERR_NO_ERROR;
}
NPError WebPluginDelegatePepper::DeviceAudioQueryCapability(int32 capability,
@@ -1038,11 +1383,16 @@
: render_view_(render_view),
plugin_(NULL),
instance_(instance),
+ nested_delegate_(NULL),
current_printer_dpi_(-1),
#if defined (OS_LINUX)
num_pages_(0),
pdf_output_done_(false),
#endif // (OS_LINUX)
+#if defined(ENABLE_GPU)
+ command_buffer_(NULL),
+ method_factory3d_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+#endif
find_identifier_(-1),
current_choose_file_callback_(NULL),
current_choose_file_user_data_(NULL) {
@@ -1080,16 +1430,21 @@
void WebPluginDelegatePepper::Paint(WebKit::WebCanvas* canvas,
const gfx::Rect& rect) {
- // Blit from background_context to context.
- if (!committed_bitmap_.isNull()) {
+ 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()) {
#if defined(OS_MACOSX)
- DrawSkBitmapToCanvas(committed_bitmap_, canvas, window_rect_,
- static_cast<int>(CGBitmapContextGetHeight(canvas)));
+ DrawSkBitmapToCanvas(committed_bitmap_, canvas, window_rect_,
+ static_cast<int>(CGBitmapContextGetHeight(canvas)));
#else
- canvas->drawBitmap(committed_bitmap_,
- SkIntToScalar(window_rect_.origin().x()),
- SkIntToScalar(window_rect_.origin().y()));
+ canvas->drawBitmap(committed_bitmap_,
+ SkIntToScalar(window_rect_.origin().x()),
+ SkIntToScalar(window_rect_.origin().y()));
#endif
+ }
}
}
@@ -1229,6 +1584,70 @@
return rv;
}
+#if defined(ENABLE_GPU)
+
+void WebPluginDelegatePepper::ScheduleHandleRepaint(
+ NPP npp, NPDeviceContext3D* context) {
+ command_buffer_->SetNotifyRepaintTask(method_factory3d_.NewRunnableMethod(
+ &WebPluginDelegatePepper::ForwardHandleRepaint,
+ npp,
+ context));
+}
+
+void WebPluginDelegatePepper::ForwardHandleRepaint(
+ NPP npp, NPDeviceContext3D* context) {
+ if (context->repaintCallback)
+ context->repaintCallback(npp, context);
+ ScheduleHandleRepaint(npp, context);
+}
+
+void WebPluginDelegatePepper::Synchronize3DContext(
+ NPDeviceContext3D* context,
+ const gpu::CommandBuffer::State& state) {
+ context->getOffset = state.get_offset;
+ context->putOffset = state.put_offset;
+ context->token = state.token;
+ context->error = static_cast<NPDeviceContext3DError>(state.error);
+}
+
+void WebPluginDelegatePepper::Device3DUpdateState(
+ NPP npp,
+ NPDeviceContext3D* context,
+ NPDeviceFlushContextCallbackPtr callback,
+ void* user_data) {
+ if (command_buffer_) {
+ Synchronize3DContext(context, command_buffer_->GetLastState());
+ if (callback)
+ callback(npp, context, NPERR_NO_ERROR, user_data);
+ }
+}
+
+#endif // ENABLE_GPU
+
+void WebPluginDelegatePepper::SendNestedDelegateGeometryToBrowser(
+ const gfx::Rect& window_rect,
+ const gfx::Rect& clip_rect) {
+ // Inform the browser about the location of the plugin on the page.
+ // It appears that initially the plugin does not get laid out correctly --
+ // possibly due to lazy creation of the nested delegate.
+ if (!nested_delegate_ ||
+ !nested_delegate_->GetPluginWindowHandle() ||
+ !render_view_) {
+ return;
+ }
+
+ webkit::npapi::WebPluginGeometry geom;
+ geom.window = nested_delegate_->GetPluginWindowHandle();
+ geom.window_rect = window_rect;
+ geom.clip_rect = clip_rect;
+ // Rects_valid must be true for this to work in the Gtk port;
+ // hopefully not having the cutout rects will not cause incorrect
+ // clipping.
+ geom.rects_valid = true;
+ geom.visible = true;
+ render_view_->DidMovePlugin(geom);
+}
+
bool WebPluginDelegatePepper::CalculatePrintedPageDimensions(
int page_number,
NPPPrintExtensions* print_extensions,
« no previous file with comments | « chrome/renderer/webplugin_delegate_pepper.h ('k') | chrome/renderer/webplugin_delegate_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698