- From: Rik Cabanier <cabanier@gmail.com>
- Date: Mon, 18 Mar 2013 10:31:43 -0700
- To: Stephen White <senorblanco@chromium.org>
- Cc: "Tab Atkins Jr." <jackalmage@gmail.com>, "public-fx@w3.org" <public-fx@w3.org>
- Message-ID: <CAGN7qDDwB-zXPOHhemL6zgWS2nsXPzspjs9tn6dg3JwUNH=iNA@mail.gmail.com>
On Mon, Mar 18, 2013 at 7:02 AM, Stephen White <senorblanco@chromium.org>wrote: > 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? > I * think* option 2 will work for both high and low DPIsince it allows you to specify percentages or css pixel values [1]: By specifying value(s) for ‘kernelUnitLength’, the kernel becomes defined in a scalable, abstract coordinate system. If ‘kernelUnitLength’ is not specified, the default value is one pixel in the offscreen bitmap, which is a pixel-based coordinate system, and thus potentially not scalable. It seems that this should work OK for line art but might cause issues for high dpi images. Option 3 could use '@media resolution' [2] and switch to a filter for that particular pixel ratio. 1: https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#feConvolveMatrixElementKernelUnitLengthAttribute 2: http://www.w3.org/blog/CSS/2012/06/14/unprefix-webkit-device-pixel-ratio/
Received on Monday, 18 March 2013 17:32:13 UTC