You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to upload images' texture data to the GPU (from main memory), we first extract the image data from the image using getImageData, then pass the image data to texImage2D, the function which uploads the data to the GPU.
This change was introduced in #414, because it was supposedly faster than passing the image itself to texImage2D. However, that's only true if the texture is not premultiplied.
Uploading textures to the GPU in WebGL is done with texImage2D, which can be passed (among other things) an <img> element, a <canvas> element, and an ImageData object.
There's a flag, WEBGL_UNPACK_PREMULTIPLY_ALPHA, that controls whether the destination texture data (that ends up on the GPU) is premultiplied or not. Because most of the ways images are stored in the DOM API are relatively "opaque" (getImageData is the only way to get at anything resembling the raw pixel data), the browser will ensure that the destination texture data is premultiplied/not premultiplied (according to your preference) by automatically converting it.
In all browsers I'm aware of, the contents of <img> and <canvas> elements are stored in memory as premultiplied, so if you set WEBGL_UNPACK_PREMULTIPLY_ALPHA to true to indicate that you want premultiplied texture data, no conversion is necessary. However, ImageData objects store un-premultiplied image data for some reason. This means that if you pass an ImageData object to texImage2D, and WEBGL_UNPACK_PREMULTIPLY_ALPHA is true, it will have to premultiply the image data before uploading it, which is slow.
#414 changed things so that instead of passing <canvas> elements to texImage2D, ImageData objects were passed instead. At the time, WEBGL_UNPACK_PREMULTIPLY_ALPHA was false, so the GPU expected non-premultiplied texture data and no conversion was necessary. This was a speed improvement over passing <canvas> elements because the browser would have to *un-*premultiply the texture data there.
However, #515 changed WEBGL_UNPACK_PREMULTIPLY_ALPHA to true, meaning that once again, uploading ImageData to the GPU requires re-premultiplying the data. At the bottom of #515, I actually mention this performance issue as an "unanswered question".
It would be faster to pass the <canvas> or <img> elements directly to texImage2D, obviating the need for any conversion.
Steps to Reproduce
In Firefox, set the webgl.perf.max-warnings preference to -1 (in about:config)
Observe this performance warning:
Operating System and Browser
All (I believe), but easiest to demonstrate on Firefox because of the performance warnings
The text was updated successfully, but these errors were encountered:
Expected Behavior
The renderer should do things the fast way
Actual Behavior
In order to upload images' texture data to the GPU (from main memory), we first extract the image data from the image using
getImageData
, then pass the image data totexImage2D
, the function which uploads the data to the GPU.This change was introduced in #414, because it was supposedly faster than passing the image itself to
texImage2D
. However, that's only true if the texture is not premultiplied.Uploading textures to the GPU in WebGL is done with
texImage2D
, which can be passed (among other things) an<img>
element, a<canvas>
element, and anImageData
object.There's a flag,
WEBGL_UNPACK_PREMULTIPLY_ALPHA
, that controls whether the destination texture data (that ends up on the GPU) is premultiplied or not. Because most of the ways images are stored in the DOM API are relatively "opaque" (getImageData
is the only way to get at anything resembling the raw pixel data), the browser will ensure that the destination texture data is premultiplied/not premultiplied (according to your preference) by automatically converting it.In all browsers I'm aware of, the contents of
<img>
and<canvas>
elements are stored in memory as premultiplied, so if you setWEBGL_UNPACK_PREMULTIPLY_ALPHA
totrue
to indicate that you want premultiplied texture data, no conversion is necessary. However,ImageData
objects store un-premultiplied image data for some reason. This means that if you pass anImageData
object totexImage2D
, andWEBGL_UNPACK_PREMULTIPLY_ALPHA
istrue
, it will have to premultiply the image data before uploading it, which is slow.#414 changed things so that instead of passing
<canvas>
elements totexImage2D
,ImageData
objects were passed instead. At the time,WEBGL_UNPACK_PREMULTIPLY_ALPHA
wasfalse
, so the GPU expected non-premultiplied texture data and no conversion was necessary. This was a speed improvement over passing<canvas>
elements because the browser would have to *un-*premultiply the texture data there.However, #515 changed
WEBGL_UNPACK_PREMULTIPLY_ALPHA
totrue
, meaning that once again, uploadingImageData
to the GPU requires re-premultiplying the data. At the bottom of #515, I actually mention this performance issue as an "unanswered question".It would be faster to pass the
<canvas>
or<img>
elements directly totexImage2D
, obviating the need for any conversion.Steps to Reproduce
webgl.perf.max-warnings
preference to-1
(inabout:config
)Operating System and Browser
All (I believe), but easiest to demonstrate on Firefox because of the performance warnings
The text was updated successfully, but these errors were encountered: