Bug 1324924 - Support ImageBitmap for Tex*Image*. (flattened) - r=bz,daoshengmu,mtseng a=gchang
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 20 Dec 2016 14:59:51 -0800
changeset 353197 39582d06756a9ff47993d4097b4fb25f041be406
parent 353196 e58d9eef4c96901f243db1491282e4619d4bd980
child 353198 970d7ef370755cb8296e0f857690c3f5ab5b25c7
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, daoshengmu, mtseng, gchang
bugs1324924
milestone52.0a2
Bug 1324924 - Support ImageBitmap for Tex*Image*. (flattened) - r=bz,daoshengmu,mtseng a=gchang MozReview-Commit-ID: JzcbzeFHyHn
dom/base/StructuredCloneHolder.cpp
dom/canvas/ImageBitmap.cpp
dom/canvas/ImageBitmap.h
dom/canvas/WebGLContext.h
dom/canvas/WebGLTextureUpload.cpp
dom/webidl/WebGL2RenderingContext.webidl
dom/webidl/WebGLRenderingContext.webidl
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -1291,17 +1291,17 @@ StructuredCloneHolder::CustomWriteTransf
       ImageBitmap* bitmap = nullptr;
       rv = UNWRAP_OBJECT(ImageBitmap, aObj, bitmap);
       if (NS_SUCCEEDED(rv)) {
         MOZ_ASSERT(bitmap);
 
         *aExtraData = 0;
         *aTag = SCTAG_DOM_IMAGEBITMAP;
         *aOwnership = JS::SCTAG_TMO_CUSTOM;
-        *aContent = bitmap->ToCloneData();
+        *aContent = bitmap->ToCloneData().release();
         MOZ_ASSERT(*aContent);
         bitmap->Close();
 
         return true;
       }
     }
   }
 
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -679,28 +679,28 @@ ImageBitmap::PrepareForDrawTarget(gfx::D
 already_AddRefed<layers::Image>
 ImageBitmap::TransferAsImage()
 {
   RefPtr<layers::Image> image = mData;
   Close();
   return image.forget();
 }
 
-ImageBitmapCloneData*
-ImageBitmap::ToCloneData()
+UniquePtr<ImageBitmapCloneData>
+ImageBitmap::ToCloneData() const
 {
-  ImageBitmapCloneData* result = new ImageBitmapCloneData();
+  UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
   result->mPictureRect = mPictureRect;
   result->mIsPremultipliedAlpha = mIsPremultipliedAlpha;
   result->mIsCroppingAreaOutSideOfSourceImage = mIsCroppingAreaOutSideOfSourceImage;
   RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
   result->mSurface = surface->GetDataSurface();
   MOZ_ASSERT(result->mSurface);
 
-  return result;
+  return Move(result);
 }
 
 /* static */ already_AddRefed<ImageBitmap>
 ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
                                  ImageBitmapCloneData* aData)
 {
   RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
 
--- a/dom/canvas/ImageBitmap.h
+++ b/dom/canvas/ImageBitmap.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_ImageBitmap_h
 #define mozilla_dom_ImageBitmap_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/ImageBitmapSource.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
 #include "nsCycleCollectionParticipant.h"
 
 struct JSContext;
 struct JSStructuredCloneReader;
 struct JSStructuredCloneWriter;
 
 class nsIGlobalObject;
 
@@ -110,18 +111,18 @@ public:
 
   /*
    * Transfer ownership of buffer to caller. So this function call
    * Close() implicitly.
    */
   already_AddRefed<layers::Image>
   TransferAsImage();
 
-  ImageBitmapCloneData*
-  ToCloneData();
+  UniquePtr<ImageBitmapCloneData>
+  ToCloneData() const;
 
   static already_AddRefed<ImageBitmap>
   CreateFromCloneData(nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData);
 
   static already_AddRefed<ImageBitmap>
   CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
                             OffscreenCanvas& aOffscreenCanvas,
                             ErrorResult& aRv);
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -200,16 +200,17 @@ struct IndexedBufferBinding
 struct TexImageSource
 {
     const dom::ArrayBufferView* mView;
     GLuint mViewElemOffset;
     GLuint mViewElemLengthOverride;
 
     const WebGLsizeiptr* mPboOffset;
 
+    const dom::ImageBitmap* mImageBitmap;
     const dom::ImageData* mImageData;
 
     const dom::Element* mDomElem;
     ErrorResult* mOut_error;
 
 protected:
     TexImageSource() {
         memset(this, 0, sizeof(*this));
@@ -243,16 +244,20 @@ struct TexImageSourceAdapter final : pub
     TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, GLuint ignored1, GLuint ignored2 = 0) {
         mPboOffset = pboOffset;
     }
 
     TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, ErrorResult* ignored) {
         mPboOffset = pboOffset;
     }
 
+    TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult*) {
+        mImageBitmap = imageBitmap;
+    }
+
     TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {
         mImageData = imageData;
     }
 
     TexImageSourceAdapter(const dom::Element* domElem, ErrorResult* const out_error) {
         mDomElem = domElem;
         mOut_error = out_error;
     }
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -8,16 +8,17 @@
 #include <algorithm>
 
 #include "CanvasUtils.h"
 #include "gfxPrefs.h"
 #include "GLBlitHelper.h"
 #include "GLContext.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/dom/HTMLVideoElement.h"
+#include "mozilla/dom/ImageBitmap.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/Unused.h"
 #include "ScopedGLHelpers.h"
 #include "TexUnpackBlob.h"
 #include "WebGLBuffer.h"
 #include "WebGLContext.h"
@@ -206,16 +207,45 @@ FromPboOffset(WebGLContext* webgl, const
 
     const bool isClientData = false;
     const auto ptr = (const uint8_t*)pboOffset;
     return MakeUnique<webgl::TexUnpackBytes>(webgl, target, width, height, depth,
                                              isClientData, ptr, availBufferBytes);
 }
 
 static UniquePtr<webgl::TexUnpackBlob>
+FromImageBitmap(WebGLContext* webgl, const char* funcName, TexImageTarget target,
+              uint32_t width, uint32_t height, uint32_t depth,
+              const dom::ImageBitmap& imageBitmap)
+{
+    UniquePtr<dom::ImageBitmapCloneData> cloneData = Move(imageBitmap.ToCloneData());
+    const RefPtr<gfx::DataSourceSurface> surf = cloneData->mSurface;
+
+    ////
+
+    if (!width) {
+        width = surf->GetSize().width;
+    }
+
+    if (!height) {
+        height = surf->GetSize().height;
+    }
+
+    ////
+
+
+    // WhatWG "HTML Living Standard" (30 October 2015):
+    // "The getImageData(sx, sy, sw, sh) method [...] Pixels must be returned as
+    //  non-premultiplied alpha values."
+    const bool isAlphaPremult = cloneData->mIsPremultipliedAlpha;
+    return MakeUnique<webgl::TexUnpackSurface>(webgl, target, width, height, depth, surf,
+                                               isAlphaPremult);
+}
+
+static UniquePtr<webgl::TexUnpackBlob>
 FromImageData(WebGLContext* webgl, const char* funcName, TexImageTarget target,
               uint32_t width, uint32_t height, uint32_t depth,
               const dom::ImageData& imageData, dom::Uint8ClampedArray* scopedArr)
 {
     DebugOnly<bool> inited = scopedArr->Init(imageData.GetDataObject());
     MOZ_ASSERT(inited);
 
     scopedArr->ComputeLengthAndData();
@@ -375,16 +405,21 @@ WebGLContext::From(const char* funcName,
                              *(src.mPboOffset));
     }
 
     if (mBoundPixelUnpackBuffer) {
         ErrorInvalidOperation("%s: PIXEL_UNPACK_BUFFER must be null.", funcName);
         return nullptr;
     }
 
+    if (src.mImageBitmap) {
+        return FromImageBitmap(this, funcName, target, width, height, depth,
+                               *(src.mImageBitmap));
+    }
+
     if (src.mImageData) {
         return FromImageData(this, funcName, target, width, height, depth,
                              *(src.mImageData), scopedArr);
     }
 
     if (src.mDomElem) {
         return FromDomElem(funcName, target, width, height, depth, *(src.mDomElem),
                            src.mOut_error);
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -360,16 +360,19 @@ interface WebGL2RenderingContextBase
     [Throws]
     void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLenum format, GLenum type, HTMLImageElement source); // May throw DOMException
     [Throws]
     void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLenum format, GLenum type, HTMLVideoElement source); // May throw DOMException
     [Throws] // Another overhead throws.
     void texImage2D(GLenum target, GLint level, GLint internalformat,
+                    GLenum format, GLenum type, ImageBitmap source);
+    [Throws] // Another overhead throws.
+    void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLenum format, GLenum type, ImageData source);
 
     [Throws] // Another overhead throws.
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLsizei width, GLsizei height,
                        GLenum format, GLenum type, ArrayBufferView? pixels);
     [Throws]
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
@@ -377,16 +380,19 @@ interface WebGL2RenderingContextBase
     [Throws]
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLenum format, GLenum type, HTMLImageElement source); // May throw DOMException
     [Throws]
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLenum format, GLenum type, HTMLVideoElement source); // May throw DOMException
     [Throws] // Another overhead throws.
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                       GLenum format, GLenum type, ImageBitmap source);
+    [Throws] // Another overhead throws.
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLenum format, GLenum type, ImageData source);
 
     // WebGL2 entrypoints:
     [Throws] // Another overhead throws.
     void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLint border, GLenum format, GLenum type, GLintptr pboOffset);
     [Throws]
     void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
