Re: [whatwg] High-density canvases

2014-06-19 Thread Stephen White
On Thu, Jun 12, 2014 at 11:42 PM, Robert O'Callahan rob...@ocallahan.org
wrote:

 I think I'd rather not take control of canvas resizing away from
 applications, even opt-in. That leads to complexity such as extra API for
 slaving other canvases. I also think we'd be better off sticking to the
 invariant that the units of canvas coordinate space are single pixels in
 the canvas bitmap; I think that simplifies things for implementers and
 authors.


I agree.


 Here's an alternative proposal which I think is a bit simpler and more
 flexible:
 Expose two new DOM attributes on HTMLCanvasElement:
 readonly attribute long preferredWidth;
 readonly attribute long preferredHeight;
 These attributes are the UA's suggested canvas size for optimizing output
 quality. It's basically what Ian's proposal would have set as the automatic
 size. We would also add a preferredsizechange event when those attributes
 change.

 Applications that want DPI-aware canvases would read those attributes and
 use them to set the size, just once if they only want to paint once, during
 each requestAnimationFrame callback for games and other animations, and in
 the preferredsizechange event handler if they are willing to paint multiple
 times but aren't actually animating. The application would be responsible
 for scaling its output to the new canvas coordinate space size. Giving the
 application control of the size change simplifies things for the browser
 and gives applications maximum flexibility, e.g. resizing ancillary
 resources as needed, or imposing constraints on the chosen size.


I like this new proposal. It works for both the canvas and WebGL use cases,
and it puts the app in control of behaviour in a way that makes sense for
immediate-mode APIs.

I assume that the size change event would fire:

   - on browser page zoom
   - on pinch-zoom
   - when a CSS animation (e.g., scale) changes the canvas size in CSS
   pixels

For browsers that implement the latter two off the main thread, perhaps
they should only fire at end-of-gesture or end-of-animation, to avoid the
rendered size being out-of-sync with scaled size by the time the canvas
gets composited.

I agree with Mark that the names need work. How about something that
incorporates device pixel in some way, to reflect that this is roughly
dpr * css scale * size?

devicePixelWidth
widthInDevicePixels
pixelExactWidth
exactPixelWidth
pixelWidth
pixelRatioExactWidth
unscaledWidth
unscaledPixelWidth
nativeWidth
nativePixelWidth

Stephen



 Rob
 --
 Jtehsauts  tshaei dS,o n Wohfy  Mdaon  yhoaus  eanuttehrotraiitny  eovni
 le atrhtohu gthot sf oirng iyvoeu rs ihnesa.rt sS?o  Whhei csha iids  teoa
 stiheer :p atroa lsyazye,d  'mYaonu,r  sGients  uapr,e  tfaokreg iyvoeunr,
 'm aotr  atnod  sgaoy ,h o'mGee.t  uTph eann dt hwea lmka'n?  gBoutt  uIp
 waanndt  wyeonut  thoo mken.o w



Re: [whatwg] High-density canvases

2013-10-02 Thread Stephen White
On Fri, Sep 27, 2013 at 5:51 PM, Ian Hickson i...@hixie.ch wrote:

 On Tue, 10 Sep 2013, Stephen White wrote:
 
  For posterity, here were our objections to the original high-DPI canvas
  spec:
 - It doesn't scale well to non-integer devicePixelRatios

 Can you elaborate on this? I don't see why the new proposal would have
 this problem, but I also don't see why the old one would, so I don't know
 if it's because I don't understand the problem or if it's because I'm
 missing something from the old proposal.


IIRC, the concern was that calling getImageData() would return surprising
results when resampling by non-integer ratios, where the returned result
very much depends on the resampling mode, and the border treatment. At any
rate, since getImageData() doesn't resample in the new proposal, this won't
be a problem.

Stephen

 One question: now that some browsers are including browser zoom (page
  zoom) in window.devicePixelRatio, will/should the new proposal
  automatically cause a resize callback on page zoom, in order to preserve
  1:1 device pixels?

 My intent was to do so, yes. In practice I presume it'd be up to the
 browser to decide how often to actually do this (e.g. if page zoom is
 being smoothly animated, you may wish to only do it every few frames).


  (Note that I think this is a problem with current JS-based
  implementations of canvas auto-scale as well, although perhaps there's a
  DOM event for this that you can listen to; I might just be showing my
  ignorance here.)

 Currently page zoom should trigger a 'resize' event, but I expect few
 pages check.


 On Tue, 10 Sep 2013, Justin Novosad wrote:
 
  There is another closely related issue that's been discussed before:
  adding a redraw callback to 2d canvas.  In the past we discussed this
  for solving the problem of recoverring from a gpu context loss, but it
  seems there may be better reasons to consider adding a redraw callback
  such as freeing memory consumed by canvas backing stores that are in
  background tabs, and re-building the content when needed. This
  discussion was revived in the past few days on the chromium graphics-dev
  mailing list:
 
 https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/graphics-dev/CQJXpXxO6dk
 
  The idea is still embryonic and we're brainstorming in this chromium
  issue: crbug.com/287823
 
  I think that discussion should be merged with this thread because a
  resize event is another case where one may want to redraw. It would be
  great to solve all of these issues together.

 I think it would make eminent sense to also fire the event ('resize', I
 guess) if the context was lost or if the canvas was about to be made
 visible again after the browser dropped the rendering, yes.

 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] High-density canvases

2013-09-10 Thread Stephen White
For posterity, here were our objections to the original high-DPI canvas
spec:

   - The API feels like a short-term hack to automagically do something
   that the developer may or may not want done (e.g., if the game/app was
   tuned for particular resolution, or for pixel-exact rendering) that we'll
   be stuck with in the web platform long after its short-term usefulness has
   expired
   - It doesn't scale well to non-integer devicePixelRatios
   - It is easy for developers to implement the above behaviour in JS if
   desired

I think the new proposal addresses the first point, since it's opt-in. I
don't think the second point is a problem, since [get|put]ImageData() will
be back to manipulating exact backing store pixels, so no non-integer
resizing will be required. The third point becomes moot.

One question: now that some browsers are including browser zoom (page zoom)
in window.devicePixelRatio, will/should the new proposal automatically
cause a resize callback on page zoom, in order to preserve 1:1 device
pixels? (Note that I think this is a problem with current JS-based
implementations of canvas auto-scale as well, although perhaps there's a
DOM event for this that you can listen to; I might just be showing my
ignorance here.)

Stephen


On Mon, Sep 9, 2013 at 8:00 PM, Ian Hickson i...@hixie.ch wrote:

 On Wed, 17 Jul 2013, Rik Cabanier wrote:
  Ian wrote:
  
   The density aspect of this might be pointless, given the failure of
   getImageDataHD(); if we're dropping that one, I'll drop this one at
   the same time.
 
  Yes, please drop it since the HD methods are going away from the one
  implementation.

 On Tue, 9 Jul 2013, Stephen White wrote:
 
  Conversely, if it helps to bring the spec closer to the implementations,
  one thing we do not intend to implement in Chrome is the automatic
  high-DPI canvas scaling (ie., auto-doubling of backing stores,
  getImageDataHD(), putImageDataHD(), etc).
 
  I believe Apple has also announced that they are dropping support for
  this in Safari 7.

 So my understanding is that the reason this feature failed is that there's
 existing content that assumes a 1:1 ratio, and having an automatic
 high-density mode was making some pages end up with canvases with four
 canvas pixels per CSS pixel (linearly) -- two from the browser making a
 native canvas, times two from the page scaling the canvas for high DPI
 displays. This is a factor of sixteen over a 1:1 canvas, a factor of four
 more than it should be for high DPI, and a big waste of resources.

 As much as sites do this manually, though, it's a huge pain in the neck to
 have to worry about pixel density when you're creating your canvas and
 drawing on it, especially if you're not drawing sprites on it.

 While we're talking about annoying things, there's also the annoyance that
 canvases tend to not take zoom into account (either density-affecting zoom
 like page zoom on desktop, or transparent zoom like pinch-zoom on mobile
 for non-mobile-optimised sites, which the site isn't supposed to know
 about): you have to remember to listen for onresize, and then manually
 blow away your canvas and recreate it at the right density and then
 squeeze it into place so that the coordinate space matches what your code
 is expecting while the canvas is actually sized for the display.

 There's also the issue of full-bleed canvases where every time the
 container changes, you have to remember to re-update the canvas coordinate
 space and repaint because otherwise your pretty page gets all warped.

 It would be nice to fix these all at once, and I think we can, by
 introducing a configuration option on getContext(), in the style of WebGL:

getContext('2d', { density: 'autosize' });

 This would trigger the following behaviour: When the context is created,
 and subsequently when the canvas changes size (e.g. due to being sized
 with CSS relative units and the element they're relative to changing), or
 when the display density changes size (e.g. due to page zoom), then:

- the width and height of the canvas bitmaps get updated to match the
  new native size of the canvas, at native density.

- the coordinate space of the canvas (context.width/context.height)
  gets updated to match the size of the canvas in CSS pixel units.

- a 'resize' event gets fired at the canvas.

 We would dump the *HD versions of the methods, and make the regular ones
 go back to returning the actual raw pixels, since that would now work fine
 and still provide HD-quality content everywhere it's available.

 What do people think?

 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] Antialiasing of line widths 1 (was Re: Blurry lines in 2D Canvas (and SVG))

2013-08-13 Thread Stephen White
On Sat, Aug 10, 2013 at 11:07 PM, Rik Cabanier caban...@gmail.com wrote:



 On Sat, Aug 10, 2013 at 7:50 AM, Glenn Maynard gl...@zewt.org wrote:

 On Sat, Aug 10, 2013 at 7:42 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 Chrome (well, Skia actually) uses a hairline mode for line widths  1.
 It draws a line of width 1, and uses the width to modulate the alpha.  I
 think the idea is to prevent blotchiness/unevenness caused by undersampling
 or missed coverage (Skia uses 16 samples of AA).


 That sounds like it should be fine, since it should give results similar
 to what users would expect from simple coverage antialiasing.

  I'm not sure that's what I'm seeing, though.
 http://jsfiddle.net/eZEyH/1/  The 0.001 width stroke is being drawn
 solid black in the pixel-centered (left) case.  In the right one,
 horizontally aligned to the edge of a pixel, the stroke disappears.  (I
 left it vertically pixel-centered, so the box didn't disappear entirely.)
 The right is what I'd expect to always happen with a lineWidth that thin.
 Similar things happen with thicker widths, the 0.001 just makes it very
 easy to see.



That is clearly a bug. :-)


Yep, seems to be a bug in Skia's raster backend. I've logged it as
https://code.google.com/p/skia/issues/detail?id=1505; feel free to add
further comments there.

Stephen




 This can become visible during animation, eg.
 http://jsfiddle.net/xSUuB/1/.  In Chrome, the line flickers between
 solid black and grey.  In Firefox, it's antialiased normally, so it
 consistently appears grey (actually shifting between one pixel of grey and
 two pixels of lighter grey).


 Yeah. Chrome seems to flip between no AA and AA which sounds like a bug in
 their algorithm.



Re: [whatwg] remove resetClip from the Canvas 2D spec

2013-08-12 Thread Stephen White
If this is strictly a performance issue, then we definitely should fix that
before adding new API, IMHO. It would be great to get some reduced test
cases where save()/restore() is a bottleneck.

(Incidentally, we did some performance fixes recently for setFont() in
Chrome.)

Stephen



