NPAPI:CoreAnimationDrawingModel

From MozillaWiki
Jump to: navigation, search

Status

Accepted, ready for implementation.

Contributors

  • Last modified: April 22, 2010
  • Authors: Anders Carlsson (Apple), Kevin Decker (Apple)
  • Contributors: Josh Aas (Mozilla Corporation)

Overview

Currently, the only way for a plug-in on Mac to use OpenGL is to attach an AGL surface manually. This has a number of drawbacks:

  • The plug-in has to move the surface in response to page scrolling, window resizing, etc
  • The plug-in needs access to the browser window's WindowRef
  • AGL is a Carbon based API and does not work in 64-bit

The Core Animation drawing model aims to solve these problems (and more) by letting the plug-in hand off a Core Animation layer to the browser. It is then up to the browser to position and size the layer.

Negotiating Core Animation

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

  • NPDrawingModelCoreAnimation (NPDrawingModel = 3)
  • NPNVsupportsCoreAnimationBool (NPNVariable = 2003)

The Core Animation drawing model only works together with the Cocoa Event Model. If the plug-in tries to use the Carbon Event model with the Core Animation drawing model, the browser will destroy the plug-in after it has been instantiated.

Vending a layer

When the plug-in has selected the drawing model, the browser will call NPP_GetValue with the

NPPVpluginCoreAnimationLayer = 1003

NPPVariable. The value should be treated as a CALayer * pointer, which the plug-in should fill in with a layer. The plug-in should retain a reference to the layer. For example:

NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
    PluginObject *obj = instance->pdata;

    switch (variable) {
        case NPPVpluginCoreAnimationLayer:
            if (!obj->layer) {
                obj->layer = getLayer();
                [obj->layer retain];   // should be balanced by a -release in NPP_Destroy
            }
            
            *((CALayer **)value) = obj->layer;
            
            return NPERR_NO_ERROR;
            
        default:
            return NPERR_GENERIC_ERROR;
    }
}

CALayer lifecycle

The browser is not responsible for releasing retained CALayer objects it receives via the "NPPVpluginCoreAnimationLayer" variable. The browser may additionally retain layers (perhaps by attaching them to views, or adding them as sublayers of browser-owned CALayers). A plugin should release the layer for an instance during or after the instance's NPP_Destroy call.

Software paints

Under certain circumstances the browser may require the plug-in to do a software paint. This is required whenever the browser needs to generate a snapshot of the page contents, for example when generating a drag-and-drop drag image, when generating history snapshots, and possibly for printing. This is not expected to be a performance-critical code path.

To support these features, the browser may send a NPCocoaEventDrawRect to a plug-in, even when the plug-in has declared itself to be using the Core Animation drawing model. The plug-in should respond by doing a software paint into the supplied CGContext. The plug-in should not makes any assumptions about the type of the CGContext; it may be a bitmap context.