202
edits
BrettWilson (talk | contribs) (Minor additions.) |
BrettWilson (talk | contribs) (Add 2D rendering details) |
||
Line 182: | Line 182: | ||
Given the threading model we have defined, it is desirable to allow InitializeRenderContext and FlushRenderContext to be called from other plugin threads than Tp. This eliminates the need to do the associated NPN_PluginThreadAsyncCall, and avoids the context switch penalties that might be associated. | Given the threading model we have defined, it is desirable to allow InitializeRenderContext and FlushRenderContext to be called from other plugin threads than Tp. This eliminates the need to do the associated NPN_PluginThreadAsyncCall, and avoids the context switch penalties that might be associated. | ||
=== 2D Rendering === | === 2D Rendering Background === | ||
Old-style NPAPI plugins display 2D graphics in one of two modes: windowless or windowed, each with their own features and limitations. The plugin can specify which mode it would prefer to execute in. | |||
This | Windowless plugins are inserted into the middle of the painting of the web page. As the page is being painted, the plugin is given the opportunity to draw the contents of the plugin directly over the previously-rendered contents of the page. This is very flexible, but has a number of downsides: | ||
* It assumes that the browser is using the platform-native surface to render the page (for example, an HDC on Windows). Some browsers may with to use third-party graphics libraries for additional flexibility. | |||
* It has no provision for an alpha channel. A plugin does antialiasing by blending itself directly onto the lower layers of the page. This poses problems for out-of-process plugins (see below) and prevents a number of optimizations. | |||
* It assumes that the plugin is executing in the same process as the page is being painted. Increasingly, browsers are moving plugins into separate processes, which requires significantly more effort on the part of the browser to emulate the in-process painting | |||
* It is platform-specific. Plugins must be specifically coded to support the native painting APIs of all host systems they run on. | |||
Windowed plugins plugins are essentially given a handle to an operating system native window, from which all interaction by the plugin is completely platform-specific. | |||
* Windowed plugins rely even more on the system native painting and events than windowless ones. | |||
* Having native windows on top of the page makes it very difficult or impossible for the browser to draw page content above the plugin, interfering with a number of common web practices such as pop-up menus. | |||
* From the browser's perspective, it is difficult to manage the child windows. For example, keep them and the page in sync when the page scrolls is challenging. | |||
==== 2D API Overview ==== | |||
We propose that only windowless plugins be supported, that compositing should be done outside the plugin, and that no native OS events should be delivered to the plugin. New APIs and events will be added to fill in the resulting holes in functionality. | |||
The 2D device provides a buffer with an alpha channel for the plugin to paint to a region of the screen. The drawing model is a retained mode where the browser will keep the current image of the plugin in a backing store. The plugin is able to update all or part of this backing store via the 2D device API as it wishes. The painting of the page is then decoupled from the generation of the image. | |||
The 2D API is particularly well suited to static or rarely-changing content. For example, a plugin implementing decoding of a new image type would decode the image and flush it to the browser only once, and would never have to execute any paint handlers or re-render the image. | |||
Animation can be implemented in the 2D device API using the callback from the flush function. After the browser paints the image to the screen, it will call the plugin's specified callback. At this point, the plugin can generate a new frame. This callback notification is the rate limiting signal so the plugin does not generate images faster than they can be painted to the screen. | |||
==== The 2D Device ==== | |||
<pre>typedef struct _NPDeviceContext2D | |||
{ | |||
/* Internal value used by the browser to identify this device. | |||
*/ | |||
void* reserved; | |||
/* A pointer to the pixel data. This data is 8-bit values in BGRA order in | |||
* memory. Each row will start |stride| bytes after the previous one. | |||
* | |||
* THIS DATA USES PREMULTIPLIED ALPHA. This means that each color channel has | |||
* been multiplied with the corresponding alpha, which makes compositing | |||
* easier. If any color channels have a value greater than the alpha value, | |||
* you'll likely get crazy colors and weird artifacts. | |||
*/ | |||
void* region; | |||
/* Length of each row of pixels in bytes. This may be larger than width * 4 | |||
* if there is padding at the end of each row to help with alignment. | |||
*/ | |||
int32 stride; | |||
/* The dirty region that the plugin has painted into the buffer. This | |||
* will be initialized to the size of the plugin image in | |||
* initializeContextPtr. The plugin can change the values to only | |||
* update portions of the image. | |||
*/ | |||
struct { | |||
int32 left; | |||
int32 top; | |||
int32 right; | |||
int32 bottom; | |||
} dirty; | |||
} NPDeviceContext2D;</pre> | |||
=== An Example === | === An Example === |
edits