On Mon, Aug 12, 2013 at 6:34 PM, Rik Cabanier caban...@gmail.com wrote:



 On Mon, Aug 12, 2013 at 2:26 PM, Justin Novosad ju...@google.com wrote:

 Ok, so here is a simple proposal:

 IDL:
 enum CanvasSaveMode { all, transform, clip, transform-and-clip };
 save(optional CanvasSaveMode mode);

 Modes:
 all: save the entire rendering context state
 transform: save only the current transform
 clip: save only the current clip

 if mode is not specified, the entire context state is saved (for backward
 compatibility)

 The restore method's interface does not change. It restores whatever
 state was saved by the matching save call.


 I wasn't really thinking about a new API surface :-)
 Can't this be fixed under the hood? The tricks that Simon is doing, could
 be done by the browser itself.

 If not, this proposal looks reasonable (if you turn it into a dict like
 Tab says).


 On Mon, Aug 12, 2013 at 4:56 PM, Simon Sarris simon.sar...@gmail.comwrote:

  Good point, I think part of the problem has to do with the fact that
 save
  is non-selective (saves all of the state).

 Yes, since save() and restore() save and restore everything, it creates
 the side effect of needing to set ctx.font/fillStyle/strokeStyle more often
 than otherwise, which are slow to set, probably because of some CSS parser
 activity, but I'm not wise enough to know.

 If there was merely a way to save and restore the context, or perhaps
 some other subset of state, that would probably work nicely too.










[whatwg] Antialiasing of line widths 1 (was Re: Blurry lines in 2D Canvas (and SVG))

2013-08-10 Thread Stephen White
On Sat, Aug 10, 2013 at 1:07 AM, Glenn Maynard gl...@zewt.org wrote:

 On Fri, Aug 9, 2013 at 11:07 PM, Rik Cabanier caban...@gmail.com wrote:


  Chrome seems ignore stroke widths that are smaller than 1 (which is
 reasonable).


 (That seems wrong to me--it should continue to draw based on pixel
 coverage--but that's a separate issue...)


  Is it? Obviously you can't draw less than a pixel, but the user did
 specify that he wants it too look black.


 strokeStyle = black doesn't mean every pixel in the stroke should be
 black.  It's the color of the pen.  If you draw over half of a pixel with
 a black pen, you get 50% grey.

 It'd be one thing if Chrome didn't antialias at all, but if Chrome is
 antialiasing a stroke with a lineWidth of 1.5, it doesn't make sense that
 it's not antialiasing a stroke with a lineWidth of 0.75.  I don't think
 this is strictly specified; the only mention of anti-aliasing is an example
 of how to do it (oversampling).


Chrome (well, Skia actually) uses a hairline mode for line widths  1. It
draws a line of width 1, and uses the width to modulate the alpha.  I think
the idea is to prevent blotchiness/unevenness caused by undersampling or
missed coverage (Skia uses 16 samples of AA).

Here's an example: hairline on the left, .2 width path on the right:
http://jsfiddle.net/FWLZt/

Stephen


 This is tangental, though.  Might want to start another thread if you want
 to go over this more, or we'll derail this one...


Done.



 --
 Glenn Maynard




Re: [whatwg] remove resetClip from the Canvas 2D spec

2013-08-09 Thread Stephen White
Although Skia could support resetClip() via SkRegion::kReplace_Op, it's
problematic for the API in general, and I think we should avoid it.

In particular, it makes it impossible to place a display list (SkPicture in
Skia parlance) inside a parent display list containing a clip and be
assured that the child will not draw outside the given region, since the
child display list can always resetClip() its way out of the parent's
clip. It probably also prevents culling optimizations for the same reason.

For example, if one used Skia to draw the entirety of a browser UI
including chrome and content, the resetClip() inside the web page contents
would overwrite the browser UI. Obviously we don't do that in Chrome, but
it goes some idea of the problem at the API level.

Stephen


On Thu, Jul 18, 2013 at 1:39 PM, Ian Hickson i...@hixie.ch wrote:

 On Tue, 29 Jan 2013, Rik Cabanier wrote:
 
  we were looking at how resetClip could be implemented in WebKit. Looking
  over the Core Graphics implementation, this feature can't be implemented
  without significant overhead. I also found an email from 2007 where
  Maciej states the same concern:
 http://permalink.gmane.org/gmane.org.w3c.whatwg.discuss/10582

 The solution on Mac is probably for Apple to update CoreGraphics to
 support this feature.

 This is a quite widely requested feature.


  Since no browser has implemented it, can it be removed from the spec?

 It's new, so no browser having implemented it is expected.


 If browsers don't implement it, it'll get removed in due course. But it
 would be sad for authors, who are the main concern here.

 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] Blurry lines in 2D Canvas (and SVG)

2013-08-09 Thread Stephen White
I think one problem you might run into is that, if you consider a stroked
line to be centered on pixel centers rather than pixel edges, then the same
path when filled and stroked would touch different pixels along each edge.

Consider a 10x10 rectangle, drawn at coordinates coordinates 5, 5. If
filled, this would fill pixels 5-14 in X and 5-14 in Y. If stroked, this
will draw 1-pixel wide rectangles centered along (5, 5) - (14, 5) - (14,
14) - (5, 5). With antialiasing this will touch pixels 4-15 in each
dimension.  http://jsfiddle.net/6KS4V/

If the stroke was instead drawn centered over half pixels, the stroked
rects would be centered along (5.5, 5.5) - (14.5, 5.5) - (14.5, 14.5) -
(14.5, 5.5) - (5.5, 5.5). This would touch pixels 5-15 in each dimension.
If drawn with transparency, the resulting left and top edges would look
different than the bottom and right edges.  E.g., http://jsfiddle.net/9xbkX/
.

(Please ignore blurriness induced by the CSS upscaling; you can remove the
CSS and use a zooming tool if you prefer).

Stephen



On Tue, Jul 23, 2013 at 7:19 PM, Rik Cabanier caban...@gmail.com wrote:

 All,

 we've noticed that if you draw lines in canvas or SVG, they always end up
 blurry.
 For instance see this fiddle: http://jsfiddle.net/V92Gn/128/

 This happens because you offset 1 pixel and then draw a half pixel stroke
 on each side. Since it covers only half the pixel, the color gets mapped to
 50% gray.
 You can work around this by doing an extra offset of half the
 devicepixelratio, but ideally this should never happen.

 Is this behavior specified somewhere?
 Is there a way to turn this off?



Re: [whatwg] Blurry lines in 2D Canvas (and SVG)

2013-08-09 Thread Stephen White
That's an interesting idea. I suppose the fully general solution would be
to have a stroke offset. E.g., with a stroke width of 4 and and offset of
2 you'd get outer, offset -2 you'd get inner, offset 1 you'd get 3
pixels outer and 1 pixel inner, etc. Dunno how useful that is, though.

Stephen


On Fri, Aug 9, 2013 at 5:24 PM, Glenn Maynard gl...@zewt.org wrote:

 On Fri, Aug 9, 2013 at 4:17 PM, Stephen White senorbla...@chromium.orgwrote:

 If the stroke was instead drawn centered over half pixels, the stroked

 rects would be centered along (5.5, 5.5) - (14.5, 5.5) - (14.5, 14.5) -
 (14.5, 5.5) - (5.5, 5.5). This would touch pixels 5-15 in each
 dimension.
 If drawn with transparency, the resulting left and top edges would look
 different than the bottom and right edges.  E.g.,
 http://jsfiddle.net/9xbkX/


 My proposal addresses this, by adding an outer stroke mode.
 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/040252.html

 --
 Glenn Maynard




Re: [whatwg] Blurry lines in 2D Canvas (and SVG)

2013-08-09 Thread Stephen White
On Fri, Aug 9, 2013 at 8:16 PM, Rik Cabanier caban...@gmail.com wrote:



 On Fri, Aug 9, 2013 at 2:17 PM, Stephen White senorbla...@chromium.orgwrote:

 I think one problem you might run into is that, if you consider a stroked
 line to be centered on pixel centers rather than pixel edges, then the same
 path when filled and stroked would touch different pixels along each edge.

 Consider a 10x10 rectangle, drawn at coordinates coordinates 5, 5. If
 filled, this would fill pixels 5-14 in X and 5-14 in Y. If stroked, this
 will draw 1-pixel wide rectangles centered along (5, 5) - (14, 5) - (14,
 14) - (5, 5). With antialiasing this will touch pixels 4-15 in each
 dimension.  http://jsfiddle.net/6KS4V/

 If the stroke was instead drawn centered over half pixels, the stroked
 rects would be centered along (5.5, 5.5) - (14.5, 5.5) - (14.5, 14.5) -
 (14.5, 5.5) - (5.5, 5.5). This would touch pixels 5-15 in each dimension.
 If drawn with transparency, the resulting left and top edges would look
 different than the bottom and right edges.  E.g.,
 http://jsfiddle.net/9xbkX/.

 (Please ignore blurriness induced by the CSS upscaling; you can remove
 the CSS and use a zooming tool if you prefer).


 Yes, I agree that strokes and fills should be treated the same to avoid
 this problem.
 I'm unsure if Glenn's suggestion for an outer and inner stroke fix the
 problem. An inner or outer stroke will look very different.


Sure, but it's up to the developer to choose. It looks like Illustrator has
something very similar; see the Align Stroke buttons here:
http://help.adobe.com/en_US/illustrator/cs/using/WSA1E31D7D-13E6-41ac-AA8C-4AD129B9FC1Ca.html.
I don't have a copy of Illustrator to try it, though.

In addition if the corners of the path don't align with the grid, you will
 get a blurry outline again.


Well, as long as you choose the right mitering style, I think the corners
would be fine. It's basically the same algorithm as normal path stroking,
except instead of translating half the stroke width on either side of the
path along the tangent, you'd just use the path as one edge and translate
the other the full stroke width.

As an experiment, I drew 4 rectangles in JSFiddle with stroke width of .5,
 .75, 1, 1.5 and 2: http://jsfiddle.net/6KS4V/2/
 I aligned them to the grid as Glenn suggested.
 This is a blown up screenshot from IE (Firefox looked the same):
 http://bit.ly/16FVCKd
 and here's one from Chrome: http://bit.ly/19Tf9Ko

 The rectangle that's 2 points wide is somewhat blurry, but the one that is
 1.5  is very bad.
 Chrome seems ignore stroke widths that are smaller than 1 (which is
 reasonable).


I think this more like what the outer stroke style would do:
http://jsfiddle.net/ZrbQh/

The interior rectangle is the same in each one, with the outer edge nudged
outwards along the tangent (the sizes may be wrong for the 1 lineWidth
cases; I didn't spend too long on it).

Stephen


 I then recreated the content in Illustrator, opened the file in Acrobat
 and took a screenshot: http://bit.ly/15loBhu
 As you can see, Acrobat doesn't apply any anti-aliasing. It seems to
 'snap' the points to the grid and adjust the stroke width so it fills whole
 pixels. I ran some experiments and I *think* this is also what CSS does.

 I believe that this could be accomplished with a new attribute in the
 graphics state. Doing it programmatically should also work but is quite
 difficult.
 I wonder if our mozilla friends that work on shumway and pdf.js are
 running into this...



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-07-23 Thread Stephen White
On Tue, Jul 16, 2013 at 6:41 PM, Ian Hickson i...@hixie.ch wrote:


 This thread was gigantic and involved many proposals. I've only included
 the last one below, since it seemed to take into account the most of the
 feedback mentioned on the thread; I haven't responded to all the
 intermediate e-mails which were mainly just a discussion amongst
 contributors, and not direct feedback on the spec itself.

 I haven't yet changed the spec. The main thrust of the feedback below ends
 with the proposal to use WebGL's 'alpha' feature for the 2D context; is
 this what implementors want to do?


We're implementing this in Chromium (currently behind the experimental
canvas features flag).




 [...]

 On Fri, 15 Feb 2013, Stephen White wrote (with roc's annotations inline
 prefixed with | and mine inline not prefixed):
 
  So let me take a stab at a brief summary of the proposals so far, and
  the pros and cons of each (correct me if I missed anything):
 
   opaque attribute or matteColor property
  pro:  fairly easy to implement
  pro:  no performance hit over regular rendering
  pro:  many opportunities for optimization
  pro:  catches all in-canvas cases of color fringing
  con:  does not handle any out-of-canvas color fringing
  con:  opt-in
 | con:  requires changes to canvas compositing spec and possibly
 |   implementations.
 
  automatic opacity detection
  pro:  catches most (all?) cases of in-canvas color fringing
  pro:  some opportunties for optimization (must be conservative in some
cases)
  con:  does not catch color fringing on CSS transforms, canvas - WebGL,
