NPAPI:AsyncDrawing: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
Line 30: Line 30:
While the plugin has the surface set as current it is not allowed to bind it to the graphics pipeline or update it in any way.
While the plugin has the surface set as current it is not allowed to bind it to the graphics pipeline or update it in any way.


The plugin is allowed to create multiple surfaces and make them current in an alternating way, making it possible to for example double or triple buffer.
The plugin is allowed to create multiple surfaces and make them current in an alternating way, making it possible to double or triple buffer.


== Surface usage API ==
== Surface usage API ==

Revision as of 23:27, 16 September 2010

Status

Under consideration.

Contributors

  • Last modified: September 16, 2010
  • Authors: Bas Schouten (Mozilla Corporation), Josh Aas (Mozilla Corporation)
  • Contributors: Robert O'Callahan (Mozilla Corporation)

Overview

This specification allows plugins to draw asynchronously to surfaces potentially located in video memory. The specified drawing model will only be valid on Windows Vista and higher in order to simplify hardware accelerated surface sharing.

Negotiating Windows Async Drawing

For documentation on negotiating drawing models, see NPAPI:Models. The drawing model variables for Windows Async are:

  • NPDrawingModelWindowsAsync (NPDrawingModel = 555)
  • NPNVsupportsWindowsAsyncBool (NPNVariable = 556)

The Windows Async Drawing Model

In the Windows async drawing model plugins can request one or more surfaces from the host that it can draw to. The plugin can draw to these surfaces at any time, asynchronously. The plugin will tell the host which surface is current at any given time and the host will display the current plugin surface for as long as it is current. While a surface is current the plugin is not allowed to modify it.

Using Hardware Surfaces

In order to allow fast drawing to any hardware surfaces the plugins will receive a HANDLE that was acquired by the host from IDXGISurface::GetSharedHandle (http://msdn.microsoft.com/en-us/library/bb174562%28v=VS.85%29.aspx). This shared handle will represent a texture which is usable as a render target and is valid as a shader resource. The plugin can open this shared handle as a texture and then use it as a render target for any drawing operations.

While the plugin has the surface set as current it is not allowed to bind it to the graphics pipeline or update it in any way.

The plugin is allowed to create multiple surfaces and make them current in an alternating way, making it possible to double or triple buffer.

Surface usage API

The following new variable types are added:

NPNVCreateSurface (NPNVariable = 557) NPPVDestroySurface (NPNVariable = 558) NPPVCurrentSurface (NPNVariable = 559)

typedef enum {
  NPSurfaceTypeSharedHandle = 1
} NPSurfaceType;
typedef struct _NPAsyncSurface
{
  NPSurfaceType type;
  uint32_t version;
  uint32_t width;
  uint32_t height;
  NPBool opaque;
  struct {
    void *handle;
  }
} NPAsyncSurface;

The NPN_GetValueProcPtr is called with NPNVCreateSurface and it will pass a pointer to _NPAsyncSurface with the type of surface it is requesting. The width and height members of the structure passed in should be set to the desired width and height of the desired surface. Opaque can be set to true in order to tell the plugin host that all pixels on the surface should be treated as opaque regardless of the alpha value. When it returns handle will contain a HANDLE that can be used for example through OpenSharedResource (http://msdn.microsoft.com/en-us/library/bb173598%28v=VS.85%29.aspx) in order to create a texture for the user.

When the surface is ready to be displayed to the screen it will call NPN_SetValueProcPtr with NPPVCurrentSurface and the pointer to the NPAsyncSurface that is to be shown.

When the plugin is done with the surface it should release any interfaces it has pointing to that surface from its device, and call NPN_SetValueProcPtr with NPPVDestroySurface with a pointer to the NPAsyncSurface that is to be destroyed. If there the destroyed surface is current, its contents will be drawn until another surface is set current or the plugin goes away.

Usage Example

ID3D10Device *pDevice10;
// Initialize device.

NPAsyncSurface *npFrontBuffer = new NPAsyncSurface;
NPAsyncSurface *npBackBuffer = new NPAsyncSurface;
ID3D10Texture2D *frontBuffer;
ID3D10Texture2D *backBuffer;

npFrontBuffer->width = npBackBuffer->width = pluginwidth;
npFrontBuffer->height = npBackBuffer->height = pluginheight;
npFrontBuffer->opaque = npBackBuffer->opaque = 1;

NPN_GetValueProcPtr(instance, NPNVCreateSurface, npFrontBuffer);
NPN_GetValueProcPtr(instance, NPNVCreateSurface, npBackBuffer);

pDevice10->OpenSharedResource(npFrontBuffer->handle, __uuidof(ID3D10Texture2D), (void**)(&frontBuffer));
pDevice10->OpenSharedResource(npBackBuffer->handle, __uuidof(ID3D10Texture2D), (void**)(&backBuffer));

while (painting) {
  // Draw to backBuffer texture
  NPN_SetValueProcPtr(instance, NPPVCurrentSurface, npBackBuffer;
  ID3D10Texture2D *tmp = frontBuffer;
  NPAsyncSurface *npTmp = npFrontBuffer;
  frontBuffer = backBuffer;
  npFrontBuffer = npBackBuffer;
  backBuffer = tmp;
  npBackBuffer = npTmp;
}

frontBuffer->Release();
backBuffer->Release();

NPN_SetValueProcPtr(instance, NPPVDestroySurface, npFrontBuffer);
NPN_SetValueProcPtr(instance, NPPVDestroySurface, npBackBuffer);

delete npFrontBuffer;
delete npBackBuffer;