NPAPI:CoreAnimationDrawingModel

From MozillaWiki
Jump to navigation Jump to search

Status

Under consideration

Background

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.

Current Proposal

Last modified: January 17, 2010 Authors: Anders Carlsson (Apple Inc), Kevin Decker (Apple Inc) Contributors: Josh Aas (Mozilla Corporation)

Querying for availability

A plug-in may, in it's NPP_New callback negotiate a drawing model. It can call NPN_GetValue with the

NPNVsupportsCoreAnimationBool = 2003

NPNVariable to query the browser for whether the Core Animation drawing model is supported. The argument is an NPBool.

The plug-in can then call NPN_SetValue to tell the browser to use the Core Animation drawing model, using the

NPNVpluginDrawingModel = 1000

NPNVariable and the

NPDrawingModelCoreAnimation = 3 

drawing model enumeration, cast to a void pointer.

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 _retained_ 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 = createLayer();
            }
            
            // Make sure to return a retained layer
            *((CALayer **)value) = [obj->layer retain];
            
            return NPERR_NO_ERROR;
            
        default:
            return NPERR_GENERIC_ERROR;
    }
}

CALayer lifecycle

It is not specified when the browser's reference to the CALayer will be released, but it could happen after the plug-in instance has been destroyed.