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.