summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-16 22:40:37 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-16 22:40:37 +0000
commit9821d0de8b140ce1cd1917260afad5f803b43ed1 (patch)
tree748eb7558cd58a8591c1ba92b30a4ddf9605580d
parent8549f5e3dd6e920fd7c72a44ba3d89b15cc03e41 (diff)
downloadchromium_src-9821d0de8b140ce1cd1917260afad5f803b43ed1.zip
chromium_src-9821d0de8b140ce1cd1917260afad5f803b43ed1.tar.gz
chromium_src-9821d0de8b140ce1cd1917260afad5f803b43ed1.tar.bz2
New experimental Pepper device API.
- makes device contexts opaque to the plugin - can get / set multiple attributes and flush with a single call (and underlying IPC message exchange) - currently works in parallel with old API - adapted pepper test plugin to use new API if use_new_npdevice_api=1 TEST=trybots, visual confirmation that pepper test plugin works with new API BUG=none Review URL: http://codereview.chromium.org/1529005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44840 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/common.gypi10
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc187
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h20
-rw-r--r--gpu/pgl/command_buffer_pepper.cc85
-rw-r--r--gpu/pgl/command_buffer_pepper.h2
-rw-r--r--gpu/pgl/pgl.cc10
-rw-r--r--third_party/npapi/bindings/npapi_extensions.h218
-rw-r--r--webkit/glue/plugins/npapi_extension_thunk.cc115
-rw-r--r--webkit/glue/plugins/webplugin_3d_device_delegate.h30
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc35
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h4
11 files changed, 702 insertions, 14 deletions
diff --git a/build/common.gypi b/build/common.gypi
index 19de56c..ca1bc7f 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -229,6 +229,9 @@
# arm_neon==0).
'arm_fpu%': 'vfpv3',
+ # Enable new NPDevice API.
+ 'enable_new_npdevice_api%': 0,
+
'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
# This will set gcc_version to XY if you are running gcc X.Y.*.
@@ -1239,6 +1242,13 @@
},
},
}],
+ ['enable_new_npdevice_api==1', {
+ 'target_defaults': {
+ 'defines': [
+ 'ENABLE_NEW_NPDEVICE_API',
+ ],
+ },
+ }],
],
'scons_settings': {
'sconsbuild_dir': '<(DEPTH)/sconsbuild',
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 9d8d651..753844d 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -74,8 +74,11 @@ struct Device2DImpl {
struct Device3DImpl {
gpu::CommandBuffer* command_buffer;
+ bool dynamically_created;
};
+const int32 kDefaultCommandBufferSize = 1024 * 1024;
+
#if defined(OS_WIN)
struct ScrollbarThemeMapping {
NPThemeItem item;
@@ -730,6 +733,7 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
// 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;
@@ -814,8 +818,16 @@ NPError WebPluginDelegatePepper::Device3DDestroyContext(
// has been destroyed.
method_factory3d_.RevokeAll();
- delete static_cast<Device3DImpl*>(context->reserved);
+ // 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_) {
@@ -867,7 +879,13 @@ NPError WebPluginDelegatePepper::Device3DMapBuffer(
return NPERR_GENERIC_ERROR;
#if defined(ENABLE_GPU)
- Buffer gpu_buffer = command_buffer_->GetTransferBuffer(id);
+ 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)
@@ -877,6 +895,171 @@ NPError WebPluginDelegatePepper::Device3DMapBuffer(
return NPERR_NO_ERROR;
}
+NPError WebPluginDelegatePepper::Device3DGetNumConfigs(int32* num_configs) {
+ if (!num_configs)
+ return NPERR_GENERIC_ERROR;
+
+ *num_configs = 1;
+ return NPERR_NO_ERROR;
+}
+
+NPError WebPluginDelegatePepper::Device3DGetConfigAttribs(
+ int32 config,
+ int32* attrib_list) {
+ // 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,
+ int32* attrib_list,
+ NPDeviceContext3D** context) {
+ 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 (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(
+ NPP id,
+ NPDeviceContext3D* context,
+ int32 callback_type,
+ NPDeviceGenericCallbackPtr callback,
+ void* callback_data) {
+ 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(
+ NPP id,
+ NPDeviceContext3D* context,
+ NPDeviceSynchronizationMode mode,
+ const int32* input_attrib_list,
+ int32* output_attrib_list,
+ NPDeviceSynchronizeContextCallbackPtr callback,
+ void* callback_data) {
+ 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,
int32* value) {
// TODO(neb,cpu) implement QueryCapability
diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h
index 543c4b9..70a113a 100644
--- a/chrome/renderer/webplugin_delegate_pepper.h
+++ b/chrome/renderer/webplugin_delegate_pepper.h
@@ -144,6 +144,26 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate,
virtual NPError Device3DMapBuffer(NPDeviceContext3D* context,
int32 id,
NPDeviceBuffer* buffer);
+ virtual NPError Device3DGetNumConfigs(int32* num_configs);
+ virtual NPError Device3DGetConfigAttribs(int32 config,
+ int32* attrib_list);
+ virtual NPError Device3DCreateContext(int32 config,
+ int32* attrib_list,
+ NPDeviceContext3D** context);
+ virtual NPError Device3DRegisterCallback(
+ NPP id,
+ NPDeviceContext3D* context,
+ int32 callback_type,
+ NPDeviceGenericCallbackPtr callback,
+ void* callback_data);
+ virtual NPError Device3DSynchronizeContext(
+ NPP id,
+ NPDeviceContext3D* context,
+ NPDeviceSynchronizationMode mode,
+ const int32* input_attrib_list,
+ int32* output_attrib_list,
+ NPDeviceSynchronizeContextCallbackPtr callback,
+ void* callback_data);
// WebPluginAudioDeviceDelegate implementation.
virtual NPError DeviceAudioQueryCapability(int32 capability, int32* value);
diff --git a/gpu/pgl/command_buffer_pepper.cc b/gpu/pgl/command_buffer_pepper.cc
index f3f0aff..4a94b9c 100644
--- a/gpu/pgl/command_buffer_pepper.cc
+++ b/gpu/pgl/command_buffer_pepper.cc
@@ -35,12 +35,49 @@ bool CommandBufferPepper::Initialize(int32 size) {
Buffer CommandBufferPepper::GetRingBuffer() {
Buffer buffer;
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ NPDeviceBuffer np_buffer;
+ device_->mapBuffer(npp_,
+ context_,
+ NP3DCommandBufferId,
+ &np_buffer);
+ buffer.ptr = np_buffer.ptr;
+ buffer.size = np_buffer.size;
+#else
buffer.ptr = context_->commandBuffer;
buffer.size = context_->commandBufferSize * sizeof(int32);
+#endif
return buffer;
}
CommandBuffer::State CommandBufferPepper::GetState() {
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ int32 output_attribs[] = {
+ NP3DAttrib_CommandBufferSize, 0,
+ NP3DAttrib_GetOffset, 0,
+ NP3DAttrib_PutOffset, 0,
+ NP3DAttrib_Token, 0,
+ NPAttrib_Error, 0,
+ NPAttrib_End
+ };
+ device_->synchronizeContext(npp_,
+ context_,
+ NPDeviceSynchronizationMode_Immediate,
+ NULL,
+ output_attribs,
+ NULL,
+ NULL);
+
+ CommandBuffer::State state;
+ state.size = output_attribs[1];
+ state.get_offset = output_attribs[3];
+ state.put_offset = output_attribs[5];
+ state.token = output_attribs[7];
+ state.error = static_cast<gpu::error::Error>(
+ output_attribs[9]);
+
+ return state;
+#else
context_->waitForProgress = false;
if (NPERR_NO_ERROR != device_->flushContext(npp_, context_, NULL, NULL))
@@ -49,9 +86,41 @@ CommandBuffer::State CommandBufferPepper::GetState() {
context_->waitForProgress = true;
return ConvertState();
+#endif // ENABLE_NEW_NPDEVICE_API
}
CommandBuffer::State CommandBufferPepper::Flush(int32 put_offset) {
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ int32 input_attribs[] = {
+ NP3DAttrib_PutOffset, put_offset,
+ NPAttrib_End
+ };
+ int32 output_attribs[] = {
+ NP3DAttrib_CommandBufferSize, 0,
+ NP3DAttrib_GetOffset, 0,
+ NP3DAttrib_PutOffset, 0,
+ NP3DAttrib_Token, 0,
+ NPAttrib_Error, 0,
+ NPAttrib_End
+ };
+ device_->synchronizeContext(npp_,
+ context_,
+ NPDeviceSynchronizationMode_Flush,
+ input_attribs,
+ output_attribs,
+ NULL,
+ NULL);
+
+ CommandBuffer::State state;
+ state.size = output_attribs[1];
+ state.get_offset = output_attribs[3];
+ state.put_offset = output_attribs[5];
+ state.token = output_attribs[7];
+ state.error = static_cast<gpu::error::Error>(
+ output_attribs[9]);
+
+ return state;
+#else
context_->waitForProgress = true;
context_->putOffset = put_offset;
@@ -59,6 +128,7 @@ CommandBuffer::State CommandBufferPepper::Flush(int32 put_offset) {
context_->error = NPDeviceContext3DError_GenericError;
return ConvertState();
+#endif // ENABLE_NEW_NPDEVICE_API
}
void CommandBufferPepper::SetGetOffset(int32 get_offset) {
@@ -100,6 +170,21 @@ void CommandBufferPepper::SetParseError(
NOTREACHED();
}
+gpu::error::Error CommandBufferPepper::GetCachedError() {
+ int32 attrib_list[] = {
+ NPAttrib_Error, 0,
+ NPAttrib_End
+ };
+ device_->synchronizeContext(npp_,
+ context_,
+ NPDeviceSynchronizationMode_Cached,
+ NULL,
+ attrib_list,
+ NULL,
+ NULL);
+ return static_cast<gpu::error::Error>(attrib_list[1]);
+}
+
CommandBuffer::State CommandBufferPepper::ConvertState() {
CommandBuffer::State state;
state.size = context_->commandBufferSize;
diff --git a/gpu/pgl/command_buffer_pepper.h b/gpu/pgl/command_buffer_pepper.h
index e75d7bf..5d11d98 100644
--- a/gpu/pgl/command_buffer_pepper.h
+++ b/gpu/pgl/command_buffer_pepper.h
@@ -37,6 +37,8 @@ class CommandBufferPepper : public gpu::CommandBuffer {
virtual void SetToken(int32 token);
virtual void SetParseError(gpu::error::Error error);
+ gpu::error::Error GetCachedError();
+
private:
CommandBuffer::State ConvertState();
diff --git a/gpu/pgl/pgl.cc b/gpu/pgl/pgl.cc
index 59c2635..cf32e6a 100644
--- a/gpu/pgl/pgl.cc
+++ b/gpu/pgl/pgl.cc
@@ -123,8 +123,13 @@ PGLBoolean PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) {
// TODO(apatrick): I'm not sure if this should actually change the
// current context if it fails. For now it gets changed even if it fails
// becuase making GL calls with a NULL context crashes.
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ if (pgl_context->command_buffer_->GetCachedError() != gpu::error::kNoError)
+ return PGL_FALSE;
+#else
if (pgl_context->device_context_->error != NPDeviceContext3DError_NoError)
return PGL_FALSE;
+#endif
}
else {
gles2::SetGLContext(NULL);
@@ -136,8 +141,13 @@ PGLBoolean PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) {
PGLBoolean PGLContextImpl::SwapBuffers() {
// Don't request latest error status from service. Just use the locally cached
// information from the last flush.
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ if (command_buffer_->GetCachedError() != gpu::error::kNoError)
+ return PGL_FALSE;
+#else
if (device_context_->error != NPDeviceContext3DError_NoError)
return PGL_FALSE;
+#endif
gles2_implementation_->SwapBuffers();
return PGL_TRUE;
diff --git a/third_party/npapi/bindings/npapi_extensions.h b/third_party/npapi/bindings/npapi_extensions.h
index ba231dc..940a7b5 100644
--- a/third_party/npapi/bindings/npapi_extensions.h
+++ b/third_party/npapi/bindings/npapi_extensions.h
@@ -157,6 +157,140 @@ typedef struct NPNExtensions NPNExtensions;
// PLEASE REMOVE THIS WHEN THE NACL CODE IS UPDATED.
typedef struct NPNExtensions NPExtensions;
+
+/* New experimental device API. */
+
+/* Mode for calls to NPDeviceSynchronizeContext. */
+typedef enum {
+ /* Get or set locally cached state without synchronizing or communicating */
+ /* with the service process (or thread). */
+ NPDeviceSynchronizationMode_Cached,
+
+ /* Exchanges state with service process (or thread). Does not wait for any */
+ /* progress before returning. */
+ NPDeviceSynchronizationMode_Immediate,
+
+ /* Exchanges state with service process (or thread). Blocks caller until */
+ /* further progress can be made. */
+ NPDeviceSynchronizationMode_Flush
+} NPDeviceSynchronizationMode;
+
+/* Get the number of configs supported by a given device. */
+typedef NPError (*NPDeviceGetNumConfigsPtr)(NPP instance,
+ int32* numConfigs);
+
+/* Get attribute values from a config. NPDeviceGetConfigs might return */
+/* multiple configs. This function can be used to examine them to */
+/* find the most suitable. For example, NPDeviceGetConfigs might return one */
+/* config with antialiasing enabled and one without. This can be determined */
+/* using this function. */
+/* Inputs: */
+/* config: The config index to extract the attributes from. */
+/* attribList: Array of input config attribute / value pairs */
+/* terminated with NPAttrib_End. */
+/* Outputs: */
+/* attribList: The values paired up with each attribute are filled in */
+/* on return. */
+typedef NPError (*NPDeviceGetConfigAttribsPtr)(NPP instance,
+ int32 config,
+ int32* attribList);
+
+/* Create a device context based on a particular device configuration and a */
+/* list config input attributes. */
+/* Inputs: */
+/* config: The device configuration to use. */
+/* attribList: NULL or an array of context specific attribute / value */
+/* pairs terminated with NPAttrib_End. */
+/* Outputs: */
+/* context: The created context. */
+typedef NPError (*NPDeviceCreateContextPtr)(NPP instance,
+ int32 config,
+ const int32* attribList,
+ NPDeviceContext** context);
+
+/* Destroy a context. */
+/* Inputs: */
+/* context: The context to destroy. */
+/*typedef NPError (*NPDestroyContext)(NPP instance, */
+/* NPDeviceContext* context); */
+
+/* This type should be cast to the type associated with the particular */
+/* callback type */
+typedef void (*NPDeviceGenericCallbackPtr)(void);
+
+/* Register a callback with a context. Callbacks are never invoked after the */
+/* associated context has been destroyed. The semantics of the particular */
+/* callback type determine which thread the callback is invoked on. It might */
+/* be the plugin thread, the thread RegisterCallback is invoked on or a */
+/* special thread created for servicing callbacks, such as an audio thread */
+/* Inputs: */
+/* callbackType: The device specific callback type */
+/* callback: The callback to invoke. The signature varies by type. Use */
+/* NULL to unregister the callback for a particular type. */
+/* callbackData: A value that is passed to the callback function. Other */
+/* callback arguments vary by type. */
+typedef NPError (*NPDeviceRegisterCallbackPtr)(
+ NPP instance,
+ NPDeviceContext* context,
+ int32 callbackType,
+ NPDeviceGenericCallbackPtr callback,
+ void* callbackData);
+
+/* Callback for NPDeviceSynchronizeContext. */
+/* Inputs: */
+/* instance: The associated plugin instance. */
+/* context: The context that was flushed. */
+/* error: Indicates success of flush operation. */
+/* data: The completion callback data that was passed to */
+/* NPDeviceSynchronizeContext. */
+typedef void (*NPDeviceSynchronizeContextCallbackPtr)(
+ NPP instance,
+ NPDeviceContext* context,
+ NPError error,
+ void* data);
+
+/* Synchronize the state of a device context. Takes lists of input and output */
+/* attributes. Generally, the input attributes are copied into the context */
+/* and the output attributes are filled in the state of the context either */
+/* after (before) the synchronization depending on whether it is synchronous */
+/* (asynchronous). The get the state of the context after an asynchronous */
+/* synchronization, call this function a second time with Cached mode after */
+/* the callback has been invoked. */
+/* Inputs: */
+/* context: The context to synchronize. */
+/* mode: The type of synchronization to perform. */
+/* inputAttribList: NULL or an array of input synchronization attribute / */
+/* value pairs terminated with NPAttrib_End. */
+/* outputAttribList: NULL or an array of output synchronization */
+/* attributes / uninitialized value pairs terminated */
+/* with NPAttrib_End. */
+/* callback: NULL for synchronous operation or completion callback function */
+/* for asynchronous operation. */
+/* callbackData: Argument passed to callback function. */
+/* Outputs: */
+/* outputAttribList: The values paired up with each attribute are filled */
+/* in on return for synchronous operation. */
+typedef NPError (*NPDeviceSynchronizeContextPtr)(
+ NPP instance,
+ NPDeviceContext* context,
+ NPDeviceSynchronizationMode mode,
+ const int32* inputAttribList,
+ int32* outputAttribList,
+ NPDeviceSynchronizeContextCallbackPtr callback,
+ void* callbackData);
+
+/* All attributes shared between devices, with the exception of */
+/* NPDeviceContextAttrib_End, have bit 31 set. Device specific attributes */
+/* have the bit clear. */
+enum {
+ /* Used to terminate arrays of attribute / value pairs. */
+ NPAttrib_End = 0,
+
+ /* Error status of context. Non-zero means error. Shared by all devices, */
+ /* though error values are device specific. */
+ NPAttrib_Error = 0x80000000,
+};
+
/* generic device interface */
struct NPDevice {
NPDeviceQueryCapabilityPtr queryCapability;
@@ -171,6 +305,17 @@ struct NPDevice {
NPDeviceMapBufferPtr mapBuffer;
NPDeviceThemeGetSize themeGetSize;
NPDeviceThemePaint themePaint;
+
+ /* Experimental device API */
+ NPDeviceGetNumConfigsPtr getNumConfigs;
+ NPDeviceGetConfigAttribsPtr getConfigAttribs;
+ NPDeviceCreateContextPtr createContext;
+/* NPDeviceDestroyContextPtr destroyContext; */
+ NPDeviceRegisterCallbackPtr registerCallback;
+ NPDeviceSynchronizeContextPtr synchronizeContext;
+/* NPDeviceCreateBufferPtr createBuffer; */
+/* NPDeviceDestroyBufferPtr destroyBuffer; */
+/* NPDeviceMapBufferPtr mapBuffer; */
};
/* returns NULL if deviceID unavailable / unrecognized */
@@ -441,6 +586,8 @@ typedef struct _NPDeviceContext3D NPDeviceContext3D;
typedef void (*NPDeviceContext3DRepaintPtr)(NPP npp,
NPDeviceContext3D* context);
+// TODO(apatrick): this need not be exposed when we switch over to the new
+// device API. It's layout can also be implementation dependent.
typedef struct _NPDeviceContext3D
{
void* reserved;
@@ -477,6 +624,77 @@ typedef struct _NPDeviceContext3D
NPDeviceContext3DError error;
} NPDeviceContext3D;
+
+/* Begin 3D specific portion of experimental device API */
+
+/* Device buffer ID reserved for command buffer */
+enum {
+ NP3DCommandBufferId = 0
+};
+
+/* 3D attributes */
+enum {
+ /* Example GetConfigAttribs attributes. See EGL 1.4 spec. */
+ /* These may be passed to GetConfigAttribs. */
+ NP3DAttrib_BufferSize = 0x3020,
+ NP3DAttrib_AlphaSize = 0x3021,
+ NP3DAttrib_BlueSize = 0x3022,
+ NP3DAttrib_GreenSize = 0x3023,
+ NP3DAttrib_RedSize = 0x3024,
+ NP3DAttrib_DepthSize = 0x3025,
+ NP3DAttrib_StencilSize = 0x3026,
+ NP3DAttrib_SurfaceType = 0x3033,
+
+ /* Example CreateContext attributes. See EGL 1.4 spec. */
+ /* These may be passed to CreateContext. */
+ NP3DAttrib_SwapBehavior = 0x3093,
+ NP3DAttrib_MultisampleResolve = 0x3099,
+
+ /* Size of command buffer in 32-bit entries. */
+ /* This may be passed to CreateContext as an input or SynchronizeContext as */
+ /* an output. */
+ NP3DAttrib_CommandBufferSize = 0x10000000,
+
+ /* These may be passed to SynchronizeContext. */
+
+ /* Offset in command buffer writer has reached. In / out.*/
+ NP3DAttrib_PutOffset,
+
+ /* Offset in command buffer reader has reached. Out only. */
+ NP3DAttrib_GetOffset,
+
+ /* Last processed token. Out only. */
+ NP3DAttrib_Token,
+};
+
+/* 3D callbacks */
+enum {
+ /* This callback is invoked whenever the plugin must repaint everything. */
+ /* This might be because the window manager must repaint a window or */
+ /* the context has been lost, for example a power management event. */
+ NP3DCallback_Repaint = 1
+};
+
+/* Flags for NPConfig3DOutAttrib_SurfaceType */
+enum {
+ NP3DSurfaceType_MultisampleResolveBox = 0x0200,
+ NP3DSurfaceType_SwapBehaviorPreserved = 0x0400
+};
+
+/* Values for NPConfig3DInAttrib_SwapBehavior */
+enum {
+ NP3DSwapBehavior_Preserved = 0x3094,
+ NP3DSwapBehavior_Destroyed = 0x3095
+};
+
+/* Values for NPConfig3DInAttrib_MultisampleResolve */
+enum {
+ NP3DMultisampleResolve_Default = 0x309A,
+ NP3DMultisampleResolve_Box = 0x309B,
+};
+
+/* End 3D specific API */
+
/* Audio --------------------------------------------------------------------*/
#define NPPepperAudioDevice 3
diff --git a/webkit/glue/plugins/npapi_extension_thunk.cc b/webkit/glue/plugins/npapi_extension_thunk.cc
index 141d960..100beef 100644
--- a/webkit/glue/plugins/npapi_extension_thunk.cc
+++ b/webkit/glue/plugins/npapi_extension_thunk.cc
@@ -277,6 +277,82 @@ static NPError Device3DMapBuffer(NPP id,
return NPERR_GENERIC_ERROR;
}
+// Experimental 3D device API --------------------------------------------------
+
+static NPError Device3DGetNumConfigs(NPP id, int32* num_configs) {
+ scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
+ if (plugin) {
+ return plugin->webplugin()->delegate()->Device3DGetNumConfigs(num_configs);
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+static NPError Device3DGetConfigAttribs(NPP id,
+ int32 config,
+ int32* attrib_list) {
+ scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
+ if (plugin) {
+ return plugin->webplugin()->delegate()->Device3DGetConfigAttribs(
+ config,
+ attrib_list);
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+static NPError Device3DCreateContext(NPP id,
+ int32 config,
+ const int32* attrib_list,
+ NPDeviceContext** context) {
+ scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
+ if (plugin) {
+ return plugin->webplugin()->delegate()->Device3DCreateContext(
+ config,
+ attrib_list,
+ reinterpret_cast<NPDeviceContext3D**>(context));
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+static NPError Device3DSynchronizeContext(
+ NPP id,
+ NPDeviceContext* context,
+ NPDeviceSynchronizationMode mode,
+ const int32* input_attrib_list,
+ int32* output_attrib_list,
+ NPDeviceSynchronizeContextCallbackPtr callback,
+ void* callback_data) {
+ scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
+ if (plugin) {
+ return plugin->webplugin()->delegate()->Device3DSynchronizeContext(
+ id,
+ static_cast<NPDeviceContext3D*>(context),
+ mode,
+ input_attrib_list,
+ output_attrib_list,
+ callback,
+ callback_data);
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
+static NPError Device3DRegisterCallback(
+ NPP id,
+ NPDeviceContext* context,
+ int32 callback_type,
+ NPDeviceGenericCallbackPtr callback,
+ void* callback_data) {
+ scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
+ if (plugin) {
+ return plugin->webplugin()->delegate()->Device3DRegisterCallback(
+ id,
+ static_cast<NPDeviceContext3D*>(context),
+ callback_type,
+ callback,
+ callback_data);
+ }
+ return NPERR_GENERIC_ERROR;
+}
+
// Audio device API ------------------------------------------------------------
static NPError DeviceAudioQueryCapability(NPP id, int32 capability,
@@ -367,6 +443,11 @@ static NPDevice* AcquireDevice(NPP id, NPDeviceID device_id) {
Device2DMapBuffer,
Device2DThemeGetSize,
Device2DThemePaint,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
};
static NPDevice device_3d = {
Device3DQueryCapability,
@@ -381,20 +462,30 @@ static NPDevice* AcquireDevice(NPP id, NPDeviceID device_id) {
Device3DMapBuffer,
NULL,
NULL,
+ Device3DGetNumConfigs,
+ Device3DGetConfigAttribs,
+ Device3DCreateContext,
+ Device3DRegisterCallback,
+ Device3DSynchronizeContext,
};
static NPDevice device_audio = {
- DeviceAudioQueryCapability,
- DeviceAudioQueryConfig,
- DeviceAudioInitializeContext,
- DeviceAudioSetStateContext,
- DeviceAudioGetStateContext,
- DeviceAudioFlushContext,
- DeviceAudioDestroyContext,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
+ DeviceAudioQueryCapability,
+ DeviceAudioQueryConfig,
+ DeviceAudioInitializeContext,
+ DeviceAudioSetStateContext,
+ DeviceAudioGetStateContext,
+ DeviceAudioFlushContext,
+ DeviceAudioDestroyContext,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
};
switch (device_id) {
diff --git a/webkit/glue/plugins/webplugin_3d_device_delegate.h b/webkit/glue/plugins/webplugin_3d_device_delegate.h
index c2c98f3..fbb46eb 100644
--- a/webkit/glue/plugins/webplugin_3d_device_delegate.h
+++ b/webkit/glue/plugins/webplugin_3d_device_delegate.h
@@ -60,6 +60,36 @@ class WebPlugin3DDeviceDelegate {
NPDeviceBuffer* buffer) {
return NPERR_GENERIC_ERROR;
}
+ virtual NPError Device3DGetNumConfigs(int32* num_configs) {
+ return NPERR_GENERIC_ERROR;
+ }
+ virtual NPError Device3DGetConfigAttribs(int32 config,
+ int32* attrib_list) {
+ return NPERR_GENERIC_ERROR;
+ }
+ virtual NPError Device3DCreateContext(int32 config,
+ const int32* attrib_list,
+ NPDeviceContext3D** context) {
+ return NPERR_GENERIC_ERROR;
+ }
+ virtual NPError Device3DRegisterCallback(
+ NPP id,
+ NPDeviceContext* context,
+ int32 callback_type,
+ NPDeviceGenericCallbackPtr callback,
+ void* callback_data) {
+ return NPERR_GENERIC_ERROR;
+ }
+ virtual NPError Device3DSynchronizeContext(
+ NPP id,
+ NPDeviceContext3D* context,
+ NPDeviceSynchronizationMode mode,
+ const int32* input_attrib_list,
+ int32* output_attrib_list,
+ NPDeviceSynchronizeContextCallbackPtr callback,
+ void* callback_data) {
+ return NPERR_GENERIC_ERROR;
+ }
protected:
WebPlugin3DDeviceDelegate() {}
diff --git a/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc
index d5df069..a440dc6 100644
--- a/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc
+++ b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc
@@ -14,8 +14,13 @@ Pepper3DTest::Pepper3DTest(NPP id, NPNetscapeFuncs *host_functions)
: PluginTest(id, host_functions),
pepper_extensions_(NULL),
device_3d_(NULL),
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ context_3d_(NULL),
+#endif
pgl_context_(PGL_NO_CONTEXT) {
+#if !defined(ENABLE_NEW_NPDEVICE_API)
memset(&context_3d_, 0, sizeof(context_3d_));
+#endif
esInitContext(&es_context_);
memset(&es_data_, 0, sizeof(es_data_));
@@ -70,6 +75,25 @@ void Pepper3DTest::CreateContext() {
}
// Initialize a 3D context.
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ int32 attrib_list[] = {
+ NP3DAttrib_CommandBufferSize, kCommandBufferSize,
+ NPAttrib_End
+ };
+ if (device_3d_->createContext(id(), 0, attrib_list,
+ reinterpret_cast<NPDeviceContext**>(&context_3d_)) != NPERR_NO_ERROR) {
+ SetError("Could not initialize 3D context");
+ SignalTestCompleted();
+ return;
+ }
+
+ device_3d_->registerCallback(
+ id(),
+ context_3d_,
+ NP3DCallback_Repaint,
+ reinterpret_cast<NPDeviceGenericCallbackPtr>(RepaintCallback),
+ NULL);
+#else
NPDeviceContext3DConfig config;
config.commandBufferSize = kCommandBufferSize;
if (device_3d_->initializeContext(id(), &config, &context_3d_)
@@ -79,6 +103,7 @@ void Pepper3DTest::CreateContext() {
return;
}
context_3d_.repaintCallback = RepaintCallback;
+#endif // ENABLE_NEW_NPDEVICE_API
// Initialize PGL and create a PGL context.
if (!pglInitialize()) {
@@ -86,7 +111,11 @@ void Pepper3DTest::CreateContext() {
SignalTestCompleted();
return;
}
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ pgl_context_ = pglCreateContext(id(), device_3d_, context_3d_);
+#else
pgl_context_ = pglCreateContext(id(), device_3d_, &context_3d_);
+#endif
if (pgl_context_ == PGL_NO_CONTEXT) {
SetError("Could not initialize PGL context");
SignalTestCompleted();
@@ -110,9 +139,15 @@ void Pepper3DTest::DestroyContext() {
}
pgl_context_ = PGL_NO_CONTEXT;
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ if (device_3d_->destroyContext(id(), context_3d_) != NPERR_NO_ERROR) {
+ SetError("Could not destroy 3D context");
+ }
+#else
if (device_3d_->destroyContext(id(), &context_3d_) != NPERR_NO_ERROR) {
SetError("Could not destroy 3D context");
}
+#endif
}
void Pepper3DTest::MakeContextCurrent() {
diff --git a/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h
index 20b10ed..7b3e2db 100644
--- a/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h
+++ b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h
@@ -44,7 +44,11 @@ class Pepper3DTest : public PluginTest {
NPExtensions* pepper_extensions_;
NPDevice* device_3d_;
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ NPDeviceContext3D* context_3d_;
+#else
NPDeviceContext3D context_3d_;
+#endif
PGLContext pgl_context_;
ESContext es_context_;