W3C home > Mailing lists > Public > public-fx@w3.org > January to March 2013

Re: Filter Effects and High DPI

From: Stephen White <senorblanco@chromium.org>
Date: Mon, 18 Mar 2013 10:02:12 -0400
Message-ID: <CAPeKFTgw5DWRxiDOUPfayP4mjMCCn30Yx5Febc7Vz57b=pAvzg@mail.gmail.com>
To: Rik Cabanier <cabanier@gmail.com>
Cc: "Tab Atkins Jr." <jackalmage@gmail.com>, "public-fx@w3.org" <public-fx@w3.org>
On Sun, Mar 17, 2013 at 10:01 PM, Rik Cabanier <cabanier@gmail.com> wrote:

>
>
> 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)
>

Thanks!  I didn't catch that.

So it seems the author's options are:

1)  Set filterRes, and have the image downsampled before all filtering
(lo-DPI results)
2)  Set kernelUnitLength, and have the image downsampled before convolution
only (lo-DPI results).
3)  Check window.devicePixelRatio, and provide a kernel sized appropriately
to the DPI (hi-DPI results).

Does that sound right?

Stephen

>
> 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 14:02:44 GMT

This archive was generated by hypermail 2.3.1 : Monday, 18 March 2013 14:02:45 GMT