Re: Filter Effects and High DPI

On Fri, Mar 15, 2013 at 12:54 PM, Tab Atkins Jr. <jackalmage@gmail.com>wrote:

> On Fri, Mar 15, 2013 at 11:59 AM, Stephen White
> <senorblanco@chromium.org> wrote:
> > In particular, in Chrome's accelerated implementation, on a high-DPI
> > display, we get high-DPI input images from the compositor.  Right now,
>  we
> > filter the high-DPI image by the original (unscaled) parameter values,
> > which, for the filters whose pixel's result depends on more than a single
> > input pixel value (e.g., blur(), drop-shadow()), results in less blurring
> > than would be visible on a non-HighDPI display.  This seems wrong.  (Last
> > time I checked, the non-composited path was downsampling the input
> > primitive, giving a non-high-DPI result but correct amounts of blur,
> > although that may have been fixed).
>
> This is a bug in our implementation, then.  The values in the
> functions are CSS values, so a length of "5px" means 5 CSS pixels, not
> 5 hardware pixels.  The browser has to scale that to whatever internal
> notion of "pixel" it's using.
>
> > For blur() and drop-shadow(), It would be straightforward to scale the
> > parameter values by the devicePixelRatio automatically, and achieve the
> > correct amount of blurring without affecting the resolution of the
> result.
> > Of course, we could downsample the input primitive for all filters, but
> that
> > would lose the high DPI even for those filters which are unaffected by
> this
> > problem, e.g., brightness() etc.
> >
> > However, for the reference filters, in particular feConvolveMatrix, it's
> not
> > clear what the optimal behaviour is.  It's tempting to simply multiply
> the
> > kernelUnitLength by the devicePixelRatio, and apply the convolution as
> > normal.  However, that also loses high DPI, and incurs the cost of a
> > downsample where it otherwise wouldn't be required (also note that
> > kernelUnitLength seems to be unimplemented in WebKit, but that's our
> > problem).  Would it be a possibility to simply upsample the kernel by
> > devicePixelRatio instead, and apply that kernel to the original unscaled
> > image?   (Or perhaps size' = (size - 1) * devicePixelRatio + 1 for odd
> > kernel sizes?)   This would result in a similar effect range, while
> > preserving the resolution of the source image.
> >
> > I have no idea if the convolution math is really correct this way,
> though.
> > I'm guessing not, since if it was, presumably the spec would have allowed
> > its use for kernelUnitLength application in general.
>
> I'm not sufficiently familiar with feConvolveMatrix to know how to
> handle it well.  However, if you get a substantially different result
> (beyond rendering/scaling artifacts), the implementation is definitely
> wrong in some way.  None of SVG or CSS should require knowledge of the
> device's DPI.
>

>From the Filter Effects spec [1]:

Because they operate on pixels, matrix convolutions are inherently
resolution-dependent. To make ‘feConvolveMatrix’ produce
resolution-independent results, an explicit value should be provided for
either the ‘filterRes’ attribute on the ‘filter’element and/or attribute
‘kernelUnitLength’.

So, this is a case where the device's DPI is allowed to make a difference.
'FilterRes' [2] should be used if you want device independent output.
It seems that for feConvolveMatrix, 'FilterRes' should have been required.
(It's weird that 'FilterRes' is not a resolution but a number of device
pixels)

1:
https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#feConvolveMatrixElement

2:
https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#FilterElementFilterResAttribute

Received on Monday, 18 March 2013 02:02:25 UTC