- From: Cyril Concolato <cyril.concolato@enst.fr>
- Date: Mon, 04 Sep 2006 09:07:35 +0200
- To: www-svg <www-svg@w3.org>, SVG WG <w3c-svg-wg@w3.org>
- Message-ID: <44FBD0B7.1070907@enst.fr>
Dear all,
This mail is a feedback from an implementation of SVG Tiny 1.2 in [1].
It discusses the design of the rendering tree and the efficiency of
setting display='none' on grouping elements.
The specification says in section "11.9 Controlling visibility and
rendering" [2]:
"When applied to a container element , setting 'display' to none causes
the container and all of its children to be excluded from the rendering
tree".
(As a side note, the second bullet in that section should read 'When the
'display' property is set to none on graphics elements, ...", shouldn't it?)
We understand this as: the meaning of display='none' is to reduce the
number of elements to traverse during rendering, thus the processing
required to render the document. We analyzed which are the elements that
display='none' allows not traversing or partial traversing.
We investigated the consequences of setting display to 'none' on the
different kinds of SVG elements:
• Animation elements:
We based our implementation on the fact that 'inherit' values in
animation attributes ('from', 'to' and 'values') are resolved based on
the location of the target element of the animation and not on the
location of the animation element itself. Given that assumption, that we
would like to be clarified (see [6]), we designed our implementation
such that the timing part of the animation is evaluated before the
rendering tree traversal and that the actual presentation value
computation is done when the target element of the rendering tree is
traversed.
This means two things:
- animation elements are not actually part of the rendering tree, and
- if the target of an animation is not part of the rendering tree, the
part of the animation that computes the presentation value is switched
off. Only the timing part and the resolution of events and the
triggering of begin, end and repeat events is needed. So, with this
design, display='none' indeed brings efficiency benefit.
• Media elements (audio, video, animation) :
The consequences are the same for media elements. We divided their
handling in two parts: timing and rendering. Timing is evaluated
beforehand so that even if the element is not part of the rendering
tree, timed events are still fired and handled. This way, when display
is set to 'none', we indeed switch off the big part of the processing.
• 'use' elements and inheritance
According to [3], inheritance of properties in elements referenced by a
'use' element is based on the location of the 'use' element. So the
target of a 'use' element has to be traversed, even if it is in a
display='none' part of the DOM tree. There is no efficiency gain there.
The only efficiency gain happens if the referencing element (the 'use')
is in the switched off DOM subtree.
• 'listener', 'handler', 'discard', 'prefetch' and 'script' elements
To our opinion, these elements should also be listed in the list of
elements not being part of the rendering tree because they do not have
rendering. It should be clarified that: 'listener' elements should still
listen to events, 'handler' elements should still handle events,
'discard' elements should still discard, 'prefetch' elements should
still prefetch resources, and 'script' elements should still be
evaluated even if they are in a subtree where 'display' is 'none',
according to their semantics, that their handling is in fact orthogonal
to the rendering.
It is clear that setting 'display'='none' does not reduce the processing
of the document in this respect, except for the fact that mouse events
are not generated from that part of the DOM tree.
• Graphics elements
Here setting the 'display' to 'none' actually brings a lot because we
switch off the rendering part and the animation interpolation part as
described above.
• the 'font-face-uri' element
I'm not an expert in this element and we did not implement it yet. But
the same argument as above applies. The referenced 'font' element should
inherit from the the 'font-face-uri' element, if inheritance applies here.
• Focus navigation
The specification [7] explains that "The SVG User Agent must not
navigate to an element which has display='none'." which means that when
setting 'display' to 'none' on a group element, one must traverse the
subtree to determine if there is an element in the focus ring to be
removed, and the opposite when setting it to other value than 'none'.
But is there another solution? We couldn't find any.
For these elements, we may have found a problem which would actually
prevent us from optimizing.
• the 'mpath' element
It should be specified that:
- no property apply to the path motion, or
- when an 'mpath' element points to a 'path' element, the 'path' element
inherits its properties from the 'mpath' element and not for its parent
element. Otherwise, the ancestors of the 'path' element need to be
processed to evaluate the 'stroke-dasharray' and 'stroke-dashoffset'
properties which are inheritable and affect the path motion.
• Paint servers: 'linearGradient', 'radialGradient' and 'solidColor'
Even though these elements are not part of the rendering (we assume
'solidColor' is not, even if not listed in the definition of rendering
tree, we believe it's a mistake), section "11.16 Gradients" of [4]
explains the following:
"Properties shall inherit into the 'linearGradient' [or
'radialGradient'] element from its ancestors; properties shall not
inherit from the element referencing the 'linearGradient' [or
'radialGradient'] element."
We tried to understand what this actually meant. The allowed elements
'into the gradient' according to the RNG (see 'GradientCommon.CM' in
[5]) are: 'desc', 'metadata', the animation elements, 'discard' and
'stop' elements. Since we assume animation elements inherit from the
target element, the only inner gradient elements that could use
properties are 'stop' elements. We searched for properties which apply
to 'stop' elements and found: 'stop-color', 'stop-opacity' and
potientally 'color'. Only 'color' is inheritable and would therefore
inherit its value through the gradient element, possibly from the parent
of the gradient element, to the stop color.
Except for 'color', the reasons for the sentences quoted above are not
obvious. But the problem is clear. Just for 'color', this sentence
forces the traversal of the display='none' subtree to retrieve the
computed value for that property on the gradient element. This might
imply computing animations at multiple levels of the display='none'
subtree. Let's look at the following example (anim_gradient.svg):
<svg viewBox="0 0 1000 1000"
xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="r1" fill="url(#MyGradient)" width="100" height="100" x="200"
y="200"/>
<rect id="r2" fill="url(#MyGradient2)" width="100" height="100" x="200"
y="500"/>
<g id="g1" display="none">
<g id="g2">
<animateColor id="a1" attributeName="stop-color" from="red" to="blue"
dur="5" begin="0" additive="replace" accumulate="none" fill="freeze"/>
<animateColor id="a1" attributeName="color" from="red" to="blue" dur="5"
begin="0" additive="replace" accumulate="none" fill="freeze"/>
<linearGradient id="MyGradient">
<stop offset="0" stop-color="green" />
<stop offset="1" stop-color="inherit" />
</linearGradient>
<linearGradient id="MyGradient2">
<stop offset="0" stop-color="green" />
<stop offset="1" stop-color="currentColor" />
</linearGradient>
</g>
</g>
</svg>
According to the current specification, since 'stop-color' is not
inheritable, the value 'inherit' is not allowed and should be ignored,
defaulting to the initial value of 'black'. Therefore, the top rectangle
'r1' should show a linear gradient from 'green' to 'black'.
On the other hand, since 'currentColor' is specified in the stop color
of the second gradient 'MyGradient2', one needs to get the computed
value for the 'color' property. This forces the evaluation of the
animation on the 'g' element called 'g2', which is actually not part of
the rendering tree. This is quite inefficient for a not so particularly
useful feature.
We tested the above example in different players:
- Adobe SVG Viewer 6.0 shows r1 correctly but for r2 shows a non
animated gradient from green to red.
- Opera 9 and Osmo4 0.4.2 show the same result. r1 is correctly
displayed (static, green-black gradient) but r2 uses a static gradient
from green to black.
- Tinyline 1.10 shows two non animated gradients from green to red.
- eSVG Viewer 2.4 shows two non animated gradients from green to white.
- Renesis 0.1 shows non animated gradients, r1 is from green to white,
r2 is from green to cyan.
We wanted to test static viewers as well, so we used the following
example (gradient_inherit.svg) :
<svg viewBox="0 0 1000 1000"
xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="g1" stop-color="blue">
<rect id="r1" fill="url(#MyGradient)" width="100" height="100" x="200"
y="200"/>
</g>
<g id="g2" stop-color="red">
<linearGradient id="MyGradient">
<stop offset="0" stop-color="green" />
<stop offset="1" stop-color="inherit" />
</linearGradient>
</g>
</svg>
And the results are:
- ASV 6, Firefox 1.5.0.6, Batik 1.6 and Osmo4 0.4.2 show green to black
- Opera 9 shows green to red
- Renesis 0.1 and eSVG Viewer show green to white
We couldn't test mobile implementations, but these tests clearly show
that there is no interoperability on this SVG 1.1 Feature. There is
definitely a need for clarification.
We suggest removing the problematic sentences in 'linearGradient' and
'radialGradient' and adding the following sentence instead, which should
also be added to the 'solidColor' element, since as a paint server, it
should behave like the gradient elements:
"Properties for this element, when inherited, shall inherit values from
the referencing element."
This change would allow for possible optimizations, described above,
when display='none' is specified on a subtree which contains gradients
or solid colors definitions.
We suggest clariyfing the 'mpath' semantics.
We also suggest clarifying the property's definitions by removing the
'inherit' value in properties which cannot be inherited. The following
informative sentence would also help:
"If a property's definition indicates 'inherited: no', the value
'inherit' is not allowed in the corresponding presentation attribute. If
specified, the value shall be ignored and the initial value of the
property shall be used."
Finally, we also suggest updating the definition of the rendering tree
to exclude animation elements, 'mpath', 'listener', 'handler',
'discard', 'prefetch' and 'script' elements.
Best regards,
Cyril Concolato
[1] http://gpac.sourceforge.net
[2] http://www.w3.org/TR/SVGMobile12/painting.html#VisibilityControl
[3] http://www.w3.org/TR/SVGMobile12/struct.html#UseElement
[4] http://www.w3.org/TR/SVGMobile12/painting.html#Gradients
[5] http://www.w3.org/Graphics/SVG/1.2/rng/Tiny-1.2/gradient-tiny.rng
[6] http://www.w3.org/mid/44FA8E22.4050000@enst.fr
[7] http://www.w3.org/TR/SVGMobile12/interact.html#navigationbehaviour
Attachments
- image/svg+xml attachment: gradient_inherit.svg
- image/svg+xml attachment: anim_gradient.svg
Received on Monday, 4 September 2006 07:37:03 UTC