NPAPI:AsyncDrawing

From MozillaWiki
Jump to navigation Jump to search

Status

Under consideration.

Contributors

  • Last modified: April 6, 2011
  • 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 that are potentially located in video memory.

Negotiating Async Drawing

For documentation on negotiating drawing models, see NPAPI:Models. This specification covers all async models, which use the same drawing mechanics with platform-specific data structures. The following models are currently specified:

  • NPDrawingModelAsyncBitmapSurface (NPDrawingModel = TBA)
  • NPDrawingModelAsyncWindowsDXGISurface (NPDrawingModel = TBA)
  • NPDrawingModelAsyncWindowsDX9ExSurface (NPDrawingModel = TBA)

Support query variables are:

  • NPNVsupportsAsyncBitmapSurfaceBool (NPNVariable = TBA)
  • NPNVsupportsAsyncWindowsDXGISurfaceBool (NPNVariable = TBA)
  • NPNVsupportsAsyncWindowsDX9ExSurfaceBool (NPNVariable = TBA)

Async Drawing Mechanics

For any async drawing model, plugins can request one or more surfaces from the host. The plugin can draw to these surfaces any more, 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. This system allows the plugin to choose whether to double or triple buffer.

Surfaces are specified via the NPAsyncSurface structure. This structure contains a pointer to a platform-specific resource of the type defined by the drawing model:

  typedef struct _NPAsyncSurface
  {
    uint32_t version;
    NPSize size;
    NPBool opaque;
    struct {
      void *handle;
    }
  } NPAsyncSurface;

New surfaces can be requested via a new function called NPN_CreateAsyncSurface:

  NPN_CreateAsyncSurface(NPP instance, NPAsyncSurface* surface);

The width and height members of the NPAsyncSurface should be set to the desired width and height of the surface. The opaque field of the NPAsyncSurface should reflect whether or not all pixels on the surface should be treated as opaque regardless of the alpha value. Upon return the handle pointer should point to a valid surface, it will be set to NULL in the failure case.

Surfaces can be destroyed via a new function called NPN_DestroyAsyncSurface:

  NPN_DestroyAsyncSurface(NPP instance, NPAsyncSurface* surface);

If the destroyed surface is current, its contents will be drawn until another surface is set current or the plugin goes away.

The currently displayed surface can be set via a new function called NPN_SetCurrentAsyncSurface:

  NPN_SetCurrentAsyncSurface(NPP instance, NPAsyncSurface* surface);

Surfaces cannot be modified while they are current.

All three functions (create, delete, set current) can be called from any thread.

NPDrawingModelAsyncBitmapSurface

This model should be available on all platforms.

The handle pointer of the NPAsyncSurface will point to an NPImageData structure.

/* "P" suffix means pre-multiplied alpha. */
typedef enum {
  NPImageFormatARGB32P   = 0x1,
  NPImageFormatARGB32    = 0x2,
  NPImageFormatRGB24     = 0x4
} NPImageFormat;

typedef struct _NPImageData
{
  uint32_t      version;
  NPImageFormat format;
  NPSize        size;
  uint32_t      stride;
  char*         data;
} NPImageData;

If an NPImageFormat is not supported then surface creation will fail.

NPDrawingModelAsyncWindowsSharedSurface

This drawing model will only be valid on Windows Vista and higher in order to simplify hardware accelerated surface sharing.

The handle pointer of the NPAsyncSurface will be a HANDLE that can be used, for example, through OpenSharedResource in order to create a texture for the user. In order to allow fast drawing to any hardware surfaces the host will acquire the handle from IDXGISurface::GetSharedHandle. 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.

This sample code illustrates usage of this drawing model:

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_CreateAsyncSurface(instance, npFrontBuffer);
NPN_CreateAsyncSurface(instance, npBackBuffer);

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

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

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

NPN_DestroyAsyncSurface(instance, npFrontBuffer);
NPN_DestroyAsyncSurface(instance, npBackBuffer);

delete npFrontBuffer;
delete npBackBuffer;

NPDrawingModelAsyncWindowsDX9ExSurface

This drawing model will only be valid on Windows Vista and higher in order to simplify hardware accelerated surface sharing.

Coming soon...

Open Issues

  • Add accelerated Linux drawing model.
  • Fill in all existing drawing models.