Make r16_ext textures work with validating decoder.

Bug: 788984
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I75a199398befeca552449cedd8f66fa175c3043d
Reviewed-on: https://chromium-review.googlesource.com/810093
Commit-Queue: Fredrik Hubinette <hubbe@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523281}
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index c3df0cc..33e2ce4 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -1317,16 +1317,18 @@
       (gl_version_info_->IsAtLeastGL(2, 1) &&
        gl::HasExtension(extensions, "GL_ARB_texture_rg")) ||
       gl::HasExtension(extensions, "GL_EXT_texture_norm16")) {
+    // TODO(hubbe): Rename ext_texture_norm16 to texture_r16
     feature_flags_.ext_texture_norm16 = true;
     g_r16_is_present = true;
-    AddExtensionString("GL_EXT_texture_norm16");
 
     // Note: EXT_texture_norm16 is not exposed through WebGL API so we validate
     // only the combinations used internally.
+    validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT);
     validators_.texture_format.AddValue(GL_RED_EXT);
     validators_.texture_internal_format.AddValue(GL_R16_EXT);
     validators_.texture_internal_format.AddValue(GL_RED_EXT);
     validators_.texture_unsized_internal_format.AddValue(GL_RED_EXT);
+    validators_.texture_internal_format_storage.AddValue(GL_R16_EXT);
   }
 
   UMA_HISTOGRAM_ENUMERATION(
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index a20c906..a03fe2c32 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -1677,6 +1677,8 @@
   EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_RED_EXT));
   EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_R16_EXT));
   EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(GL_RED_EXT));
+  EXPECT_TRUE(
+      info_->validators()->texture_internal_format_storage.IsValid(GL_R16_EXT));
 }
 
 TEST_P(FeatureInfoTest, InitializeCHROMIUM_ycbcr_422_imageTrue) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
index 334ccf0..17d773b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -4080,6 +4080,26 @@
                                     GL_LUMINANCE_ALPHA32F_ARB);
 }
 
+TEST_P(GLES2DecoderManualInitTest, TexImage2Dnorm16OnGLES2) {
+  InitState init;
+  init.extensions = "GL_EXT_texture_norm16";
+  init.gl_version = "opengl es 2.0";
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 16, 17, 0, GL_RED, GL_UNSIGNED_SHORT,
+               0, 0);
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexImage2Dnorm16OnGLES3) {
+  InitState init;
+  init.extensions = "GL_EXT_texture_norm16";
+  init.gl_version = "opengl es 3.0";
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_R16_EXT, 16, 17, 0, GL_RED,
+               GL_UNSIGNED_SHORT, 0, 0);
+}
+
 class GLES2DecoderCompressedFormatsTest : public GLES2DecoderManualInitTest {
  public:
   GLES2DecoderCompressedFormatsTest() = default;
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 7e9559c..437e0b9 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -251,6 +251,9 @@
         {GL_RG, GL_RG, GL_FLOAT},
         {GL_RED, GL_RED, GL_HALF_FLOAT_OES},
         {GL_RG, GL_RG, GL_HALF_FLOAT_OES},
+
+        // Exposed by GL_EXT_texture_norm16
+        {GL_RED, GL_RED, GL_UNSIGNED_SHORT},
     };
 
     for (size_t ii = 0; ii < arraysize(kSupportedFormatTypes); ++ii) {
@@ -3540,6 +3543,7 @@
     case GL_R8_SNORM:
     case GL_R16F:
     case GL_R32F:
+    case GL_R16_EXT:
       return GL_RED;
     case GL_R8UI:
     case GL_R8I:
@@ -3688,6 +3692,8 @@
       return GL_UNSIGNED_SHORT;
     case GL_R16I:
       return GL_SHORT;
+    case GL_R16_EXT:
+      return GL_UNSIGNED_SHORT;
     case GL_R32UI:
       return GL_UNSIGNED_INT;
     case GL_R32I:
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 4721c12..788a9dc 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -2760,5 +2760,19 @@
   ExpectInvalid(true, GL_RGB_INTEGER, GL_INT, GL_RGBA8);
 }
 
+TEST_F(TextureFormatTypeValidationTest, ES2WithTextureNorm16) {
+  SetupFeatureInfo("GL_EXT_texture_norm16", "OpenGL ES 2.0",
+                   CONTEXT_TYPE_OPENGLES2);
+
+  ExpectValid(true, GL_RED, GL_UNSIGNED_SHORT, GL_RED);
+}
+
+TEST_F(TextureFormatTypeValidationTest, ES3WithTextureNorm16) {
+  SetupFeatureInfo("GL_EXT_texture_norm16", "OpenGL ES 3.0",
+                   CONTEXT_TYPE_OPENGLES3);
+
+  ExpectValid(true, GL_RED, GL_UNSIGNED_SHORT, GL_R16_EXT);
+}
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
index 7dd571a3..22d51ae 100644
--- a/ui/gl/gl_gl_api_implementation.cc
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -60,6 +60,9 @@
         case GL_UNSIGNED_BYTE:
           gl_internal_format = GL_R8_EXT;
           break;
+        case GL_UNSIGNED_SHORT:
+          gl_internal_format = GL_R16_EXT;
+          break;
         case GL_HALF_FLOAT_OES:
           gl_internal_format = GL_R16F_EXT;
           break;