Bug 11164

Summary: SVG opacity code needs further optimizations
Product: WebKit Reporter: Eric Seidel (no email) <eric>
Component: SVGAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Minor CC: igor.oliveira, krit
Priority: P4    
Version: 420+   
Hardware: Mac   
OS: OS X 10.4   

Description Eric Seidel (no email) 2006-10-05 06:09:00 PDT
SVG opacity code could be further optimized.

Right now our largest inefficiency in the opacity code is the number of times we call beginTransparencyLayer/endTransparencyLayer.  Each call creates a new context the size of the current clip region.  This can mean many large mallocs and frees.

An example:

<g opacity="0.5">
    <rect x="223" y="490" width="483" height="142" style="fill:red" />
    <g opacity="0.5">
        <rect x="377" y="82" width="271" height="121" style="fill:blue; fill-opacity:0.5" />
    </g>
</g>

This results in the use of two transparency layers when only one is truly necessary.  This modified SVG would render exactly the same:

<g opacity="0.5">
    <rect x="223" y="490" width="483" height="142" style="fill:red" />
    <rect x="377" y="82" width="271" height="121" style="fill:blue; fill-opacity:0.25" />
</g>

Containers need not create a transparency layer if they know that they only contain non-overlapping objects consisting of a simple fill or stroke (not both).
Comment 1 Dirk Schulze 2009-05-01 13:27:09 PDT
Isn't it possible to do it without transparencyLayer's? If an element has an opacity < 1.0, we multiply the opacity of it's childs with the opacity of the current element.
The last element of the tree is something that is rendered by SVGPaintServerSolid, -Pattern, Gradient and we use globalOpacity there.
Images need an extra handler, because they are not rendered via an SVGPaintServer.
That means for you example:

<g>
    <rect x="223" y="490" width="483" height="142" style="fill:red; fill-opacity:0.5" />
    <g>
        <rect x="377" y="82" width="271" height="121" style="fill:blue;
fill-opacity:0.125" />
    </g>
</g>
Comment 2 Dirk Schulze 2010-01-01 02:53:17 PST
Isn't it faster to use context->setAlpha(float) instead of transparencyLayer's, and let the graphic engine let do the work? Or are there other problems with it?