Title: [268578] trunk/Source/WebCore
Revision
268578
Author
[email protected]
Date
2020-10-16 03:55:59 -0700 (Fri, 16 Oct 2020)

Log Message

Refactor WebGL implementation to use only GraphicsContextGL part 1
https://bugs.webkit.org/show_bug.cgi?id=217213
<rdar://problem/69876105>

Patch by Kimmo Kinnunen <[email protected]> on 2020-10-16
Reviewed by Dean Jackson.

Part 1 of work towards WebGL implementation which uses
GraphicsContextGL abstract base class instead of
GraphicsContextGLOpenGL concrete class.

Move pixel data related static helper funcions from
GraphicsContextGLOpenGL to GraphicsContextGL. These are
normal pixel format calculation functions that do not have
concrete class implementation details. Move pixel pack related
structures to GraphicsContextGL.

Rename GraphicsContextGLOpenGL::ImageExtractor to
GraphicsContextGLImageExtractor. The GraphicsContextGL class
interface is already quite lengthy and the image extractor
is not very tied to the context class.

Introduce a virtual member function in GraphicsContextGL for
each call that is likely needed for the WebGL implementation.

No new tests, a refactor.

* WebCore.xcodeproj/project.pbxproj:
* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::getPackPixelStoreParams const):
(WebCore::WebGL2RenderingContext::getUnpackPixelStoreParams const):
* html/canvas/WebGL2RenderingContext.h:
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::texImageArrayBufferViewHelper):
(WebCore::WebGLRenderingContextBase::texImageImpl):
(WebCore::WebGLRenderingContextBase::getPackPixelStoreParams const):
(WebCore::WebGLRenderingContextBase::getUnpackPixelStoreParams const):
* html/canvas/WebGLRenderingContextBase.h:
* platform/graphics/GraphicsContextGL.cpp:
(WebCore::getDataFormat):
(WebCore::texelBytesForFormat):
(WebCore::packPixels):
(WebCore::GraphicsContextGL::computeFormatAndTypeParameters):
(WebCore::GraphicsContextGL::computeImageSizeInBytes):
(WebCore::GraphicsContextGL::possibleFormatAndTypeForInternalFormat):
(WebCore::GraphicsContextGL::packImageData):
(WebCore::GraphicsContextGL::extractImageData):
(WebCore::GraphicsContextGL::extractTextureData):
* platform/graphics/GraphicsContextGL.h:
(WebCore::GraphicsContextGL::Client::~Client):
(WebCore::GraphicsContextGL::addClient):
(WebCore::GraphicsContextGL::removeClient):
(WebCore::GraphicsContextGL::getInternalFramebufferSize const):
* platform/graphics/GraphicsContextGLImageExtractor.cpp: Copied from Source/WebCore/platform/graphics/win/GraphicsContextGLDirect2D.cpp.
(WebCore::GraphicsContextGLImageExtractor::GraphicsContextGLImageExtractor):
* platform/graphics/GraphicsContextGLImageExtractor.h: Added.
(WebCore::GraphicsContextGLImageExtractor::extractSucceeded):
(WebCore::GraphicsContextGLImageExtractor::imagePixelData):
(WebCore::GraphicsContextGLImageExtractor::imageWidth):
(WebCore::GraphicsContextGLImageExtractor::imageHeight):
(WebCore::GraphicsContextGLImageExtractor::imageSourceFormat):
(WebCore::GraphicsContextGLImageExtractor::imageAlphaOp):
(WebCore::GraphicsContextGLImageExtractor::imageSourceUnpackAlignment):
(WebCore::GraphicsContextGLImageExtractor::imageHtmlDomSource):
* platform/graphics/angle/GraphicsContextGLANGLE.cpp:
* platform/graphics/cairo/GraphicsContextGLCairo.cpp:
(WebCore::GraphicsContextGLImageExtractor::extractImage):
* platform/graphics/cg/GraphicsContextGLCG.cpp:
(WebCore::GraphicsContextGLImageExtractor::extractImage):
* platform/graphics/opengl/GraphicsContextGLOpenGL.cpp:
(WebCore::GraphicsContextGLOpenGL::texImage2DResourceSafe):
* platform/graphics/opengl/GraphicsContextGLOpenGL.h:
* platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp:
* platform/graphics/win/GraphicsContextGLDirect2D.cpp:
(WebCore::GraphicsContextGLImageExtractor::extractImage):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (268577 => 268578)


--- trunk/Source/WebCore/ChangeLog	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/ChangeLog	2020-10-16 10:55:59 UTC (rev 268578)
@@ -1,3 +1,80 @@
+2020-10-16  Kimmo Kinnunen  <[email protected]>
+
+        Refactor WebGL implementation to use only GraphicsContextGL part 1
+        https://bugs.webkit.org/show_bug.cgi?id=217213
+        <rdar://problem/69876105>
+
+        Reviewed by Dean Jackson.
+
+        Part 1 of work towards WebGL implementation which uses
+        GraphicsContextGL abstract base class instead of
+        GraphicsContextGLOpenGL concrete class.
+
+        Move pixel data related static helper funcions from
+        GraphicsContextGLOpenGL to GraphicsContextGL. These are
+        normal pixel format calculation functions that do not have
+        concrete class implementation details. Move pixel pack related
+        structures to GraphicsContextGL.
+
+        Rename GraphicsContextGLOpenGL::ImageExtractor to
+        GraphicsContextGLImageExtractor. The GraphicsContextGL class
+        interface is already quite lengthy and the image extractor
+        is not very tied to the context class.
+
+        Introduce a virtual member function in GraphicsContextGL for
+        each call that is likely needed for the WebGL implementation.
+
+        No new tests, a refactor.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/canvas/WebGL2RenderingContext.cpp:
+        (WebCore::WebGL2RenderingContext::getPackPixelStoreParams const):
+        (WebCore::WebGL2RenderingContext::getUnpackPixelStoreParams const):
+        * html/canvas/WebGL2RenderingContext.h:
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::texImageArrayBufferViewHelper):
+        (WebCore::WebGLRenderingContextBase::texImageImpl):
+        (WebCore::WebGLRenderingContextBase::getPackPixelStoreParams const):
+        (WebCore::WebGLRenderingContextBase::getUnpackPixelStoreParams const):
+        * html/canvas/WebGLRenderingContextBase.h:
+        * platform/graphics/GraphicsContextGL.cpp:
+        (WebCore::getDataFormat):
+        (WebCore::texelBytesForFormat):
+        (WebCore::packPixels):
+        (WebCore::GraphicsContextGL::computeFormatAndTypeParameters):
+        (WebCore::GraphicsContextGL::computeImageSizeInBytes):
+        (WebCore::GraphicsContextGL::possibleFormatAndTypeForInternalFormat):
+        (WebCore::GraphicsContextGL::packImageData):
+        (WebCore::GraphicsContextGL::extractImageData):
+        (WebCore::GraphicsContextGL::extractTextureData):
+        * platform/graphics/GraphicsContextGL.h:
+        (WebCore::GraphicsContextGL::Client::~Client):
+        (WebCore::GraphicsContextGL::addClient):
+        (WebCore::GraphicsContextGL::removeClient):
+        (WebCore::GraphicsContextGL::getInternalFramebufferSize const):
+        * platform/graphics/GraphicsContextGLImageExtractor.cpp: Copied from Source/WebCore/platform/graphics/win/GraphicsContextGLDirect2D.cpp.
+        (WebCore::GraphicsContextGLImageExtractor::GraphicsContextGLImageExtractor):
+        * platform/graphics/GraphicsContextGLImageExtractor.h: Added.
+        (WebCore::GraphicsContextGLImageExtractor::extractSucceeded):
+        (WebCore::GraphicsContextGLImageExtractor::imagePixelData):
+        (WebCore::GraphicsContextGLImageExtractor::imageWidth):
+        (WebCore::GraphicsContextGLImageExtractor::imageHeight):
+        (WebCore::GraphicsContextGLImageExtractor::imageSourceFormat):
+        (WebCore::GraphicsContextGLImageExtractor::imageAlphaOp):
+        (WebCore::GraphicsContextGLImageExtractor::imageSourceUnpackAlignment):
+        (WebCore::GraphicsContextGLImageExtractor::imageHtmlDomSource):
+        * platform/graphics/angle/GraphicsContextGLANGLE.cpp:
+        * platform/graphics/cairo/GraphicsContextGLCairo.cpp:
+        (WebCore::GraphicsContextGLImageExtractor::extractImage):
+        * platform/graphics/cg/GraphicsContextGLCG.cpp:
+        (WebCore::GraphicsContextGLImageExtractor::extractImage):
+        * platform/graphics/opengl/GraphicsContextGLOpenGL.cpp:
+        (WebCore::GraphicsContextGLOpenGL::texImage2DResourceSafe):
+        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
+        * platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp:
+        * platform/graphics/win/GraphicsContextGLDirect2D.cpp:
+        (WebCore::GraphicsContextGLImageExtractor::extractImage):
+
 2020-10-16  Youenn Fablet  <[email protected]>
 
         Add support for GPUProcess WebAudio media element providers

Modified: trunk/Source/WebCore/Sources.txt (268577 => 268578)


--- trunk/Source/WebCore/Sources.txt	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/Sources.txt	2020-10-16 10:55:59 UTC (rev 268578)
@@ -1895,6 +1895,7 @@
 platform/graphics/GradientImage.cpp
 platform/graphics/GraphicsContext.cpp
 platform/graphics/GraphicsContextGL.cpp
+platform/graphics/GraphicsContextGLImageExtractor.cpp
 platform/graphics/GraphicsContextImpl.cpp
 platform/graphics/GraphicsLayer.cpp
 platform/graphics/GraphicsLayerTransform.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (268577 => 268578)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-10-16 10:55:59 UTC (rev 268578)
@@ -2218,6 +2218,7 @@
 		7AF9B20F18CFB5F400C64BEF /* JSVTTRegionList.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */; };
 		7BB34A152534579100029D08 /* WebGLLayerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A132534579100029D08 /* WebGLLayerClient.h */; };
 		7BB34A1725345CB200029D08 /* GraphicsContextGLANGLEUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */; };
+		7BB34A48253776CA00029D08 /* GraphicsContextGLImageExtractor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7BE7427381FA906FBB4F0F2C /* JSSVGGraphicsElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */; };
 		7C029C6E2493C8F800268204 /* ColorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C029C6D2493C8F800268204 /* ColorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7C1843FE1C8B7283002EB973 /* Autofill.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C1843FC1C8B7283002EB973 /* Autofill.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -10070,6 +10071,8 @@
 		7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVTTRegionList.h; sourceTree = "<group>"; };
 		7BB34A132534579100029D08 /* WebGLLayerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLLayerClient.h; sourceTree = "<group>"; };
 		7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLANGLEUtilities.h; sourceTree = "<group>"; };
+		7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLImageExtractor.h; sourceTree = "<group>"; };
+		7BB34A47253776C700029D08 /* GraphicsContextGLImageExtractor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContextGLImageExtractor.cpp; sourceTree = "<group>"; };
 		7C011F3D24FAD360005BEF10 /* Settings.cpp.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = Settings.cpp.erb; sourceTree = "<group>"; };
 		7C011F3E24FAD360005BEF10 /* InternalSettingsGenerated.cpp.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = InternalSettingsGenerated.cpp.erb; sourceTree = "<group>"; };
 		7C011F3F24FAD360005BEF10 /* InternalSettingsGenerated.idl.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = InternalSettingsGenerated.idl.erb; sourceTree = "<group>"; };
@@ -26146,6 +26149,8 @@
 				313DE86D23A96966008FC47B /* GraphicsContextGL.cpp */,
 				313DE86F23A96967008FC47B /* GraphicsContextGL.h */,
 				7C330A011DF8FAC600D3395C /* GraphicsContextGLAttributes.h */,
+				7BB34A47253776C700029D08 /* GraphicsContextGLImageExtractor.cpp */,
+				7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */,
 				0F0012401FAD881000531D76 /* GraphicsContextImpl.cpp */,
 				0F00123F1FAD87D600531D76 /* GraphicsContextImpl.h */,
 				0F580B090F12A2690051D689 /* GraphicsLayer.cpp */,
@@ -31622,6 +31627,7 @@
 				313DE87023A96973008FC47B /* GraphicsContextGL.h in Headers */,
 				7BB34A1725345CB200029D08 /* GraphicsContextGLANGLEUtilities.h in Headers */,
 				7C330A021DF8FAC600D3395C /* GraphicsContextGLAttributes.h in Headers */,
+				7BB34A48253776CA00029D08 /* GraphicsContextGLImageExtractor.h in Headers */,
 				49C7B9FC1042D3650009D447 /* GraphicsContextGLOpenGL.h in Headers */,
 				319A728823C267FE0085353C /* GraphicsContextGLOpenGLManager.h in Headers */,
 				2DACB9E923755D0000B4C185 /* GraphicsContextImpl.h in Headers */,

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (268577 => 268578)


--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -3002,9 +3002,9 @@
     return m_maxTransformFeedbackSeparateAttribs;
 }
 
