Animated gifs work with canvas drawImage & webgl textures in Chrome but not Firefox

RESOLVED INVALID

Status

()

defect
RESOLVED INVALID
8 years ago
2 years ago

People

(Reporter: bobby, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

Tonight, I tried using drawImage to render a gif's pixels on a canvas for use on a WebGL texture. Interestingly, Firefox only renders the first frame of the gif animation, while Chrome renders whichever frame is currently displayed (which I'm assuming is correct).

Firefox's behaviour is equivalent to Chrome's only once "display: none" is set on the gif. Then, both browsers only display the first frame of the gif on the canvas.

Simple canvas demo: http://robothaus.org/bugs/gifs/gif-test.html

Awesome WebGL demo: http://cjcliffe.github.com/CubicVR.js/cubicvr/tests/gifs/gifs.html
CC'ing some people as I really don't know whether we want to do that. Does any spec require it? I can't talk about canvas2d at all; for WebGL it seems strange to do automatic animation. For example texImage2D calls on video elements only grab one frame; if we wanted to automatically animate textures, not clear to me how we'd do it, would we run a timer in a separate thread? If yes how do we prevent having 2 threads touch the GL context at the same time, without a performance-killing locking mechanism? AFAIK OpenGL functions are not guaranteed to be reentrant, and they work on a shared state machine which itself may not like to be touched by multiple threads concurrently. Moreover, a texImage2D call relies on a lot of GL state, such as the texture binding, texparameters, pixelstore parameters UNPACK_ALIGNMENT, COLORSPACE_CONVERSION...) so that would imply quite a bit of state churn. In short, I'm surprised that Chrome supports that and would like to know how they did it.
For the 2D context:

> When the drawImage() method is passed an animated image as its image
> argument, the user agent must use the poster frame of the animation,
> or, if there is no poster frame, the first frame of the animation.

http://www.whatwg.org/html/#images
This test seems to think that it should be the first frame: http://w3c-test.org/html/tests/approved/canvas/2d.drawImage.animated.gif.html
@bjacob I wasn't sure if any spec requires it. Just thought it should work the same as a video element. As a video element progresses through its frame, using its pixels somewhere (canvas, WebGL texture, etc.) will actually grab current frame, and not just the beginning one. We already have the facilities to update textures on a per-frame basis with new pixel information. It just seems that getting said pixel information from a gif is broken.

@Ms2ger, @Robert: that's what I feared. If that's the case, I guess there isn't much we can do about it.

In general, it's annoying that this works in Chrome. Seems like a pretty obvious thing to try to do when everything else (like <video>) works as expected.
> If that's the case, I guess there isn't much we can do about it.

Well, you can try to get the spec changed, depending on what other browsers do....
(In reply to comment #4)
> @bjacob I wasn't sure if any spec requires it. Just thought it should work
> the same as a video element. As a video element progresses through its
> frame, using its pixels somewhere (canvas, WebGL texture, etc.) will
> actually grab current frame, and not just the beginning one. We already have
> the facilities to update textures on a per-frame basis with new pixel
> information. It just seems that getting said pixel information from a gif is
> broken.

Oh OK, I thought that you were talking about having the texture auto-update itself to play the animation, and thought that was a crazy idea :)
(In reply to comment #6)
> and thought that was a crazy idea :)

To be clear, the only crazy person here is me for having even imagined such an idea :)

Comment 9

8 years ago
can you check if the object is using .gif(.apng) as at least one of it's textures
and only update these objects on the per-frame basis?
(In reply to comment #9)
> can you check if the object is using .gif(.apng) as at least one of it's
> textures
> and only update these objects on the per-frame basis?
Not entirely sure what you mean. If you're implying any amount of automation of the process, that's what we don't need to have. I want a gif to act like a gif, regardless of what we do with it. At time X, I expect to have frame Y of the gif, not frame 1.

Comment 11

7 years ago
(In reply to Benoit Jacob [:bjacob] from comment #6)
> (In reply to comment #4)
> Oh OK, I thought that you were talking about having the texture auto-update
> itself to play the animation, and thought that was a crazy idea :)

(That would be crazy!)

But even when I have a Javascript setInterval() updating the canvas with new frames from the image/video, it doesn't work. Works with <video> tags in FF. Works with animated GIFs in OSX Safari and Chrome (even Android), but not FF 10. FF only shows first frame.

Check here for example: http://odbol.com/gif_jockey.php (use last page of video clips to load the animated GIFs) 

Side note: This is for a in-browser VJ program called LSD (Layer Synthesis Device)  I'm occasionally working on. It may not be in the spec, but it sure would be cool to have!
Thank you for the link.  I posted a testcase based on it in https://bugs.webkit.org/show_bug.cgi?id=74779
Is this WONTFIX? (At least pending a spec change?)
At least pending a spec change, yes.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.