etc
 
  context.textAntialising = { 'none', 'grayscale', 'subpixel' }
  pro:  very easy to implement
  pro:  no performance hit
  con:  does not catch any cases of color fringing; completely up to web
developer
  con:  opt-in
 | con:  requires specification and implementation of what happens when
 |   subpixel AA is drawn over transparent background.
 
  collect commands into a buffer, flush buffer only when compositing
  canvas to page, and decide on subpixel AA at that point.
  pro:  catches all cases of color fringing
  con:  in some cases, requires an infinite buffer (e.g., a canvas that
never clears, and only accumulates drawing frame-to-frame means
you must accumulate commands indefinitely)
 or giving up and using grayscale at some point
  con:  difficult to implement (e.g., canvas-to-canvas drawImage(), etc)
  con:  may introduce performance hit due to re-rendering with and without
subpixel AA (in cases where you would rather have just gone
without)
   con:  doesn't handle pixel manipulation cases (since you can't return
 two sets of pixels and you can't regenerate the stuff that script
 is generating based on the returned pixels)
 
  two buffers (one grayscale, one LCD AA)
  pro:  handles all cases of color fringing
  pro:  moderately easy to implement
  con:  RAM (or VRAM) usage is doubled
  con:  possibly-unnecessary performance hit
  con:  must be opt-in

 [...]

 On Wed, 20 Feb 2013, Rik Cabanier wrote:
 
  So now we have:
  - don't do this on pinch-zoom devices
  - don't do this for HW accelerated canvases
  - don't do this if the canvas dpi doesn't match the screen
  - don't do this if there are transforms
  - authors will have to be very careful when using this feature since it
 can
  turn on or off or cause rendering glitches.
 
  Is it still worth pursuing this?

 On Thu, 21 Feb 2013, Stephen White wrote:
 
  I believe it is.  Even with those constraints, there are a large number
  of applications which can benefit from text which looks as good as the
  native platform can provide.
 
  That said, I also think Robert is right that we should not spec out
  precisely when subpixel AA text will occur in any of these automatic
  modes, since:
 
  1) there are some platforms/devices which don't do LCD text at all
 
  2) It may be too restrictive for the browser implementor, e.g., they
 may be essentially required to implement deferred rendering or two
 backing stores in order to meet the resulting spec, which seems
 onerous
 
  Subpixel AA text aside, I still think it's worth spec'ing out mozOpaque,
  if only just for the optimization opportunities that we don't get with
  an automatic solution (e.g., putImageData).  Its implementation is
  fairly straightforward (much more so than the other options above), and
  it won't break any existing content.
 
  To me, the it breaks compositing argument falls into the doctor, it
  hurts when I do this category:  the user is specifically opting into an
  opaque backing store, and so the changes in behaviour for compositing
  modes which reference destination alpha are expected, just as they are
  when using DST_ALPHA blending modes in a WebGL context created with the
  alpha attribute set to false.

 On Fri, 22 Feb 2013, Robert O'Callahan wrote:
 
  I think Rik is convincing me that we shouldn't

Re: [whatwg] Adding 2D Canvas features (Was: Grouping in canvas 2d)

2013-07-09 Thread Stephen White
Conversely, if it helps to bring the spec closer to the implementations,
one thing we do not intend to implement in Chrome is the automatic high-DPI
canvas scaling (ie., auto-doubling of backing stores, getImageDataHD(),
putImageDataHD(), etc).

I believe Apple has also announced that they are dropping support for this
in Safari 7.

Stephen



On Fri, Jun 28, 2013 at 3:30 PM, Tom Wiltzius wiltz...@chromium.org wrote:

 The only major Canvas2D features being actively developed in Chromium right
 now are:

  - having a canvas context alpha attribute
  - text decoration
  - compositing and blending
  - canvas access in workers

 (easily referenced from http://www.chromestatus.com/features)

 It is concerning to me that the list of other unimplemented features that
 aren't being worked on could block the standardization of the above (all of
 which have been discussed on this list at one point, but not all of which
 are in the spec yet).

 How can we help reconcile this discrepancy?


 On Fri, Jun 14, 2013 at 11:54 AM, Rik Cabanier caban...@gmail.com wrote:

  I agree that hit regions should be high on the priority list. They've
 been
  in the spec for a while and are absolutely required for accessibility.
  I will try to follow up on this feature with the browsers. We recently
  added a basic Path object to WebKit and I know that mozilla is looking at
  the path object.
 
  At this point, I wouldn't ask to add begin/endLayer to the spec. Instead,
  we will talk to the browser vendors and work on implementing the feature.
  Just putting it in the spec is not enough to get an implementation...
 
  On Fri, Jun 14, 2013 at 10:42 AM, Ian Hickson i...@hixie.ch wrote:
 
   On Fri, 14 Jun 2013, Brian Salomon wrote:
   
As an implementor, we would prefer the layer approach. This would
 have
lower overhead in Chromium/Skia. We can make better decisions about
caching and deferred rendering. It also seems like a really handy API
for devs, especially the ability to inherit the graphics state. Would
the spec have anything to say about beginLayer()/endLayer()
 balancing,
especially with respect to RAF?
  
   I have no ojection to adding this to the spec, but right now the spec
 has
   a bunch of features that aren't implemented, and there's a long list of
   other features people want that aren't yet specced. I'm very hesitant
 to
   get the spec further and further away from implementations.
  
   For example, here are some of the bug numbers for canvas feature
   requests:
  
   11399   canvas Locking individual color channels (e.g. drawing to
 alpha
only)
   21835   canvas Path object should have a way to add paths keeping
 only
the union given a fill rule
   21939   canvas Path objects would be much more useful if their
individual commands (moveTo, lineTo, etc.) could be
inspected from JavaScript [...]
   8794canvas lineWidth = 'hairline'
   11739   canvas clearPath() that clears pixels the way clearRect()
 does,
but using a path
   9236canvas Detecting the intersection of Path objects
   9235canvas perspective transformations
   18751   canvas a way to get the coordinate of the last point in a
 path
   21346   canvas Have ImageBitmap expose height and width attributes
  
   (Bugs accessible from https://www.w3.org/Bugs/Public/)
  
   There's also the printCallback API proposal from Mozilla:
  
 
 http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Sep/0371.html
  
   Adding a parameter to drawImage for sprite sheets to avoid bleeding,
   proposal from Chrome:
  
 
 http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Dec/0088.html
  
   Stroke alignment:
  
 
 http://lists.w3.org/Archives/Public/public-whatwg-archive/2010Jul/0238.html
  
   Page flipping instead of double buffering:
  
 
 http://lists.w3.org/Archives/Public/public-whatwg-archive/2013Jan/0073.html
  
   Inner shadows:
  
  
 
 http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-November/038079.html
  
  
   Plus, as I mentioned, things in the spec that aren't implemented
 widely:
   Right now, the things in the spec that aren't widely implemented are
 the
   things that were needed for accessibility (hit regions) and the things
   that are the basis for some of the most-requested features (Paths).
  
  
   I think before we add more features, it's important that we figure out
   which browsers want to implement which features, and that we start with
   the highest priority ones.
  
   --
   Ian Hickson   U+1047E)\._.,--,'``.
  fL
   http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._
 ,.
   Things that are impossible just take longer.
 `._.-(,_..'--(,_..'`-.;.'
  
 



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-04-19 Thread Stephen White
Thanks for your comments.

On Fri, Apr 19, 2013 at 12:53 PM, Rik Cabanier caban...@gmail.com wrote:

 Nice!

 The behaviour of putImageData() and putImageDataHD() is to premultiply the
 RGB components by the alpha component as usual, but write 1.0 into
 destination alpha. In other words, if (r, g, b, a) are the component values
 in a given pixel passed to putImageData[HD](), then r' = ar, g' = ag, b' =
 ab are the colour components of the resulting canvas pixel, and (r', g',
 b', 1.0) is written to the canvas backing store.

 I think that's confusing. Maybe cut that sentence since it isn't needed.
 (Having the black backing store implies this behavior)


Do you mean, remove both sentences, or just the last one?  I wanted to make
it clear that the RGB is still premultiplied with the original alpha, even
though the alpha is subsequently ignored.

attribute boolean alpha;

 Should it be read-only?


Hmm, I have no idea.  WebGL's doesn't have it, but I'm not enough of an IDL
expert to know whether it's necessary.



 Canvas2DContextAttributes getContextAttributes();

 Maybe make it an attribute:

 attribute Canvas2DContextAttributes attributes:


I'm following WebGL syntax here as well.  Apparently WebGL's is nullable,
though, so I've added ? here.

Stephen


 On Fri, Apr 19, 2013 at 9:13 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 Here's a short proposal I've written up for the getContext('2d', { alpha:
 false } ) version of this idea (much of it culled from the mega-thread
 above).

 http://wiki.whatwg.org/wiki/CanvasOpaque

 Comments are welcome.

 Stephen





Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-04-03 Thread Stephen White
Would Mozilla (or other browser vendors) be interested in implementing the
hint as Gregg described above?

If so, we could break out the LCD text issue from canvas opacity, and
consider the latter on its own merits, since it has benefits apart from LCD
text (i.e., performance). Regarding that, if I'm reading correctly,
Vladimir Vukicevic has expressed support on webkit-dev for the
ctx.getContext('2d', { alpha: false }) proposal (basically, a syntactic
rewrite of canvas opaque). Does this indeed have traction with other
browser vendors?

As for naming, I would prefer that it be something like ctx.fontSmoothing
or ctx.fontSmoothingHint, to align more closely with canvas's
ctx.imageSmoothingEnabled and webkit's -webkit-font-smoothing CSS property.
 -webkit-font-smoothing has none, antialiased and
subpixel-antialiased as options. I think it's ok to explicitly call out
subpixel antialiasing, even if the platform (or UA) does not support it,
especially if the attribute explicitly describes itself as a hint.

Stephen


On Sun, Mar 17, 2013 at 11:17 PM, Gregg Tavares g...@google.com wrote:

 On Sun, Mar 17, 2013 at 1:40 PM, Robert O'Callahan rob...@ocallahan.org
 wrote:

  On Sat, Mar 16, 2013 at 5:52 PM, Gregg Tavares g...@google.com wrote:
 
  Let me ask again in a different way ;-)  Specifically about LCD style
  antialiasing.
 
  What about a context attribute antialiasRenderingQualityHint for now
  with
  2 settings default and displayDependent
 
 context.antialiasRenderingQualityHint = displayDependent
 
 
  How would this interact with canvas opacity? E.g. if the author uses
  displayDependent and then draws text over transparent pixels in the
 canvas,
  what is the UA supposed to do?
 

 Whatever the UA wants. It's a hint. From my POV, since the spec doesn't say
 anything about anti-aliasing then it really doesn't matter.

 My preference, if I was programming a UA, would be if the user sets
 displayDependent and the UA is running on a lo-dpi machine I'd
 unconditionally render LCD-AA with the assumption that the canvas is
 composited on white. If they want some other color they'd fill the canvas
 with as solid color first. Personally I don't think that needs to be
 specced, but it would be my suggestion. As I mentioned, even without this
 hint the spec doesn't prevent a UA from unconditionally using LCD-AA.

 Very few developers are going to run into issues. Most developers that use
 canvas aren't going to set the hint. Most developers that use canvas dont'
 make it transparent nor do they CSS rotate/scale them. For those few
 developers that do happen to blend and/or rotate/scale AND set the hint
 they'll get probably get some fringing but there (a) there was no guarantee
 they wouldn't already have that problem since as pointed out, the spec
 doesn't specify AA nor what kind, and (b) if they care they'll either stop
 using the hint or they'll search for why is my canvas fringy and the
 answer will pop up on stackoverlow and they can choose one of the
 solutions.



 
  Rob
  --
  Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
  Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
  bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
  lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe
 fynir
  — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
  tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]
 



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-04-03 Thread Stephen White
On Wed, Apr 3, 2013 at 12:04 PM, Gregg Tavares g...@google.com wrote:




 On Wed, Apr 3, 2013 at 8:41 AM, Stephen White senorbla...@chromium.orgwrote:

 Would Mozilla (or other browser vendors) be interested in implementing
 the hint as Gregg described above?

 If so, we could break out the LCD text issue from canvas opacity, and
 consider the latter on its own merits, since it has benefits apart from LCD
 text (i.e., performance). Regarding that, if I'm reading correctly,
 Vladimir Vukicevic has expressed support on webkit-dev for the
 ctx.getContext('2d', { alpha: false }) proposal (basically, a syntactic
 rewrite of canvas opaque). Does this indeed have traction with other
 browser vendors?

 As for naming, I would prefer that it be something like ctx.fontSmoothing
 or ctx.fontSmoothingHint, to align more closely with canvas's
 ctx.imageSmoothingEnabled and webkit's -webkit-font-smoothing CSS property.
  -webkit-font-smoothing has none, antialiased and
 subpixel-antialiased as options. I think it's ok to explicitly call out
 subpixel antialiasing, even if the platform (or UA) does not support it,
 especially if the attribute explicitly describes itself as a hint.



 Why call it Font smoothing? Shouldn't a UA be able to also render paths
 using the same hint?


