Gecko:2DGraphicsSketch: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
Line 58: Line 58:


''Paths (conceptually) keep all their coordinates in user space because that's what we want when we retain paths, e.g. for SVG shapes.'' The cairo/canvas-2D feature where path points are transformed by the current matrix as they're added can and should be emulated at the nsCanvasRenderingContext2D layer. (Basically we'd emit the path in user space coordinates, but if we detect a matrix change we'd convert the current path to device space coordinates and maintain it in device space thereafter.)
''Paths (conceptually) keep all their coordinates in user space because that's what we want when we retain paths, e.g. for SVG shapes.'' The cairo/canvas-2D feature where path points are transformed by the current matrix as they're added can and should be emulated at the nsCanvasRenderingContext2D layer. (Basically we'd emit the path in user space coordinates, but if we detect a matrix change we'd convert the current path to device space coordinates and maintain it in device space thereafter.)
Bas: I think this is generally not the best idea. Cairo's model of converting at drawing time avoids a lot of transformation in the general case. I believe a wiser model would be like Direct2D does, where a path object exposes a transform method, which writes a transformed version of the path into another 'pathbuilder' (see my comments below). Backends can then internally optimize this process (i.e. simply transform an internal triangulation which was kept with the path) that makes retaining a good thing. But at the same time in the common case where a path is retained but not transformed differently the triangulation for a path can easily be re-used every time it's drawn, without having to figure out if the transform changed etc.


Paths can only be used with a DrawTarget using the same backend type.
Paths can only be used with a DrawTarget using the same backend type.
Line 85: Line 87:
''Folding into DrawTarget enables optimizations for backends like CoreGraphics where we can emit the path into the underlying context and the final Path object can temporarily point back to the context and say "I'm the current path in that context", thus avoiding having to copy the path out of the context if we
''Folding into DrawTarget enables optimizations for backends like CoreGraphics where we can emit the path into the underlying context and the final Path object can temporarily point back to the context and say "I'm the current path in that context", thus avoiding having to copy the path out of the context if we
don't start building a new path until the Path wrapper is destroyed.''
don't start building a new path until the Path wrapper is destroyed.''
''Bas'' I absolutely disagree here. I think this is a very bad idea, we should do something like Direct2D does with GeometrySinks (much like your pathbuilder suggestion). It makes for a better API and allows easier asynchronous path creation and such things going forward. I agree it allows a limited optimization for coregraphics but I think it's bad practice to make a poor API decision in order to adapt to another poor API choice.
In my code that I'm working on for Tessellation I've got an API 'kind of' like what I'd want to do (http://hg.mozilla.org/users/bschouten_mozilla.com/2drender/file/115d4e1f71cb/core/Path.h). I'd also expose a SetTransform on the pathbuilder, so that transformation of the points can occur while the path is written easily, without the need to do another O(n) pass to perform transformation.
I'm also not sure I agree on the general light weight stack based wrapper ideas. Although I do agree that it's nice to avoid a heap allocation. On the other hand heap allocations are pretty cheap (at least on windows, I've never tried on other platforms but I'm assuming its the same), and if you look at how many of them for example the STL classes generally execute internally with excellent performance characteristics, I doubt it's going to matter much since we won't be creating -that- many paths. Having these refcounted also gives the advantage of easily allowing us to move ownership between threads when we work on backends that implement concurrency for certain operations. Without having to use obscure methods to link these path wrappers to actual path objects.
The bottom line is except for some small modifications (for example allowing the transform to be set on the pathbuilder to avoid a needless iteration when transforming a set of coordinates in user space, while at the same time avoiding the need for the API user to 'pre-transform'), I think the ID2D1Geometry model is much more solid than the one proposed here.


== Clips ==
== Clips ==
Confirmed users
138

edits

Navigation menu