-GraphicsContextGLOpenGL::PixelStoreParams WebGL2RenderingContext::getPackPixelStoreParams() const
+WebGLRenderingContextBase::PixelStoreParams WebGL2RenderingContext::getPackPixelStoreParams() const
 {
-    GraphicsContextGLOpenGL::PixelStoreParams params;
+    PixelStoreParams params;
     params.alignment = m_packAlignment;
     params.rowLength = m_packRowLength;
     params.skipPixels = m_packSkipPixels;
@@ -3012,9 +3012,9 @@
     return params;
 }
 
-GraphicsContextGLOpenGL::PixelStoreParams WebGL2RenderingContext::getUnpackPixelStoreParams(TexImageDimension dimension) const
+WebGLRenderingContextBase::PixelStoreParams WebGL2RenderingContext::getUnpackPixelStoreParams(TexImageDimension dimension) const
 {
-    GraphicsContextGLOpenGL::PixelStoreParams params;
+    PixelStoreParams params;
     params.alignment = m_unpackAlignment;
     params.rowLength = m_unpackRowLength;
     params.skipPixels = m_unpackSkipPixels;

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (268577 => 268578)


--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h	2020-10-16 10:55:59 UTC (rev 268578)
@@ -256,8 +256,8 @@
 
     GCGLuint maxTransformFeedbackSeparateAttribs() const;
 
-    GraphicsContextGLOpenGL::PixelStoreParams getPackPixelStoreParams() const override;
-    GraphicsContextGLOpenGL::PixelStoreParams getUnpackPixelStoreParams(TexImageDimension) const override;
+    PixelStoreParams getPackPixelStoreParams() const override;
+    PixelStoreParams getUnpackPixelStoreParams(TexImageDimension) const override;
 
     bool checkAndTranslateAttachments(const char* functionName, GCGLenum, Vector<GCGLenum>&);
 

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (268577 => 268578)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -50,6 +50,7 @@
 #include "FrameLoaderClient.h"
 #include "FrameView.h"
 #include "GraphicsContext.h"
+#include "GraphicsContextGLImageExtractor.h"
 #include "HTMLCanvasElement.h"
 #include "HTMLImageElement.h"
 #include "HTMLVideoElement.h"
@@ -4888,7 +4889,7 @@
         ASSERT(sourceType == TexImageDimension::Tex2D);
         // Only enter here if width or height is non-zero. Otherwise, call to the
         // underlying driver to generate appropriate GL errors if needed.
-        GraphicsContextGLOpenGL::PixelStoreParams unpackParams = getUnpackPixelStoreParams(TexImageDimension::Tex2D);
+        PixelStoreParams unpackParams = getUnpackPixelStoreParams(TexImageDimension::Tex2D);
         GCGLint dataStoreWidth = unpackParams.rowLength ? unpackParams.rowLength : width;
         if (unpackParams.skipPixels + width > dataStoreWidth) {
             synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, functionName, "Invalid unpack params combination.");
@@ -4945,7 +4946,7 @@
     if (m_unpackFlipY)
         adjustedSourceImageRect.setY(image->height() - adjustedSourceImageRect.maxY());
 
-    GraphicsContextGLOpenGL::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContextGL::NONE, ignoreNativeImageAlphaPremultiplication);
+    GraphicsContextGLImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContextGL::NONE, ignoreNativeImageAlphaPremultiplication);
     if (!imageExtractor.extractSucceeded()) {
         synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "bad image data");
         return;
@@ -6307,17 +6308,17 @@
     return Int32Array::tryCreate(value, length);
 }
 
-GraphicsContextGLOpenGL::PixelStoreParams WebGLRenderingContextBase::getPackPixelStoreParams() const
+WebGLRenderingContextBase::PixelStoreParams WebGLRenderingContextBase::getPackPixelStoreParams() const
 {
-    GraphicsContextGLOpenGL::PixelStoreParams params;
+    PixelStoreParams params;
     params.alignment = m_packAlignment;
     return params;
 }
 
-GraphicsContextGLOpenGL::PixelStoreParams WebGLRenderingContextBase::getUnpackPixelStoreParams(TexImageDimension dimension) const
+WebGLRenderingContextBase::PixelStoreParams WebGLRenderingContextBase::getUnpackPixelStoreParams(TexImageDimension dimension) const
 {
     UNUSED_PARAM(dimension);
-    GraphicsContextGLOpenGL::PixelStoreParams params;
+    PixelStoreParams params;
     params.alignment = m_unpackAlignment;
     return params;
 }

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (268577 => 268578)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2020-10-16 10:55:59 UTC (rev 268578)
@@ -851,10 +851,10 @@
     void texImage2DBase(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLsizei byteLength, const void* pixels);
     void texSubImage2DBase(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum internalformat, GCGLenum format, GCGLenum type, GCGLsizei byteLength, const void* pixels);
     static const char* getTexImageFunctionName(TexImageFunctionID);
+    using PixelStoreParams = GraphicsContextGL::PixelStoreParams;
+    virtual PixelStoreParams getPackPixelStoreParams() const;
+    virtual PixelStoreParams getUnpackPixelStoreParams(TexImageDimension) const;
 
-    virtual GraphicsContextGLOpenGL::PixelStoreParams getPackPixelStoreParams() const;
-    virtual GraphicsContextGLOpenGL::PixelStoreParams getUnpackPixelStoreParams(TexImageDimension) const;
-
 #if !USE(ANGLE)
     bool checkTextureCompleteness(const char*, bool);
 

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContextGL.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/GraphicsContextGL.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContextGL.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -31,9 +31,379 @@
 #if ENABLE(GRAPHICS_CONTEXT_GL)
 
 #include "ExtensionsGL.h"
