Gecko:Layers: Difference between revisions

Jump to navigation Jump to search
1,567 bytes added ,  29 October 2009
Line 191: Line 191:
We need to be able to restructure our code around layers without sacrificing performance on existing non-accelerated cairo-only backends. Therefore we cannot require an implementation to actually construct a temporary surface for each layer.
We need to be able to restructure our code around layers without sacrificing performance on existing non-accelerated cairo-only backends. Therefore we cannot require an implementation to actually construct a temporary surface for each layer.


For example, suppose we have some normal content, covered by an opacity:0.5 element, covered by some more normal content. Currently we'd render the bottommost content directly to the destination (actually to a backbuffer, but that's irrelevant here), then we'd create a temporary surface, render in the translucent content, composite that onto the destination, and then render the topmost content directly to the destination. A naive layers implementation would render the bottommost content directly to a temporary surface, render the translucent content to another temporary surface, render the topmost content to another temporary surface, and then composite them each onto the destination. That would be an unacceptable performance hit when compositing must be done on the CPU. (Also, since the topmost content layer is likely to not have a transparent background, we are likely to disable subpixel antialiasing for the topmost content, which we would like to avoid if possible.)
For example, suppose we have some normal content, covered by an opacity:0.5 element, covered by some more normal content. Currently we'd render the bottommost content directly to the destination (actually to a backbuffer, but that's irrelevant here), then we'd create a temporary surface, render in the translucent content, composite that onto the destination, and then render the topmost content directly to the destination. A naive layers implementation would render the bottommost content directly to a temporary surface, render the translucent content to another temporary surface, render the topmost content to another temporary surface, and then composite them each onto the destination. That would be an unacceptable performance hit when compositing must be done on the CPU, especially if the buffers will not be saved and used again, because animation is not present or memory is scarce. (Also, since the topmost content layer is likely to not have a transparent background, we are likely to disable subpixel antialiasing for the topmost content, which we would like to avoid if possible.)
 
To enable an efficient immediate-mode implementation, we impose some constraints on the use of the layers API. First, define "mutation" as a call to any setter method on Layer, or a call to beginDraw or copyFrom on RenderedLayer, or a call to insertBefore or removeChild on ContainerLayer (when we add layer APIs, they may need to be added to this list). Then we impose the following rule:
* After calling RenderedLayer::beginDraw, you are not allowed to mutate any layer before or equal to the RenderedLayer in a pre-order traversal of the layer tree.
 
Then we can have an immediate-mode layer implementation which works just like our current code. When we call beginDraw, everything before the RenderedLayer has already been drawn, and we know the final values of the properties controlling rendering of this layer and its ancestors. If conditions are right, i.e. the opacity of this layer is 1.0, transform is affine, etc, we can avoid creating a buffer for this layer, and just return a gfxContext that renders directly into some ancestor buffer. The fact that we don't have this layer's contents stored anywhere is reflected by keeping the layer's valid region empty.
 
Note that this restriction means you must add all children to a ContainerLayer before rendering into any of them, and in particular you must add a RenderedLayer to its parent before rendering into it. These constraints are easy enough for the display list subsystem to satisfy.


= Jeff =
= Jeff =
1,295

edits

Navigation menu