Make pack and unpack image extensions enableable.

BUG=angleproject:1523

Change-Id: Ic728a777ad7e05373de03ee98e9b0a17101cd45d
Reviewed-on: https://chromium-review.googlesource.com/688102
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp
index 7fb90f3..927f9d3 100644
--- a/src/libANGLE/Caps.cpp
+++ b/src/libANGLE/Caps.cpp
@@ -652,7 +652,7 @@
         map["GL_ANGLE_framebuffer_blit"] = esOnlyExtension(&Extensions::framebufferBlit);
         map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisample);
         map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArrays);
-        map["GL_ANGLE_pack_reverse_row_order"] = esOnlyExtension(&Extensions::packReverseRowOrder);
+        map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrder);
         map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivatives);
         map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLOD);
         map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth);
@@ -666,8 +666,8 @@
         map["GL_OES_EGL_image_external"] = esOnlyExtension(&Extensions::eglImageExternal);
         map["GL_OES_EGL_image_external_essl3"] = esOnlyExtension(&Extensions::eglImageExternalEssl3);
         map["GL_NV_EGL_stream_consumer_external"] = esOnlyExtension(&Extensions::eglStreamConsumerExternal);
-        map["GL_EXT_unpack_subimage"] = esOnlyExtension(&Extensions::unpackSubimage);
-        map["GL_NV_pack_subimage"] = esOnlyExtension(&Extensions::packSubimage);
+        map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
+        map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
         map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat);
         map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject);
         map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug);
diff --git a/src/libANGLE/ContextState.cpp b/src/libANGLE/ContextState.cpp
index c96552e..baf35d4 100644
--- a/src/libANGLE/ContextState.cpp
+++ b/src/libANGLE/ContextState.cpp
@@ -183,7 +183,6 @@
         case GL_RENDERBUFFER_BINDING:
         case GL_CURRENT_PROGRAM:
         case GL_PACK_ALIGNMENT:
-        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
         case GL_UNPACK_ALIGNMENT:
         case GL_GENERATE_MIPMAP_HINT:
         case GL_RED_BITS:
@@ -234,6 +233,16 @@
             *numParams = 1;
             return true;
         }
+        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+        {
+            if (!getExtensions().packReverseRowOrder)
+            {
+                return false;
+            }
+            *type      = GL_INT;
+            *numParams = 1;
+            return true;
+        }
         case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
         case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
         {
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index a254961..f932954 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -5374,6 +5374,12 @@
             break;
 
         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+            if (!context->getExtensions().packReverseRowOrder)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
+            }
+            break;
+
         case GL_UNPACK_ROW_LENGTH:
         case GL_UNPACK_IMAGE_HEIGHT:
         case GL_UNPACK_SKIP_IMAGES:
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 0d098aa..ae4aa0f 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -698,6 +698,121 @@
     }
 }
 
+// Test enabling the GL_ANGLE_pack_reverse_row_order extension
+TEST_P(WebGLCompatibilityTest, EnablePackReverseRowOrderExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_ANGLE_pack_reverse_row_order"));
+
+    GLint result = 0;
+    glGetIntegerv(GL_PACK_REVERSE_ROW_ORDER_ANGLE, &result);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+    if (extensionRequestable("GL_ANGLE_pack_reverse_row_order"))
+    {
+        glRequestExtensionANGLE("GL_ANGLE_pack_reverse_row_order");
+        EXPECT_GL_NO_ERROR();
+
+        glGetIntegerv(GL_PACK_REVERSE_ROW_ORDER_ANGLE, &result);
+        glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
+        EXPECT_GL_NO_ERROR();
+    }
+}
+
+// Test enabling the GL_EXT_unpack_subimage extension
+TEST_P(WebGLCompatibilityTest, EnablePackUnpackSubImageExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_EXT_unpack_subimage"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    constexpr GLenum parameters[] = {
+        GL_UNPACK_ROW_LENGTH_EXT, GL_UNPACK_SKIP_ROWS_EXT, GL_UNPACK_SKIP_PIXELS_EXT,
+    };
+
+    for (GLenum param : parameters)
+    {
+        GLint resultI = 0;
+        glGetIntegerv(param, &resultI);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        GLfloat resultF = 0.0f;
+        glGetFloatv(param, &resultF);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        glPixelStorei(param, 0);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    if (extensionRequestable("GL_EXT_unpack_subimage"))
+    {
+        glRequestExtensionANGLE("GL_EXT_unpack_subimage");
+        EXPECT_GL_NO_ERROR();
+
+        for (GLenum param : parameters)
+        {
+            GLint resultI = 0;
+            glGetIntegerv(param, &resultI);
+
+            GLfloat resultF = 0.0f;
+            glGetFloatv(param, &resultF);
+
+            glPixelStorei(param, 0);
+
+            EXPECT_GL_NO_ERROR();
+        }
+    }
+}
+
+// Test enabling the GL_NV_pack_subimage extension
+TEST_P(WebGLCompatibilityTest, EnablePackPackSubImageExtension)
+{
+    EXPECT_FALSE(extensionEnabled("GL_NV_pack_subimage"));
+
+    // This extensions become core in in ES3/WebGL2.
+    ANGLE_SKIP_TEST_IF(getClientMajorVersion() >= 3);
+
+    constexpr GLenum parameters[] = {
+        GL_PACK_ROW_LENGTH, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_PIXELS,
+    };
+
+    for (GLenum param : parameters)
+    {
+        GLint resultI = 0;
+        glGetIntegerv(param, &resultI);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        GLfloat resultF = 0.0f;
+        glGetFloatv(param, &resultF);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        glPixelStorei(param, 0);
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    if (extensionRequestable("GL_NV_pack_subimage"))
+    {
+        glRequestExtensionANGLE("GL_NV_pack_subimage");
+        EXPECT_GL_NO_ERROR();
+
+        for (GLenum param : parameters)
+        {
+            GLint resultI = 0;
+            glGetIntegerv(param, &resultI);
+
+            GLfloat resultF = 0.0f;
+            glGetFloatv(param, &resultF);
+
+            glPixelStorei(param, 0);
+
+            EXPECT_GL_NO_ERROR();
+        }
+    }
+}
+
 // Verify that the context generates the correct error when the framebuffer attachments are
 // different sizes
 TEST_P(WebGLCompatibilityTest, FramebufferAttachmentSizeMissmatch)