In Neutrino, graphics drivers are independent of the graphics system. The driver that you supply is implemented as a shared object that can be used by Photon (io-graphics) or by applications using the Neutrino Graphics Framework (via io-display).

At this time, Photon/GF coexistence isn't supported. Although graphics drivers are generic and can be loaded by either io-display or io-graphics, both process can't run at the same time. This means that GF-based applications can't run under Photon. This functionality will be available in a future release.

You provide a set of well defined entry points, and the
appropriate graphics system dynamically loads your driver and calls the entry points.

Under GF, different entry points can be called from different places, and some knowledge of where and when the various entry points may be called is necessary in order to determine how your driver should be structured.

All access to graphical functionality is provided to the application by
the GF client library. The GF client library may, in turn, initiate a
call into the graphics driver.
This could happen in one of two ways:

A direct call into the graphics driver, within the application's
address space

A message pass to io-display, which in turn could initiate calls into the graphics driver within io-display's address space.

A GF-based application

Since a driver may be called from within different address spaces, your
driver will need to keep track of shared data (which is stored in
memory visible to all address spaces) as well as state data which is
only accessible within a single address space.

The driver is provided with a shared memory area, in which it can store
“global” driver state data. The driver should include a global symbol,
of type int, named devg_shmem_size, which indicates how much memory
needs to be allocated by the Framework to store the shared data.

The
driver should be very careful about storing pointers in this shared
memory, since a pointer does not have any meaning outside of the address
space in which it was created.

Additionally, a driver may allocate per-address-space state data, which can
be used to keep track of per-client rendering state.

Later, we will specify which entry points may be called from within the
address space of io-display, and which ones may be called directly from within the address space of the client (see Address spaces and calling rules).

For more information about the architecture of the QNX Graphics Framework, see the QNX Advanced Graphics TDK Developer's Guide.

By way of example, this is how your driver interacts with Photon and
the graphics driver subsystem,
io-graphics,
under QNX Neutrino:

How a driver interacts with Photon.

As you can see from the above diagram, a set of Photon infrastructure
components are responsible for the interface to Photon:

Connector

Presents the graphical region to Photon.
This is the area that's defined to be shown on the graphical screen.

Draw stream interpreter

Interprets Photon's draw stream and
decodes the graphical commands into scans, bitmaps, images, and fills,
and passes them to the graphics driver.
The interpreter also converts the draw stream from whatever endian
format it's in to native-endian format.