I think it would be better to control antialiasing for fonts and paths
independently. In addition to providing greater control, subpixel
antialiasing usually only benefits small, detailed paths such as fonts.
Large paths don't benefit greatly from it.

On a practical level, most platform graphics APIs don't provide subpixel
antialiasing for paths, only for text.  So it would have to be implemented
as a custom path renderer, and it would have to have access to the LCD
subpixel structure and orientation, which many platform APIs may not
provide.

Stephen


 Stephen


 On Sun, Mar 17, 2013 at 11:17 PM, Gregg Tavares g...@google.com wrote:

 On Sun, Mar 17, 2013 at 1:40 PM, Robert O'Callahan rob...@ocallahan.org
 wrote:

  On Sat, Mar 16, 2013 at 5:52 PM, Gregg Tavares g...@google.com
 wrote:
 
  Let me ask again in a different way ;-)  Specifically about LCD style
  antialiasing.
 
  What about a context attribute antialiasRenderingQualityHint for now
  with
  2 settings default and displayDependent
 
 context.antialiasRenderingQualityHint = displayDependent
 
 
  How would this interact with canvas opacity? E.g. if the author uses
  displayDependent and then draws text over transparent pixels in the
 canvas,
  what is the UA supposed to do?
 

 Whatever the UA wants. It's a hint. From my POV, since the spec doesn't
 say
 anything about anti-aliasing then it really doesn't matter.

 My preference, if I was programming a UA, would be if the user sets
 displayDependent and the UA is running on a lo-dpi machine I'd
 unconditionally render LCD-AA with the assumption that the canvas is
 composited on white. If they want some other color they'd fill the canvas
 with as solid color first. Personally I don't think that needs to be
 specced, but it would be my suggestion. As I mentioned, even without this
 hint the spec doesn't prevent a UA from unconditionally using LCD-AA.

 Very few developers are going to run into issues. Most developers that
 use
 canvas aren't going to set the hint. Most developers that use canvas
 dont'
 make it transparent nor do they CSS rotate/scale them. For those few
 developers that do happen to blend and/or rotate/scale AND set the hint
 they'll get probably get some fringing but there (a) there was no
 guarantee
 they wouldn't already have that problem since as pointed out, the spec
 doesn't specify AA nor what kind, and (b) if they care they'll either
 stop
 using the hint or they'll search for why is my canvas fringy and the
 answer will pop up on stackoverlow and they can choose one of the
 solutions.



 
  Rob
  --
  Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
  Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
  bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng
 nzbat
  lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe
 fynir
  — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq
 gb
  tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]
 






Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-14 Thread Stephen White
On Wed, Mar 13, 2013 at 10:28 PM, Gregg Tavares g...@google.com wrote:




 On Wed, Mar 13, 2013 at 1:18 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Thu, Mar 14, 2013 at 8:04 AM, Gregg Tavares g...@google.com wrote:

 It seems like an opaque canvas should be an orthogonal issue to
 subpixel-aa. Subpixel AA seems like it should be a Canvas2DRenderingContext
 setting though maybe with a name like

ctx.antialiasingRenderQuality =

 With options of

none
grayscale
bestForDeviceIfAxisAlignedAndNotScaledOrBlended


 My mistake. They should be

 none
 alpha

 bestForDeviceIfNotCanvasIsNotRotatedAndCanvasIsNotScaledAndCanvasIsOpaque


Don't forget
AndCanvasIsNotFilteredAndCanvasIsNotDrawnViaWebGLThroughAShaderWhichModifiesFragmentColour.
 :)

(And actually, this name sort of leads me to believe the opposite:  that
the API will take care of these cases for me, and I don't have to worry
about them.)

Naming aside, this is basically the proposal from message #1 in this thread
(and mine from partway through).  The objections were that this is a
footgun with which web developers should not be trusted.  For the record, I
don't agree with that assessment.  However, since it seemed that moz-opaque
had at least some chance of being implemented by other browser vendors, and
provides a generally useful optimization, I was pursuing that approach
instead.


 Stephen



 ;-)

 Yes, I know that's a horrible name but it spells out the limitation of the
 higher quality aa needed on some devices. A dev can opt in (Since the
 default is alpha which is what happens today).

 If they opt in

 (a) it will look good if they follow the rules

 and

 (b) as the world transitions to HD-DPI it will end up being alpha so it's
 forward compatible.




 Ugh!


 This would let the developer choose. It would be clear what the limits
 are, when to use it, and would let the developer choose what they need,
 even in an opaque canvas.


 Then we would need to come up with a spec for what happens when you
 composite subpixel AA over non-opaque pixels, including how the per-channel
 alpha values are combined to form a single alpha value. IIRC in some cases
 (D2D) you just can't do it.

 If we said that in a non-opaque canvas, subpixel AA is treated as
 grayscale, that would be OK.


 sure.




 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]





Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-14 Thread Stephen White
On Wed, Mar 13, 2013 at 2:48 PM, Gregg Tavares g...@google.com wrote:

 Sorry for only mentioning this so late but is there any chance to steer
 this to be more inline with WebGL?

 WebGL already has the option to have an opaque canvas using context
 creation parameters. In WebGL it's

gl = canvas.getContext(webgl, {alpha: false});

 If we go forward with an opaque attribute now you have 2 conflicting
 settings.

canvas.opaque = true;
gl = canvas.getContext(webgl, {alpha: true});

 Who wins that conflict? Yea, I know we could come up with rules. ( the 2
 settings, etc...)

 But, there are other context creation attributes we'd like to see on a 2d
 canvas. One that comes to mind is 'preserveDrawingBuffer'.
 preserveDrawingBuffer: false in WebGL means that the canvas is double
 buffered. This is a performance win since most browsers using GPU
 compositing need to copy the contents of the canvas when compositing.
 Setting preseverDrawingBuffer: false (which is the default in WebGL) means
 the browser can double buffer and avoid the copy. We'd like to see that
 same attribute for 2D canvas/contexts to get the same perf benefit for
 canvas games, etc.


 So, given we want more creation attributes and given WebGL already has a
 way to declare opaqueness why not follow the existing method and add
 context creation parameters to 2d canvas to solve this issue rather than
 make a new and conflicting 'opaque' attribute?


I have no major objections to this approach, so long as it doesn't make
this change contingent on a WebGL spec change.  In particular, it's
tempting to unify the IDL between Canvas  WebGL (although it may not be
necessary -- I'm far from an IDL expert.)  Here, let me show you my
ignorance:  can we create a

interface Canvas2DContextAttributes {
  attribute boolean alpha;
}

which has no relation to WebGLContextAttributes?

Then we get at least the duck typing such that

ctx = canvas.getContext('2d', {alpha: false });

and

ctx = canvas.getContext('webgl', {alpha: false });

both work, although one is coerced into a WebGLContextAttributes and the
other to a Canvas2DContextAttributes.

Does that make sense?

Stephen


Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-12 Thread Stephen White
On Mon, Mar 11, 2013 at 4:32 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 8:23 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 7:53 AM, Stephen White senorbla...@chromium.org
  wrote:

 All other canvas functionality behaves as normal, including operations
 which modify the alpha values of the backing store.  However, any such
 transparency values will be ignored when compositing the canvas into the
 page, and the canvas will be treated as if every pixel has an alpha of 1.0.


 That would mean getImageData can return non-1.0 alpha values, which is
 probably not what you want to implement.


 That's what Firefox/Linux does (in fact, it always seems to return 0.0
 alpha from getImageData()).


 We definitely shouldn't spec that! And I'm pretty sure that behavior would
 vary across Firefox platforms. But we need to have consistent behavior here.

  I considered three options:

 1)  Prevent non-1.0 alpha ever getting into the canvas.  At a minimum,
 this would require the following:

- For putImageData, apply premultiplication, then write 1.0 alpha
into the canvas.
- Change initialization and clearRect() to clear to opaque black
instead of transparent black.
- Modify all canvas compositing modes to leave destination alpha
unchanged

 The latter is easy to do in OpenGL and CoreGraphics, but hard to do in
 Skia, and hard to do in accelerated CoreGraphics (IOSurfaces don't seem to
 support any opaque formats, although I could be wrong -- that was just from
 an hour or so of experimentation).  I'm not sure about Cairo.


 You can always implement it slowly using readback. I think we should just
 spec this, and maybe note that authors shouldn't use non-over operators on
 opaque canvases. Over time we'll probably find a way to make it fast
 everywhere.


I'm a little leery of spec'ing something that has negative performance
implications.  As an example, the darker compositing mode was removed
from the spec due to hardware-accelerated performance concerns, IIRC.
 OTOH, unlike that change, this spec should not have performance
implications for OpenGL or Direct3D acceleration, only CoreGraphics via
IOSurface and skia (so far).

How would you feel about simply mapping the dest-alpha-modifying
compositing modes to source-over, as in proposal 2) above?

Stephen




 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-12 Thread Stephen White
Here's a draft of proposal (1) above:

Motivation:  Compositing a canvas element into the page can be expensive,
due to blending operations, and lack of opportunity for culling.  Since
arbitrary graphics operations can affect the opacity of the canvas, it is
difficult to determine programmatically whether the canvas is opaque.
 Allowing the developer to explicitly mark a canvas as opaque allows the
user agent to optimize blending at page composite time, as well to cull
fully-obscured elements behind the canvas.

Description:

The opaque attribute is a boolean attribute of the canvas element, whose
presence indicates that the alpha values in the canvas backing store must
be 1.0 at all times.  All canvas operations are modified to preserve this
invariant.  If the opaque attribute is not present, or if parsing its
value returns an error, then the default value (false) must be used instead.

When a canvas has the opaque attribute, the backing store must be
initialized to opaque black (rgba(0, 0, 0, 1.0)), instead of transparent
black (rgba(0, 0, 0, 0.0)).  Setting, changing, removing or setting the
attribute redundantly to its existing value causes the canvas to be cleared
to the appropriate value.