+#include "FormatConverter.h"
+#include "Image.h"
+#include "ImageData.h"
+#include "ImageObserver.h"
 
 namespace WebCore {
 
+static GraphicsContextGL::DataFormat getDataFormat(GCGLenum destinationFormat, GCGLenum destinationType)
+{
+    GraphicsContextGL::DataFormat dstFormat = GraphicsContextGL::DataFormat::RGBA8;
+    switch (destinationType) {
+    case GraphicsContextGL::BYTE:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RED:
+        case GraphicsContextGL::RED_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::R8_S;
+            break;
+        case GraphicsContextGL::RG:
+        case GraphicsContextGL::RG_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RG8_S;
+            break;
+        case GraphicsContextGL::RGB:
+        case GraphicsContextGL::RGB_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGB8_S;
+            break;
+        case GraphicsContextGL::RGBA:
+        case GraphicsContextGL::RGBA_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA8_S;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::UNSIGNED_BYTE:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RGB:
+        case GraphicsContextGL::RGB_INTEGER:
+        case GraphicsContextGL::SRGB:
+            dstFormat = GraphicsContextGL::GraphicsContextGL::DataFormat::RGB8;
+            break;
+        case GraphicsContextGL::RGBA:
+        case GraphicsContextGL::RGBA_INTEGER:
+        case GraphicsContextGL::SRGB_ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA8;
+            break;
+        case GraphicsContextGL::ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::A8;
+            break;
+        case GraphicsContextGL::LUMINANCE:
+        case GraphicsContextGL::RED:
+        case GraphicsContextGL::RED_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::R8;
+            break;
+        case GraphicsContextGL::RG:
+        case GraphicsContextGL::RG_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RG8;
+            break;
+        case GraphicsContextGL::LUMINANCE_ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::RA8;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::SHORT:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RED_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::R16_S;
+            break;
+        case GraphicsContextGL::RG_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RG16_S;
+            break;
+        case GraphicsContextGL::RGB_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGB16_S;
+            break;
+        case GraphicsContextGL::RGBA_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA16_S;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::UNSIGNED_SHORT:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RED_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::R16;
+            break;
+        case GraphicsContextGL::DEPTH_COMPONENT:
+            dstFormat = GraphicsContextGL::DataFormat::D16;
+            break;
+        case GraphicsContextGL::RG_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RG16;
+            break;
+        case GraphicsContextGL::RGB_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGB16;
+            break;
+        case GraphicsContextGL::RGBA_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA16;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::INT:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RED_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::R32_S;
+            break;
+        case GraphicsContextGL::RG_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RG32_S;
+            break;
+        case GraphicsContextGL::RGB_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGB32_S;
+            break;
+        case GraphicsContextGL::RGBA_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA32_S;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::UNSIGNED_INT:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RED_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::R32;
+            break;
+        case GraphicsContextGL::DEPTH_COMPONENT:
+            dstFormat = GraphicsContextGL::DataFormat::D32;
+            break;
+        case GraphicsContextGL::RG_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RG32;
+            break;
+        case GraphicsContextGL::RGB_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGB32;
+            break;
+        case GraphicsContextGL::RGBA_INTEGER:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA32;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::HALF_FLOAT_OES: // OES_texture_half_float
+    case GraphicsContextGL::HALF_FLOAT:
+        switch (destinationFormat) {
+        case GraphicsContextGL::RGBA:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA16F;
+            break;
+        case GraphicsContextGL::RGB:
+            dstFormat = GraphicsContextGL::DataFormat::RGB16F;
+            break;
+        case GraphicsContextGL::RG:
+            dstFormat = GraphicsContextGL::DataFormat::RG16F;
+            break;
+        case GraphicsContextGL::ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::A16F;
+            break;
+        case GraphicsContextGL::LUMINANCE:
+        case GraphicsContextGL::RED:
+            dstFormat = GraphicsContextGL::DataFormat::R16F;
+            break;
+        case GraphicsContextGL::LUMINANCE_ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::RA16F;
+            break;
+        case GraphicsContextGL::SRGB:
+            dstFormat = GraphicsContextGL::DataFormat::RGB16F;
+            break;
+        case GraphicsContextGL::SRGB_ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA16F;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::FLOAT: // OES_texture_float
+        switch (destinationFormat) {
+        case GraphicsContextGL::RGBA:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA32F;
+            break;
+        case GraphicsContextGL::RGB:
+            dstFormat = GraphicsContextGL::DataFormat::RGB32F;
+            break;
+        case GraphicsContextGL::RG:
+            dstFormat = GraphicsContextGL::DataFormat::RG32F;
+            break;
+        case GraphicsContextGL::ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::A32F;
+            break;
+        case GraphicsContextGL::LUMINANCE:
+        case GraphicsContextGL::RED:
+            dstFormat = GraphicsContextGL::DataFormat::R32F;
+            break;
+        case GraphicsContextGL::DEPTH_COMPONENT:
+            dstFormat = GraphicsContextGL::DataFormat::D32F;
+            break;
+        case GraphicsContextGL::LUMINANCE_ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::RA32F;
+            break;
+        case GraphicsContextGL::SRGB:
+            dstFormat = GraphicsContextGL::DataFormat::RGB32F;
+            break;
+        case GraphicsContextGL::SRGB_ALPHA:
+            dstFormat = GraphicsContextGL::DataFormat::RGBA32F;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        break;
+    case GraphicsContextGL::UNSIGNED_SHORT_4_4_4_4:
+        dstFormat = GraphicsContextGL::DataFormat::RGBA4444;
+        break;
+    case GraphicsContextGL::UNSIGNED_SHORT_5_5_5_1:
+        dstFormat = GraphicsContextGL::DataFormat::RGBA5551;
+        break;
+    case GraphicsContextGL::UNSIGNED_SHORT_5_6_5:
+        dstFormat = GraphicsContextGL::DataFormat::RGB565;
+        break;
+    case GraphicsContextGL::UNSIGNED_INT_5_9_9_9_REV:
+        dstFormat = GraphicsContextGL::DataFormat::RGB5999;
+        break;
+    case GraphicsContextGL::UNSIGNED_INT_24_8:
+        dstFormat = GraphicsContextGL::DataFormat::DS24_8;
+        break;
+    case GraphicsContextGL::UNSIGNED_INT_10F_11F_11F_REV:
+        dstFormat = GraphicsContextGL::DataFormat::RGB10F11F11F;
+        break;
+    case GraphicsContextGL::UNSIGNED_INT_2_10_10_10_REV:
+        dstFormat = GraphicsContextGL::DataFormat::RGBA2_10_10_10;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return dstFormat;
+}
+
+ALWAYS_INLINE static unsigned texelBytesForFormat(GraphicsContextGL::DataFormat format)
+{
+    switch (format) {
+    case GraphicsContextGL::DataFormat::R8:
+    case GraphicsContextGL::DataFormat::R8_S:
+    case GraphicsContextGL::DataFormat::A8:
+        return 1;
+    case GraphicsContextGL::DataFormat::RG8:
+    case GraphicsContextGL::DataFormat::RG8_S:
+    case GraphicsContextGL::DataFormat::RA8:
+    case GraphicsContextGL::DataFormat::AR8:
+    case GraphicsContextGL::DataFormat::RGBA5551:
+    case GraphicsContextGL::DataFormat::RGBA4444:
+    case GraphicsContextGL::DataFormat::RGB565:
+    case GraphicsContextGL::DataFormat::A16F:
+    case GraphicsContextGL::DataFormat::R16:
+    case GraphicsContextGL::DataFormat::R16_S:
+    case GraphicsContextGL::DataFormat::R16F:
+    case GraphicsContextGL::DataFormat::D16:
+        return 2;
+    case GraphicsContextGL::DataFormat::RGB8:
+    case GraphicsContextGL::DataFormat::RGB8_S:
+    case GraphicsContextGL::DataFormat::BGR8:
+        return 3;
+    case GraphicsContextGL::DataFormat::RGBA8:
+    case GraphicsContextGL::DataFormat::RGBA8_S:
+    case GraphicsContextGL::DataFormat::ARGB8:
+    case GraphicsContextGL::DataFormat::ABGR8:
+    case GraphicsContextGL::DataFormat::BGRA8:
+    case GraphicsContextGL::DataFormat::R32:
+    case GraphicsContextGL::DataFormat::R32_S:
+    case GraphicsContextGL::DataFormat::R32F:
+    case GraphicsContextGL::DataFormat::A32F:
+    case GraphicsContextGL::DataFormat::RA16F:
+    case GraphicsContextGL::DataFormat::RGBA2_10_10_10:
+    case GraphicsContextGL::DataFormat::RGB10F11F11F:
+    case GraphicsContextGL::DataFormat::RGB5999:
+    case GraphicsContextGL::DataFormat::RG16:
+    case GraphicsContextGL::DataFormat::RG16_S:
+    case GraphicsContextGL::DataFormat::RG16F:
+    case GraphicsContextGL::DataFormat::D32:
+    case GraphicsContextGL::DataFormat::D32F:
+    case GraphicsContextGL::DataFormat::DS24_8:
+        return 4;
+    case GraphicsContextGL::DataFormat::RGB16:
+    case GraphicsContextGL::DataFormat::RGB16_S:
+    case GraphicsContextGL::DataFormat::RGB16F:
+        return 6;
+    case GraphicsContextGL::DataFormat::RGBA16:
+    case GraphicsContextGL::DataFormat::RGBA16_S:
+    case GraphicsContextGL::DataFormat::RA32F:
+    case GraphicsContextGL::DataFormat::RGBA16F:
+    case GraphicsContextGL::DataFormat::RG32:
+    case GraphicsContextGL::DataFormat::RG32_S:
+    case GraphicsContextGL::DataFormat::RG32F:
+        return 8;
+    case GraphicsContextGL::DataFormat::RGB32:
+    case GraphicsContextGL::DataFormat::RGB32_S:
+    case GraphicsContextGL::DataFormat::RGB32F:
+        return 12;
+    case GraphicsContextGL::DataFormat::RGBA32:
+    case GraphicsContextGL::DataFormat::RGBA32_S:
+    case GraphicsContextGL::DataFormat::RGBA32F:
+        return 16;
+    default:
+        return 0;
+    }
+}
+
+
+// Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
+// data into the specified OpenGL destination format and type.
+// A sourceUnpackAlignment of zero indicates that the source
+// data is tightly packed. Non-zero values may take a slow path.
+// Destination data will have no gaps between rows.
+static bool packPixels(const uint8_t* sourceData, GraphicsContextGL::DataFormat sourceDataFormat, unsigned sourceDataWidth, unsigned sourceDataHeight, const IntRect& sourceDataSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, unsigned destinationFormat, unsigned destinationType, GraphicsContextGL::AlphaOp alphaOp, void* destinationData, bool flipY)
+{
+    ASSERT(depth >= 1);
+    UNUSED_PARAM(sourceDataHeight); // Derived from sourceDataSubRectangle.height().
+    if (!unpackImageHeight)
+        unpackImageHeight = sourceDataSubRectangle.height();
+    int validSrc = sourceDataWidth * texelBytesForFormat(sourceDataFormat);
+    int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
+    int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
+    int srcRowOffset = sourceDataSubRectangle.x() * texelBytesForFormat(sourceDataFormat);
+
+    GraphicsContextGL::DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
+    int dstStride = sourceDataSubRectangle.width() * texelBytesForFormat(dstDataFormat);
+    if (flipY) {
+        destinationData = static_cast<uint8_t*>(destinationData) + dstStride * ((depth * sourceDataSubRectangle.height()) - 1);
+        dstStride = -dstStride;
+    }
+    if (!GraphicsContextGL::hasAlpha(sourceDataFormat) || !GraphicsContextGL::hasColor(sourceDataFormat) || !GraphicsContextGL::hasColor(dstDataFormat))
+        alphaOp = GraphicsContextGL::AlphaOp::DoNothing;
+
+    if (sourceDataFormat == dstDataFormat && alphaOp == GraphicsContextGL::AlphaOp::DoNothing) {
+        const uint8_t* basePtr = sourceData + srcStride * sourceDataSubRectangle.y();
+        const uint8_t* baseEnd = sourceData + srcStride * sourceDataSubRectangle.maxY();
+
+        // If packing multiple images into a 3D texture, and flipY is true,
+        // then the sub-rectangle is pointing at the start of the
+        // "bottommost" of those images. Since the source pointer strides in
+        // the positive direction, we need to back it up to point at the
+        // last, or "topmost", of these images.
+        if (flipY && depth > 1) {
+            const ptrdiff_t distanceToTopImage = (depth - 1) * srcStride * unpackImageHeight;
+            basePtr -= distanceToTopImage;
+            baseEnd -= distanceToTopImage;
+        }
+
+        unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
+        uint8_t* dst = static_cast<uint8_t*>(destinationData);
+
+        for (int i = 0; i < depth; ++i) {
+            const uint8_t* ptr = basePtr;
+            const uint8_t* ptrEnd = baseEnd;
+            while (ptr < ptrEnd) {
+                memcpy(dst, ptr + srcRowOffset, rowSize);
+                ptr += srcStride;
+                dst += dstStride;
+            }
+            basePtr += unpackImageHeight * srcStride;
+            baseEnd += unpackImageHeight * srcStride;
+        }
+        return true;
+    }
+
+    FormatConverter converter(
+        sourceDataSubRectangle, depth,
+        unpackImageHeight, sourceData, destinationData,
+        srcStride, srcRowOffset, dstStride);
+    converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
+    if (!converter.success())
+        return false;
+    return true;
+}
+
+
 GraphicsContextGL::GraphicsContextGL(GraphicsContextGLAttributes attrs, Destination destination, GraphicsContextGL*)
     : m_attrs(attrs)
     , m_destination(destination)
@@ -184,6 +554,332 @@
     }
 }
 
+bool GraphicsContextGL::computeFormatAndTypeParameters(GCGLenum format, GCGLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
+{
+    switch (format) {
+    case GraphicsContextGL::ALPHA:
+    case GraphicsContextGL::LUMINANCE:
+    case GraphicsContextGL::RED:
+    case GraphicsContextGL::RED_INTEGER:
+    case GraphicsContextGL::DEPTH_COMPONENT:
+    case GraphicsContextGL::DEPTH_STENCIL: // Treat it as one component.
+        *componentsPerPixel = 1;
+        break;
+    case GraphicsContextGL::LUMINANCE_ALPHA:
+    case GraphicsContextGL::RG:
+    case GraphicsContextGL::RG_INTEGER:
+        *componentsPerPixel = 2;
+        break;
+    case GraphicsContextGL::RGB:
+    case GraphicsContextGL::RGB_INTEGER:
+    case ExtensionsGL::SRGB_EXT:
+        *componentsPerPixel = 3;
+        break;
+    case GraphicsContextGL::RGBA:
+    case GraphicsContextGL::RGBA_INTEGER:
+    case ExtensionsGL::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
+    case ExtensionsGL::SRGB_ALPHA_EXT:
+        *componentsPerPixel = 4;
+        break;
+    default:
+        return false;
+    }
+
+    switch (type) {
+    case GraphicsContextGL::BYTE:
+        *bytesPerComponent = sizeof(GCGLbyte);
+        break;
+    case GraphicsContextGL::UNSIGNED_BYTE:
+        *bytesPerComponent = sizeof(GCGLubyte);
+        break;
+    case GraphicsContextGL::SHORT:
+        *bytesPerComponent = sizeof(GCGLshort);
+        break;
+    case GraphicsContextGL::UNSIGNED_SHORT:
+        *bytesPerComponent = sizeof(GCGLushort);
+        break;
+    case GraphicsContextGL::UNSIGNED_SHORT_5_6_5:
+    case GraphicsContextGL::UNSIGNED_SHORT_4_4_4_4:
+    case GraphicsContextGL::UNSIGNED_SHORT_5_5_5_1:
+        *componentsPerPixel = 1;
+        *bytesPerComponent = sizeof(GCGLushort);
+        break;
+    case GraphicsContextGL::INT:
+        *bytesPerComponent = sizeof(GCGLint);
+        break;
+    case GraphicsContextGL::UNSIGNED_INT:
+        *bytesPerComponent = sizeof(GCGLuint);
+        break;
+    case GraphicsContextGL::UNSIGNED_INT_24_8:
+    case GraphicsContextGL::UNSIGNED_INT_10F_11F_11F_REV:
+    case GraphicsContextGL::UNSIGNED_INT_5_9_9_9_REV:
+    case GraphicsContextGL::UNSIGNED_INT_2_10_10_10_REV:
+        *componentsPerPixel = 1;
+        *bytesPerComponent = sizeof(GCGLuint);
+        break;
+    case GraphicsContextGL::FLOAT: // OES_texture_float
+        *bytesPerComponent = sizeof(GCGLfloat);
+        break;
+    case GraphicsContextGL::HALF_FLOAT:
+    case GraphicsContextGL::HALF_FLOAT_OES: // OES_texture_half_float
+        *bytesPerComponent = sizeof(GCGLhalffloat);
+        break;
+    case GraphicsContextGL::FLOAT_32_UNSIGNED_INT_24_8_REV:
+        *bytesPerComponent = sizeof(GCGLfloat) + sizeof(GCGLuint);
+        break;
+    default:
+        return false;
+    }
+    return true;
+}
+
+GCGLenum GraphicsContextGL::computeImageSizeInBytes(GCGLenum format, GCGLenum type, GCGLsizei width, GCGLsizei height, GCGLsizei depth, const PixelStoreParams& params, unsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes)
+{
+    ASSERT(imageSizeInBytes);
+    ASSERT(params.alignment == 1 || params.alignment == 2 || params.alignment == 4 || params.alignment == 8);
+    ASSERT(params.rowLength >= 0);
+    ASSERT(params.imageHeight >= 0);
+    ASSERT(params.skipPixels >= 0);
+    ASSERT(params.skipRows >= 0);
+    ASSERT(params.skipImages >= 0);
+    if (width < 0 || height < 0 || depth < 0)
+        return GraphicsContextGL::INVALID_VALUE;
+    if (!width || !height || !depth) {
+        *imageSizeInBytes = 0;
+        if (paddingInBytes)
+            *paddingInBytes = 0;
+        if (skipSizeInBytes)
+            *skipSizeInBytes = 0;
+        return GraphicsContextGL::NO_ERROR;
+    }
+
+    int rowLength = params.rowLength > 0 ? params.rowLength : width;
+    int imageHeight = params.imageHeight > 0 ? params.imageHeight : height;
+
+    unsigned bytesPerComponent, componentsPerPixel;
+    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
+        return GraphicsContextGL::INVALID_ENUM;
+    unsigned bytesPerGroup = bytesPerComponent * componentsPerPixel;
+    Checked<uint32_t, RecordOverflow> checkedValue = static_cast<uint32_t>(rowLength);
+    checkedValue *= bytesPerGroup;
+    if (checkedValue.hasOverflowed())
+        return GraphicsContextGL::INVALID_VALUE;
+
+    unsigned lastRowSize;
+    if (params.rowLength > 0 && params.rowLength != width) {
+        Checked<uint32_t, RecordOverflow> tmp = width;
+        tmp *= bytesPerGroup;
+        if (tmp.hasOverflowed())
+            return GraphicsContextGL::INVALID_VALUE;
+        lastRowSize = tmp.unsafeGet();
+    } else
+        lastRowSize = checkedValue.unsafeGet();
+
+    unsigned padding = 0;
+    unsigned residual = checkedValue.unsafeGet() % params.alignment;
+    if (residual) {
+        padding = params.alignment - residual;
+        checkedValue += padding;
+    }
+    if (checkedValue.hasOverflowed())
+        return GraphicsContextGL::INVALID_VALUE;
+    unsigned paddedRowSize = checkedValue.unsafeGet();
+
+    Checked<uint32_t, RecordOverflow> rows = imageHeight;
+    rows *= (depth - 1);
+    // Last image is not affected by IMAGE_HEIGHT parameter.
+    rows += height;
+    if (rows.hasOverflowed())
+        return GraphicsContextGL::INVALID_VALUE;
+    checkedValue *= (rows - 1);
+    // Last row is not affected by ROW_LENGTH parameter.
+    checkedValue += lastRowSize;
+    if (checkedValue.hasOverflowed())
+        return GraphicsContextGL::INVALID_VALUE;
+    *imageSizeInBytes = checkedValue.unsafeGet();
+    if (paddingInBytes)
+        *paddingInBytes = padding;
+
+    Checked<uint32_t, RecordOverflow> skipSize = 0;
+    if (params.skipImages > 0) {
+        Checked<uint32_t, RecordOverflow> tmp = paddedRowSize;
+        tmp *= imageHeight;
+        tmp *= params.skipImages;
+        if (tmp.hasOverflowed())
+            return GraphicsContextGL::INVALID_VALUE;
+        skipSize += tmp.unsafeGet();
+    }
+    if (params.skipRows > 0) {
+        Checked<uint32_t, RecordOverflow> tmp = paddedRowSize;
+        tmp *= params.skipRows;
+        if (tmp.hasOverflowed())
+            return GraphicsContextGL::INVALID_VALUE;
+        skipSize += tmp.unsafeGet();
+    }
+    if (params.skipPixels > 0) {
+        Checked<uint32_t, RecordOverflow> tmp = bytesPerGroup;
+        tmp *= params.skipPixels;
+        if (tmp.hasOverflowed())
+            return GraphicsContextGL::INVALID_VALUE;
+        skipSize += tmp.unsafeGet();
+    }
+    if (skipSize.hasOverflowed())
+        return GraphicsContextGL::INVALID_VALUE;
+    if (skipSizeInBytes)
+        *skipSizeInBytes = skipSize.unsafeGet();
+
+    checkedValue += skipSize.unsafeGet();
+    if (checkedValue.hasOverflowed())
+        return GraphicsContextGL::INVALID_VALUE;
+    return GraphicsContextGL::NO_ERROR;
+}
+
+#if !USE(ANGLE)
+bool GraphicsContextGL::possibleFormatAndTypeForInternalFormat(GCGLenum internalFormat, GCGLenum& format, GCGLenum& type)
+{
+#define POSSIBLE_FORMAT_TYPE_CASE(internalFormatMacro, formatMacro, typeMacro) case internalFormatMacro: \
+        format = formatMacro; \
+        type = typeMacro; \
+        break;
+
+    switch (internalFormat) {
+        POSSIBLE_FORMAT_TYPE_CASE(RGB, RGB, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA, RGBA, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(LUMINANCE_ALPHA, LUMINANCE_ALPHA, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(LUMINANCE, LUMINANCE, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(ALPHA, ALPHA, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(R8, RED, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(R8_SNORM, RED, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(R16F, RED, HALF_FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(R32F, RED, FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(R8UI, RED_INTEGER, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(R8I, RED_INTEGER, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(R16UI, RED_INTEGER, UNSIGNED_SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(R16I, RED_INTEGER, SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(R32UI, RED_INTEGER, UNSIGNED_INT);
+        POSSIBLE_FORMAT_TYPE_CASE(R32I, RED_INTEGER, INT);
+        POSSIBLE_FORMAT_TYPE_CASE(RG8, RG, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RG8_SNORM, RG, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RG16F, RG, HALF_FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(RG32F, RG, FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(RG8UI, RG_INTEGER, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RG8I, RG_INTEGER, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RG16UI, RG_INTEGER, UNSIGNED_SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(RG16I, RG_INTEGER, SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(RG32UI, RG_INTEGER, UNSIGNED_INT);
+        POSSIBLE_FORMAT_TYPE_CASE(RG32I, RG_INTEGER, INT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB8, RGB, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(SRGB8, RGB, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB565, RGB, UNSIGNED_SHORT_5_6_5);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB8_SNORM, RGB, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(R11F_G11F_B10F, RGB, UNSIGNED_INT_10F_11F_11F_REV);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB9_E5, RGB, UNSIGNED_INT_5_9_9_9_REV);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB16F, RGB, HALF_FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB32F, RGB, FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB8UI, RGB_INTEGER, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB8I, RGB_INTEGER, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB16UI, RGB_INTEGER, UNSIGNED_SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB16I, RGB_INTEGER, SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB32UI, RGB_INTEGER, UNSIGNED_INT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB32I, RGB_INTEGER, INT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA8, RGBA, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(SRGB8_ALPHA8, RGBA, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA8_SNORM, RGBA, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB5_A1, RGBA, UNSIGNED_SHORT_5_5_5_1);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA4, RGBA, UNSIGNED_SHORT_4_4_4_4);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB10_A2, RGBA, UNSIGNED_INT_2_10_10_10_REV);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA16F, RGBA, HALF_FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA32F, RGBA, FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA8UI, RGBA_INTEGER, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA8I, RGBA_INTEGER, BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(RGB10_A2UI, RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA16UI, RGBA_INTEGER, UNSIGNED_SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA16I, RGBA_INTEGER, SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA32I, RGBA_INTEGER, INT);
+        POSSIBLE_FORMAT_TYPE_CASE(RGBA32UI, RGBA_INTEGER, UNSIGNED_INT);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH_COMPONENT16, DEPTH_COMPONENT, UNSIGNED_SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH_COMPONENT, DEPTH_COMPONENT, UNSIGNED_SHORT);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH_COMPONENT24, DEPTH_COMPONENT, UNSIGNED_INT);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH_COMPONENT32F, DEPTH_COMPONENT, FLOAT);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH_STENCIL, DEPTH_STENCIL, UNSIGNED_INT_24_8);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH24_STENCIL8, DEPTH_STENCIL, UNSIGNED_INT_24_8);
+        POSSIBLE_FORMAT_TYPE_CASE(DEPTH32F_STENCIL8, DEPTH_STENCIL, FLOAT_32_UNSIGNED_INT_24_8_REV);
+        POSSIBLE_FORMAT_TYPE_CASE(ExtensionsGL::SRGB_EXT, ExtensionsGL::SRGB_EXT, UNSIGNED_BYTE);
+        POSSIBLE_FORMAT_TYPE_CASE(ExtensionsGL::SRGB_ALPHA_EXT, ExtensionsGL::SRGB_ALPHA_EXT, UNSIGNED_BYTE);
+    default:
+        return false;
+    }
+#undef POSSIBLE_FORMAT_TYPE_CASE
+
+    return true;
+}
+#endif // !USE(ANGLE)
+
+bool GraphicsContextGL::packImageData(Image* image, const void* pixels, GCGLenum format, GCGLenum type, bool flipY, AlphaOp alphaOp, DataFormat sourceFormat, unsigned sourceImageWidth, unsigned sourceImageHeight, const IntRect& sourceImageSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, Vector<uint8_t>& data)
+{
+    if (!image || !pixels)
+        return false;
+
+    unsigned packedSize;
+    // Output data is tightly packed (alignment == 1).
+    PixelStoreParams params;
+    params.alignment = 1;
+    if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), sourceImageSubRectangle.height(), depth, params, &packedSize, nullptr, nullptr) != GraphicsContextGL::NO_ERROR)
+        return false;
+    data.resize(packedSize);
+
+    if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, sourceImageWidth, sourceImageHeight, sourceImageSubRectangle, depth, sourceUnpackAlignment, unpackImageHeight, format, type, alphaOp, data.data(), flipY))
+        return false;
+    if (ImageObserver* observer = image->imageObserver())
+        observer->didDraw(*image);
+    return true;
+}
+
+bool GraphicsContextGL::extractImageData(ImageData* imageData, DataFormat sourceDataFormat, const IntRect& sourceImageSubRectangle, int depth, int unpackImageHeight, GCGLenum format, GCGLenum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data)
+{
+    if (!imageData)
+        return false;
+    int width = imageData->width();
+    int height = imageData->height();
+
+    unsigned packedSize;
+    // Output data is tightly packed (alignment == 1).
+    PixelStoreParams params;
+    params.alignment = 1;
+    if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), sourceImageSubRectangle.height(), depth, params, &packedSize, nullptr, nullptr) != GraphicsContextGL::NO_ERROR)
+        return false;
+    data.resize(packedSize);
+
+    if (!packPixels(imageData->data()->data(), sourceDataFormat, width, height, sourceImageSubRectangle, depth, 0, unpackImageHeight, format, type, premultiplyAlpha ? AlphaOp::DoPremultiply : AlphaOp::DoNothing, data.data(), flipY))
+        return false;
+
+    return true;
+}
+
+bool GraphicsContextGL::extractTextureData(unsigned width, unsigned height, GCGLenum format, GCGLenum type, const PixelStoreParams& unpackParams, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data)
+{
+    // Assumes format, type, etc. have already been validated.
+    DataFormat sourceDataFormat = getDataFormat(format, type);
+
+    // Resize the output buffer.
+    unsigned componentsPerPixel, bytesPerComponent;
+    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
+        return false;
+    unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
+    data.resize(width * height * bytesPerPixel);
+
+    unsigned imageSizeInBytes, skipSizeInBytes;
+    computeImageSizeInBytes(format, type, width, height, 1, unpackParams, &imageSizeInBytes, nullptr, &skipSizeInBytes);
+    const uint8_t* srcData = static_cast<const uint8_t*>(pixels);
+    if (skipSizeInBytes)
+        srcData += skipSizeInBytes;
+
+    if (!packPixels(srcData, sourceDataFormat, unpackParams.rowLength ? unpackParams.rowLength : width, height, IntRect(0, 0, width, height), 1, unpackParams.alignment, 0, format, type, (premultiplyAlpha ? AlphaOp::DoPremultiply : AlphaOp::DoNothing), data.data(), flipY))
+        return false;
+
+    return true;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBGL)

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h	2020-10-16 10:55:59 UTC (rev 268578)
@@ -33,6 +33,7 @@
 #include "IntRect.h"
 #include "IntSize.h"
 #include "PlatformLayer.h"
+#include <wtf/HashSet.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
@@ -888,6 +889,15 @@
 #endif
     }
 
+    class Client {
+    public:
+        virtual ~Client() { }
+        virtual void didComposite() = 0;
+        virtual void forceContextLost() = 0;
+        virtual void recycleContext() = 0;
+        virtual void dispatchContextChangedNotification() = 0;
+    };
+
     struct ActiveInfo {
         String name;
         GCGLenum type;
@@ -897,6 +907,9 @@
     GraphicsContextGL(GraphicsContextGLAttributes, Destination = Destination::Offscreen, GraphicsContextGL* sharedContext = nullptr);
     virtual ~GraphicsContextGL() = default;
 
+    void addClient(Client& client) { m_clients.add(&client); }
+    void removeClient(Client& client) { m_clients.remove(&client); }
+
     // ========== WebGL 1 entry points.
 
     virtual void activeTexture(GCGLenum texture) = 0;
@@ -1253,13 +1266,90 @@
 
     // ========== Non-WebGL based entry points.
 
+    virtual void setContextVisibility(bool) = 0;
+
+    virtual GraphicsContextGLPowerPreference powerPreferenceUsedForCreation() const = 0;
+
+    virtual bool isGLES2Compliant() const = 0;
+
+    // Synthesizes an OpenGL error which will be returned from a
+    // later call to getError. This is used to emulate OpenGL ES
+    // 2.0 behavior on the desktop and to enforce additional error
+    // checking mandated by WebGL.
+    //
+    // Per the behavior of glGetError, this stores at most one
+    // instance of any given error, and returns them from calls to
+    // getError in the order they were added.
+    virtual void synthesizeGLError(GCGLenum error) = 0;
+
+    virtual void setFailNextGPUStatusCheck() = 0;
+
+    virtual void prepareForDisplay() = 0;
+
+#if !USE(ANGLE)
+    // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
+    // Return true if no GL error is synthesized.
+    // By default, alignment is 4, the OpenGL default setting.
+    virtual bool texImage2DResourceSafe(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLint alignment = 4) =  0;
+#endif
+
+    IntSize getInternalFramebufferSize() const { return IntSize(m_currentWidth, m_currentHeight); }
+
     static unsigned getClearBitsByAttachmentType(GCGLenum);
     static unsigned getClearBitsByFormat(GCGLenum);
 
     static uint8_t getChannelBitsByFormat(GCGLenum);
 
+    struct PixelStoreParams final {
+        GCGLint alignment { 4 };
+        GCGLint rowLength { 0 };
+        GCGLint imageHeight { 0 };
+        GCGLint skipPixels { 0 };
+        GCGLint skipRows { 0 };
+        GCGLint skipImages { 0 };
+    };
+
+    // Computes the components per pixel and bytes per component
+    // for the given format and type combination. Returns false if
+    // either was an invalid enum.
+    static bool computeFormatAndTypeParameters(GCGLenum format, GCGLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent);
+
+    // Computes the image size in bytes. If paddingInBytes is not null, padding
+    // is also calculated in return. Returns NO_ERROR if succeed, otherwise
+    // return the suggested GL error indicating the cause of the failure:
+    //   INVALID_VALUE if width/height is negative or overflow happens.
+    //   INVALID_ENUM if format/type is illegal.
+    static GCGLenum computeImageSizeInBytes(GCGLenum format, GCGLenum type, GCGLsizei width, GCGLsizei height, GCGLsizei depth, const PixelStoreParams&, unsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes);
+
+#if !USE(ANGLE)
+    static bool possibleFormatAndTypeForInternalFormat(GCGLenum internalFormat, GCGLenum& format, GCGLenum& type);
+#endif // !USE(ANGLE)
+
+    // Extracts the contents of the given ImageData into the passed Vector,
+    // packing the pixel data according to the given format and type,
+    // and obeying the flipY and premultiplyAlpha flags. Returns true
+    // upon success.
+    static bool extractImageData(ImageData*, DataFormat, const IntRect& sourceImageSubRectangle, int depth, int unpackImageHeight, GCGLenum format, GCGLenum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data);
+
+    // Helper function which extracts the user-supplied texture
+    // data, applying the flipY and premultiplyAlpha parameters.
+    // If the data is not tightly packed according to the passed
+    // unpackParams, the output data will be tightly packed.
+    // Returns true if successful, false if any error occurred.
+    static bool extractTextureData(unsigned width, unsigned height, GCGLenum format, GCGLenum type, const PixelStoreParams& unpackParams, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data);
+
+    // Packs the contents of the given Image which is passed in |pixels| into the passed Vector
+    // according to the given format and type, and obeying the flipY and AlphaOp flags.
+    // Returns true upon success.
+    static bool packImageData(Image*, const void* pixels, GCGLenum format, GCGLenum type, bool flipY, AlphaOp, DataFormat sourceFormat, unsigned sourceImageWidth, unsigned sourceImageHeight, const IntRect& sourceImageSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, Vector<uint8_t>& data);
+
     Destination destination() const { return m_destination; }
 
+protected:
+    int m_currentWidth { 0 };
+    int m_currentHeight { 0 };
+    HashSet<Client*> m_clients;
+
 private:
     GraphicsContextGLAttributes m_attrs;
     Destination m_destination;

Copied: trunk/Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.cpp (from rev 268577, trunk/Source/WebCore/platform/graphics/win/GraphicsContextGLDirect2D.cpp) (0 => 268578)


--- trunk/Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GraphicsContextGLImageExtractor.h"
+
+#if ENABLE(GRAPHICS_CONTEXT_GL)
+
+namespace WebCore {
+
+GraphicsContextGLImageExtractor::GraphicsContextGLImageExtractor(Image* image, DOMSource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication)
+{
+    m_image = image;
+    m_imageHtmlDomSource = imageHtmlDomSource;
+    m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile, ignoreNativeImageAlphaPremultiplication);
+}
+
+}
+
+#endif

Added: trunk/Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.h (0 => 268578)


--- trunk/Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.h	2020-10-16 10:55:59 UTC (rev 268578)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(GRAPHICS_CONTEXT_GL)
+
+#include "GraphicsContextGL.h"
+
+namespace WebCore {
+
+class GraphicsContextGLImageExtractor {
+public:
+    using DOMSource = GraphicsContextGL::DOMSource;
+    using DataFormat = GraphicsContextGL::DataFormat;
+    using AlphaOp = GraphicsContextGL::AlphaOp;
+    GraphicsContextGLImageExtractor(Image*, DOMSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication);
+
+    // Each platform must provide an implementation of this method to deallocate or release resources
+    // associated with the image if needed.
+    ~GraphicsContextGLImageExtractor();
+
+    bool extractSucceeded() { return m_extractSucceeded; }
+    const void* imagePixelData() { return m_imagePixelData; }
+    unsigned imageWidth() { return m_imageWidth; }
+    unsigned imageHeight() { return m_imageHeight; }
+    DataFormat imageSourceFormat() { return m_imageSourceFormat; }
+    AlphaOp imageAlphaOp() { return m_alphaOp; }
+    unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
+    DOMSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
+private:
+    // Each platform must provide an implementation of this method.
+    // Extracts the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc,
+    // needs to lock the resources or relevant data if needed and returns true upon success
+    bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication);
+
+#if USE(CAIRO)
+    RefPtr<cairo_surface_t> m_imageSurface;
+#elif USE(CG)
+    RetainPtr<CGImageRef> m_cgImage;
+    RetainPtr<CGImageRef> m_decodedImage;
+    RetainPtr<CFDataRef> m_pixelData;
+    UniqueArray<uint8_t> m_formalizedRGBA8Data;
+#endif
+    Image* m_image;
+    DOMSource m_imageHtmlDomSource;
+    bool m_extractSucceeded;
+    const void* m_imagePixelData;
+    unsigned m_imageWidth;
+    unsigned m_imageHeight;
+    DataFormat m_imageSourceFormat;
+    AlphaOp m_alphaOp;
+    unsigned m_imageSourceUnpackAlignment;
+};
+
+}
+
+#endif

Modified: trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -707,11 +707,6 @@
     gl::Flush();
 }
 
-IntSize GraphicsContextGLOpenGL::getInternalFramebufferSize() const
-{
-    return IntSize(m_currentWidth, m_currentHeight);
-}
-
 void GraphicsContextGLOpenGL::activeTexture(GCGLenum texture)
 {
     makeContextCurrent();

Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextGLCairo.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextGLCairo.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextGLCairo.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -31,6 +31,7 @@
 #if ENABLE(GRAPHICS_CONTEXT_GL) && USE(CAIRO)
 
 #include "CairoUtilities.h"
+#include "GraphicsContextGLImageExtractor.h"
 #include "Image.h"
 #include "ImageSource.h"
 #include "PlatformContextCairo.h"
@@ -39,9 +40,9 @@
 
 namespace WebCore {
 
-GraphicsContextGLOpenGL::ImageExtractor::~ImageExtractor() = default;
+GraphicsContextGLImageExtractor::~GraphicsContextGLImageExtractor() = default;
 
-bool GraphicsContextGLOpenGL::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool)
+bool GraphicsContextGLImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool)
 {
     if (!m_image)
         return false;

Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextGLCG.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextGLCG.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextGLCG.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -30,6 +30,7 @@
 
 #include "BitmapImage.h"
 #include "GraphicsContextCG.h"
+#include "GraphicsContextGLImageExtractor.h"
 #include "GraphicsContextGLOpenGL.h"
 #include "Image.h"
 #include "ImageBufferUtilitiesCG.h"
@@ -317,9 +318,9 @@
 
 }
 
-GraphicsContextGLOpenGL::ImageExtractor::~ImageExtractor() = default;
+GraphicsContextGLImageExtractor::~GraphicsContextGLImageExtractor() = default;
 
-bool GraphicsContextGLOpenGL::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication)
+bool GraphicsContextGLImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication)
 {
     if (!m_image)
         return false;

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -31,246 +31,10 @@
 #if ENABLE(GRAPHICS_CONTEXT_GL)
 
 #include "ExtensionsGL.h"
-#include "FormatConverter.h"
-#include "Image.h"
-#include "ImageData.h"
-#include "ImageObserver.h"
 #include <wtf/UniqueArray.h>
 
 namespace WebCore {
 
-namespace {
-
-GraphicsContextGL::DataFormat getDataFormat(GCGLenum destinationFormat, GCGLenum destinationType)
-{
-    GraphicsContextGL::DataFormat dstFormat = GraphicsContextGL::DataFormat::RGBA8;
-    switch (destinationType) {
-    case GraphicsContextGL::BYTE:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RED:
-        case GraphicsContextGL::RED_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::R8_S;
-            break;
-        case GraphicsContextGL::RG:
-        case GraphicsContextGL::RG_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RG8_S;
-            break;
-        case GraphicsContextGL::RGB:
-        case GraphicsContextGL::RGB_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGB8_S;
-            break;
-        case GraphicsContextGL::RGBA:
-        case GraphicsContextGL::RGBA_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA8_S;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::UNSIGNED_BYTE:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RGB:
-        case GraphicsContextGL::RGB_INTEGER:
-        case GraphicsContextGL::SRGB:
-            dstFormat = GraphicsContextGL::GraphicsContextGL::DataFormat::RGB8;
-            break;
-        case GraphicsContextGL::RGBA:
-        case GraphicsContextGL::RGBA_INTEGER:
-        case GraphicsContextGL::SRGB_ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA8;
-            break;
-        case GraphicsContextGL::ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::A8;
-            break;
-        case GraphicsContextGL::LUMINANCE:
-        case GraphicsContextGL::RED:
-        case GraphicsContextGL::RED_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::R8;
-            break;
-        case GraphicsContextGL::RG:
-        case GraphicsContextGL::RG_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RG8;
-            break;
-        case GraphicsContextGL::LUMINANCE_ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::RA8;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::SHORT:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RED_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::R16_S;
-            break;
-        case GraphicsContextGL::RG_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RG16_S;
-            break;
-        case GraphicsContextGL::RGB_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGB16_S;
-            break;
-        case GraphicsContextGL::RGBA_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA16_S;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::UNSIGNED_SHORT:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RED_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::R16;
-            break;
-        case GraphicsContextGL::DEPTH_COMPONENT:
-            dstFormat = GraphicsContextGL::DataFormat::D16;
-            break;
-        case GraphicsContextGL::RG_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RG16;
-            break;
-        case GraphicsContextGL::RGB_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGB16;
-            break;
-        case GraphicsContextGL::RGBA_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA16;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::INT:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RED_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::R32_S;
-            break;
-        case GraphicsContextGL::RG_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RG32_S;
-            break;
-        case GraphicsContextGL::RGB_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGB32_S;
-            break;
-        case GraphicsContextGL::RGBA_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA32_S;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::UNSIGNED_INT:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RED_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::R32;
-            break;
-        case GraphicsContextGL::DEPTH_COMPONENT:
-            dstFormat = GraphicsContextGL::DataFormat::D32;
-            break;
-        case GraphicsContextGL::RG_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RG32;
-            break;
-        case GraphicsContextGL::RGB_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGB32;
-            break;
-        case GraphicsContextGL::RGBA_INTEGER:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA32;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::HALF_FLOAT_OES: // OES_texture_half_float
-    case GraphicsContextGL::HALF_FLOAT:
-        switch (destinationFormat) {
-        case GraphicsContextGL::RGBA:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA16F;
-            break;
-        case GraphicsContextGL::RGB:
-            dstFormat = GraphicsContextGL::DataFormat::RGB16F;
-            break;
-        case GraphicsContextGL::RG:
-            dstFormat = GraphicsContextGL::DataFormat::RG16F;
-            break;
-        case GraphicsContextGL::ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::A16F;
-            break;
-        case GraphicsContextGL::LUMINANCE:
-        case GraphicsContextGL::RED:
-            dstFormat = GraphicsContextGL::DataFormat::R16F;
-            break;
-        case GraphicsContextGL::LUMINANCE_ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::RA16F;
-            break;
-        case GraphicsContextGL::SRGB:
-            dstFormat = GraphicsContextGL::DataFormat::RGB16F;
-            break;
-        case GraphicsContextGL::SRGB_ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA16F;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::FLOAT: // OES_texture_float
-        switch (destinationFormat) {
-        case GraphicsContextGL::RGBA:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA32F;
-            break;
-        case GraphicsContextGL::RGB:
-            dstFormat = GraphicsContextGL::DataFormat::RGB32F;
-            break;
-        case GraphicsContextGL::RG:
-            dstFormat = GraphicsContextGL::DataFormat::RG32F;
-            break;
-        case GraphicsContextGL::ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::A32F;
-            break;
-        case GraphicsContextGL::LUMINANCE:
-        case GraphicsContextGL::RED:
-            dstFormat = GraphicsContextGL::DataFormat::R32F;
-            break;
-        case GraphicsContextGL::DEPTH_COMPONENT:
-            dstFormat = GraphicsContextGL::DataFormat::D32F;
-            break;
-        case GraphicsContextGL::LUMINANCE_ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::RA32F;
-            break;
-        case GraphicsContextGL::SRGB:
-            dstFormat = GraphicsContextGL::DataFormat::RGB32F;
-            break;
-        case GraphicsContextGL::SRGB_ALPHA:
-            dstFormat = GraphicsContextGL::DataFormat::RGBA32F;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        break;
-    case GraphicsContextGL::UNSIGNED_SHORT_4_4_4_4:
-        dstFormat = GraphicsContextGL::DataFormat::RGBA4444;
-        break;
-    case GraphicsContextGL::UNSIGNED_SHORT_5_5_5_1:
-        dstFormat = GraphicsContextGL::DataFormat::RGBA5551;
-        break;
-    case GraphicsContextGL::UNSIGNED_SHORT_5_6_5:
-        dstFormat = GraphicsContextGL::DataFormat::RGB565;
-        break;
-    case GraphicsContextGL::UNSIGNED_INT_5_9_9_9_REV:
-        dstFormat = GraphicsContextGL::DataFormat::RGB5999;
-        break;
-    case GraphicsContextGL::UNSIGNED_INT_24_8:
-        dstFormat = GraphicsContextGL::DataFormat::DS24_8;
-        break;
-    case GraphicsContextGL::UNSIGNED_INT_10F_11F_11F_REV:
-        dstFormat = GraphicsContextGL::DataFormat::RGB10F11F11F;
-        break;
-    case GraphicsContextGL::UNSIGNED_INT_2_10_10_10_REV:
-        dstFormat = GraphicsContextGL::DataFormat::RGBA2_10_10_10;
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    return dstFormat;
-}
-
-} // anonymous namespace
-
 void GraphicsContextGLOpenGL::resetBuffersToAutoClear()
 {
     GCGLuint buffers = GraphicsContextGL::COLOR_BUFFER_BIT;
@@ -307,6 +71,7 @@
     m_buffersToAutoClear = 0;
 }
 
+#if !USE(ANGLE)
 bool GraphicsContextGLOpenGL::texImage2DResourceSafe(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLint unpackAlignment)
 {
     ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);
@@ -313,7 +78,7 @@
     UniqueArray<unsigned char> zero;
     if (width > 0 && height > 0) {
         unsigned size;
-        GraphicsContextGLOpenGL::PixelStoreParams params;
+        PixelStoreParams params;
         params.alignment = unpackAlignment;
         GCGLenum error = computeImageSizeInBytes(format, type, width, height, 1, params, &size, nullptr, nullptr);
         if (error != GraphicsContextGL::NO_ERROR) {
@@ -329,485 +94,9 @@
     }
     return texImage2D(target, level, internalformat, width, height, border, format, type, zero.get());
 }
+#endif
 
-bool GraphicsContextGLOpenGL::computeFormatAndTypeParameters(GCGLenum format, GCGLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
-{
-    switch (format) {
-    case GraphicsContextGL::ALPHA:
-    case GraphicsContextGL::LUMINANCE:
-    case GraphicsContextGL::RED:
-    case GraphicsContextGL::RED_INTEGER:
-    case GraphicsContextGL::DEPTH_COMPONENT:
-    case GraphicsContextGL::DEPTH_STENCIL: // Treat it as one component.
-        *componentsPerPixel = 1;
-        break;
-    case GraphicsContextGL::LUMINANCE_ALPHA:
-    case GraphicsContextGL::RG:
-    case GraphicsContextGL::RG_INTEGER:
-        *componentsPerPixel = 2;
-        break;
-    case GraphicsContextGL::RGB:
-    case GraphicsContextGL::RGB_INTEGER:
-    case ExtensionsGL::SRGB_EXT:
-        *componentsPerPixel = 3;
-        break;
-    case GraphicsContextGL::RGBA:
-    case GraphicsContextGL::RGBA_INTEGER:
-    case ExtensionsGL::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
-    case ExtensionsGL::SRGB_ALPHA_EXT:
-        *componentsPerPixel = 4;
-        break;
-    default:
-        return false;
-    }
 
-    switch (type) {
-    case GraphicsContextGL::BYTE:
-        *bytesPerComponent = sizeof(GCGLbyte);
-        break;
-    case GraphicsContextGL::UNSIGNED_BYTE:
-        *bytesPerComponent = sizeof(GCGLubyte);
-        break;
-    case GraphicsContextGL::SHORT:
-        *bytesPerComponent = sizeof(GCGLshort);
-        break;
-    case GraphicsContextGL::UNSIGNED_SHORT:
-        *bytesPerComponent = sizeof(GCGLushort);
-        break;
-    case GraphicsContextGL::UNSIGNED_SHORT_5_6_5:
-    case GraphicsContextGL::UNSIGNED_SHORT_4_4_4_4:
-    case GraphicsContextGL::UNSIGNED_SHORT_5_5_5_1:
-        *componentsPerPixel = 1;
-        *bytesPerComponent = sizeof(GCGLushort);
-        break;
-    case GraphicsContextGL::INT:
-        *bytesPerComponent = sizeof(GCGLint);
-        break;
-    case GraphicsContextGL::UNSIGNED_INT:
-        *bytesPerComponent = sizeof(GCGLuint);
-        break;
-    case GraphicsContextGL::UNSIGNED_INT_24_8:
-    case GraphicsContextGL::UNSIGNED_INT_10F_11F_11F_REV:
-    case GraphicsContextGL::UNSIGNED_INT_5_9_9_9_REV:
-    case GraphicsContextGL::UNSIGNED_INT_2_10_10_10_REV:
-        *componentsPerPixel = 1;
-        *bytesPerComponent = sizeof(GCGLuint);
-        break;
-    case GraphicsContextGL::FLOAT: // OES_texture_float
-        *bytesPerComponent = sizeof(GCGLfloat);
-        break;
-    case GraphicsContextGL::HALF_FLOAT:
-    case GraphicsContextGL::HALF_FLOAT_OES: // OES_texture_half_float
-        *bytesPerComponent = sizeof(GCGLhalffloat);
-        break;
-    case GraphicsContextGL::FLOAT_32_UNSIGNED_INT_24_8_REV:
-        *bytesPerComponent = sizeof(GCGLfloat) + sizeof(GCGLuint);
-        break;
-    default:
-        return false;
-    }
-    return true;
-}
-
-#if !USE(ANGLE)
-bool GraphicsContextGLOpenGL::possibleFormatAndTypeForInternalFormat(GCGLenum internalFormat, GCGLenum& format, GCGLenum& type)
-{
-#define POSSIBLE_FORMAT_TYPE_CASE(internalFormatMacro, formatMacro, typeMacro) case internalFormatMacro: \
-        format = formatMacro; \
-        type = GraphicsContextGLOpenGL::typeMacro; \
-        break;
-
-    switch (internalFormat) {
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB               , GraphicsContextGL::RGB            , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA              , GraphicsContextGL::RGBA           , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::LUMINANCE_ALPHA   , GraphicsContextGL::LUMINANCE_ALPHA, UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::LUMINANCE         , GraphicsContextGL::LUMINANCE      , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::ALPHA             , GraphicsContextGL::ALPHA          , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R8                , GraphicsContextGL::RED            , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R8_SNORM          , GraphicsContextGL::RED            , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R16F              , GraphicsContextGL::RED            , HALF_FLOAT                    );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R32F              , GraphicsContextGL::RED            , FLOAT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R8UI              , GraphicsContextGL::RED_INTEGER    , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R8I               , GraphicsContextGL::RED_INTEGER    , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R16UI             , GraphicsContextGL::RED_INTEGER    , UNSIGNED_SHORT                );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R16I              , GraphicsContextGL::RED_INTEGER    , SHORT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R32UI             , GraphicsContextGL::RED_INTEGER    , UNSIGNED_INT                  );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R32I              , GraphicsContextGL::RED_INTEGER    , INT                           );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG8               , GraphicsContextGL::RG             , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG8_SNORM         , GraphicsContextGL::RG             , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG16F             , GraphicsContextGL::RG             , HALF_FLOAT                    );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG32F             , GraphicsContextGL::RG             , FLOAT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG8UI             , GraphicsContextGL::RG_INTEGER     , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG8I              , GraphicsContextGL::RG_INTEGER     , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG16UI            , GraphicsContextGL::RG_INTEGER     , UNSIGNED_SHORT                );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG16I             , GraphicsContextGL::RG_INTEGER     , SHORT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG32UI            , GraphicsContextGL::RG_INTEGER     , UNSIGNED_INT                  );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RG32I             , GraphicsContextGL::RG_INTEGER     , INT                           );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB8              , GraphicsContextGL::RGB            , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::SRGB8             , GraphicsContextGL::RGB            , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB565            , GraphicsContextGL::RGB            , UNSIGNED_SHORT_5_6_5          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB8_SNORM        , GraphicsContextGL::RGB            , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::R11F_G11F_B10F    , GraphicsContextGL::RGB            , UNSIGNED_INT_10F_11F_11F_REV  );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB9_E5           , GraphicsContextGL::RGB            , UNSIGNED_INT_5_9_9_9_REV      );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB16F            , GraphicsContextGL::RGB            , HALF_FLOAT                    );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB32F            , GraphicsContextGL::RGB            , FLOAT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB8UI            , GraphicsContextGL::RGB_INTEGER    , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB8I             , GraphicsContextGL::RGB_INTEGER    , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB16UI           , GraphicsContextGL::RGB_INTEGER    , UNSIGNED_SHORT                );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB16I            , GraphicsContextGL::RGB_INTEGER    , SHORT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB32UI           , GraphicsContextGL::RGB_INTEGER    , UNSIGNED_INT                  );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB32I            , GraphicsContextGL::RGB_INTEGER    , INT                           );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA8             , GraphicsContextGL::RGBA           , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::SRGB8_ALPHA8      , GraphicsContextGL::RGBA           , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA8_SNORM       , GraphicsContextGL::RGBA           , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB5_A1           , GraphicsContextGL::RGBA           , UNSIGNED_SHORT_5_5_5_1        );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA4             , GraphicsContextGL::RGBA           , UNSIGNED_SHORT_4_4_4_4        );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB10_A2          , GraphicsContextGL::RGBA           , UNSIGNED_INT_2_10_10_10_REV   );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA16F           , GraphicsContextGL::RGBA           , HALF_FLOAT                    );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA32F           , GraphicsContextGL::RGBA           , FLOAT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA8UI           , GraphicsContextGL::RGBA_INTEGER   , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA8I            , GraphicsContextGL::RGBA_INTEGER   , BYTE                          );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGB10_A2UI        , GraphicsContextGL::RGBA_INTEGER   , UNSIGNED_INT_2_10_10_10_REV   );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA16UI          , GraphicsContextGL::RGBA_INTEGER   , UNSIGNED_SHORT                );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA16I           , GraphicsContextGL::RGBA_INTEGER   , SHORT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA32I           , GraphicsContextGL::RGBA_INTEGER   , INT                           );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::RGBA32UI          , GraphicsContextGL::RGBA_INTEGER   , UNSIGNED_INT                  );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH_COMPONENT16 , GraphicsContextGL::DEPTH_COMPONENT, UNSIGNED_SHORT                );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH_COMPONENT   , GraphicsContextGL::DEPTH_COMPONENT, UNSIGNED_SHORT                );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH_COMPONENT24 , GraphicsContextGL::DEPTH_COMPONENT, UNSIGNED_INT                  );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH_COMPONENT32F, GraphicsContextGL::DEPTH_COMPONENT, FLOAT                         );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH_STENCIL     , GraphicsContextGL::DEPTH_STENCIL  , UNSIGNED_INT_24_8             );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH24_STENCIL8  , GraphicsContextGL::DEPTH_STENCIL  , UNSIGNED_INT_24_8             );
-    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContextGL::DEPTH32F_STENCIL8 , GraphicsContextGL::DEPTH_STENCIL  , FLOAT_32_UNSIGNED_INT_24_8_REV);
-    POSSIBLE_FORMAT_TYPE_CASE(ExtensionsGL::SRGB_EXT               , ExtensionsGL::SRGB_EXT            , UNSIGNED_BYTE                 );
-    POSSIBLE_FORMAT_TYPE_CASE(ExtensionsGL::SRGB_ALPHA_EXT         , ExtensionsGL::SRGB_ALPHA_EXT      , UNSIGNED_BYTE                 );
-    default:
-        return false;
-    }
-#undef POSSIBLE_FORMAT_TYPE_CASE
-
-    return true;
-}
-#endif // !USE(ANGLE)
-
-GCGLenum GraphicsContextGLOpenGL::computeImageSizeInBytes(
-    GCGLenum format, GCGLenum type, GCGLsizei width, GCGLsizei height, GCGLsizei depth, const GraphicsContextGLOpenGL::PixelStoreParams& params,
-    unsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes)
-{
-    ASSERT(imageSizeInBytes);
-    ASSERT(params.alignment == 1 || params.alignment == 2 || params.alignment == 4 || params.alignment == 8);
-    ASSERT(params.rowLength >= 0);
-    ASSERT(params.imageHeight >= 0);
-    ASSERT(params.skipPixels >= 0);
-    ASSERT(params.skipRows >= 0);
-    ASSERT(params.skipImages >= 0);
-    if (width < 0 || height < 0 || depth < 0)
-        return GraphicsContextGL::INVALID_VALUE;
-    if (!width || !height || !depth) {
-        *imageSizeInBytes = 0;
-        if (paddingInBytes)
-            *paddingInBytes = 0;
-        if (skipSizeInBytes)
-            *skipSizeInBytes = 0;
-        return GraphicsContextGL::NO_ERROR;
-    }
-
-    int rowLength = params.rowLength > 0 ? params.rowLength : width;
-    int imageHeight = params.imageHeight > 0 ? params.imageHeight : height;
-
-    unsigned bytesPerComponent, componentsPerPixel;
-    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
-        return GraphicsContextGL::INVALID_ENUM;
-    unsigned bytesPerGroup = bytesPerComponent * componentsPerPixel;
-    Checked<uint32_t, RecordOverflow> checkedValue = static_cast<uint32_t>(rowLength);
-    checkedValue *= bytesPerGroup;
-    if (checkedValue.hasOverflowed())
-        return GraphicsContextGL::INVALID_VALUE;
-
-    unsigned lastRowSize;
-    if (params.rowLength > 0 && params.rowLength != width) {
-        Checked<uint32_t, RecordOverflow> tmp = width;
-        tmp *= bytesPerGroup;
-        if (tmp.hasOverflowed())
-            return GraphicsContextGL::INVALID_VALUE;
-        lastRowSize = tmp.unsafeGet();
-    } else
-        lastRowSize = checkedValue.unsafeGet();
-
-    unsigned padding = 0;
-    unsigned residual = checkedValue.unsafeGet() % params.alignment;
-    if (residual) {
-        padding = params.alignment - residual;
-        checkedValue += padding;
-    }
-    if (checkedValue.hasOverflowed())
-        return GraphicsContextGL::INVALID_VALUE;
-    unsigned paddedRowSize = checkedValue.unsafeGet();
-
-    Checked<uint32_t, RecordOverflow> rows = imageHeight;
-    rows *= (depth - 1);
-    // Last image is not affected by IMAGE_HEIGHT parameter.
-    rows += height;
-    if (rows.hasOverflowed())
-        return GraphicsContextGL::INVALID_VALUE;
-    checkedValue *= (rows - 1);
-    // Last row is not affected by ROW_LENGTH parameter.
-    checkedValue += lastRowSize;
-    if (checkedValue.hasOverflowed())
-        return GraphicsContextGL::INVALID_VALUE;
-    *imageSizeInBytes = checkedValue.unsafeGet();
-    if (paddingInBytes)
-        *paddingInBytes = padding;
-
-    Checked<uint32_t, RecordOverflow> skipSize = 0;
-    if (params.skipImages > 0) {
-        Checked<uint32_t, RecordOverflow> tmp = paddedRowSize;
-        tmp *= imageHeight;
-        tmp *= params.skipImages;
-        if (tmp.hasOverflowed())
-            return GraphicsContextGL::INVALID_VALUE;
-        skipSize += tmp.unsafeGet();
-    }
-    if (params.skipRows > 0) {
-        Checked<uint32_t, RecordOverflow> tmp = paddedRowSize;
-        tmp *= params.skipRows;
-        if (tmp.hasOverflowed())
-            return GraphicsContextGL::INVALID_VALUE;
-        skipSize += tmp.unsafeGet();
-    }
-    if (params.skipPixels > 0) {
-        Checked<uint32_t, RecordOverflow> tmp = bytesPerGroup;
-        tmp *= params.skipPixels;
-        if (tmp.hasOverflowed())
-            return GraphicsContextGL::INVALID_VALUE;
-        skipSize += tmp.unsafeGet();
-    }
-    if (skipSize.hasOverflowed())
-        return GraphicsContextGL::INVALID_VALUE;
-    if (skipSizeInBytes)
-        *skipSizeInBytes = skipSize.unsafeGet();
-
-    checkedValue += skipSize.unsafeGet();
-    if (checkedValue.hasOverflowed())
-        return GraphicsContextGL::INVALID_VALUE;
-    return GraphicsContextGL::NO_ERROR;
-}
-
-GraphicsContextGLOpenGL::PixelStoreParams::PixelStoreParams()
-    : alignment(4)
-    , rowLength(0)
-    , imageHeight(0)
-    , skipPixels(0)
-    , skipRows(0)
-    , skipImages(0)
-{
-}
-
-GraphicsContextGLOpenGL::ImageExtractor::ImageExtractor(Image* image, DOMSource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication)
-{
-    m_image = image;
-    m_imageHtmlDomSource = imageHtmlDomSource;
-    m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile, ignoreNativeImageAlphaPremultiplication);
-}
-
-bool GraphicsContextGLOpenGL::packImageData(Image* image, const void* pixels, GCGLenum format, GCGLenum type, bool flipY, AlphaOp alphaOp, DataFormat sourceFormat, unsigned sourceImageWidth, unsigned sourceImageHeight, const IntRect& sourceImageSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, Vector<uint8_t>& data)
-{
-    if (!image || !pixels)
-        return false;
-
-    unsigned packedSize;
-    // Output data is tightly packed (alignment == 1).
-    PixelStoreParams params;
-    params.alignment = 1;
-    if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), sourceImageSubRectangle.height(), depth, params, &packedSize, nullptr, nullptr) != GraphicsContextGL::NO_ERROR)
-        return false;
-    data.resize(packedSize);
-
-    if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, sourceImageWidth, sourceImageHeight, sourceImageSubRectangle, depth, sourceUnpackAlignment, unpackImageHeight, format, type, alphaOp, data.data(), flipY))
-        return false;
-    if (ImageObserver* observer = image->imageObserver())
-        observer->didDraw(*image);
-    return true;
-}
-
-bool GraphicsContextGLOpenGL::extractImageData(
-    ImageData* imageData, DataFormat sourceDataFormat, const IntRect& sourceImageSubRectangle,
-    int depth, int unpackImageHeight, GCGLenum format, GCGLenum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data)
-{
-    if (!imageData)
-        return false;
-    int width = imageData->width();
-    int height = imageData->height();
-
-    unsigned packedSize;
-    // Output data is tightly packed (alignment == 1).
-    PixelStoreParams params;
-    params.alignment = 1;
-    if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), sourceImageSubRectangle.height(), depth, params, &packedSize, nullptr, nullptr) != GraphicsContextGL::NO_ERROR)
-        return false;
-    data.resize(packedSize);
-
-    if (!packPixels(imageData->data()->data(), sourceDataFormat, width, height, sourceImageSubRectangle, depth, 0, unpackImageHeight, format, type, premultiplyAlpha ? AlphaOp::DoPremultiply : AlphaOp::DoNothing, data.data(), flipY))
-        return false;
-
-    return true;
-}
-
-bool GraphicsContextGLOpenGL::extractTextureData(unsigned width, unsigned height, GCGLenum format, GCGLenum type, const PixelStoreParams& unpackParams, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data)
-{
-    // Assumes format, type, etc. have already been validated.
-    DataFormat sourceDataFormat = getDataFormat(format, type);
-
-    // Resize the output buffer.
-    unsigned componentsPerPixel, bytesPerComponent;
-    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
-        return false;
-    unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
-    data.resize(width * height * bytesPerPixel);
-
-    unsigned imageSizeInBytes, skipSizeInBytes;
-    computeImageSizeInBytes(format, type, width, height, 1, unpackParams, &imageSizeInBytes, nullptr, &skipSizeInBytes);
-    const uint8_t* srcData = static_cast<const uint8_t*>(pixels);
-    if (skipSizeInBytes)
-        srcData += skipSizeInBytes;
-
-    if (!packPixels(srcData, sourceDataFormat, unpackParams.rowLength ? unpackParams.rowLength : width, height, IntRect(0, 0, width, height), 1, unpackParams.alignment, 0, format, type, (premultiplyAlpha ? AlphaOp::DoPremultiply : AlphaOp::DoNothing), data.data(), flipY))
-        return false;
-
-    return true;
-}
-
-ALWAYS_INLINE unsigned TexelBytesForFormat(GraphicsContextGL::DataFormat format)
-{
-    switch (format) {
-    case GraphicsContextGL::DataFormat::R8:
-    case GraphicsContextGL::DataFormat::R8_S:
-    case GraphicsContextGL::DataFormat::A8:
-        return 1;
-    case GraphicsContextGL::DataFormat::RG8:
-    case GraphicsContextGL::DataFormat::RG8_S:
-    case GraphicsContextGL::DataFormat::RA8:
-    case GraphicsContextGL::DataFormat::AR8:
-    case GraphicsContextGL::DataFormat::RGBA5551:
-    case GraphicsContextGL::DataFormat::RGBA4444:
-    case GraphicsContextGL::DataFormat::RGB565:
-    case GraphicsContextGL::DataFormat::A16F:
-    case GraphicsContextGL::DataFormat::R16:
-    case GraphicsContextGL::DataFormat::R16_S:
-    case GraphicsContextGL::DataFormat::R16F:
-    case GraphicsContextGL::DataFormat::D16:
-        return 2;
-    case GraphicsContextGL::DataFormat::RGB8:
-    case GraphicsContextGL::DataFormat::RGB8_S:
-    case GraphicsContextGL::DataFormat::BGR8:
-        return 3;
-    case GraphicsContextGL::DataFormat::RGBA8:
-    case GraphicsContextGL::DataFormat::RGBA8_S:
-    case GraphicsContextGL::DataFormat::ARGB8:
-    case GraphicsContextGL::DataFormat::ABGR8:
-    case GraphicsContextGL::DataFormat::BGRA8:
-    case GraphicsContextGL::DataFormat::R32:
-    case GraphicsContextGL::DataFormat::R32_S:
-    case GraphicsContextGL::DataFormat::R32F:
-    case GraphicsContextGL::DataFormat::A32F:
-    case GraphicsContextGL::DataFormat::RA16F:
-    case GraphicsContextGL::DataFormat::RGBA2_10_10_10:
-    case GraphicsContextGL::DataFormat::RGB10F11F11F:
-    case GraphicsContextGL::DataFormat::RGB5999:
-    case GraphicsContextGL::DataFormat::RG16:
-    case GraphicsContextGL::DataFormat::RG16_S:
-    case GraphicsContextGL::DataFormat::RG16F:
-    case GraphicsContextGL::DataFormat::D32:
-    case GraphicsContextGL::DataFormat::D32F:
-    case GraphicsContextGL::DataFormat::DS24_8:
-        return 4;
-    case GraphicsContextGL::DataFormat::RGB16:
-    case GraphicsContextGL::DataFormat::RGB16_S:
-    case GraphicsContextGL::DataFormat::RGB16F:
-        return 6;
-    case GraphicsContextGL::DataFormat::RGBA16:
-    case GraphicsContextGL::DataFormat::RGBA16_S:
-    case GraphicsContextGL::DataFormat::RA32F:
-    case GraphicsContextGL::DataFormat::RGBA16F:
-    case GraphicsContextGL::DataFormat::RG32:
-    case GraphicsContextGL::DataFormat::RG32_S:
-    case GraphicsContextGL::DataFormat::RG32F:
-        return 8;
-    case GraphicsContextGL::DataFormat::RGB32:
-    case GraphicsContextGL::DataFormat::RGB32_S:
-    case GraphicsContextGL::DataFormat::RGB32F:
-        return 12;
-    case GraphicsContextGL::DataFormat::RGBA32:
-    case GraphicsContextGL::DataFormat::RGBA32_S:
-    case GraphicsContextGL::DataFormat::RGBA32F:
-        return 16;
-    default:
-        return 0;
-    }
-}
-
-bool GraphicsContextGLOpenGL::packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned sourceDataWidth, unsigned sourceDataHeight, const IntRect& sourceDataSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, unsigned destinationFormat, unsigned destinationType, AlphaOp alphaOp, void* destinationData, bool flipY)
-{
-    ASSERT(depth >= 1);
-    UNUSED_PARAM(sourceDataHeight); // Derived from sourceDataSubRectangle.height().
-    if (!unpackImageHeight)
-        unpackImageHeight = sourceDataSubRectangle.height();
-    int validSrc = sourceDataWidth * TexelBytesForFormat(sourceDataFormat);
-    int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
-    int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
-    int srcRowOffset = sourceDataSubRectangle.x() * TexelBytesForFormat(sourceDataFormat);
-
-    DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
-    int dstStride = sourceDataSubRectangle.width() * TexelBytesForFormat(dstDataFormat);
-    if (flipY) {
-        destinationData = static_cast<uint8_t*>(destinationData) + dstStride * ((depth * sourceDataSubRectangle.height()) - 1);
-        dstStride = -dstStride;
-    }
-    if (!hasAlpha(sourceDataFormat) || !hasColor(sourceDataFormat) || !hasColor(dstDataFormat))
-        alphaOp = AlphaOp::DoNothing;
-
-    if (sourceDataFormat == dstDataFormat && alphaOp == AlphaOp::DoNothing) {
-        const uint8_t* basePtr = sourceData + srcStride * sourceDataSubRectangle.y();
-        const uint8_t* baseEnd = sourceData + srcStride * sourceDataSubRectangle.maxY();
-
-        // If packing multiple images into a 3D texture, and flipY is true,
-        // then the sub-rectangle is pointing at the start of the
-        // "bottommost" of those images. Since the source pointer strides in
-        // the positive direction, we need to back it up to point at the
-        // last, or "topmost", of these images.
-        if (flipY && depth > 1) {
-            const ptrdiff_t distanceToTopImage = (depth - 1) * srcStride * unpackImageHeight;
-            basePtr -= distanceToTopImage;
-            baseEnd -= distanceToTopImage;
-        }
-
-        unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
-        uint8_t* dst = static_cast<uint8_t*>(destinationData);
-
-        for (int i = 0; i < depth; ++i) {
-            const uint8_t* ptr = basePtr;
-            const uint8_t* ptrEnd = baseEnd;
-            while (ptr < ptrEnd) {
-                memcpy(dst, ptr + srcRowOffset, rowSize);
-                ptr += srcStride;
-                dst += dstStride;
-            }
-            basePtr += unpackImageHeight * srcStride;
-            baseEnd += unpackImageHeight * srcStride;
-        }
-        return true;
-    }
-
-    FormatConverter converter(
-        sourceDataSubRectangle, depth,
-        unpackImageHeight, sourceData, destinationData,
-        srcStride, srcRowOffset, dstStride);
-    converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
-    if (!converter.success())
-        return false;
-    return true;
-}
-
 #if !PLATFORM(COCOA)
 void GraphicsContextGLOpenGL::setContextVisibility(bool)
 {

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h	2020-10-16 10:55:59 UTC (rev 268578)
@@ -87,29 +87,20 @@
 
 class GraphicsContextGLOpenGLPrivate;
 
-class GraphicsContextGLOpenGL : public GraphicsContextGL
+class GraphicsContextGLOpenGL final : public GraphicsContextGL
 #if PLATFORM(COCOA)
     , private WebGLLayerClient
 #endif
 {
 public:
-    class Client {
-    public:
-        virtual ~Client() { }
-        virtual void didComposite() = 0;
-        virtual void forceContextLost() = 0;
-        virtual void recycleContext() = 0;
-        virtual void dispatchContextChangedNotification() = 0;
-    };
-
     static RefPtr<GraphicsContextGLOpenGL> create(GraphicsContextGLAttributes, HostWindow*, Destination = Destination::Offscreen);
     virtual ~GraphicsContextGLOpenGL();
 
 #if PLATFORM(COCOA)
     static Ref<GraphicsContextGLOpenGL> createShared(GraphicsContextGLOpenGL& sharedContext);
-    PlatformGraphicsContextGL platformGraphicsContextGL() const override { return m_contextObj; }
-    PlatformGLObject platformTexture() const override { return m_texture; }
-    CALayer* platformLayer() const override { return reinterpret_cast<CALayer*>(m_webGLLayer.get()); }
+    PlatformGraphicsContextGL platformGraphicsContextGL() const final { return m_contextObj; }
+    PlatformGLObject platformTexture() const final { return m_texture; }
+    CALayer* platformLayer() const final { return reinterpret_cast<CALayer*>(m_webGLLayer.get()); }
     PlatformGraphicsContextGLDisplay platformDisplay() const { return m_displayObj; }
     PlatformGraphicsContextGLConfig platformConfig() const { return m_configObj; }
     static GCGLenum IOSurfaceTextureTarget();
@@ -130,9 +121,6 @@
     static bool releaseCurrentContext(ReleaseBehavior);
 #endif
 
-    void addClient(Client& client) { m_clients.add(&client); }
-    void removeClient(Client& client) { m_clients.remove(&client); }
-
     // With multisampling on, blit from multisampleFBO to regular FBO.
     void prepareTexture();
 
@@ -145,82 +133,12 @@
     // Compile a shader without going through ANGLE.
     void compileShaderDirect(PlatformGLObject);
 
-    // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
-    // Return true if no GL error is synthesized.
-    // By default, alignment is 4, the OpenGL default setting.
-    bool texImage2DResourceSafe(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLint alignment = 4);
-
-    bool isGLES2Compliant() const;
-
-    //----------------------------------------------------------------------
-    // Helpers for texture uploading and pixel readback.
-    //
-
-    struct PixelStoreParams final {
-        PixelStoreParams();
-
-        GCGLint alignment;
-        GCGLint rowLength;
-        GCGLint imageHeight;
-        GCGLint skipPixels;
-        GCGLint skipRows;
-        GCGLint skipImages;
-    };
-
-    // Computes the components per pixel and bytes per component
-    // for the given format and type combination. Returns false if
-    // either was an invalid enum.
-    static bool computeFormatAndTypeParameters(GCGLenum format,
-        GCGLenum type,
-        unsigned* componentsPerPixel,
-        unsigned* bytesPerComponent);
-
-    // Computes the image size in bytes. If paddingInBytes is not null, padding
-    // is also calculated in return. Returns NO_ERROR if succeed, otherwise
-    // return the suggested GL error indicating the cause of the failure:
-    //   INVALID_VALUE if width/height is negative or overflow happens.
-    //   INVALID_ENUM if format/type is illegal.
-    static GCGLenum computeImageSizeInBytes(GCGLenum format,
-        GCGLenum type,
-        GCGLsizei width,
-        GCGLsizei height,
-        GCGLsizei depth,
-        const PixelStoreParams&,
-        unsigned* imageSizeInBytes,
-        unsigned* paddingInBytes,
-        unsigned* skipSizeInBytes);
-
 #if !USE(ANGLE)
-    static bool possibleFormatAndTypeForInternalFormat(GCGLenum internalFormat, GCGLenum& format, GCGLenum& type);
-#endif // !USE(ANGLE)
+    bool texImage2DResourceSafe(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLint alignment = 4) final;
+#endif
 
-    // Extracts the contents of the given ImageData into the passed Vector,
-    // packing the pixel data according to the given format and type,
-    // and obeying the flipY and premultiplyAlpha flags. Returns true
-    // upon success.
-    static bool extractImageData(ImageData*,
-        DataFormat,
-        const IntRect& sourceImageSubRectangle,
-        int depth,
-        int unpackImageHeight,
-        GCGLenum format,
-        GCGLenum type,
-        bool flipY,
-        bool premultiplyAlpha,
-        Vector<uint8_t>& data);
+    bool isGLES2Compliant() const final;
 
-    // Helper function which extracts the user-supplied texture
-    // data, applying the flipY and premultiplyAlpha parameters.
-    // If the data is not tightly packed according to the passed
-    // unpackParams, the output data will be tightly packed.
-    // Returns true if successful, false if any error occurred.
-    static bool extractTextureData(unsigned width, unsigned height,
-        GCGLenum format, GCGLenum type,
-        const PixelStoreParams& unpackParams,
-        bool flipY, bool premultiplyAlpha,
-        const void* pixels,
-        Vector<uint8_t>& data);
-
     //----------------------------------------------------------------------
     // Entry points for WebGL.
     //
@@ -537,7 +455,7 @@
     void resetBuffersToAutoClear();
     void setBuffersToAutoClear(GCGLbitfield);
     GCGLbitfield getBuffersToAutoClear() const;
-    void enablePreserveDrawingBuffer() override;
+    void enablePreserveDrawingBuffer() final;
 
     void dispatchContextChangedNotification();
     void simulateContextChanged();
@@ -550,17 +468,13 @@
     void primitiveRestartIndex(GCGLuint) final;
 #endif
 
-#if PLATFORM(COCOA)
-    bool reshapeDisplayBufferBacking();
-    bool bindDisplayBufferBacking(std::unique_ptr<IOSurface> backing, void* pbuffer);
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA) && PLATFORM(MAC)
     void updateCGLContext();
 #endif
-#endif // PLATFORM(COCOA)
 
-    void setContextVisibility(bool);
+    void setContextVisibility(bool) final;
 
-    GraphicsContextGLPowerPreference powerPreferenceUsedForCreation() const { return m_powerPreferenceUsedForCreation; }
+    GraphicsContextGLPowerPreference powerPreferenceUsedForCreation() const final { return m_powerPreferenceUsedForCreation; }
 
     // Support for buffer creation and deletion
     PlatformGLObject createBuffer() final;
@@ -577,15 +491,7 @@
     void deleteShader(PlatformGLObject) final;
     void deleteTexture(PlatformGLObject) final;
 
-    // Synthesizes an OpenGL error which will be returned from a
-    // later call to getError. This is used to emulate OpenGL ES
-    // 2.0 behavior on the desktop and to enforce additional error
-    // checking mandated by WebGL.
-    //
-    // Per the behavior of glGetError, this stores at most one
-    // instance of any given error, and returns them from calls to
-    // getError in the order they were added.
-    void synthesizeGLError(GCGLenum error);
+    void synthesizeGLError(GCGLenum error) final;
 
     // Read real OpenGL errors, and move them to the synthetic
     // error list. Return true if at least one error is moved.
@@ -597,59 +503,8 @@
     // determine this.
     ExtensionsGL& getExtensions() final;
 
-    IntSize getInternalFramebufferSize() const;
+    void setFailNextGPUStatusCheck() final { m_failNextStatusCheck = true; }
 
-    // Packs the contents of the given Image which is passed in |pixels| into the passed Vector
-    // according to the given format and type, and obeying the flipY and AlphaOp flags.
-    // Returns true upon success.
-    static bool packImageData(Image*, const void* pixels, GCGLenum format, GCGLenum type, bool flipY, AlphaOp, DataFormat sourceFormat, unsigned sourceImageWidth, unsigned sourceImageHeight, const IntRect& sourceImageSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, Vector<uint8_t>& data);
-
-    class ImageExtractor {
-    public:
-        ImageExtractor(Image*, DOMSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication);
-
-        // Each platform must provide an implementation of this method to deallocate or release resources
-        // associated with the image if needed.
-        ~ImageExtractor();
-
-        bool extractSucceeded() { return m_extractSucceeded; }
-        const void* imagePixelData() { return m_imagePixelData; }
-        unsigned imageWidth() { return m_imageWidth; }
-        unsigned imageHeight() { return m_imageHeight; }
-        DataFormat imageSourceFormat() { return m_imageSourceFormat; }
-        AlphaOp imageAlphaOp() { return m_alphaOp; }
-        unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
-        DOMSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
-    private:
-        // Each platform must provide an implementation of this method.
-        // Extracts the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc,
-        // needs to lock the resources or relevant data if needed and returns true upon success
-        bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication);
-
-#if USE(CAIRO)
-        RefPtr<cairo_surface_t> m_imageSurface;
-#elif USE(CG)
-        RetainPtr<CGImageRef> m_cgImage;
-        RetainPtr<CGImageRef> m_decodedImage;
-        RetainPtr<CFDataRef> m_pixelData;
-        UniqueArray<uint8_t> m_formalizedRGBA8Data;
-#endif
-        Image* m_image;
-        DOMSource m_imageHtmlDomSource;
-        bool m_extractSucceeded;
-        const void* m_imagePixelData;
-        unsigned m_imageWidth;
-        unsigned m_imageHeight;
-        DataFormat m_imageSourceFormat;
-        AlphaOp m_alphaOp;
-        unsigned m_imageSourceUnpackAlignment;
-    };
-
-    void setFailNextGPUStatusCheck() { m_failNextStatusCheck = true; }
-
-    GCGLenum activeTextureUnit() const { return m_state.activeTextureUnit; }
-    GCGLenum currentBoundTexture() const { return m_state.currentBoundTexture(); }
-    GCGLenum currentBoundTarget() const { return m_state.currentBoundTarget(); }
     unsigned textureSeed(GCGLuint texture) { return m_state.textureSeedCount.count(texture); }
 
 #if PLATFORM(MAC)
