NPAPI:DrawImage
Problem Summary
Very painful to render plugin content to non-X surfaces on linux with XServer. (for mozilla if MOZ_X11 defined then HandleEvent is operating with XEvent). When browser rendering it's content into memory buffer or to some other surface (Qt::RasterPaintEngine/cairo-image-surface which are not very friendly with X), then we are forced to do data moving X-client-X...
Proposal
I'm proposing a NPAPI Drawing model which would allow a plugin to render directly into 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 possibility to implement 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 default event model system, specific to platform
- If NPEventModelIndependent was negotiated as supported, then browser and plugin should negotiate also 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 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 plugin should decide which format's supported by plugin and browser (remove bits which are not supported by plugin), and set 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.