Gfx glue layer removal: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
m (s/Cairo/cairo/, added Category:Mozilla 2)
Line 4: Line 4:
* All code calls <tt>gfx/thebes</tt> interfaces directly
* All code calls <tt>gfx/thebes</tt> interfaces directly
** mostly this is <tt>nsIFrame::Paint</tt> methods, but there are others
** mostly this is <tt>nsIFrame::Paint</tt> methods, but there are others
* Not possible to implement a non-Cairo rendering backend anymore
* Not possible to implement a non-cairo rendering backend anymore
** I believe this is already not possible; several <tt>nsIFrame::Paint</tt> methods already call <tt>gfx*</tt> interfaces directly
** I believe this is already not possible; several <tt>nsIFrame::Paint</tt> methods already call <tt>gfx*</tt> interfaces directly
** Non-Thebes <tt>gfx/src/*</tt> backends should be deleted early in the process, to remove false hits from automated scans for code needing conversion
** Non-Thebes <tt>gfx/src/*</tt> backends should be deleted early in the process, to remove false hits from automated scans for code needing conversion
Line 120: Line 120:


:::: <tt>nsColorNames</tt>, <tt>nsCUPSShim</tt>, <tt>nsPSPrinterList</tt>, <tt>nsITheme</tt> (where is the implementation?)
:::: <tt>nsColorNames</tt>, <tt>nsCUPSShim</tt>, <tt>nsPSPrinterList</tt>, <tt>nsITheme</tt> (where is the implementation?)
[[Category:Mozilla 2]]

Revision as of 09:25, 24 April 2008

Goal

  • Eliminate the glue layer in gfx/src/thebes
  • All code calls gfx/thebes interfaces directly
    • mostly this is nsIFrame::Paint methods, but there are others
  • Not possible to implement a non-cairo rendering backend anymore
    • I believe this is already not possible; several nsIFrame::Paint methods already call gfx* interfaces directly
    • Non-Thebes gfx/src/* backends should be deleted early in the process, to remove false hits from automated scans for code needing conversion
    • I am unclear on whether gfx/src/psshared is still useful
    • Code loose in gfx/src and gfx/src/shared needs to be dealt with case-by-case
  • End point: should be possible to remove gfx/src altogether (perhaps gfx/thebes/src becomes gfx/src, gfx/thebes/public merged into gfx/public?)

Plan

  • Work out unit conversion issues (see next section)
  • Identify and strip source files which are currently unused or can easily be made unused
  • DeCOMtaminate where appropriate, eliminating nsI classes
  • For each cluster of objects listed below under "Classes involved", refactor all code out of the non-gfx* classes, so that they are perfect wrappers or even typedefs for the gfx* classes
  • Bubble use of gfx* direct interfaces upward into paint methods, layout class data members, etc. until all uses of the old interfaces are gone

Unit conversion

Issues:

  • layout should still do its work in nscoord units (1/60th of a CSS pixel), per offline discussion with dbaron
  • gfx is expecting gfxFloat units (device pixels)
  • we don't want to sprinkle conversions through every paint method
  • because gfxFloat is a floating point type, changing the sequence of arithmetic operations may change what actually gets drawn (see bug 376180 for an example of this)
  • nsRenderingContextThebes currently has easy access to the nscoord-to-device conversion ratio (mP2A and the FROM_TWIPS[sic] macros), whereas it's somewhat awkward to get it from a paint method (PresContext()->AppUnitsPerDevPixel() is the best way I can find, and that expands to something like four pointer dereferences under the hood).
  • There are several bugs relating to coordinate systems and behavior at overflow: bug 265084, bug 370006, bug 379616, (please add to this list...)

Possibilities:

  • keep the conversions at the layout/gfx interface:
    • define implicit conversion operators, so passing nscoord and related types to gfxContext functions makes the compiler generate conversion code in the paint method
      • for this to work, nscoord would have to be a class type
      • the conversion operators would need to know the conversion ratio; see above
    • change gfx{Float,Point,Size,Rect} to take nscoord-family inputs and convert internally
      • for this to work, gfxFloat would have to be a class type
      • also, these types would need to know the conversion ratio, which might mean they need to be told what gfxContext they're being created for
  • push the conversion down into gfx:
    • overload all gfxContext methods to take nscoord family arguments, do the conversions in the thebes layer
      • ugly, exposes nscoord types in gfx
    • make the cairo transformation matrix do all the work (so the thebes layer continues to use its own types, but the numbers are in the same units that layout uses)
      • facilitates replacing ns* types with gfx* types bubbling upward
      • could be error prone if anyone else messes with the matrix
    • might not give the same rounding behavior as currently
  • other ideas?

Overall I like "make the cairo transformation matrix do all the work" best, but I'm worried about its getting messed with. Perhaps we can enforce a use discipline similar to PDF's - you can save and restore the current matrix, you can "concatenate" a transformation onto the existing matrix, but you can't wipe out the existing matrix and start over.

Classes involved

Note that these lists were generated by a lot of staring at the output of a Dehydra script of dubious correctness. I may have missed things.

  • Graphics objects: these come in clusters, either ns<thing> and gfx<thing> parallel implementations, or an nsI<thing> interface, a nsThebes<thing> shim, and (usually) a gfx<thing> real implementation. In both cases the desired end point is that there is only gfx<thing>.
nsFont, gfxFont
nsColor, gfxRGBA
nsCoord, gfxFloat
nsPoint, gfxPoint
nsRect, gfxRect
nsSize, gfxSize
nsMargin (no equivalent?)
nsTransform2D, gfxMatrix
nsFontCache, gfxFontCache
nsIFontMetrics, nsIThebesFontMetrics, nsThebesFontMetrics, nsBoundingMetrics, gfxFont::Metrics
nsIImage, nsThebesImage, gfxIImageFrame, gfxImageFrame, gfx*Surface (?)
nsIRegion, nsRegion, nsThebesRegion, nsIScriptableRegion, nsScriptableRegion
nsTextDimensions, gfxGlyphExtents (?)
nsIFontEnumerator, nsThebesFontEnumerator
  • Context classes: like the graphics objects, they come in clusters, but I think we want to collapse all of these into one class, gfxContext. (If the distinction between device context and rendering context is useful - I have no hard evidence, though I suspect it isn't - we would want to keep nsRenderingContext too, but de-COM it.)
nsIDeviceContext, DeviceContextImpl, nsThebesDeviceContext
nsIRenderingContext, nsRenderingContextImpl, nsThebesRenderingContext
gfxContext
  • Thebes-only graphics objects: there is no nsI-level interface to these (that I found). Probably they can be left alone.
gfxFlattenedPath, gfxFontGroup, gfxFontStyle, gfxMatrix, gfxPattern, gfxSkipChars, gfxSkipCharsBuilder, gfxSkipCharsIterator, gfxTextRun, gfxTextRunCache, gfxTextRunFactory, gfxTextRunWordCache
  • Helper classes: probably do not need messing with except incidentally.
gfxContextAutoSaveRestore, nsRegionRectIterator
  • Thebes internal implementation and unit tests (I think). Again, probably do not need messing with except incidentally.
gfxASurface, gfxImageSurface, gfxXlibSurface, gfxXlibNativeRenderer, other gfx*Surface and gfx*NativeRenderer classes not used under X11/gtk
gfxFontNameList, gfxFontTestItem, gfxFontTestStore, gfxPangoFont, gfxPangoFontWrapper
other gfx*Font* classes not used under X11/gtk; note that Pango has ATSUI and Uniscribe back ends, but using Pango universally, if desirable, should be a separate project
gfxPlatform, gfxSparseBitSet
  • Other things defined in gfx headers, whose role I am uncertain of:
nsColorNames, nsCUPSShim, nsPSPrinterList, nsITheme (where is the implementation?)