@@ -657,17 +512,11 @@
     void screenDidChange(PlatformDisplayID);
 #endif
 
-    void prepareForDisplay();
+    void prepareForDisplay() final;
 
 private:
     GraphicsContextGLOpenGL(GraphicsContextGLAttributes, HostWindow*, Destination = Destination::Offscreen, GraphicsContextGLOpenGL* sharedContext = nullptr);
 
-    // Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
-    // data into the specified OpenGL destination format and type.
-    // A sourceUnpackAlignment of zero indicates that the source
-    // data is tightly packed. Non-zero values may take a slow path.
-    // Destination data will have no gaps between rows.
-    static bool packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned sourceDataWidth, unsigned sourceDataHeight, const IntRect& sourceDataSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, unsigned destinationFormat, unsigned destinationType, AlphaOp, void* destinationData, bool flipY);
 
     // Take into account the user's requested context creation attributes,
     // in particular stencil and antialias, and determine which could or
@@ -695,13 +544,12 @@
 
 #if PLATFORM(COCOA)
     bool allowOfflineRenderers() const;
+    bool reshapeDisplayBufferBacking();
+    bool bindDisplayBufferBacking(std::unique_ptr<IOSurface> backing, void* pbuffer);
     // WebGLLayerClient overrides.
-    void didDisplay() override;
+    void didDisplay() final;
 #endif
 
