NPAPI:DrawImage

From MozillaWiki
Jump to navigation Jump to search

Problem Summary

It is very painful to render plugin content to non-X surfaces on Linux using X11. (For Mozilla if MOZ_X11 is defined then HandleEvent is operating with XEvent's). When browser renders its content into a memory buffer or to some other surface (Qt::RasterPaintEngine/cairo-image-surface which are not very friendly to X), then we are forced to do data moving X-client-X...

Proposal

I propose an NPAPI Drawing model which would allow a plugin to render directly into an image memory buffer, without involving XSurface.

Event model negotiation

For documentation on negotiating event models, see NPAPI:Models. The event model variables for all platforms are:

* NPEventModelNative - (Native platform default events, X/HWND... )
* NPEventModelIndependent
* NPNVsupportsNativeBool (NPNVariable = 3000)
* NPNVsupportsIndependentBool (NPNVariable = 3001)

We should provide the possibility to implement a different event model for all platforms (not only Mac OS X).

NPEventModelNative

Plugin and browser consider event structure as native event pointer, and Handling works as it is now by default in windowless mode.

NPEventModelIndependent

typedef struct _NPEvent
{
  void*         event;       /* event structure pointer */
  NPEventType   type;        /* typ of event, defined in NPEventType */
} NPEvent;
typedef enum {
  NPEventType_Native = 0x0001,   /* Native event structure specific to platform (XEvent, HWND...)
  NPEventType_DrawImage = 0x0002,     /* Draw Image even type, event structure == NPImageData.
  NPEventType_GetFocusEvent = ....
  ............
  Other events which are need to be platform independent
  ............
} NPEventType;

NPEventModelType negotiation

Browser and plugin should negotiate Event model type:

  • if no supported model type defined or NPEventModelNative only, then we use the default event model system, specific to platform
  • If NPEventModelIndependent was negotiated as supported, then browser and plugin should also negotiate the list of supported events

NPEventType negotiation

NPNVsupportsEventTypes = 4000

NPEventType aTypes;
browser->getvalue(instance, NPNVsupportsEventTypes, &aTypes)

Then plugin should decide which event supported by plugin and browser (remove bits which are not supported by plugin), and set value to browser:

browser->setvalue(instance, NPNVsupportsEventTypes, commonTypes);

Drawing Model

For documentation on negotiating drawing model, see NPAPI:Models. The drawing model variables for Platform independent image rendering are:

* NPDrawingModelImage (NPDrawingModel = 0) 
* NPNVsupportsDrawImageBool (NPNVariable = 2000) 

NPDrawingModelImage

Using NPImageData structure as event where NPImageData:

typedef struct _NPImageData
{
  /* Image data parameters */
  char*         data;       /* image pointer */
  int32_t       stride;     /* Stride of data image pointer */
  NPImageFormat format;     /* Format of image pointer */
  NPSize        dataSize;   /* Data buffer size */
  /* Clip rectangle, must be used for trusted plugins */
  int32_t       x;          /* Expose x relative to 0,0 of plugin window area*/
  int32_t       y;          /* Expose y relative to 0,0 of plugin window area */
  uint32_t      width;      /* Expose width */
  uint32_t      height;     /* Expose height */
  /* Position and scale values for plugin area */
  float         translateX; /* translate X matrix value, (x offset) */
  float         translateY; /* translate Y matrix value, (y offset) */
  /* Defines plugin window size on scaled context, if 1 then size = window size */
  float         scaleX;     /* scale X matrix value */
  float         scaleY;     /* scale Y matrix value */
} NPImageData;

where NPImageFormat (similar to the current Cairo image format list):

typedef enum {
  NPImageFormatARGB32 = 0x0001,
  NPImageFormatRGB24 = 0x0002,
  NPImageFormatRGB16_565 = 0x0004,
  NPImageFormatA8 = 0x0008,
  NPImageFormatA1 = 0x0010
} NPImageFormat;

NPImageFormat type negotiation

NPNVsupportsImageFormat = 5000,

Implementation is similar to Event types negotiation

NPImageFormat aFormats;
browser->getvalue(instance, NPNVsupportsImageFormat, &aFormats)

Then the plugin should decide which formats supported by plugin and browser (remove bits which are not supported by plugin), and send a value to browser:

browser->setvalue(instance, NPNVsupportsImageFormat, commonFormats);

And then browser should use only formats enumerated in commonFormats value.

According to plugin state (transparency), and platform preffered depth/image-format browser will send event to plugin with specific format.