When a canvas has the opaque attribute, clearRect() clears to opaque black
instead of transparent black.

The behaviour of putImageData() and putImageDataHD() when a canvas has the
opaque attribute is to premultiply the RGB components by the alpha
component as usual, but write 1.0 into destination alpha.  In other words,
if (r, g, b, a) are the component values in a given pixel passed to
putImageData[HD](), then r' = ar, g' = ag, b' = ab are the colour
components of the resulting canvas pixel, and (r', g', b', 1.0) is written
to the canvas backing store.

When a canvas has the opaque attribute, all globalCompositeOperation modes
behave as normal and the resulting RGB components are written to the canvas
backing store, but the alpha component is left unchanged at 1.0.

Stephen



On Tue, Mar 12, 2013 at 12:53 PM, Stephen White senorbla...@chromium.orgwrote:


 On Mon, Mar 11, 2013 at 4:32 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 8:23 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan rob...@ocallahan.org
  wrote:

 On Tue, Mar 12, 2013 at 7:53 AM, Stephen White 
 senorbla...@chromium.org wrote:

 All other canvas functionality behaves as normal, including operations
 which modify the alpha values of the backing store.  However, any such
 transparency values will be ignored when compositing the canvas into the
 page, and the canvas will be treated as if every pixel has an alpha of 
 1.0.


 That would mean getImageData can return non-1.0 alpha values, which is
 probably not what you want to implement.


 That's what Firefox/Linux does (in fact, it always seems to return 0.0
 alpha from getImageData()).


 We definitely shouldn't spec that! And I'm pretty sure that behavior
 would vary across Firefox platforms. But we need to have consistent
 behavior here.

  I considered three options:

 1)  Prevent non-1.0 alpha ever getting into the canvas.  At a minimum,
 this would require the following:

- For putImageData, apply premultiplication, then write 1.0 alpha
into the canvas.
- Change initialization and clearRect() to clear to opaque black
instead of transparent black.
- Modify all canvas compositing modes to leave destination alpha
unchanged

 The latter is easy to do in OpenGL and CoreGraphics, but hard to do in
 Skia, and hard to do in accelerated CoreGraphics (IOSurfaces don't seem to
 support any opaque formats, although I could be wrong -- that was just from
 an hour or so of experimentation).  I'm not sure about Cairo.


 You can always implement it slowly using readback. I think we should just
 spec this, and maybe note that authors shouldn't use non-over operators on
 opaque canvases. Over time we'll probably find a way to make it fast
 everywhere.


 I'm a little leery of spec'ing something that has negative performance
 implications.  As an example, the darker compositing mode was removed
 from the spec due to hardware-accelerated performance concerns, IIRC.
  OTOH, unlike that change, this spec should not have performance
 implications for OpenGL or Direct3D acceleration, only CoreGraphics via
 IOSurface and skia (so far).

 How would you feel about simply mapping the dest-alpha-modifying
 compositing modes to source-over, as in proposal 2) above?

 Stephen




 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]





Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-11 Thread Stephen White
Here's a first draft of a proposal to standardize moz-opaque.  (Note that
Firefox/Linux and Firefox/Win differ in their implementation of moz-opaque.
 This proposal is most similar to the Firefox/Linux implementation, but
with the canvas cleared to opaque black as in the Firefox/Win version).

Motivation:  Compositing a canvas element into the page can be expensive,
due to blending operations, and lack of opportunity for culling.  Since
arbitrary graphics operations can affect the opacity of the canvas, it is
difficult to determine programmatically whether the canvas is opaque.
 Allowing the developer to explicitly mark a canvas as opaque allows the
user agent to optimize blending at page composite time, as well as culling
obscured elements behind the canvas.

Description:

The opaque attribute is a boolean attribute of the canvas element, whose
presence indicates that the alpha values in the canvas backing store must
be ignored when compositing the canvas into the page.  If the attribute is
not present, or if parsing its value returns an error, then the default
value (false) must be used instead.

When a canvas has the opaque attribute, the backing store must be
initialized to opaque black (rgba(0, 0, 0, 1.0)), instead of transparent
black (rgba(0, 0, 0, 0.0)).  Changing or removing the attribute after
initialization causes the canvas to be cleared to the appropriate value.

All other canvas functionality behaves as normal, including operations
which modify the alpha values of the backing store.  However, any such
transparency values will be ignored when compositing the canvas into the
page, and the canvas will be treated as if every pixel has an alpha of 1.0.

Stephen


On Fri, Mar 8, 2013 at 6:57 PM, Stephen White senorbla...@chromium.orgwrote:

 On Sat, Feb 23, 2013 at 6:48 AM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Sat, Feb 23, 2013 at 4:59 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Thu, Feb 21, 2013 at 7:01 PM, Rik Cabanier caban...@gmail.comwrote:

 On Fri, Feb 22, 2013 at 10:33 AM, Robert O'Callahan 
 rob...@ocallahan.org wrote:

 I think a fully automatic solution that tries to use subpixel AA but
 is always able to render grayscale AA if needed is the way to go. Possibly
 with an author hint to suggest opting into a more expensive rendering 
 path.


 Here are the problems I see with that approach:

 1)  In order to avoid a performance hit for existing content, it still
 requires a spec change (the hint)
 2)  Even with the hint, when the author knows they want LCD AA, they
 still incur a performance penalty of drawing to two buffers.
 3)  It still can't handle all cases, such as canvas - WebGL, which will
 have to remain grayscale-only, even when the author knows it would be safe
 for their application.


 I agree those are problems. All of the available options have problems.


 Given that that's the case, I am going to move forward with the opaque
 attribute, since I feel it is the lesser of all the evils presented thus
 far.  Paying the cost of two buffers and double-rendering just isn't
 palatable, IMHO.


  Also, what form should this authoring hint take?  Is it going to
 explicitly call out LCD AA?  In that case, how is it better than an opt-in
 canvas attribute?  If it doesn't explicitly call out LCD AA, but that's the
 only effect it has, what should it be called?


 Perhaps we could use text-rendering:optimizeLegibility on the canvas
 element.


 We also might be over-thinking the danger that LCD AA poses.

 Firefox/Linux and Firefox/Mac are both currently shipping with LCD AA
 turned on unconditionally in canvas, and it's trivial to make them expose
 color fringing.  WebKit nightlies (Safari build) seem do the same, although
 Safari 6.0 doesn't.

 Stephen


  I also have concerns that the knowledge of when it's safe to use the
 LCD AA buffer is going to spread throughout the browser codebase, even in
 areas which currently have no knowledge of canvas, in order to handle all
 the special cases.  This may just be an implementation detail (and may be
 avoidable, this is TBD), but it does have the potential to introduce
 dependencies or complicate implementation.


 Maybe.


 Maybe I'm missing something, but if we're going down the automatic road,
 why do we need a new function/attribute?  Why not simply detect when a
 canvas-sized fillRect() has been performed with an opaque fillStyle?  This
 would also allow optimization of existing content.


 I agree.

 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]





Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-11 Thread Stephen White
On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 7:53 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 All other canvas functionality behaves as normal, including operations
 which modify the alpha values of the backing store.  However, any such
 transparency values will be ignored when compositing the canvas into the
 page, and the canvas will be treated as if every pixel has an alpha of 1.0.


 That would mean getImageData can return non-1.0 alpha values, which is
 probably not what you want to implement.


That's what Firefox/Linux does (in fact, it always seems to return 0.0
alpha from getImageData()).

I considered three options:

1)  Prevent non-1.0 alpha ever getting into the canvas.  At a minimum, this
would require the following:

   - For putImageData, apply premultiplication, then write 1.0 alpha into
   the canvas.
   - Change initialization and clearRect() to clear to opaque black instead
   of transparent black.
   - Modify all canvas compositing modes to leave destination alpha
   unchanged

The latter is easy to do in OpenGL and CoreGraphics, but hard to do in
Skia, and hard to do in accelerated CoreGraphics (IOSurfaces don't seem to
support any opaque formats, although I could be wrong -- that was just from
an hour or so of experimentation).  I'm not sure about Cairo.

2)  Same as (1), but force all destination-alpha-referencing compositing
modes to source-over (or raise an exception).  This seems somewhat
draconian, and doesn't match what either Firefox implementation currently
does.

3)  Ignore the canvas per-pixel alpha at page composite time.  This seems
to be what Firefox/Linux does.

Stephen



 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-03-08 Thread Stephen White
On Sat, Feb 23, 2013 at 6:48 AM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Sat, Feb 23, 2013 at 4:59 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Thu, Feb 21, 2013 at 7:01 PM, Rik Cabanier caban...@gmail.com wrote:

 On Fri, Feb 22, 2013 at 10:33 AM, Robert O'Callahan 
 rob...@ocallahan.org wrote:

 I think a fully automatic solution that tries to use subpixel AA but is
 always able to render grayscale AA if needed is the way to go. Possibly
 with an author hint to suggest opting into a more expensive rendering path.


 Here are the problems I see with that approach:

 1)  In order to avoid a performance hit for existing content, it still
 requires a spec change (the hint)
 2)  Even with the hint, when the author knows they want LCD AA, they
 still incur a performance penalty of drawing to two buffers.
 3)  It still can't handle all cases, such as canvas - WebGL, which will
 have to remain grayscale-only, even when the author knows it would be safe
 for their application.


 I agree those are problems. All of the available options have problems.


Given that that's the case, I am going to move forward with the opaque
attribute, since I feel it is the lesser of all the evils presented thus
far.  Paying the cost of two buffers and double-rendering just isn't
palatable, IMHO.


  Also, what form should this authoring hint take?  Is it going to
 explicitly call out LCD AA?  In that case, how is it better than an opt-in
 canvas attribute?  If it doesn't explicitly call out LCD AA, but that's the
 only effect it has, what should it be called?


 Perhaps we could use text-rendering:optimizeLegibility on the canvas
 element.


We also might be over-thinking the danger that LCD AA poses.

Firefox/Linux and Firefox/Mac are both currently shipping with LCD AA
turned on unconditionally in canvas, and it's trivial to make them expose
color fringing.  WebKit nightlies (Safari build) seem do the same, although
Safari 6.0 doesn't.

Stephen


  I also have concerns that the knowledge of when it's safe to use the LCD
 AA buffer is going to spread throughout the browser codebase, even in areas
 which currently have no knowledge of canvas, in order to handle all the
 special cases.  This may just be an implementation detail (and may be
 avoidable, this is TBD), but it does have the potential to introduce
 dependencies or complicate implementation.


 Maybe.


 Maybe I'm missing something, but if we're going down the automatic road,
 why do we need a new function/attribute?  Why not simply detect when a
 canvas-sized fillRect() has been performed with an opaque fillStyle?  This
 would also allow optimization of existing content.


 I agree.

 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-22 Thread Stephen White
On Thu, Feb 21, 2013 at 7:01 PM, Rik Cabanier caban...@gmail.com wrote:



 On Fri, Feb 22, 2013 at 10:33 AM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 I think Rik is convincing me that we shouldn't expose mozOpaque or any
 other explicit subpixel AA control to the Web. It will be very easy for Web
 authors to test it in one place and discover that it works without
 realizing that they're causing problems for some users.

 I think a fully automatic solution that tries to use subpixel AA but is
 always able to render grayscale AA if needed is the way to go. Possibly
 with an author hint to suggest opting into a more expensive rendering path.


Here are the problems I see with that approach:

1)  In order to avoid a performance hit for existing content, it still
requires a spec change (the hint)
2)  Even with the hint, when the author knows they want LCD AA, they still
incur a performance penalty of drawing to two buffers.
3)  It still can't handle all cases, such as canvas - WebGL, which will
have to remain grayscale-only, even when the author knows it would be safe
for their application.

Also, what form should this authoring hint take?  Is it going to explicitly
call out LCD AA?  In that case, how is it better than an opt-in canvas
attribute?  If it doesn't explicitly call out LCD AA, but that's the only
effect it has, what should it be called?

