Plugins diagram

May 27, 2009

Here's a nice ASCII art diagram of the various rectangles involved in drawing plugins. The following comments show why progress on making them work on Linux is slow. (From [webplugin_delegate_impl_gtk.cc][], which is a bit ugly right now since it still needs to unfork from its parent file...)

// The actual dirty region is just the intersection of the plugin window and
// the clip window with the damage region. However, the plugin wants to draw
// relative to the containing window's origin, so our pixmap must be from the
// window's origin down to the bottom-right edge of the dirty region.
//
// Typical case:
// X-----------------------------------+-----------------------------+
// |                                   |                             |
// |    pixmap     +-------------------+                             |
// |               |   damage          |                window       |
// |               |                   |                             |
// |           +---+-------------------+-------------+               |
// |           |   |                   |   clip      |               |
// |       +---+---+-------------------+----------+  |               |
// |       |   |   |                   |          |  |               |
// |       |   |   | draw              |          |  |               |
// |       |   |   |                   |          |  |               |
// +-------+---+---+-------------------+----------+--+               |
// |       |       |                   |          |                  |
// |       |       +-------------------+          |                  |
// |       |                                      |                  |
// |       |        plugin                        |                  |
// |       +--------------------------------------+                  |
// |                                                                 |
// |                                                                 |
// +-----------------------------------------------------------------+
// X = origin
//
// NPAPI doesn't properly define which coordinates each of
// - window.clipRect, window.x and window.y in the SetWindow call
// - x and y in GraphicsExpose HandleEvent call
// are relative to, nor does it define what the pixmap is relative to.
//
// Any sane values for them just don't work with the flash plugin. Firefox
// has some interesting behavior. Experiments showed that:
// - window.clipRect is always in the same space as window.x and window.y
// - in the first SetWindow call, or when scrolling, window.x and window.y are
// the coordinates of the plugin relative to the window.
// - whenever only a part of the plugin is drawn, Firefox issues a SetWindow
// call before each GraphicsExpose event, that sets the drawing origin to
// (0, 0) as if the plugin was scrolled to be partially out of the view. The
// GraphicsExpose event has coordinates relative to the "window" (assuming
// that virtual scroll). The pixmap is also relative to the window. It always
// sets the clip rect to the draw rect.
//
// Attempts to deviate from that makes Flash render at the wrong place in the
// pixmap, or render the wrong pixels.
//
// Flash plugin:
// X-----------------------------------------------------------------+
// |                                                                 |
// |               +-------------------+        "real" window        |
// |               |   damage          |                             |
// |               |                   |                             |
// |           +---+-------------------+-------------+               |
// |           |   |                   | "real" clip |               |
// |       +---+---O===================#==========#==#===============#
// |       |   |   H draw              |          |  |               H
// |       |   |   H = pixmap          |          |  |               H
// |       |   |   H = "apparent" clip |          |  |               H
// |       +   +---#-------------------+----------+--+               H
// |       |       H                   |          |                  H
// |       |       H-------------------+          |                  H
// |       |       H                              |                  H
// |       |       H  plugin                      |                  H
// |       +-------#------------------------------+                  H
// |               H                                                 H
// |               H                  "apparent" window              H
// +---------------#=================================================#
// X = "real" origin
// O = "apparent" origin
// "real" means as seen by Chrome
// "apparent" means as seen by the plugin.