diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-16 22:40:37 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-16 22:40:37 +0000 |
commit | 9821d0de8b140ce1cd1917260afad5f803b43ed1 (patch) | |
tree | 748eb7558cd58a8591c1ba92b30a4ddf9605580d | |
parent | 8549f5e3dd6e920fd7c72a44ba3d89b15cc03e41 (diff) | |
download | chromium_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.gypi | 10 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.cc | 187 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.h | 20 | ||||
-rw-r--r-- | gpu/pgl/command_buffer_pepper.cc | 85 | ||||
-rw-r--r-- | gpu/pgl/command_buffer_pepper.h | 2 | ||||
-rw-r--r-- | gpu/pgl/pgl.cc | 10 | ||||
-rw-r--r-- | third_party/npapi/bindings/npapi_extensions.h | 218 | ||||
-rw-r--r-- | webkit/glue/plugins/npapi_extension_thunk.cc | 115 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_3d_device_delegate.h | 30 | ||||
-rw-r--r-- | webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc | 35 | ||||
-rw-r--r-- | webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h | 4 |
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_; |