-    int m_currentWidth { 0 };
-    int m_currentHeight { 0 };
-
 #if PLATFORM(COCOA)
     RetainPtr<WebGLLayer> m_webGLLayer;
     PlatformGraphicsContextGL m_contextObj { nullptr };
@@ -888,8 +736,6 @@
     std::unique_ptr<GraphicsContextGLOpenGLPrivate> m_private;
 #endif
 
-    HashSet<Client*> m_clients;
-
     bool m_isForWebGL2 { false };
     bool m_usingCoreProfile { false };
 

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -425,11 +425,6 @@
     return true;
 }
 
-IntSize GraphicsContextGLOpenGL::getInternalFramebufferSize() const
-{
-    return IntSize(m_currentWidth, m_currentHeight);
-}
-
 void GraphicsContextGLOpenGL::activeTexture(GCGLenum texture)
 {
     makeContextCurrent();

Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextGLDirect2D.cpp (268577 => 268578)


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextGLDirect2D.cpp	2020-10-16 09:48:57 UTC (rev 268577)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextGLDirect2D.cpp	2020-10-16 10:55:59 UTC (rev 268578)
@@ -29,6 +29,7 @@
 #if ENABLE(GRAPHICS_CONTEXT_GL) && USE(DIRECT2D)
 
 #include "COMPtr.h"
+#include "GraphicsContextGLImageExtractor.h"
 #include "NotImplemented.h"
 #include <d2d1.h>
 #include <d2d1effects.h>
@@ -35,9 +36,9 @@
 
 namespace WebCore {
 
-GraphicsContextGLOpenGL::ImageExtractor::~ImageExtractor() = default;
+GraphicsContextGLImageExtractor::~GraphicsContextGLImageExtractor() = default;
 
-bool GraphicsContextGLOpenGL::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication)
+bool GraphicsContextGLImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile, bool ignoreNativeImageAlphaPremultiplication)
 {
     if (!m_image)
         return false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to