I also have concerns that the knowledge of when it's safe to use the LCD AA
buffer is going to spread throughout the browser codebase, even in areas
which currently have no knowledge of canvas, in order to handle all the
special cases.  This may just be an implementation detail (and may be
avoidable, this is TBD), but it does have the potential to introduce
dependencies or complicate implementation.



 Great! I think matteColor (or matteStyle to be more consistent) can easily
 be implemented. We can optimize rendering later.


 So, if a mattecolor is set the UA can assume that:


Maybe I'm missing something, but if we're going down the automatic road,
why do we need a new function/attribute?  Why not simply detect when a
canvas-sized fillRect() has been performed with an opaque fillStyle?  This
would also allow optimization of existing content.

Stephen

- all compositing operation within the canvas can ignore background alpha
 - the canvas can be copied directly to the screen (unless another effect
 is applied to the canvas element or its ancestor)

 If mattecolor is set, the UA should matte with that color. If a
 compositing operation (that introduces alpha) is used, the matte operation
 needs to be repeated.

 Rik



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-21 Thread Stephen White
On Tue, Feb 19, 2013 at 11:31 PM, Rik Cabanier caban...@gmail.com wrote:

 So now we have:
 - don't do this on pinch-zoom devices
 - don't do this for HW accelerated canvases
 - don't do this if the canvas dpi doesn't match the screen

- don't do this if there are transforms
 - authors will have to be very careful when using this feature since it
 can turn on or off or cause rendering glitches.

 Is it still worth pursuing this?


I believe it is.  Even with those constraints, there are a large number of
applications which can benefit from text which looks as good as the native
platform can provide.

That said, I also think Robert is right that we should not spec out
precisely when subpixel AA text will occur in any of these automatic modes,
since:

1)  there are some platforms/devices which don't do LCD text at all
2)  It may be too restrictive for the browser implementor, e.g., they may
be essentially required to implement deferred rendering or two backing
stores in order to meet the resulting spec, which seems onerous

Subpixel AA text aside, I still think it's worth spec'ing out mozOpaque, if
only just for the optimization opportunities that we don't get with an
automatic solution (e.g., putImageData).  Its implementation is fairly
straightforward (much more so than the other options above), and it won't
break any existing content.

To me, the it breaks compositing argument falls into the doctor, it
hurts when I do this category:  the user is specifically opting into an
opaque backing store, and so the changes in behaviour for compositing modes
which reference destination alpha are expected, just as they are when using
DST_ALPHA blending modes in a WebGL context created with the alpha
attribute set to false.

Stephen



 On Tue, Feb 19, 2013 at 3:40 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Tue, Feb 19, 2013 at 5:19 PM, Stephen White 
 senorbla...@chromium.orgwrote:

 Even with text on an opaque background, I think you still have to worry
 about the case of transformed canvases.  E.g., text drawn over an opaque
 background into a single still frame canvas, but then subsequently rotated
 via CSS transforms from 0 degrees through non-0.  The first frame can use
 subpixel AA, but then subsequent frames can't.  So I think you need to keep
 the command stream around (first case) or
 always render two buffers as soon as you draw text.  That seems like a
 pretty heavy burden.

 For canvas-WebGL the problem becomes pretty much intractable, since
 there's no way to know what a given shader will do to the pixels.  So I
 think you'd always have to give up and do grayscale AA in that case.


 Yes, you're quite right.


 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]





Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-18 Thread Stephen White
On Sat, Feb 16, 2013 at 4:09 AM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Sat, Feb 16, 2013 at 11:09 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Fri, Feb 15, 2013 at 2:37 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Sat, Feb 16, 2013 at 4:35 AM, Stephen White senorbla...@chromium.org
  wrote:

 Even within canvas, there may be a way to break it if the LCD AA text
 is drawn first and a dest-alpha compositing mode is used overtop (I haven't
 verified this though).


 I don't think that's a problem. All destination alpha values will be 1
 even after the subpixel AA test is painted, and you'll treat it as normal.


  I was thinking something like this:

 - draw subpixel AA text over an opaque background
 - draw a partially-transparent rect with destination-atop mode over the
 subpixel AA text

  Now some of the subpixel AA text is still there, but the destination
 alpha is non-1, so things will go bad when you composite into the page.
  (At least I think it will.. Porter-Duff makes my head spin sometimes.)


 I don't see the problem. After the first step, you have an RGBA buffer
 that represents exactly the result of the rendering. The second step treats
 it exactly like any other RGBA buffer. Am I being dense?


No, it's probably me.  I was thinking that since there was a way to
introduce non-1 alpha into the backing store after-the-fact, it would break
the previously-performed subpixel coverage blending.  But perhaps not.



 The suggestion on the list earlier was to keep two versions of the canvas
 buffer: one with grayscale AA, another with subpixel AA, and composite with
 the subpixel AA buffer when we can do that safely, otherwise use the
 grayscale AA version. In many implementations there would be a performance
 hit for this, so it would make sense to have authors opt-in to that
 performance hit.


 It would also be a needless performance hit if the developer knew that
 they always wanted subpixel AA, and that their app would never fringe.


 I don't think the developer can ever know that. They'd have to assume the
 browser/platform does not have a quick-zoom feature, which is an assumption
 developers shouldn't be making. Although I guess we could just declare that
 that case isn't important enough to matter.


Well, pretty much all devices that have pinch-zoom today are high-DPI, and
don't implement subpixel AA.  :)   But no, I don't think that's not a good
assumption to bake into the web platform.


 So let me take a stab at a brief summary of the proposals so far, and the
 pros and cons of each (correct me if I missed anything):

 moz-opaque
 pro:  fairly easy to implement
 pro:  no performance hit over regular rendering
 pro:  many opportunities for optimization
 pro:  catches all in-canvas cases of color fringing
 con:  does not handle any out-of-canvas color fringing
 con:  opt-in


 Additional con: requires changes to canvas compositing spec and possibly
 implementations.


Yes, since it's new behaviour it'll require spec changes.  I guess we can
consider that as part of con of being opt-in.

automatic opacity detection
 pro:  catches most (all?) cases of in-canvas color fringing
 pro:  some opportunties for optimization (must be conservative in some
 cases)

 con:  does not catch color fringing on CSS transforms, canvas - WebGL, etc

 context attribute (something like:  context.textAntialising = { 'none',
 'grayscale', 'subpixel' })
 pro:  very easy to implement
 pro:  no performance hit
 con:  does not catch any cases of color fringing; completely up to web
 developer
 con:  opt-in


 Additional con: requires specification and implementation of what happens
 when subpixel AA is drawn over transparent background.


 deferred canvas rendering (collect commands into a buffer, flush buffer
 only when compositing canvas to page, and decide on subpixel AA at that
 point)
 pro:  catches all cases of color fringing
 con:  in some cases, requires an infinite buffer (e.g., a canvas that
 never clears, and only accumulates drawing frame-to-frame means you must
 accumulate commands indefinitely)


 Not really true, you can just give up on the complex cases and draw
 grayscale whenever you feel like it.


And leave the behaviour unspecified, I'm guessing?  Doesn't that least to
inconsistent behaviour between browsers?  Even within one implementation,
if you had content whose command stream varied over the maximum buffer
length threshold, it'd toggle between subpixel and grayscale AA. Not sure
if this is a case worth worrying about, but it does feel like it's exposing
more of the implementation that one would like.

Stephen



 con:  difficult to implement (e.g., canvas-to-canvas drawImage(), etc)
 con:  may introduce performance hit due to re-rendering with and without
 subpixel AA (in cases where you would rather have just gone without)

 two buffers (one grayscale, one LCD AA)
 pro:  handles all cases of color fringing
 pro:  moderately easy to implement
 con:  RAM

Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-18 Thread Stephen White
On Sat, Feb 16, 2013 at 4:12 AM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Sat, Feb 16, 2013 at 11:09 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 deferred canvas rendering (collect commands into a buffer, flush buffer
 only when compositing canvas to page, and decide on subpixel AA at that
 point)
 pro:  catches all cases of color fringing
 con:  in some cases, requires an infinite buffer (e.g., a canvas that
 never clears, and only accumulates drawing frame-to-frame means you must
 accumulate commands indefinitely)
 con:  difficult to implement (e.g., canvas-to-canvas drawImage(), etc)
 con:  may introduce performance hit due to re-rendering with and without
 subpixel AA (in cases where you would rather have just gone without)

 two buffers (one grayscale, one LCD AA)
 pro:  handles all cases of color fringing
 pro:  moderately easy to implement
 con:  RAM (or VRAM) usage is doubled
 con:  possibly-unnecessary performance hit
 con:  must be opt-in


 Both of these schemes can actually be optimized some more: As long as no
 text is drawn to a canvas, you can freely rasterize (in the first case) or
 use just one buffer (in the second case). In fact, this is true as long as
 no text is drawn to a canvas over non-opaque pixels. So a lot of canvas
 usage could be handled with little or no performance hit.


Even with text on an opaque background, I think you still have to worry
about the case of transformed canvases.  E.g., text drawn over an opaque
background into a single still frame canvas, but then subsequently rotated
via CSS transforms from 0 degrees through non-0.  The first frame can use
subpixel AA, but then subsequent frames can't.  So I think you need to keep
the command stream around (first case) or
always render two buffers as soon as you draw text.  That seems like a
pretty heavy burden.

For canvas-WebGL the problem becomes pretty much intractable, since
there's no way to know what a given shader will do to the pixels.  So I
think you'd always have to give up and do grayscale AA in that case.

Stephen



 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-15 Thread Stephen White
On Thu, Feb 14, 2013 at 10:21 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Thu, Feb 14, 2013 at 11:59 PM, Stephen White 
 senorbla...@chromium.orgwrote:

 I think this is difficult to do in the general case, such as
 putImageData() or drawImage() or patterns, since you would need to examine
 all the pixels of the source image to determine if they contain non-1
 alpha.  This would be cost-prohibitive.


 If it's just for the purposes of optimization, you could be conservative
 and simply clear the flag when there's the potential for (but not certainty
 of) non-1 alpha.  But if you're also using that flag to allow subpixel AA,
 the behaviour becomes quite unpredictable for the web developer and hard to
 spec crisply.


 What if we just said
 a) non-over operators clear the subpixel AA flag
 b) putImageData clears the subpixel AA flag
 Both of these are infrequently used AFAIK. Authors could work around most
 cases of b) by doing putImageData to another canvas and compositing it into
 the destination with 'over'.


Even with these constraints, I don't think we can guarantee that it's safe
to use LCD AA text. Once you've drawn with LCD AA text, even if it's safe
at the time of drawing, there's no guarantee that it will be safe later.
 For instance, if you then drawImage() that canvas rotated into another
canvas, or even just full-page-zoom it, you'll see colour fringing. Or
apply CSS 2D or 3D transforms. There are also existing apps which use
canvas for 2D text glyphs, and then transform and place them rotated in
WebGL. Those will show colour fringing. Even within canvas, there may be a
way to break it if the LCD AA text is drawn first and a dest-alpha
compositing mode is used overtop (I haven't verified this though).

So I'm starting to think that LCD AA text really has to be opt-in, to avoid
breaking existing content. By opting it, you're agreeing that these
artifacts are acceptable for your app. For example, you know that even if
you're going to do a canvas-to-canvas draw, you're always going to draw at
1:1 scale and no rotation.

Stephen




 How bad would that be? Would it help if we added an attribute to the
 canvas to let authors detect whether the subpixel AA flag is set?


 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-15 Thread Stephen White
On Fri, Feb 15, 2013 at 2:37 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Sat, Feb 16, 2013 at 4:35 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 Even with these constraints, I don't think we can guarantee that it's
 safe to use LCD AA text. Once you've drawn with LCD AA text, even if it's
 safe at the time of drawing, there's no guarantee that it will be safe
 later.  For instance, if you then drawImage() that canvas rotated into
 another canvas, or even just full-page-zoom it, you'll see colour fringing.
 Or apply CSS 2D or 3D transforms. There are also existing apps which use
 canvas for 2D text glyphs, and then transform and place them rotated in
 WebGL. Those will show colour fringing.


 This came up on the list earlier.

 Even within canvas, there may be a way to break it if the LCD AA text is
 drawn first and a dest-alpha compositing mode is used overtop (I haven't
 verified this though).


 I don't think that's a problem. All destination alpha values will be 1
 even after the subpixel AA test is painted, and you'll treat it as normal.


I was thinking something like this:

- draw subpixel AA text over an opaque background
- draw a partially-transparent rect with destination-atop mode over the
subpixel AA text

Now some of the subpixel AA text is still there, but the destination alpha
is non-1, so things will go bad when you composite into the page.  (At
least I think it will.. Porter-Duff makes my head spin sometimes.)


  So I'm starting to think that LCD AA text really has to be opt-in, to
 avoid breaking existing content. By opting it, you're agreeing that these
 artifacts are acceptable for your app. For example, you know that even if
 you're going to do a canvas-to-canvas draw, you're always going to draw at
 1:1 scale and no rotation.


 It's difficult to know that on a mobile browser or any other browser where
 you have some kind of fast zoom UI.

 The suggestion on the list earlier was to keep two versions of the canvas
 buffer: one with grayscale AA, another with subpixel AA, and composite with
 the subpixel AA buffer when we can do that safely, otherwise use the
 grayscale AA version. In many implementations there would be a performance
 hit for this, so it would make sense to have authors opt-in to that
 performance hit.


It would also be a needless performance hit if the developer knew that they
always wanted subpixel AA, and that their app would never fringe.


 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]


So let me take a stab at a brief summary of the proposals so far, and the
pros and cons of each (correct me if I missed anything):

moz-opaque
pro:  fairly easy to implement
pro:  no performance hit over regular rendering
pro:  many opportunities for optimization
pro:  catches all in-canvas cases of color fringing
con:  does not handle any out-of-canvas color fringing
con:  opt-in

automatic opacity detection
pro:  catches most (all?) cases of in-canvas color fringing
pro:  some opportunties for optimization (must be conservative in some
cases)
con:  does not catch color fringing on CSS transforms, canvas - WebGL, etc

context attribute (something like:  context.textAntialising = { 'none',
'grayscale', 'subpixel' })
pro:  very easy to implement
pro:  no performance hit
con:  does not catch any cases of color fringing; completely up to web
developer
con:  opt-in

deferred canvas rendering (collect commands into a buffer, flush buffer
only when compositing canvas to page, and decide on subpixel AA at that
point)
pro:  catches all cases of color fringing
con:  in some cases, requires an infinite buffer (e.g., a canvas that never
clears, and only accumulates drawing frame-to-frame means you must
accumulate commands indefinitely)
con:  difficult to implement (e.g., canvas-to-canvas drawImage(), etc)
con:  may introduce performance hit due to re-rendering with and without
subpixel AA (in cases where you would rather have just gone without)

two buffers (one grayscale, one LCD AA)
pro:  handles all cases of color fringing
pro:  moderately easy to implement
con:  RAM (or VRAM) usage is doubled
con:  possibly-unnecessary performance hit
con:  must be opt-in


Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-14 Thread Stephen White
On Wed, Feb 13, 2013 at 11:35 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Thu, Feb 14, 2013 at 5:16 PM, Rik Cabanier caban...@gmail.com wrote:

 Looking at the WebKit implementation, I'm unsure how 'opaque' can
 implemented for accelerated canvas. It might work with non-accelerated
 canvas but would have to run some experiments.
 I also look at mozilla's Core Graphics implementation and unless I'm
 missing something, it doesn't have special code to handle 'opaque'. When do
 you use this parameter?


 CanvasRenderingContext2D::GetSurfaceFormat is part of the process. That
 selects a surface format that is passed down to the graphics layer when
 creating the canvas surface. It's true that we don't currently do anything
 with that when drawing with CoreGraphics. That would need to be cleaned up
 before we started promoting this feature.

 Now that you mention it, having to modify the definition of compositing is
 a bit of a bummer for the 'opaque' attribute approach. I think we could do
 everything we want using your approach --- internally keeping a flag to
 indicate whether the alpha values of the canvas are all 1, setting it when
 the canvas is filled with a solid color and clearing it when non-over
 drawing (or clear()) are used. Let's try that!


I think this is difficult to do in the general case, such as putImageData()
or drawImage() or patterns, since you would need to examine all the pixels
of the source image to determine if they contain non-1 alpha.  This would
be cost-prohibitive.

If it's just for the purposes of optimization, you could be conservative
and simply clear the flag when there's the potential for (but not certainty
of) non-1 alpha.  But if you're also using that flag to allow subpixel AA,
the behaviour becomes quite unpredictable for the web developer and hard to
spec crisply.

We could consider separating the two concepts again.  In an earlier thread,
there was an attempt to automatically determine all the places where it's
safe to enabled subpixel AA, but that seemed to result in a complex
implementation, with all cases still not being covered (such as
canvas-to-canvas drawImage()). The other alternative is programmatic
control over subpixel AA, using a context attribute. That was the first
thing that Justin proposed in the earlier thread, and would be my
preference as well (a fully-loaded footgun:  you can shoot yourself with
it, but the behaviour and performance characteristics are very easy to
understand and spec).  But there didn't seem to be agreement around that
either.

Which is how I ended up at the moz-opaque flag.  it restricts canvas to
the subset of operations which result in a 1 alpha in the backing store, to
allow optimizations and the use of subpixel AA.  I think that is actually
quite a useful subset (generally, the subset that doesn't need destination
alpha).  I believe the same thing can be achieved in WebGL by setting the
alpha attribute to false in WebGLContextAttributes.

Stephen


 But I think matte is unnecessarily obscure. How about adding a
 clear(DOMString) method that does a 'copy' of the color to the entire
 canvas buffer? The color could default to rgba(0,0,0,0).


 Rob
 --
 Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
 Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
 bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
 lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
 — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
 tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]



Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-13 Thread Stephen White
On Tue, Feb 12, 2013 at 6:14 PM, Rik Cabanier caban...@gmail.com wrote:



 On Tue, Feb 12, 2013 at 2:56 PM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Fri, Nov 23, 2012 at 6:04 PM, Ian Hickson i...@hixie.ch wrote:

  On Thu, 29 Mar 2012, Jeremy Apthorp wrote:
   On Thu, Mar 29, 2012 at 10:25 AM, Jeremy Apthorp 
 jere...@chromium.org
  wrote:
On Thu, Mar 29, 2012 at 8:41 AM, Ian Hickson i...@hixie.ch wrote:
On Fri, 13 Jan 2012, Jeremy Apthorp wrote:

 I'd like to draw non-antialiased lines in a canvas. Currently
 it
 seems that the only way to do this is to directly access the
 pixel
 data.

 Is there a reason there's no way to turn off antialiasing?
   
What's the use case?
   
Pixel-art style games.
  
   Specifically: even with the new image smoothing stuff in place for
   drawImage, a 1:2 diagonal line will still be anti-aliased (only the
   antialiasing will look silly scaled up to 2x).
 
  Do you have an example of a game where lines are drawn using a line API
  without antialiasing, then scaled up? Most pixel art games I've seen
  tend to use bitmaps for that kind of thing.
 
 
  On Mon, 12 Nov 2012, Justin Novosad wrote:
  
   For many types of apps, DOM-based rendering is uncompetitively slow
   [so we should make text rendering in canvas more controllable]
 
  This seems like something we should fix, not something we should work
  around by having people use canvas instead. Using canvas has all kinds
 of
  terrible side-effects, like reducing the likely accessibility of the
 page,
  making searcheability much worse, etc.
 
  Also, do you have any metrics showing the magnitude of this problem on
  real-world sites that might consider using canvas instead?
 
 
   If LCD text were enable-able, authors would have to be mindful of a
   number of caveats in order to avoid rendering artifacts.
 
  Do we have any reason to believe the majority of authors would make the
  right decisions here?
 
  (The main reason we haven't provided control over things like
 antialiasing
  is that many authors tend to make terribly bad decisions.) (Before
 anyone
  gets offended, by the way: that you are reading this almost guarantees
  that you are above average in terms of authoring ability.)
 
 
  On Tue, Nov 13, 2012 at 9:37 PM, Robert O'Callahan wrote:
  
   We'd have to define what happens when you use subpixel antialiasing
   incorrectly, because we can be pretty sure authors will use it
   incorrectly and expect to get interoperable behavior.
 
  That's certainly true.
 
 
   Mozilla supports a mozOpaque attribute which makes the canvas buffer
   RGBX (initialized to solid black) and enables subpixel antialiasing
 for
   most text drawing. That might be enough to address your use-cases.
 
  I haven't specified this; if other vendors intend to implement this let
 me
  know and I can spec it. I'm not sure it's worth it though.
 

 [blowing the dust off this thread]

 Folks on the Chrome team are looking into implementing this attribute, and
 would be interested in seeing it spec'ed.


 What are you implementing? Initializing the canvas to black or subpixel
 antialiasing?


We're interested in both aspects:  the opportunity for culling and blending
optimizations at composite time, as well as enabling subpixel AA.

Stephen




 
  On Wed, 14 Nov 2012, Robert O'Callahan wrote:
   On Wed, Nov 14, 2012 at 8:09 AM, Justin Novosad ju...@chromium.org
  wrote:
   
Are there precedents for exposing features with documented caveats?
(excluding caveats that were discovered after the fact)
  
   Yes, and many of them have been extremely problematic, because Web
   authors will ignore the caveats.
 
  Right. I'd really like to avoid adding more if we can help it.
 
 
  On Wed, 14 Nov 2012, Justin Novosad wrote:
  
   There is a recent improvement in Chrome called deferred 2D canvas
   rendering (enabled by default as of Chrome 23).  It is a mechanism
 that
   records 2d canvas commands during JS execution, and only executes them
   for real when the render buffer needs to be resolved (draw to screen,
   getImageData, toDataURL, etc.).  If you want to check it out, the guts
   are in Skia: SkGPipe is a sort of FIFO for graphics commands,
   SkDeferredCanvas is a wrapper that manages the GPipe and automatically
   flushes it and applies some command culling optimizations.
  
   So to come back to the problem of with and without subpixel AA
 buffers:
   if rendering is deferred, the non-AA buffer would never get rasterized
   (and possibly never even allocated), unless it needs to be.  Obviously
   there are practical limitations, for example we cannot store an
   unlimited stream of recorded commands, so if the canvas draws
   indefinitely without ever being cleared, at some point we have to
   rasterize the non-AA buffer just so that we can safely discard the
   recording data. Also, if at record time the necessary conditions for
   subpixel AA are not met, perhaps we just

Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-13 Thread Stephen White
On Wed, Feb 13, 2013 at 12:22 PM, Rik Cabanier caban...@gmail.com wrote:

 For blending optimizations, it might be better to introduce a function
 instead of a boolean attribute like 'opaque'.
 What you really want, is to matte [1] the canvas with a solid color so you
 can optimize compositing.

 How about this API:

 void applyMatte(DOMString color); // color is a CSS rgb color value (alpha
 is ignored)


 When you call this function, the canvas is matted with that color. If it's
 the first drawing call, you can just fill the canvas with that color (no
 compositing needed)
 After matting, you no longer have to read or update the alpha channel
 since it's always 1 which should speed up drawing.


Just to be sure we're on the same page, when I mentioned compositing
optimizations, I was referring to compositing the canvas backing store into
the page, not compositing operations within the canvas itself.

