Open GoogleCodeExporter opened 9 years ago
Fixing this will also make it possible to get rid of CanvasLayer (except
perhaps as a convenience), because there would be no difference between it and
an ImageLayer wrapped around a CanvasImage.
Original comment by jgw@google.com
on 13 May 2011 at 2:32
Is there a workaround for this?
Original comment by matt...@mastracci.com
on 11 Jun 2011 at 1:54
Here's a quick workaround to make CanvasImages work somewhat in ImageLayers in
HTML mode. I suspect that this won't reflect modifications to the canvas in
ImageLayers after they've been painted once, but it's good enough for simple
tasks like mirroring a sprite:
Index: src/forplay/html/HtmlImage.java
===================================================================
--- src/forplay/html/HtmlImage.java (revision 4)
+++ src/forplay/html/HtmlImage.java (working copy)
@@ -41,9 +41,11 @@
// only used in the WebGL renderer.
private WebGLTexture tex, pow2tex;
+ private boolean canvas;
HtmlImage(CanvasElement img) {
this.img = img.cast();
+ canvas = true;
}
HtmlImage(ImageElement img) {
@@ -87,7 +89,7 @@
@Override
public boolean isReady() {
- return isComplete(this.img);
+ return canvas || isComplete(this.img);
}
/*
Original comment by matt...@mastracci.com
on 11 Jun 2011 at 4:09
@Matt: The really tricky part is in handling dom/canvas mode. This is one of
those many Great Oversights in browser API design:
- you can draw to a canvas
- you can draw canvases to other canvases
- you can stick a canvas in the dom
- but you can't easily use a canvas in *multiple places* in the dom (!)
If we look at the three main browsers, at least two of them have (incompatible,
non-standard) solutions to this problem:
- WebKit has background:-webkit-canvas
(http://www.webkit.org/blog/176/css-canvas-drawing/).
- Firefox4 has background:-moz-element
(https://developer.mozilla.org/en/CSS/-moz-element).
- IE9 has jack.
The only solution I can come up with on IE9 is to use toDataURL() and shove the
resulting base64-encoded ball of crap into a style, which is shared by all
ImageLayer instances (putting the data url into each ImageLayer's <img> element
as its 'src' is *extremely* expensive, because you end up duplicating the image
all over the place via its url).
But there's a subtle semantic difference between the FF/WebKit solutions and
the IE9 data url hack -- the former are immediate (i.e., the ImageLayers are
updated as soon as you paint to the canvas), whereas the latter requires a
manual step (copying the data url into the style) before changes are visible.
Oddly enough, though, in GL mode we actually *want* there to be a manual step,
so we can tell the developer that it will be a relatively expensive operation.
This is because it boils down to a glTexImage2D() call, which obviously
requires a texture copy (anecdotally, it seems to be even more expensive than I
would have thought in Chrome -- it may be copying across processes at the
moment).
So... Long-story-short, I think we need to implement this in such a way that
the behavior is the same across browsers. The easiest way to do this would be
to implement the IE9 CSS hack everywhere in dom/canvas mode, implement the
obvious thing in GL, and add an explicit method on either Canvas or CanvasImage
that's required to flush changes.
Then I'd like to explicitly deprecate (and soon remove) CanvasLayer, in favor
of CanvasImage + ImageLayer. This will be both simpler (one less layer type),
and less surprising, because it won't have any performance surprises (frequent
paints to a CanvasLayer right now can be a lot more expensive than you'd think).
Original comment by jgw@google.com
on 14 Jun 2011 at 1:51
Original issue reported on code.google.com by
jgw@google.com
on 13 May 2011 at 2:32