Confirmed users
856
edits
(→API) |
No edit summary |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
= Gecko Needs = | = Gecko Needs = | ||
== Semantics == | === Semantics === | ||
The basics of cairo's semantics seem to be OK --- fill path/stroke path/showglyphs, with source patterns, destination surfaces, operators, etc. | The basics of cairo's semantics seem to be OK --- fill path/stroke path/showglyphs, with source patterns, destination surfaces, operators, etc. | ||
Line 9: | Line 9: | ||
* Mask-based complex clipping is really slow and therefore pointless | * Mask-based complex clipping is really slow and therefore pointless | ||
* Allowing changes to the CTM during path emission is useless for us | * Allowing changes to the CTM during path emission is useless for us | ||
* [[Gecko:2DGraphicsThoughts/ErrorHandling]] | |||
== API == | === API === | ||
Gecko doesn't make much use of the statefulness of contexts. Every time we draw a display item, we reset most of the state. The exceptions are clipping and transforms. (But we often do need to be able to reset clipping to a given clipping state.) | Gecko doesn't make much use of the statefulness of contexts. Every time we draw a display item, we reset most of the state. The exceptions are clipping and transforms. (But we often do need to be able to reset clipping to a given clipping state.) | ||
Line 20: | Line 21: | ||
We can do without pushgroup and make do with temporary surfaces quite easily. I don't think we need device offsets. | We can do without pushgroup and make do with temporary surfaces quite easily. I don't think we need device offsets. | ||
The context/surface distinction can be simplified. We do need some abstraction for source images that encompasses in-memory buffers, native objects, and temporary surfaces. But we don't draw into a surface with multiple contexts at the same time. We can get by with context creation functions that create a context for specific targets --- an in-memory buffer, a native target, or a PDF stream --- just like cairo surface creation does today. We also need an API to create a "similar surface" of a given size and content-type; this would create a context and a source image object together. | The context/surface distinction can be simplified. We do need some abstraction for source images that encompasses in-memory buffers, native objects, and temporary surfaces ... maybe these can be different kinds of patterns. But we don't draw into a surface with multiple contexts at the same time. We can get by with context creation functions that create a context for specific targets --- an in-memory buffer, a native target, or a PDF stream --- just like cairo surface creation does today. We also need an API to create a "similar surface" of a given size and content-type; this would create a context and a source image object together. | ||
We don't really care about API convenience in Gecko. Unlike a regular application, we don't draw specific content, we just provide abstractions. So for example we only paint gradients in a couple of places, we only paint text in a few places, etc. Therefore we don't need to worry about passing lots of parameters to functions. | We don't really care about API convenience in Gecko. Unlike a regular application, we don't draw specific content, we just provide abstractions. So for example we only paint gradients in a couple of places, we only paint text in a few places, etc. Therefore we don't need to worry about passing lots of parameters to functions. | ||
We don't care about API stability. | We don't care about API stability. | ||
=== Remoting === | |||
We need an API that can be remoted very efficiently, since we'll need it for sandboxed content processes that want to use D2D or whatever for drawing. | |||
We probably need to assume from the start that system gfx libs can't be used in a sandboxed process. (Correct this if it's wrong!) | |||
Options for remoting seem to be | |||
# Map API to something like the cairo-image-surface backend; i.e., don't remote anything except references to rendered shmem images. | |||
# Map API to protocol designed exactly for remoting the API | |||
# Map API to GL, re-use GL protocol we'll need for webgl | |||
# Map API to backend-specific protocols | |||
We'll likely want (1) for systems without a GPU, although we might regress on systems with very good SW libs (on which we could potentially use (2) or (4) to erase the regression). To use D2D, we need either (2) or (4). (3) is attractive for sharing more code. (4) is unattractive for forking more code. | |||
(cjones) Seems like the best solution is to support (1) (on some thread) and (2). | |||
= Performance = | = Performance = | ||
Line 36: | Line 53: | ||
= Proposal = | = Proposal = | ||
== API == | === API === | ||
Stateful abstractions are a pain because we reset them a lot anyway and mapping one stateful abstraction onto another is tricky where they don't quite match up (e.g. semantics of changing the transform while emitting a path). | Stateful abstractions are a pain because we reset them a lot anyway and mapping one stateful abstraction onto another is tricky where they don't quite match up (e.g. semantics of changing the transform while emitting a path). | ||
Line 52: | Line 69: | ||
Provide explicit API for fillRect and other canvas operations so we don't have to waste time in backends identifying which fast path to use having gone through a generic path operation. | Provide explicit API for fillRect and other canvas operations so we don't have to waste time in backends identifying which fast path to use having gone through a generic path operation. | ||
== Implementation == | === Implementation === | ||
For optimal efficiency with stateful backends we need to figure out what state needs to be updated at each drawing call and only update that state. For example, with Quartz, if the operator, antialiasing mode, clip and source pattern are the same as the previous drawing call, we shouldn't do Quartz calls to set them. Packing flags and modes into a single flags word will help quick identification of changes. We'll want to be able to identify reused clips and source patterns efficiently without making those objects too heavyweight. This may require some ingenuity. | For optimal efficiency with stateful backends we need to figure out what state needs to be updated at each drawing call and only update that state. For example, with Quartz, if the operator, antialiasing mode, clip and source pattern are the same as the previous drawing call, we shouldn't do Quartz calls to set them. Packing flags and modes into a single flags word will help quick identification of changes. We'll want to be able to identify reused clips and source patterns efficiently without making those objects too heavyweight. This may require some ingenuity. | ||
=== Plan Of Attack === | |||
Start with canvas. We have performance needs there, the risk is lower and the implementation burden is lower. | |||
* Implement new gfx API as a wrapper around cairo | |||
* Clone nsCanvasRenderingContext2D with a run-time switch to use new implementation | |||
* New Context2D uses new gfx API | |||
** At this point we have something that works and we can iterate on the gfx API | |||
* Implement new D2D and/or Quartz backends | |||
** At this point we should have significant performance wins on real Web apps and something we want to ship | |||
* Implement GL backend (lots more work) | |||
* Extend API and backends with all the functionality we need | |||
* Reimplement gfxContext on top of new gfx API (compile time switch probably needed, or possibly a branch) | |||
* Incrementally convert all our graphics code to the new API | |||
= Meeting Notes = | |||
* Post-FF4, update cairo and plug in cairo-gl to canvas to see how it goes | |||
* Don't make a big investment in improving cairo-gl | |||
* Follow above plan | |||
* Do easy things to make new-gfx reusable by other projects (simple STL, bool, namespaces) but not hard things (threads) | |||
* Try GL backend on ANGLE before we commit to D3D backend(s) | |||
* Options for improving software rendering | |||
** New-API over Skia | |||
** Improve cairo |