One advantage of using an element attribute is that it could be used at
backing store allocation time, to allocate RGB instead of RGBA.  Forcing a
reallocation of the backing store on attribute change would be consistent
with changing width and height of the canvas, which have the same effect.
 Doing so on a context operation would not.

If we did use a context function approach as you suggest, how would
subpixel AA be handled?  Would it be enabled on first call of the function
and never disabled?  Is there a way to query if the canvas is opaque once
it's called?  (I'm assuming that all changes to canvas alpha after the
first call would have to be ignored, since otherwise you'd have to sniff
every operation to see if it affected alpha, and reset the bit, although
perhaps I'm misunderstanding your proposal.)

Stephen


Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-13 Thread Stephen White
On Wed, Feb 13, 2013 at 5:31 PM, Rik Cabanier caban...@gmail.com wrote:

 On Wed, Feb 13, 2013 at 11:25 AM, Stephen White senorbla...@chromium.org
 wrote:

  On Wed, Feb 13, 2013 at 12:22 PM, Rik Cabanier caban...@gmail.com
 wrote:
 
  For blending optimizations, it might be better to introduce a function
  instead of a boolean attribute like 'opaque'.
  What you really want, is to matte [1] the canvas with a solid color so
  you can optimize compositing.
 
  How about this API:
 
  void applyMatte(DOMString color); // color is a CSS rgb color value
  (alpha is ignored)
 
 
  When you call this function, the canvas is matted with that color. If
  it's the first drawing call, you can just fill the canvas with that
 color
  (no compositing needed)
  After matting, you no longer have to read or update the alpha channel
  since it's always 1 which should speed up drawing.
 
 
  Just to be sure we're on the same page, when I mentioned compositing
  optimizations, I was referring to compositing the canvas backing store
 into
  the page, not compositing operations within the canvas itself.
 

 sorry, I didn't mean to say blending. This is for optimizing compositing
 within the canvas and of the canvas into the page.


 
  One advantage of using an element attribute is that it could be used at
  backing store allocation time, to allocate RGB instead of RGBA.  Forcing
 a
  reallocation of the backing store on attribute change would be consistent
  with changing width and height of the canvas, which have the same effect.
   Doing so on a context operation would not.
 

 why not? There is no reason for you to allocate the backing store until
 it's needed.


True.  I was just trying to understand when you would use this function
more than once during canvas lifetime.  Presumably, that's the reason for
having a function, no?  If so, and you don't maintain any special state
about the opacity of the canvas, how is this different from an rgb()
fillRect()?


 The strange thing with an element attribute is that you can't change it
 back and it's also detached from the JS code that does the drawing.


You can change it back programmatically through the DOM, as you can with
the element width and height.


  If we did use a context function approach as you suggest, how would
  subpixel AA be handled?  Would it be enabled on first call of the
 function
  and never disabled?
 

 I did not think about subpixel AA.
 If I read the mozilla proposal correctly, they do AA if they know that the
 canvas is opaque.
 So, with my proposal, there would be no AA until you call 'applyMatte'
 (assuming you follow the mozilla way of doing AA).


OK, so there would have to be a bit of state saved at that point, in order
to know if subpixel AA is allowable?

At any rate, I don't think this works if you subsequently modify the
canvas's alpha (see below).



  Is there a way to query if the canvas is opaque once it's called?
 

 Wouldn't the user know that he called 'applyMatte'? Also why do you want to
 query it?



   (I'm assuming that all changes to canvas alpha after the first call
 would
  have to be ignored, since otherwise you'd have to sniff every operation
 to
  see if it affected alpha, and reset the bit, although perhaps I'm
  misunderstanding your proposal.)
 

 No, you don't have to do that and can still use alpha.
 Simple alpha compositing is defined as follows [1] (in premultiplied
 alpha):

 co = cs + cb x (1 - αs)
 αo = αs + αb x (1 - αs)


 If you know that the backdrop is matted (αb = 1), the second formula always
 resolves to 1 so you can skip it.


The problem is, canvas supports more than simple (source-over) compositing,
so there are ways of modifying the destination alpha back to non-1, e.g., a
primitive with non-1 alpha drawn with source-copy, or via putImageData().
 At that point, the state of the canvas's alpha is unknown, so the page
compositor can make no assumptions about its opacity.

Stephen


Re: [whatwg] Enabling LCD Text and antialiasing in canvas

2013-02-12 Thread Stephen White
On Fri, Nov 23, 2012 at 6:04 PM, Ian Hickson i...@hixie.ch wrote:

 On Thu, 29 Mar 2012, Jeremy Apthorp wrote:
  On Thu, Mar 29, 2012 at 10:25 AM, Jeremy Apthorp jere...@chromium.org
 wrote:
   On Thu, Mar 29, 2012 at 8:41 AM, Ian Hickson i...@hixie.ch wrote:
   On Fri, 13 Jan 2012, Jeremy Apthorp wrote:
   
I'd like to draw non-antialiased lines in a canvas. Currently it
seems that the only way to do this is to directly access the pixel
data.
   
Is there a reason there's no way to turn off antialiasing?
  
   What's the use case?
  
   Pixel-art style games.
 
  Specifically: even with the new image smoothing stuff in place for
  drawImage, a 1:2 diagonal line will still be anti-aliased (only the
  antialiasing will look silly scaled up to 2x).

 Do you have an example of a game where lines are drawn using a line API
 without antialiasing, then scaled up? Most pixel art games I've seen
 tend to use bitmaps for that kind of thing.


 On Mon, 12 Nov 2012, Justin Novosad wrote:
 
  For many types of apps, DOM-based rendering is uncompetitively slow
  [so we should make text rendering in canvas more controllable]

 This seems like something we should fix, not something we should work
 around by having people use canvas instead. Using canvas has all kinds of
 terrible side-effects, like reducing the likely accessibility of the page,
 making searcheability much worse, etc.

 Also, do you have any metrics showing the magnitude of this problem on
 real-world sites that might consider using canvas instead?


  If LCD text were enable-able, authors would have to be mindful of a
  number of caveats in order to avoid rendering artifacts.

 Do we have any reason to believe the majority of authors would make the
 right decisions here?

 (The main reason we haven't provided control over things like antialiasing
 is that many authors tend to make terribly bad decisions.) (Before anyone
 gets offended, by the way: that you are reading this almost guarantees
 that you are above average in terms of authoring ability.)


 On Tue, Nov 13, 2012 at 9:37 PM, Robert O'Callahan wrote:
 
  We'd have to define what happens when you use subpixel antialiasing
  incorrectly, because we can be pretty sure authors will use it
  incorrectly and expect to get interoperable behavior.

 That's certainly true.


  Mozilla supports a mozOpaque attribute which makes the canvas buffer
  RGBX (initialized to solid black) and enables subpixel antialiasing for
  most text drawing. That might be enough to address your use-cases.

 I haven't specified this; if other vendors intend to implement this let me
 know and I can spec it. I'm not sure it's worth it though.


[blowing the dust off this thread]

Folks on the Chrome team are looking into implementing this attribute, and
would be interested in seeing it spec'ed.

Thanks,

Stephen



 On Wed, 14 Nov 2012, Robert O'Callahan wrote:
  On Wed, Nov 14, 2012 at 8:09 AM, Justin Novosad ju...@chromium.org
 wrote:
  
   Are there precedents for exposing features with documented caveats?
   (excluding caveats that were discovered after the fact)
 
  Yes, and many of them have been extremely problematic, because Web
  authors will ignore the caveats.

 Right. I'd really like to avoid adding more if we can help it.


 On Wed, 14 Nov 2012, Justin Novosad wrote:
 
  There is a recent improvement in Chrome called deferred 2D canvas
  rendering (enabled by default as of Chrome 23).  It is a mechanism that
  records 2d canvas commands during JS execution, and only executes them
  for real when the render buffer needs to be resolved (draw to screen,
  getImageData, toDataURL, etc.).  If you want to check it out, the guts
  are in Skia: SkGPipe is a sort of FIFO for graphics commands,
  SkDeferredCanvas is a wrapper that manages the GPipe and automatically
  flushes it and applies some command culling optimizations.
 
  So to come back to the problem of with and without subpixel AA buffers:
  if rendering is deferred, the non-AA buffer would never get rasterized
  (and possibly never even allocated), unless it needs to be.  Obviously
  there are practical limitations, for example we cannot store an
  unlimited stream of recorded commands, so if the canvas draws
  indefinitely without ever being cleared, at some point we have to
  rasterize the non-AA buffer just so that we can safely discard the
  recording data. Also, if at record time the necessary conditions for
  subpixel AA are not met, perhaps we just forget about it.
 
  I admit this is a complex solution for implementors, but it makes the
  management of subpixel-AA safety transparent to web authors.

 I think it'd be reasonable (for some definition of reasonable that
 relates to whether it's compatible with the spec, anyway) for implementors
 to do this today, without having to expose any control to the author.


 On Thu, 15 Nov 2012, Fred Andrews wrote:
 
  The canvas that scripts draw into could be over-sized with the UA down
  sampling 

Re: [whatwg] Canvas in Workers

2013-01-09 Thread Stephen White
On Thu, Jan 3, 2013 at 7:46 PM, Gregg Tavares g...@google.com wrote:

 On Tue, Dec 11, 2012 at 9:04 AM, Ian Hickson i...@hixie.ch wrote:

  On Tue, 11 Dec 2012, Gregg Tavares (社ç~T¨) wrote:
  
   discussion seems to have died down here but I'd like to bring up
 another
   issue
  
   In WebGL land we have creation attributes on the drawingbuffer made
 for a
   canvas. Example
  
   gl = canvas.getContext(webgl, { preserveDrawingBuffer: false });
  
   We're working out the details on how to set those options for the case
   where we have 1 context and multiple canvases.
  
   The particular option above would apparently be a huge perf win for
   canvas 2d for mobile. Which suggests that whatever API is decided on it
   would be nice if it worked for both APIs the same.
 
  What does it do?
 

 Effectively it makes the canvas double buffered.

 Right now by 2d canvases are effectively single buffered. At the
 appropriate time a copy
 of the canvas is made and passed to the compositor. This copy is slow,
 especially on
 mobile.


Currently, to lower the VRAM footprint and improve performance, we don't do
a copy in 2d canvas.  We temporarily transfer ownership of the texture to
the compositor at commit time, and block the renderer until the composite
is complete.  That may change, however.

Stephen



 Apple requested that for WebGL the default be for double buffering. When
 double buffered, when the canvas is composited (when the current JavaScript
 event exits)
 the canvas's buffer is given to the compositor and the canvas is given a
 new buffer (or
 an old one). That new buffer is cleared, meaning the contents is gone. It's
 up to the app to
 draw stuff into again. If nothing is drawn the compositor will continue to
 use the
 buffer it acquired earlier.

 In WebGL you can opt into the slower copy path. For Canvas 2D while the
 default
 has to remain the slow copy path it would be nice to be able to opt into
 the faster
 swap double buffered path.







 
  In the 2D canvas, whenever you bind to a new canvas, the context is reset
  to its default state, the context's hit region list is reset, and the
  context's bitmap is reset. The next time the context is flushed, the
  canvas itself is always reset (since flushing the context causes the
  bitmap and hit region list to be pushed to the canvas, replacing whatever
  was there before).
 
  --
  Ian Hickson   U+1047E)\._.,--,'``.fL
  http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
  Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
 



[whatwg] Canvas: imageSmoothingEnabled not part of the state stack?

2012-05-18 Thread Stephen White
Looking into some of the features recently added to the canvas spec, I
noticed that imageSmoothingEnabled wasn't added to the list of attributes
saved and restored in the canvas state (in sec. 4.8.11.1.1).  This also
seems to be the case for the new line dash parameters.

Intentional, or oversight?

Stephen