@@ -398,16 +404,20 @@ interface WebGL2RenderingContextBase
                     HTMLImageElement source); // May throw DOMException
     [Throws]
     void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLint border, GLenum format, GLenum type,
                     HTMLVideoElement source); // May throw DOMException
     [Throws] // Another overhead throws.
     void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLint border, GLenum format, GLenum type,
+                    ImageBitmap source);
+    [Throws] // Another overhead throws.
+    void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                    GLint border, GLenum format, GLenum type,
                     ImageData source);
     [Throws] // Another overhead throws.
     void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLint border, GLenum format, GLenum type, ArrayBufferView srcData,
                     GLuint srcOffset);
 
     [Throws] // Another overhead throws.
     void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
@@ -422,16 +432,20 @@ interface WebGL2RenderingContextBase
                     HTMLImageElement source); // May throw DOMException
     [Throws]
     void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLsizei depth, GLint border, GLenum format, GLenum type,
                     HTMLVideoElement source); // May throw DOMException
     [Throws] // Another overhead throws.
     void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLsizei depth, GLint border, GLenum format, GLenum type,
+                    ImageBitmap source);
+    [Throws] // Another overhead throws.
+    void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                    GLsizei depth, GLint border, GLenum format, GLenum type,
                     ImageData source);
     [Throws] // Another overhead throws.
     void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView? srcData);
     [Throws] // Another overhead throws.
     void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                     GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView srcData,
                     GLuint srcOffset);
@@ -449,16 +463,20 @@ interface WebGL2RenderingContextBase
                        HTMLImageElement source); // May throw DOMException
     [Throws]
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
                        GLsizei height, GLenum format, GLenum type,
                        HTMLVideoElement source); // May throw DOMException
     [Throws] // Another overhead throws.
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
                        GLsizei height, GLenum format, GLenum type,
+                       ImageBitmap source);
+    [Throws] // Another overhead throws.
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+                       GLsizei height, GLenum format, GLenum type,
                        ImageData source);
     [Throws] // Another overhead throws.
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
                        GLsizei height, GLenum format, GLenum type, ArrayBufferView srcData,
                        GLuint srcOffset);
 
     [Throws] // Another overhead throws.
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
@@ -474,16 +492,20 @@ interface WebGL2RenderingContextBase
                        HTMLImageElement source); // May throw DOMException
     [Throws]
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
                        GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
                        HTMLVideoElement source); // May throw DOMException
     [Throws] // Another overhead throws.
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
                        GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+                       ImageBitmap source);
+    [Throws] // Another overhead throws.
+    void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                       GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
                        ImageData source);
     [Throws] // Another overhead throws.
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
                        GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
                        ArrayBufferView? srcData, optional GLuint srcOffset = 0);
 
     void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
                            GLint x, GLint y, GLsizei width, GLsizei height);
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -739,16 +739,19 @@ interface WebGLRenderingContext {
     // texImage2D has WebGL2 overloads.
     // Overloads must share [Throws].
     [Throws] // Can't actually throw.
     void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLsizei width, GLsizei height, GLint border, GLenum format,
                     GLenum type, ArrayBufferView? pixels);
     [Throws] // Can't actually throw.
     void texImage2D(GLenum target, GLint level, GLint internalformat,
+                    GLenum format, GLenum type, ImageBitmap pixels);
+    [Throws] // Can't actually throw.
+    void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLenum format, GLenum type, ImageData pixels);
     [Throws]
     void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLenum format, GLenum type, HTMLImageElement image); // May throw DOMException
     [Throws]
     void texImage2D(GLenum target, GLint level, GLint internalformat,
                     GLenum format, GLenum type, HTMLCanvasElement canvas); // May throw DOMException
     [Throws]
@@ -757,16 +760,19 @@ interface WebGLRenderingContext {
 
     // texSubImage2D has WebGL2 overloads.
     [Throws] // Can't actually throw.
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLsizei width, GLsizei height,
                        GLenum format, GLenum type, ArrayBufferView? pixels);
     [Throws] // Can't actually throw.
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                       GLenum format, GLenum type, ImageBitmap pixels);
+    [Throws] // Can't actually throw.
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLenum format, GLenum type, ImageData pixels);
     [Throws]
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLenum format, GLenum type, HTMLImageElement image); // May throw DOMException
     [Throws]
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                        GLenum format, GLenum type, HTMLCanvasElement canvas); // May throw DOMException
     [Throws]