[PDNCF] Backport ImageManager class and its dependencies 90/287190/3
authoruzair <uzair.jaleel@samsung.com>
Thu, 5 Jan 2023 08:01:55 +0000 (13:31 +0530)
committerBot Blink <blinkbot@samsung.com>
Wed, 25 Jan 2023 03:58:39 +0000 (03:58 +0000)
Zero copy video rendering path is dependent on chromium GL_CHROMIUM_image
extension but open source plans to deprecate it in future and hence
some part of code is removed before 108 branch was forked for tizen and the new
CHROMIUM_shared_image extension path is not completely present in 108 version.

For now we partially backport [1] and [2] to bringup TBM path.

[1] https://chromium-review.googlesource.com/c/chromium/src/+/3582497
[2] https://chromium-review.googlesource.com/c/chromium/src/+/3743320

Change-Id: If3d8eff200650113bd5b4893bb1636cd9895cb03
Signed-off-by: uzair <uzair.jaleel@samsung.com>
43 files changed:
gpu/GLES2/gl2chromium_autogen.h
gpu/GLES2/gl2extchromium.h
gpu/command_buffer/build_gles2_cmd_buffer.py
gpu/command_buffer/client/gles2_c_lib_autogen.h
gpu/command_buffer/client/gles2_cmd_helper_autogen.h
gpu/command_buffer/client/gles2_implementation_autogen.h
gpu/command_buffer/client/gles2_implementation_impl_autogen.h
gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
gpu/command_buffer/client/gles2_interface_autogen.h
gpu/command_buffer/client/gles2_interface_stub_autogen.h
gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
gpu/command_buffer/client/gles2_trace_implementation_autogen.h
gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
gpu/command_buffer/common/gles2_cmd_format_autogen.h
gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
gpu/command_buffer/common/gles2_cmd_ids_autogen.h
gpu/command_buffer/gles2_cmd_buffer_functions.txt
gpu/command_buffer/service/BUILD.gn
gpu/command_buffer/service/command_buffer_task_executor.h
gpu/command_buffer/service/context_group.cc
gpu/command_buffer/service/context_group.h
gpu/command_buffer/service/gles2_cmd_decoder.cc
gpu/command_buffer/service/gles2_cmd_decoder.h
gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
gpu/command_buffer/service/image_manager.cc [new file with mode: 0644]
gpu/command_buffer/service/image_manager.h [new file with mode: 0644]
gpu/gles2_conform_support/egl/context.cc
gpu/gles2_conform_support/egl/context.h
gpu/ipc/common/gpu_channel.mojom
gpu/ipc/in_process_command_buffer.cc
gpu/ipc/service/command_buffer_stub.cc
gpu/ipc/service/command_buffer_stub.h
gpu/ipc/service/gles2_command_buffer_stub.cc
gpu/ipc/service/gles2_command_buffer_stub.h
gpu/ipc/service/gpu_channel.cc
gpu/ipc/service/gpu_channel.h
ui/gl/gl_image.cc
ui/gl/gl_image.h

index f0b3a3d..efcb0d3 100644 (file)
 #define glCreateAndConsumeTextureCHROMIUM \
   GLES2_GET_FUN(CreateAndConsumeTextureCHROMIUM)
 #define glBindUniformLocationCHROMIUM GLES2_GET_FUN(BindUniformLocationCHROMIUM)
+#define glBindTexImage2DCHROMIUM GLES2_GET_FUN(BindTexImage2DCHROMIUM)
+#define glBindTexImage2DWithInternalformatCHROMIUM \
+  GLES2_GET_FUN(BindTexImage2DWithInternalformatCHROMIUM)
+#define glReleaseTexImage2DCHROMIUM GLES2_GET_FUN(ReleaseTexImage2DCHROMIUM)
 #define glTraceBeginCHROMIUM GLES2_GET_FUN(TraceBeginCHROMIUM)
 #define glTraceEndCHROMIUM GLES2_GET_FUN(TraceEndCHROMIUM)
 #define glDiscardFramebufferEXT GLES2_GET_FUN(DiscardFramebufferEXT)
index da4583a..44036b8 100644 (file)
@@ -63,6 +63,43 @@ typedef GLboolean (GL_APIENTRY PFNGLUNMAPBUFFERCHROMIUM) (GLuint target);
 #endif
 #endif  /* GL_CHROMIUM_pixel_transfer_buffer_object */
 
+/* GL_CHROMIUM_image */
+#ifndef GL_CHROMIUM_image
+#define GL_CHROMIUM_image 1
+
+typedef struct _ClientBuffer* ClientBuffer;
+
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM(ClientBuffer buffer,
+                                                    GLsizei width,
+                                                    GLsizei height,
+                                                    GLenum internalformat);
+GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM(GLuint image_id);
+GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM(GLenum target,
+                                                     GLint imageId);
+GL_APICALL void GL_APIENTRY
+glBindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                           GLenum internalformat,
+                                           GLint imageId);
+GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM(GLenum target,
+                                                        GLint imageId);
+#endif
+typedef GLuint(GL_APIENTRYP PFNGLCREATEIMAGECHROMIUMPROC)(
+    ClientBuffer buffer,
+    GLsizei width,
+    GLsizei height,
+    GLenum internalformat);
+typedef void(GL_APIENTRYP PFNGLDESTROYIMAGECHROMIUMPROC)(GLuint image_id);
+typedef void(GL_APIENTRYP PFNGLBINDTEXIMAGE2DCHROMIUMPROC)(GLenum target,
+                                                           GLint imageId);
+typedef void(GL_APIENTRYP PFNGLBINDTEXIMAGE2DWITHINTERNALFORMATCHROMIUMPROC)(
+    GLenum target,
+    GLenum internalformat,
+    GLint imageId);
+typedef void(GL_APIENTRYP PFNGLRELEASETEXIMAGE2DCHROMIUMPROC)(GLenum target,
+                                                              GLint imageId);
+#endif /* GL_CHROMIUM_image */
+
 #ifndef GL_RGB_YCRCB_420_CHROMIUM
 #define GL_RGB_YCRCB_420_CHROMIUM 0x78FA
 #endif
index 453d713..b8bef5e 100755 (executable)
@@ -3885,6 +3885,21 @@ _FUNCTION_INFO = {
     'unit_test': False,
     'pepper_interface': 'VertexArrayObject',
   },
+  'BindTexImage2DCHROMIUM': {
+    'decoder_func': 'DoBindTexImage2DCHROMIUM',
+    'unit_test': False,
+    'extension': "CHROMIUM_image",
+   },
+  'BindTexImage2DWithInternalformatCHROMIUM': {
+    'decoder_func': 'DoBindTexImage2DWithInternalformatCHROMIUM',
+    'unit_test': False,
+    'extension': "CHROMIUM_image",
+   },
+  'ReleaseTexImage2DCHROMIUM': {
+    'decoder_func': 'DoReleaseTexImage2DCHROMIUM',
+    'unit_test': False,
+    'extension': "CHROMIUM_image",
+   },
   'IsVertexArrayOES': {
     'type': 'Is',
     'extension': 'OES_vertex_array_object',
index 161c43e..7114150 100644 (file)
@@ -1546,6 +1546,19 @@ void GL_APIENTRY GLES2BindUniformLocationCHROMIUM(GLuint program,
                                                   const char* name) {
   gles2::GetGLContext()->BindUniformLocationCHROMIUM(program, location, name);
 }
+void GL_APIENTRY GLES2BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+  gles2::GetGLContext()->BindTexImage2DCHROMIUM(target, imageId);
+}
+void GL_APIENTRY
+GLES2BindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                              GLenum internalformat,
+                                              GLint imageId) {
+  gles2::GetGLContext()->BindTexImage2DWithInternalformatCHROMIUM(
+      target, internalformat, imageId);
+}
+void GL_APIENTRY GLES2ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+  gles2::GetGLContext()->ReleaseTexImage2DCHROMIUM(target, imageId);
+}
 void GL_APIENTRY GLES2TraceBeginCHROMIUM(const char* category_name,
                                          const char* trace_name) {
   gles2::GetGLContext()->TraceBeginCHROMIUM(category_name, trace_name);
@@ -2908,6 +2921,19 @@ extern const NameToFunc g_gles2_function_table[] = {
         reinterpret_cast<GLES2FunctionPointer>(glBindUniformLocationCHROMIUM),
     },
     {
+        "glBindTexImage2DCHROMIUM",
+        reinterpret_cast<GLES2FunctionPointer>(glBindTexImage2DCHROMIUM),
+    },
+    {
+        "glBindTexImage2DWithInternalformatCHROMIUM",
+        reinterpret_cast<GLES2FunctionPointer>(
+            glBindTexImage2DWithInternalformatCHROMIUM),
+    },
+    {
+        "glReleaseTexImage2DCHROMIUM",
+        reinterpret_cast<GLES2FunctionPointer>(glReleaseTexImage2DCHROMIUM),
+    },
+    {
         "glTraceBeginCHROMIUM",
         reinterpret_cast<GLES2FunctionPointer>(glTraceBeginCHROMIUM),
     },
index 7676f76..1de1be1 100644 (file)
@@ -2923,6 +2923,32 @@ void BindUniformLocationCHROMIUMBucket(GLuint program,
   }
 }
 
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+  gles2::cmds::BindTexImage2DCHROMIUM* c =
+      GetCmdSpace<gles2::cmds::BindTexImage2DCHROMIUM>();
+  if (c) {
+    c->Init(target, imageId);
+  }
+}
+
+void BindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                              GLenum internalformat,
+                                              GLint imageId) {
+  gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM* c =
+      GetCmdSpace<gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM>();
+  if (c) {
+    c->Init(target, internalformat, imageId);
+  }
+}
+
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+  gles2::cmds::ReleaseTexImage2DCHROMIUM* c =
+      GetCmdSpace<gles2::cmds::ReleaseTexImage2DCHROMIUM>();
+  if (c) {
+    c->Init(target, imageId);
+  }
+}
+
 void TraceBeginCHROMIUM(GLuint category_bucket_id, GLuint name_bucket_id) {
   gles2::cmds::TraceBeginCHROMIUM* c =
       GetCmdSpace<gles2::cmds::TraceBeginCHROMIUM>();
index b556b23..f1c6a51 100644 (file)
@@ -1090,6 +1090,14 @@ void BindUniformLocationCHROMIUM(GLuint program,
                                  GLint location,
                                  const char* name) override;
 
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+
+void BindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                              GLenum internalformat,
+                                              GLint imageId) override;
+
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+
 void TraceBeginCHROMIUM(const char* category_name,
                         const char* trace_name) override;
 
index a8586eb..1b945f0 100644 (file)
@@ -3326,6 +3326,40 @@ void GLES2Implementation::CopySubTextureCHROMIUM(
   CheckGLError();
 }
 
+void GLES2Implementation::BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTexImage2DCHROMIUM("
+                     << GLES2Util::GetStringTextureBindTarget(target) << ", "
+                     << imageId << ")");
+  helper_->BindTexImage2DCHROMIUM(target, imageId);
+  CheckGLError();
+}
+
+void GLES2Implementation::BindTexImage2DWithInternalformatCHROMIUM(
+    GLenum target,
+    GLenum internalformat,
+    GLint imageId) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG(
+      "[" << GetLogPrefix() << "] glBindTexImage2DWithInternalformatCHROMIUM("
+          << GLES2Util::GetStringTextureBindTarget(target) << ", "
+          << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
+          << imageId << ")");
+  helper_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat,
+                                                    imageId);
+  CheckGLError();
+}
+
+void GLES2Implementation::ReleaseTexImage2DCHROMIUM(GLenum target,
+                                                    GLint imageId) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReleaseTexImage2DCHROMIUM("
+                     << GLES2Util::GetStringTextureBindTarget(target) << ", "
+                     << imageId << ")");
+  helper_->ReleaseTexImage2DCHROMIUM(target, imageId);
+  CheckGLError();
+}
+
 void GLES2Implementation::DiscardFramebufferEXT(GLenum target,
                                                 GLsizei count,
                                                 const GLenum* attachments) {
index 6f17bb3..c2d65f1 100644 (file)
@@ -2874,6 +2874,39 @@ TEST_F(GLES2ImplementationTest, VertexAttribDivisorANGLE) {
   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
 }
 
+TEST_F(GLES2ImplementationTest, BindTexImage2DCHROMIUM) {
+  struct Cmds {
+    cmds::BindTexImage2DCHROMIUM cmd;
+  };
+  Cmds expected;
+  expected.cmd.Init(GL_TEXTURE_2D, 2);
+
+  gl_->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, 2);
+  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, BindTexImage2DWithInternalformatCHROMIUM) {
+  struct Cmds {
+    cmds::BindTexImage2DWithInternalformatCHROMIUM cmd;
+  };
+  Cmds expected;
+  expected.cmd.Init(GL_TEXTURE_2D, GL_ALPHA, 3);
+
+  gl_->BindTexImage2DWithInternalformatCHROMIUM(GL_TEXTURE_2D, GL_ALPHA, 3);
+  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, ReleaseTexImage2DCHROMIUM) {
+  struct Cmds {
+    cmds::ReleaseTexImage2DCHROMIUM cmd;
+  };
+  Cmds expected;
+  expected.cmd.Init(GL_TEXTURE_2D, 2);
+
+  gl_->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, 2);
+  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
 TEST_F(GLES2ImplementationTest, DiscardFramebufferEXT) {
   GLenum data[2][1] = {{0}};
   struct Cmds {
index 9867b5d..d24bf67 100644 (file)
@@ -814,6 +814,11 @@ virtual GLuint CreateAndConsumeTextureCHROMIUM(const GLbyte* mailbox) = 0;
 virtual void BindUniformLocationCHROMIUM(GLuint program,
                                          GLint location,
                                          const char* name) = 0;
+virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0;
+virtual void BindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                                      GLenum internalformat,
+                                                      GLint imageId) = 0;
+virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0;
 virtual void TraceBeginCHROMIUM(const char* category_name,
                                 const char* trace_name) = 0;
 virtual void TraceEndCHROMIUM() = 0;
index 0127a24..c799d22 100644 (file)
@@ -790,6 +790,11 @@ GLuint CreateAndConsumeTextureCHROMIUM(const GLbyte* mailbox) override;
 void BindUniformLocationCHROMIUM(GLuint program,
                                  GLint location,
                                  const char* name) override;
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void BindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                              GLenum internalformat,
+                                              GLint imageId) override;
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
 void TraceBeginCHROMIUM(const char* category_name,
                         const char* trace_name) override;
 void TraceEndCHROMIUM() override;
index 7d3af70..0dc071a 100644 (file)
@@ -1056,6 +1056,14 @@ GLuint GLES2InterfaceStub::CreateAndConsumeTextureCHROMIUM(
 void GLES2InterfaceStub::BindUniformLocationCHROMIUM(GLuint /* program */,
                                                      GLint /* location */,
                                                      const char* /* name */) {}
+void GLES2InterfaceStub::BindTexImage2DCHROMIUM(GLenum /* target */,
+                                                GLint /* imageId */) {}
+void GLES2InterfaceStub::BindTexImage2DWithInternalformatCHROMIUM(
+    GLenum /* target */,
+    GLenum /* internalformat */,
+    GLint /* imageId */) {}
+void GLES2InterfaceStub::ReleaseTexImage2DCHROMIUM(GLenum /* target */,
+                                                   GLint /* imageId */) {}
 void GLES2InterfaceStub::TraceBeginCHROMIUM(const char* /* category_name */,
                                             const char* /* trace_name */) {}
 void GLES2InterfaceStub::TraceEndCHROMIUM() {}
index 9c075c5..2103e9e 100644 (file)
@@ -790,6 +790,11 @@ GLuint CreateAndConsumeTextureCHROMIUM(const GLbyte* mailbox) override;
 void BindUniformLocationCHROMIUM(GLuint program,
                                  GLint location,
                                  const char* name) override;
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void BindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                              GLenum internalformat,
+                                              GLint imageId) override;
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
 void TraceBeginCHROMIUM(const char* category_name,
                         const char* trace_name) override;
 void TraceEndCHROMIUM() override;
index 071fc7c..e22cb21 100644 (file)
@@ -2217,6 +2217,28 @@ void GLES2TraceImplementation::BindUniformLocationCHROMIUM(GLuint program,
   gl_->BindUniformLocationCHROMIUM(program, location, name);
 }
 
+void GLES2TraceImplementation::BindTexImage2DCHROMIUM(GLenum target,
+                                                      GLint imageId) {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindTexImage2DCHROMIUM");
+  gl_->BindTexImage2DCHROMIUM(target, imageId);
+}
+
+void GLES2TraceImplementation::BindTexImage2DWithInternalformatCHROMIUM(
+    GLenum target,
+    GLenum internalformat,
+    GLint imageId) {
+  TRACE_EVENT_BINARY_EFFICIENT0(
+      "gpu", "GLES2Trace::BindTexImage2DWithInternalformatCHROMIUM");
+  gl_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat,
+                                                imageId);
+}
+
+void GLES2TraceImplementation::ReleaseTexImage2DCHROMIUM(GLenum target,
+                                                         GLint imageId) {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ReleaseTexImage2DCHROMIUM");
+  gl_->ReleaseTexImage2DCHROMIUM(target, imageId);
+}
+
 void GLES2TraceImplementation::TraceBeginCHROMIUM(const char* category_name,
                                                   const char* trace_name) {
   TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TraceBeginCHROMIUM");
index 0c8b458..c6e3715 100644 (file)
@@ -14537,6 +14537,126 @@ static_assert(
     offsetof(BindUniformLocationCHROMIUMBucket, name_bucket_id) == 12,
     "offset of BindUniformLocationCHROMIUMBucket name_bucket_id should be 12");
 
+struct BindTexImage2DCHROMIUM {
+  typedef BindTexImage2DCHROMIUM ValueType;
+  static const CommandId kCmdId = kBindTexImage2DCHROMIUM;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() { header.SetCmd<ValueType>(); }
+
+  void Init(GLenum _target, GLint _imageId) {
+    SetHeader();
+    target = _target;
+    imageId = _imageId;
+  }
+
+  void* Set(void* cmd, GLenum _target, GLint _imageId) {
+    static_cast<ValueType*>(cmd)->Init(_target, _imageId);
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+  uint32_t target;
+  int32_t imageId;
+};
+
+static_assert(sizeof(BindTexImage2DCHROMIUM) == 12,
+              "size of BindTexImage2DCHROMIUM should be 12");
+static_assert(offsetof(BindTexImage2DCHROMIUM, header) == 0,
+              "offset of BindTexImage2DCHROMIUM header should be 0");
+static_assert(offsetof(BindTexImage2DCHROMIUM, target) == 4,
+              "offset of BindTexImage2DCHROMIUM target should be 4");
+static_assert(offsetof(BindTexImage2DCHROMIUM, imageId) == 8,
+              "offset of BindTexImage2DCHROMIUM imageId should be 8");
+
+struct BindTexImage2DWithInternalformatCHROMIUM {
+  typedef BindTexImage2DWithInternalformatCHROMIUM ValueType;
+  static const CommandId kCmdId = kBindTexImage2DWithInternalformatCHROMIUM;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() { header.SetCmd<ValueType>(); }
+
+  void Init(GLenum _target, GLenum _internalformat, GLint _imageId) {
+    SetHeader();
+    target = _target;
+    internalformat = _internalformat;
+    imageId = _imageId;
+  }
+
+  void* Set(void* cmd, GLenum _target, GLenum _internalformat, GLint _imageId) {
+    static_cast<ValueType*>(cmd)->Init(_target, _internalformat, _imageId);
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+  uint32_t target;
+  uint32_t internalformat;
+  int32_t imageId;
+};
+
+static_assert(sizeof(BindTexImage2DWithInternalformatCHROMIUM) == 16,
+              "size of BindTexImage2DWithInternalformatCHROMIUM should be 16");
+static_assert(
+    offsetof(BindTexImage2DWithInternalformatCHROMIUM, header) == 0,
+    "offset of BindTexImage2DWithInternalformatCHROMIUM header should be 0");
+static_assert(
+    offsetof(BindTexImage2DWithInternalformatCHROMIUM, target) == 4,
+    "offset of BindTexImage2DWithInternalformatCHROMIUM target should be 4");
+static_assert(offsetof(BindTexImage2DWithInternalformatCHROMIUM,
+                       internalformat) == 8,
+              "offset of BindTexImage2DWithInternalformatCHROMIUM "
+              "internalformat should be 8");
+static_assert(
+    offsetof(BindTexImage2DWithInternalformatCHROMIUM, imageId) == 12,
+    "offset of BindTexImage2DWithInternalformatCHROMIUM imageId should be 12");
+
+struct ReleaseTexImage2DCHROMIUM {
+  typedef ReleaseTexImage2DCHROMIUM ValueType;
+  static const CommandId kCmdId = kReleaseTexImage2DCHROMIUM;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() { header.SetCmd<ValueType>(); }
+
+  void Init(GLenum _target, GLint _imageId) {
+    SetHeader();
+    target = _target;
+    imageId = _imageId;
+  }
+
+  void* Set(void* cmd, GLenum _target, GLint _imageId) {
+    static_cast<ValueType*>(cmd)->Init(_target, _imageId);
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+  uint32_t target;
+  int32_t imageId;
+};
+
+static_assert(sizeof(ReleaseTexImage2DCHROMIUM) == 12,
+              "size of ReleaseTexImage2DCHROMIUM should be 12");
+static_assert(offsetof(ReleaseTexImage2DCHROMIUM, header) == 0,
+              "offset of ReleaseTexImage2DCHROMIUM header should be 0");
+static_assert(offsetof(ReleaseTexImage2DCHROMIUM, target) == 4,
+              "offset of ReleaseTexImage2DCHROMIUM target should be 4");
+static_assert(offsetof(ReleaseTexImage2DCHROMIUM, imageId) == 8,
+              "offset of ReleaseTexImage2DCHROMIUM imageId should be 8");
+
 struct TraceBeginCHROMIUM {
   typedef TraceBeginCHROMIUM ValueType;
   static const CommandId kCmdId = kTraceBeginCHROMIUM;
index 5f45c44..d4b335c 100644 (file)
@@ -4795,6 +4795,47 @@ TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUMBucket) {
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
+TEST_F(GLES2FormatTest, BindTexImage2DCHROMIUM) {
+  cmds::BindTexImage2DCHROMIUM& cmd =
+      *GetBufferAs<cmds::BindTexImage2DCHROMIUM>();
+  void* next_cmd =
+      cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindTexImage2DCHROMIUM::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+  EXPECT_EQ(static_cast<GLint>(12), cmd.imageId);
+  CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, BindTexImage2DWithInternalformatCHROMIUM) {
+  cmds::BindTexImage2DWithInternalformatCHROMIUM& cmd =
+      *GetBufferAs<cmds::BindTexImage2DWithInternalformatCHROMIUM>();
+  void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11),
+                           static_cast<GLenum>(12), static_cast<GLint>(13));
+  EXPECT_EQ(static_cast<uint32_t>(
+                cmds::BindTexImage2DWithInternalformatCHROMIUM::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+  EXPECT_EQ(static_cast<GLenum>(12), cmd.internalformat);
+  EXPECT_EQ(static_cast<GLint>(13), cmd.imageId);
+  CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, ReleaseTexImage2DCHROMIUM) {
+  cmds::ReleaseTexImage2DCHROMIUM& cmd =
+      *GetBufferAs<cmds::ReleaseTexImage2DCHROMIUM>();
+  void* next_cmd =
+      cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ReleaseTexImage2DCHROMIUM::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+  EXPECT_EQ(static_cast<GLint>(12), cmd.imageId);
+  CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
 TEST_F(GLES2FormatTest, TraceBeginCHROMIUM) {
   cmds::TraceBeginCHROMIUM& cmd = *GetBufferAs<cmds::TraceBeginCHROMIUM>();
   void* next_cmd =
index 4a47970..430f843 100644 (file)
   OP(ProduceTextureDirectCHROMIUMImmediate)                    /* 542 */ \
   OP(CreateAndConsumeTextureINTERNALImmediate)                 /* 543 */ \
   OP(BindUniformLocationCHROMIUMBucket)                        /* 544 */ \
-  OP(TraceBeginCHROMIUM)                                       /* 545 */ \
-  OP(TraceEndCHROMIUM)                                         /* 546 */ \
-  OP(DiscardFramebufferEXTImmediate)                           /* 547 */ \
-  OP(LoseContextCHROMIUM)                                      /* 548 */ \
-  OP(DrawBuffersEXTImmediate)                                  /* 549 */ \
-  OP(DiscardBackbufferCHROMIUM)                                /* 550 */ \
-  OP(FlushDriverCachesCHROMIUM)                                /* 551 */ \
-  OP(SetActiveURLCHROMIUM)                                     /* 552 */ \
-  OP(ContextVisibilityHintCHROMIUM)                            /* 553 */ \
-  OP(CoverageModulationCHROMIUM)                               /* 554 */ \
-  OP(BlendBarrierKHR)                                          /* 555 */ \
-  OP(BindFragDataLocationIndexedEXTBucket)                     /* 556 */ \
-  OP(BindFragDataLocationEXTBucket)                            /* 557 */ \
-  OP(GetFragDataIndexEXT)                                      /* 558 */ \
-  OP(InitializeDiscardableTextureCHROMIUM)                     /* 559 */ \
-  OP(UnlockDiscardableTextureCHROMIUM)                         /* 560 */ \
-  OP(LockDiscardableTextureCHROMIUM)                           /* 561 */ \
-  OP(WindowRectanglesEXTImmediate)                             /* 562 */ \
-  OP(CreateGpuFenceINTERNAL)                                   /* 563 */ \
-  OP(WaitGpuFenceCHROMIUM)                                     /* 564 */ \
-  OP(DestroyGpuFenceCHROMIUM)                                  /* 565 */ \
-  OP(SetReadbackBufferShadowAllocationINTERNAL)                /* 566 */ \
-  OP(FramebufferTextureMultiviewOVR)                           /* 567 */ \
-  OP(MaxShaderCompilerThreadsKHR)                              /* 568 */ \
-  OP(CreateAndTexStorage2DSharedImageINTERNALImmediate)        /* 569 */ \
-  OP(BeginSharedImageAccessDirectCHROMIUM)                     /* 570 */ \
-  OP(EndSharedImageAccessDirectCHROMIUM)                       /* 571 */ \
-  OP(EnableiOES)                                               /* 572 */ \
-  OP(DisableiOES)                                              /* 573 */ \
-  OP(BlendEquationiOES)                                        /* 574 */ \
-  OP(BlendEquationSeparateiOES)                                /* 575 */ \
-  OP(BlendFunciOES)                                            /* 576 */ \
-  OP(BlendFuncSeparateiOES)                                    /* 577 */ \
-  OP(ColorMaskiOES)                                            /* 578 */ \
-  OP(IsEnablediOES)                                            /* 579 */
+  OP(BindTexImage2DCHROMIUM)                                   /* 545 */ \
+  OP(BindTexImage2DWithInternalformatCHROMIUM)                 /* 546 */ \
+  OP(ReleaseTexImage2DCHROMIUM)                                /* 547 */ \
+  OP(TraceBeginCHROMIUM)                                       /* 548 */ \
+  OP(TraceEndCHROMIUM)                                         /* 549 */ \
+  OP(DiscardFramebufferEXTImmediate)                           /* 550 */ \
+  OP(LoseContextCHROMIUM)                                      /* 551 */ \
+  OP(DrawBuffersEXTImmediate)                                  /* 552 */ \
+  OP(DiscardBackbufferCHROMIUM)                                /* 553 */ \
+  OP(FlushDriverCachesCHROMIUM)                                /* 554 */ \
+  OP(SetActiveURLCHROMIUM)                                     /* 555 */ \
+  OP(ContextVisibilityHintCHROMIUM)                            /* 556 */ \
+  OP(CoverageModulationCHROMIUM)                               /* 557 */ \
+  OP(BlendBarrierKHR)                                          /* 558 */ \
+  OP(BindFragDataLocationIndexedEXTBucket)                     /* 559 */ \
+  OP(BindFragDataLocationEXTBucket)                            /* 560 */ \
+  OP(GetFragDataIndexEXT)                                      /* 561 */ \
+  OP(InitializeDiscardableTextureCHROMIUM)                     /* 562 */ \
+  OP(UnlockDiscardableTextureCHROMIUM)                         /* 563 */ \
+  OP(LockDiscardableTextureCHROMIUM)                           /* 564 */ \
+  OP(WindowRectanglesEXTImmediate)                             /* 565 */ \
+  OP(CreateGpuFenceINTERNAL)                                   /* 566 */ \
+  OP(WaitGpuFenceCHROMIUM)                                     /* 567 */ \
+  OP(DestroyGpuFenceCHROMIUM)                                  /* 568 */ \
+  OP(SetReadbackBufferShadowAllocationINTERNAL)                /* 569 */ \
+  OP(FramebufferTextureMultiviewOVR)                           /* 570 */ \
+  OP(MaxShaderCompilerThreadsKHR)                              /* 571 */ \
+  OP(CreateAndTexStorage2DSharedImageINTERNALImmediate)        /* 572 */ \
+  OP(BeginSharedImageAccessDirectCHROMIUM)                     /* 573 */ \
+  OP(EndSharedImageAccessDirectCHROMIUM)                       /* 574 */ \
+  OP(EnableiOES)                                               /* 575 */ \
+  OP(DisableiOES)                                              /* 576 */ \
+  OP(BlendEquationiOES)                                        /* 577 */ \
+  OP(BlendEquationSeparateiOES)                                /* 578 */ \
+  OP(BlendFunciOES)                                            /* 579 */ \
+  OP(BlendFuncSeparateiOES)                                    /* 580 */ \
+  OP(ColorMaskiOES)                                            /* 581 */ \
+  OP(IsEnablediOES)                                            /* 582 */
 
 enum CommandId {
   kOneBeforeStartPoint =
index 590507a..a2801cd 100644 (file)
@@ -323,6 +323,9 @@ GL_APICALL void         GL_APIENTRY glProduceTextureDirectCHROMIUM (GLidBindText
 GL_APICALL GLuint       GL_APIENTRY glCreateAndConsumeTextureCHROMIUM (const GLbyte* mailbox);
 GL_APICALL void         GL_APIENTRY glCreateAndConsumeTextureINTERNAL (GLuint texture, const GLbyte* mailbox);
 GL_APICALL void         GL_APIENTRY glBindUniformLocationCHROMIUM (GLidProgram program, GLint location, const char* name);
+GL_APICALL void         GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId);
+GL_APICALL void         GL_APIENTRY glBindTexImage2DWithInternalformatCHROMIUM (GLenumTextureBindTarget target, GLenumTextureInternalFormat internalformat, GLint imageId);
+GL_APICALL void         GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId);
 GL_APICALL void         GL_APIENTRY glTraceBeginCHROMIUM (const char* category_name, const char* trace_name);
 GL_APICALL void         GL_APIENTRY glTraceEndCHROMIUM (void);
 GL_APICALL void         GL_APIENTRY glDiscardFramebufferEXT (GLenumFramebufferTarget target, GLsizei count, const GLenum* attachments);
index 4632c26..a03eceb 100644 (file)
@@ -48,6 +48,8 @@ target(link_target_type, "service_sources") {
     "gpu_switches.h",
     "image_factory.cc",
     "image_factory.h",
+    "image_manager.cc",
+    "image_manager.h",
     "mailbox_manager.h",
     "memory_tracking.cc",
     "memory_tracking.h",
index 56f94e7..b01d55f 100644 (file)
@@ -13,6 +13,7 @@
 #include "gpu/command_buffer/common/activity_flags.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
+#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/passthrough_discardable_manager.h"
 #include "gpu/command_buffer/service/sequence_id.h"
 #include "gpu/command_buffer/service/service_discardable_manager.h"
@@ -91,6 +92,8 @@ class GPU_GLES2_EXPORT CommandBufferTaskExecutor {
   MailboxManager* mailbox_manager() const { return mailbox_manager_; }
 
   // Not const because these return inner pointers.
+
+  gles2::ImageManager* image_manager() { return &image_manager_; }
   ServiceDiscardableManager* discardable_manager() {
     return &discardable_manager_;
   }
@@ -118,6 +121,7 @@ class GPU_GLES2_EXPORT CommandBufferTaskExecutor {
   gl::GLSurfaceFormat share_group_surface_format_;
   std::unique_ptr<gles2::ProgramCache> owned_program_cache_;
   raw_ptr<gles2::ProgramCache> program_cache_;
+  gles2::ImageManager image_manager_;
   ServiceDiscardableManager discardable_manager_;
   PassthroughDiscardableManager passthrough_discardable_manager_;
   gles2::ShaderTranslatorCache shader_translator_cache_;
index 0638760..b714271 100644 (file)
@@ -76,6 +76,7 @@ ContextGroup::ContextGroup(
     FramebufferCompletenessCache* framebuffer_completeness_cache,
     const scoped_refptr<FeatureInfo>& feature_info,
     bool bind_generates_resource,
+    ImageManager* image_manager,
     gpu::ImageFactory* image_factory,
     gl::ProgressReporter* progress_reporter,
     const GpuFeatureInfo& gpu_feature_info,
@@ -118,6 +119,7 @@ ContextGroup::ContextGroup(
       uniform_buffer_offset_alignment_(1u),
       program_cache_(nullptr),
       feature_info_(feature_info),
+      image_manager_(image_manager),
       image_factory_(image_factory),
       use_passthrough_cmd_decoder_(false),
       passthrough_resources_(new PassthroughResources),
index 0aaaf27..6760a38 100644 (file)
@@ -44,6 +44,7 @@ namespace gles2 {
 
 class ProgramCache;
 class BufferManager;
+class ImageManager;
 class RenderbufferManager;
 class ProgramManager;
 class SamplerManager;
@@ -68,6 +69,7 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
                FramebufferCompletenessCache* framebuffer_completeness_cache,
                const scoped_refptr<FeatureInfo>& feature_info,
                bool bind_generates_resource,
+               ImageManager* image_manager,
                gpu::ImageFactory* image_factory,
                gl::ProgressReporter* progress_reporter,
                const GpuFeatureInfo& gpu_feature_info,
@@ -164,6 +166,8 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
     return feature_info_.get();
   }
 
+  ImageManager* image_manager() const { return image_manager_; }
+
   gpu::ImageFactory* image_factory() const { return image_factory_; }
 
   const GpuPreferences& gpu_preferences() const {
@@ -309,6 +313,8 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
 
   scoped_refptr<FeatureInfo> feature_info_;
 
+  raw_ptr<ImageManager> image_manager_;
+
   raw_ptr<gpu::ImageFactory> image_factory_;
 
   std::vector<base::WeakPtr<DecoderContext>> decoders_;
index 0f2c253..43e00a8 100644 (file)
@@ -65,6 +65,7 @@
 #include "gpu/command_buffer/service/gpu_state_tracer.h"
 #include "gpu/command_buffer/service/gpu_tracer.h"
 #include "gpu/command_buffer/service/image_factory.h"
+#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/logger.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/memory_tracking.h"
@@ -963,6 +964,8 @@ class GLES2DecoderImpl : public GLES2Decoder,
     return vertex_array_manager_.get();
   }
 
+  ImageManager* image_manager() { return group_->image_manager(); }
+
   MemoryTracker* memory_tracker() {
     return group_->memory_tracker();
   }
@@ -1221,6 +1224,16 @@ class GLES2DecoderImpl : public GLES2Decoder,
                  uint32_t texture_target,
                  gl::GLImage* image,
                  bool can_bind_to_sampler) override;
+  void DoBindTexImage2DCHROMIUM(GLenum target, GLint image_id);
+  void DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                                  GLenum internalformat,
+                                                  GLint image_id);
+  // Common implementation of DoBindTexImage2DCHROMIUM entry points.
+  void BindTexImage2DCHROMIUMImpl(const char* function_name,
+                                  GLenum target,
+                                  GLenum internalformat,
+                                  GLint image_id);
+  void DoReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id);
 
   void DoTraceEndCHROMIUM(void);
 
@@ -18586,6 +18599,115 @@ void GLES2DecoderImpl::BindImage(uint32_t client_texture_id,
                                        : gpu::gles2::Texture::UNBOUND);
 }
 
+void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(GLenum target, GLint image_id) {
+  TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
+
+  BindTexImage2DCHROMIUMImpl("glBindTexImage2DCHROMIUM", target, 0, image_id);
+}
+
+void GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM(
+    GLenum target,
+    GLenum internalformat,
+    GLint image_id) {
+  TRACE_EVENT0("gpu",
+               "GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM");
+
+  BindTexImage2DCHROMIUMImpl("glBindTexImage2DWithInternalformatCHROMIUM",
+                             target, internalformat, image_id);
+}
+
+void GLES2DecoderImpl::BindTexImage2DCHROMIUMImpl(const char* function_name,
+                                                  GLenum target,
+                                                  GLenum internalformat,
+                                                  GLint image_id) {
+  if (target == GL_TEXTURE_CUBE_MAP) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, function_name, "invalid target");
+    return;
+  }
+
+  // Default target might be conceptually valid, but disallow it to avoid
+  // accidents.
+  TextureRef* texture_ref =
+      texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
+  if (!texture_ref) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "no texture bound");
+    return;
+  }
+
+  gl::GLImage* image = image_manager()->LookupImage(image_id);
+  if (!image) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
+                       "no image found with the given ID");
+    return;
+  }
+
+  Texture::ImageState image_state = Texture::UNBOUND;
+
+  if (image->ShouldBindOrCopy() == gl::GLImage::BIND) {
+    ScopedGLErrorSuppressor suppressor(
+        "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", error_state_.get());
+
+    // Note: We fallback to using CopyTexImage() before the texture is used
+    // when BindTexImage() fails.
+    if (internalformat) {
+      if (image->BindTexImageWithInternalformat(target, internalformat))
+        image_state = Texture::BOUND;
+    } else {
+      if (image->BindTexImage(target))
+        image_state = Texture::BOUND;
+    }
+  }
+
+  gfx::Size size = image->GetSize();
+  GLenum texture_internalformat =
+      internalformat ? internalformat : image->GetInternalFormat();
+  texture_manager()->SetLevelInfo(texture_ref, target, 0,
+                                  texture_internalformat, size.width(),
+                                  size.height(), 1, 0, image->GetDataFormat(),
+                                  image->GetDataType(), gfx::Rect(size));
+  texture_manager()->SetLevelImage(texture_ref, target, 0, image, image_state);
+}
+
+void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(GLenum target,
+                                                   GLint image_id) {
+  TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
+
+  // Default target might be conceptually valid, but disallow it to avoid
+  // accidents.
+  TextureRef* texture_ref =
+      texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
+  if (!texture_ref) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReleaseTexImage2DCHROMIUM",
+                       "no texture bound");
+    return;
+  }
+
+  gl::GLImage* image = image_manager()->LookupImage(image_id);
+  if (!image) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReleaseTexImage2DCHROMIUM",
+                       "no image found with the given ID");
+    return;
+  }
+
+  Texture::ImageState image_state;
+
+  // Do nothing when image is not currently bound.
+  if (texture_ref->texture()->GetLevelImage(target, 0, &image_state) != image)
+    return;
+
+  if (image_state == Texture::BOUND) {
+    ScopedGLErrorSuppressor suppressor(
+        "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", error_state_.get());
+
+    image->ReleaseTexImage(target);
+    texture_manager()->SetLevelInfo(texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
+                                    GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect());
+  }
+
+  texture_manager()->SetLevelImage(texture_ref, target, 0, nullptr,
+                                   Texture::UNBOUND);
+}
+
 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
index dc7f727..62bf9e9 100644 (file)
@@ -46,6 +46,7 @@ class CopyTexImageResourceManager;
 class CopyTextureCHROMIUMResourceManager;
 class FramebufferManager;
 class GLES2Util;
+class ImageManager;
 class Logger;
 class Outputter;
 class ShaderTranslatorInterface;
index c07937b..e45bf73 100644 (file)
@@ -5026,6 +5026,64 @@ error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureINTERNALImmediate(
   return error::kNoError;
 }
 
+error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::BindTexImage2DCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::BindTexImage2DCHROMIUM*>(
+          cmd_data);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLint imageId = static_cast<GLint>(c.imageId);
+  if (!validators_->texture_bind_target.IsValid(target)) {
+    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindTexImage2DCHROMIUM", target,
+                                    "target");
+    return error::kNoError;
+  }
+  DoBindTexImage2DCHROMIUM(target, imageId);
+  return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindTexImage2DWithInternalformatCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::
+                       BindTexImage2DWithInternalformatCHROMIUM*>(cmd_data);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLenum internalformat = static_cast<GLenum>(c.internalformat);
+  GLint imageId = static_cast<GLint>(c.imageId);
+  if (!validators_->texture_bind_target.IsValid(target)) {
+    LOCAL_SET_GL_ERROR_INVALID_ENUM(
+        "glBindTexImage2DWithInternalformatCHROMIUM", target, "target");
+    return error::kNoError;
+  }
+  if (!validators_->texture_internal_format.IsValid(internalformat)) {
+    LOCAL_SET_GL_ERROR_INVALID_ENUM(
+        "glBindTexImage2DWithInternalformatCHROMIUM", internalformat,
+        "internalformat");
+    return error::kNoError;
+  }
+  DoBindTexImage2DWithInternalformatCHROMIUM(target, internalformat, imageId);
+  return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::ReleaseTexImage2DCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::ReleaseTexImage2DCHROMIUM*>(
+          cmd_data);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLint imageId = static_cast<GLint>(c.imageId);
+  if (!validators_->texture_bind_target.IsValid(target)) {
+    LOCAL_SET_GL_ERROR_INVALID_ENUM("glReleaseTexImage2DCHROMIUM", target,
+                                    "target");
+    return error::kNoError;
+  }
+  DoReleaseTexImage2DCHROMIUM(target, imageId);
+  return error::kNoError;
+}
+
 error::Error GLES2DecoderImpl::HandleTraceEndCHROMIUM(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
index ab2f90a..c716981 100644 (file)
@@ -3012,6 +3012,52 @@ error::Error GLES2DecoderPassthroughImpl::HandleSetActiveURLCHROMIUM(
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::BindTexImage2DCHROMIUMImpl(
+    GLenum target,
+    GLenum internalformat,
+    GLint imageId) {
+  TextureTarget target_enum = GLenumToTextureTarget(target);
+  if (target_enum == TextureTarget::kCubeMap ||
+      target_enum == TextureTarget::kUnkown) {
+    InsertError(GL_INVALID_ENUM, "Invalid target");
+    return error::kNoError;
+  }
+
+  gl::GLImage* image = group_->image_manager()->LookupImage(imageId);
+  if (image == nullptr) {
+    InsertError(GL_INVALID_OPERATION, "No image found with the given ID");
+    return error::kNoError;
+  }
+
+  const BoundTexture& bound_texture =
+      bound_textures_[static_cast<size_t>(target_enum)][active_texture_unit_];
+  if (bound_texture.texture == nullptr) {
+    InsertError(GL_INVALID_OPERATION, "No texture bound");
+    return error::kNoError;
+  }
+
+  if (image->ShouldBindOrCopy() == gl::GLImage::BIND) {
+    if (internalformat)
+      image->BindTexImageWithInternalformat(target, internalformat);
+    else
+      image->BindTexImage(target);
+  } else {
+    image->CopyTexImage(target);
+  }
+
+  // Target is already validated
+  UpdateTextureSizeFromTarget(target);
+
+  DCHECK(bound_texture.texture != nullptr);
+  bound_texture.texture->SetLevelImage(target, 0, image);
+
+  // If there was any GLImage bound to |target| on this texture unit, then
+  // forget it.
+  RemovePendingBindingTexture(target, active_texture_unit_);
+
+  return error::kNoError;
+}
+
 void GLES2DecoderPassthroughImpl::VerifyServiceTextureObjectsExist() {
   resources_->texture_object_map.ForEach(
       [this](GLuint client_id, scoped_refptr<TexturePassthrough> texture) {
index e46b8ae..2e791c8 100644 (file)
@@ -25,6 +25,7 @@
 #include "gpu/command_buffer/service/client_service_map.h"
 #include "gpu/command_buffer/service/context_group.h"
 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/logger.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/passthrough_abstract_texture_impl.h"
@@ -465,6 +466,10 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl
   // up-to-date.
   void LazilyUpdateCurrentlyBoundElementArrayBuffer();
 
+  error::Error BindTexImage2DCHROMIUMImpl(GLenum target,
+                                          GLenum internalformat,
+                                          GLint image_id);
+
   void VerifyServiceTextureObjectsExist();
 
   bool IsEmulatedFramebufferBound(GLenum target) const;
index 3a96342..cd4a3e0 100644 (file)
@@ -873,6 +873,11 @@ error::Error DoCreateAndConsumeTextureINTERNAL(GLuint texture_client_id,
 error::Error DoBindUniformLocationCHROMIUM(GLuint program,
                                            GLint location,
                                            const char* name);
+error::Error DoBindTexImage2DCHROMIUM(GLenum target, GLint imageId);
+error::Error DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target,
+                                                        GLenum internalformat,
+                                                        GLint imageId);
+error::Error DoReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId);
 error::Error DoTraceBeginCHROMIUM(const char* category_name,
                                   const char* trace_name);
 error::Error DoTraceEndCHROMIUM();
index 9b09ddf..9b51b08 100644 (file)
@@ -4572,6 +4572,55 @@ error::Error GLES2DecoderPassthroughImpl::DoBindUniformLocationCHROMIUM(
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::DoBindTexImage2DCHROMIUM(
+    GLenum target,
+    GLint imageId) {
+  return BindTexImage2DCHROMIUMImpl(target, 0, imageId);
+}
+
+error::Error
+GLES2DecoderPassthroughImpl::DoBindTexImage2DWithInternalformatCHROMIUM(
+    GLenum target,
+    GLenum internalformat,
+    GLint imageId) {
+  return BindTexImage2DCHROMIUMImpl(target, internalformat, imageId);
+}
+
+error::Error GLES2DecoderPassthroughImpl::DoReleaseTexImage2DCHROMIUM(
+    GLenum target,
+    GLint imageId) {
+  TextureTarget target_enum = GLenumToTextureTarget(target);
+  if (target_enum == TextureTarget::kCubeMap ||
+      target_enum == TextureTarget::kUnkown) {
+    InsertError(GL_INVALID_ENUM, "Invalid target");
+    return error::kNoError;
+  }
+
+  const BoundTexture& bound_texture =
+      bound_textures_[static_cast<size_t>(target_enum)][active_texture_unit_];
+  if (bound_texture.texture == nullptr) {
+    InsertError(GL_INVALID_OPERATION, "No texture bound");
+    return error::kNoError;
+  }
+
+  gl::GLImage* image = group_->image_manager()->LookupImage(imageId);
+  if (image == nullptr) {
+    InsertError(GL_INVALID_OPERATION, "No image found with the given ID");
+    return error::kNoError;
+  }
+
+  // Only release the image if it is currently bound
+  if (bound_texture.texture->GetLevelImage(target, 0) == image) {
+    image->ReleaseTexImage(target);
+    bound_texture.texture->SetLevelImage(target, 0, nullptr);
+  }
+
+  // Target is already validated
+  UpdateTextureSizeFromTarget(target);
+
+  return error::kNoError;
+}
+
 error::Error GLES2DecoderPassthroughImpl::DoTraceBeginCHROMIUM(
     const char* category_name,
     const char* trace_name) {
index 09295b0..e52e094 100644 (file)
@@ -4302,6 +4302,54 @@ GLES2DecoderPassthroughImpl::HandleCreateAndConsumeTextureINTERNALImmediate(
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::HandleBindTexImage2DCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::BindTexImage2DCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::BindTexImage2DCHROMIUM*>(
+          cmd_data);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLint imageId = static_cast<GLint>(c.imageId);
+  error::Error error = DoBindTexImage2DCHROMIUM(target, imageId);
+  if (error != error::kNoError) {
+    return error;
+  }
+  return error::kNoError;
+}
+
+error::Error
+GLES2DecoderPassthroughImpl::HandleBindTexImage2DWithInternalformatCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::
+                       BindTexImage2DWithInternalformatCHROMIUM*>(cmd_data);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLenum internalformat = static_cast<GLenum>(c.internalformat);
+  GLint imageId = static_cast<GLint>(c.imageId);
+  error::Error error = DoBindTexImage2DWithInternalformatCHROMIUM(
+      target, internalformat, imageId);
+  if (error != error::kNoError) {
+    return error;
+  }
+  return error::kNoError;
+}
+
+error::Error GLES2DecoderPassthroughImpl::HandleReleaseTexImage2DCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::ReleaseTexImage2DCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::ReleaseTexImage2DCHROMIUM*>(
+          cmd_data);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLint imageId = static_cast<GLint>(c.imageId);
+  error::Error error = DoReleaseTexImage2DCHROMIUM(target, imageId);
+  if (error != error::kNoError) {
+    return error;
+  }
+  return error::kNoError;
+}
+
 error::Error GLES2DecoderPassthroughImpl::HandleTraceEndCHROMIUM(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/image_manager.cc b/gpu/command_buffer/service/image_manager.cc
new file mode 100644 (file)
index 0000000..d7ca6d0
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/image_manager.h"
+
+#include <stdint.h>
+
+#include "base/check.h"
+#include "ui/gl/gl_image.h"
+
+namespace gpu {
+namespace gles2 {
+
+ImageManager::ImageManager() = default;
+
+ImageManager::~ImageManager() = default;
+
+void ImageManager::AddImage(gl::GLImage* image, int32_t service_id) {
+  DCHECK(images_.find(service_id) == images_.end());
+  images_[service_id] = image;
+}
+
+void ImageManager::RemoveImage(int32_t service_id) {
+  DCHECK(images_.find(service_id) != images_.end());
+  images_.erase(service_id);
+}
+
+gl::GLImage* ImageManager::LookupImage(int32_t service_id) {
+  GLImageMap::const_iterator iter = images_.find(service_id);
+  if (iter != images_.end())
+    return iter->second.get();
+
+  return nullptr;
+}
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/image_manager.h b/gpu/command_buffer/service/image_manager.h
new file mode 100644 (file)
index 0000000..8397eee
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_
+
+#include <stdint.h>
+
+#include <unordered_map>
+
+#include "base/memory/ref_counted.h"
+#include "gpu/gpu_export.h"
+
+namespace gl {
+class GLImage;
+}
+
+namespace gpu {
+namespace gles2 {
+
+// This class keeps track of the images and their state.
+class GPU_EXPORT ImageManager {
+ public:
+  ImageManager();
+  ~ImageManager();
+  ImageManager(const ImageManager&) = delete;
+  ImageManager& operator=(const ImageManager&) = delete;
+
+  void AddImage(gl::GLImage* image, int32_t service_id);
+  void RemoveImage(int32_t service_id);
+  gl::GLImage* LookupImage(int32_t service_id);
+
+ private:
+  typedef std::unordered_map<int32_t, scoped_refptr<gl::GLImage>> GLImageMap;
+  GLImageMap images_;
+};
+
+}  // namespace gles2
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_
index 35fe874..9dfd81f 100644 (file)
@@ -255,8 +255,8 @@ bool Context::CreateService(gl::GLSurface* gl_surface) {
   scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
       gpu_preferences, true, &mailbox_manager_, nullptr /* memory_tracker */,
       &translator_cache_, &completeness_cache_, feature_info, true,
-      nullptr /* image_factory */, nullptr /* progress_reporter */,
-      gpu_feature_info, &discardable_manager_,
+      &image_manager_, nullptr /* image_factory */,
+      nullptr /* progress_reporter */, gpu_feature_info, &discardable_manager_,
       &passthrough_discardable_manager_, &shared_image_manager_));
 
   auto command_buffer = std::make_unique<gpu::CommandBufferDirect>();
index f8d0b38..54dbc99 100644 (file)
@@ -15,6 +15,7 @@
 #include "gpu/command_buffer/service/command_buffer_direct.h"
 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
 #include "gpu/command_buffer/service/gpu_tracer.h"
+#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
 #include "gpu/command_buffer/service/passthrough_discardable_manager.h"
 #include "gpu/command_buffer/service/service_discardable_manager.h"
@@ -116,6 +117,7 @@ class Context : public base::RefCountedThreadSafe<Context>,
 
   gpu::gles2::MailboxManagerImpl mailbox_manager_;
   gpu::gles2::TraceOutputter outputter_;
+  gpu::gles2::ImageManager image_manager_;
   gpu::ServiceDiscardableManager discardable_manager_;
   gpu::PassthroughDiscardableManager passthrough_discardable_manager_;
   gpu::SharedImageManager shared_image_manager_;
index 717c9f0..e83f981 100644 (file)
@@ -238,6 +238,15 @@ interface GpuChannel {
   ReleaseSysmemBufferCollection(mojo_base.mojom.UnguessableToken id);
 };
 
+struct CreateImageParams {
+  int32 id;
+  gfx.mojom.GpuMemoryBufferHandle gpu_memory_buffer;
+  gfx.mojom.Size size;
+  gfx.mojom.BufferFormat format;
+  gfx.mojom.BufferPlane plane;
+  uint64 image_release_count;
+};
+
 // Interface used to issue commands to a specific CommandBuffer instance in the
 // GPU process.
 interface CommandBuffer {
@@ -258,6 +267,17 @@ interface CommandBuffer {
   // Requests retrieval of a GpuFenceHandle by ID.
   GetGpuFenceHandle(uint32 id) => (gfx.mojom.GpuFenceHandle? fence_handle);
 
+  // Creates an image from an existing gpu memory buffer. The id that can be
+  // used to identify the image from a command buffer.
+  //
+  // TODO(crbug.com/1216120): Remove this once CreateImageCHROMIUM is gone.
+  CreateImage(CreateImageParams params);
+
+  // Destroys a previously created image identified by `id`.
+  //
+  // TODO(crbug.com/1216120): Remove this once CreateImageCHROMIUM is gone.
+  DestroyImage(int32 id);
+
   // Asynchronously waits until the SyncToken is signaled, then sends a
   // corresponding SignalAck on the CommandBufferClient interface, using
   // `signal_id` to identify this request.
index 0d9a6b3..8bf1b65 100644 (file)
@@ -249,9 +249,9 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread(
       task_executor_->mailbox_manager(), std::move(memory_tracker),
       task_executor_->shader_translator_cache(),
       task_executor_->framebuffer_completeness_cache(), feature_info,
-      params.attribs.bind_generates_resource, params.image_factory,
-      nullptr /* progress_reporter */, task_executor_->gpu_feature_info(),
-      task_executor_->discardable_manager(),
+      params.attribs.bind_generates_resource, task_executor_->image_manager(),
+      params.image_factory, nullptr /* progress_reporter */,
+      task_executor_->gpu_feature_info(), task_executor_->discardable_manager(),
       task_executor_->passthrough_discardable_manager(),
       task_executor_->shared_image_manager());
 
index 88de4e9..8c87d63 100644 (file)
@@ -544,6 +544,14 @@ void CommandBufferStub::GetGpuFenceHandle(uint32_t id,
   std::move(callback).Run(gfx::GpuFenceHandle());
 }
 
+void CommandBufferStub::CreateImage(mojom::CreateImageParamsPtr params) {
+  DLOG(ERROR) << "CreateImage unsupported.";
+}
+
+void CommandBufferStub::DestroyImage(int32_t id) {
+  DLOG(ERROR) << "DestroyImage unsupported.";
+}
+
 void CommandBufferStub::OnDestroyTransferBuffer(int32_t id) {
   TRACE_EVENT0("gpu", "CommandBufferStub::OnDestroyTransferBuffer");
 
index 9089132..2d1b5cd 100644 (file)
@@ -220,6 +220,8 @@ class GPU_IPC_SERVICE_EXPORT CommandBufferStub
                                 gfx::GpuFenceHandle handle) override;
   void GetGpuFenceHandle(uint32_t id,
                          GetGpuFenceHandleCallback callback) override;
+  void CreateImage(mojom::CreateImageParamsPtr params) override;
+  void DestroyImage(int32_t id) override;
   void SignalSyncToken(const SyncToken& sync_token, uint32_t id) override;
   void SignalQuery(uint32_t query, uint32_t id) override;
   void BindMediaReceiver(mojo::GenericPendingAssociatedReceiver receiver,
index be556d7..cd81adc 100644 (file)
@@ -26,6 +26,7 @@
 #include "gpu/command_buffer/service/gl_context_virtual.h"
 #include "gpu/command_buffer/service/gl_state_restorer_impl.h"
 #include "gpu/command_buffer/service/gpu_fence_manager.h"
+#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/logger.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/memory_tracking.h"
@@ -110,7 +111,7 @@ gpu::ContextResult GLES2CommandBufferStub::Initialize(
         manager->mailbox_manager(), CreateMemoryTracker(),
         manager->shader_translator_cache(),
         manager->framebuffer_completeness_cache(), feature_info,
-        init_params.attribs.bind_generates_resource,
+        init_params.attribs.bind_generates_resource, channel_->image_manager(),
         gmb_factory ? gmb_factory->AsImageFactory() : nullptr,
         manager->watchdog() /* progress_reporter */,
         manager->gpu_feature_info(), manager->discardable_manager(),
@@ -508,6 +509,68 @@ void GLES2CommandBufferStub::GetGpuFenceHandle(
   std::move(callback).Run(std::move(handle));
 }
 
+void GLES2CommandBufferStub::CreateImage(mojom::CreateImageParamsPtr params) {
+  TRACE_EVENT0("gpu", "GLES2CommandBufferStub::OnCreateImage");
+  const int32_t id = params->id;
+  const gfx::Size& size = params->size;
+  const gfx::BufferFormat& format = params->format;
+  const gfx::BufferPlane& plane = params->plane;
+  const uint64_t image_release_count = params->image_release_count;
+  ScopedContextOperation operation(*this);
+  if (!operation.is_context_current())
+    return;
+
+  gles2::ImageManager* image_manager = channel_->image_manager();
+  DCHECK(image_manager);
+  if (image_manager->LookupImage(id)) {
+    LOG(ERROR) << "Image already exists with same ID.";
+    return;
+  }
+
+  if (!gpu::IsImageFromGpuMemoryBufferFormatSupported(
+          format, gles2_decoder_->GetCapabilities())) {
+    LOG(ERROR) << "Format is not supported.";
+    return;
+  }
+
+  if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, format)) {
+    LOG(ERROR) << "Invalid image size for format.";
+    return;
+  }
+
+  if (!gpu::IsPlaneValidForGpuMemoryBufferFormat(plane, format)) {
+    LOG(ERROR) << "Invalid plane " << gfx::BufferPlaneToString(plane) << " for "
+               << gfx::BufferFormatToString(format);
+    return;
+  }
+
+  scoped_refptr<gl::GLImage> image = channel()->CreateImageForGpuMemoryBuffer(
+      std::move(params->gpu_memory_buffer), size, format, plane,
+      surface_handle_);
+  if (!image.get())
+    return;
+
+  image_manager->AddImage(image.get(), id);
+  if (image_release_count)
+    sync_point_client_state_->ReleaseFenceSync(image_release_count);
+}
+
+void GLES2CommandBufferStub::DestroyImage(int32_t id) {
+  TRACE_EVENT0("gpu", "GLES2CommandBufferStub::OnDestroyImage");
+  ScopedContextOperation operation(*this);
+  if (!operation.is_context_current())
+    return;
+
+  gles2::ImageManager* image_manager = channel_->image_manager();
+  DCHECK(image_manager);
+  if (!image_manager->LookupImage(id)) {
+    LOG(ERROR) << "Image with ID doesn't exist.";
+    return;
+  }
+
+  image_manager->RemoveImage(id);
+}
+
 void GLES2CommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {}
 
 }  // namespace gpu
index 4568fe5..973134f 100644 (file)
@@ -66,6 +66,9 @@ class GPU_IPC_SERVICE_EXPORT GLES2CommandBufferStub
   void GetGpuFenceHandle(uint32_t gpu_fence_id,
                          GetGpuFenceHandleCallback callback) override;
 
+  void CreateImage(mojom::CreateImageParamsPtr params) override;
+  void DestroyImage(int32_t id) override;
+
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
 
   // The group of contexts that share namespaces with this context.
index 11b35bf..b00928a 100644 (file)
@@ -41,6 +41,7 @@
 #include "base/unguessable_token.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/service/image_factory.h"
+#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/memory_tracking.h"
 #include "gpu/command_buffer/service/scheduler.h"
@@ -50,6 +51,7 @@
 #include "gpu/ipc/service/gles2_command_buffer_stub.h"
 #include "gpu/ipc/service/gpu_channel_manager.h"
 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
+#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "gpu/ipc/service/image_decode_accelerator_stub.h"
 #include "gpu/ipc/service/raster_command_buffer_stub.h"
 #include "gpu/ipc/service/webgpu_command_buffer_stub.h"
@@ -541,6 +543,7 @@ GpuChannel::GpuChannel(
       task_runner_(task_runner),
       io_task_runner_(io_task_runner),
       share_group_(share_group),
+      image_manager_(new gles2::ImageManager()),
       is_gpu_host_(is_gpu_host),
       filter_(base::MakeRefCounted<GpuChannelMessageFilter>(
           this,
@@ -1078,4 +1081,22 @@ uint64_t GpuChannel::GetMemoryUsage() const {
   return size;
 }
 
+scoped_refptr<gl::GLImage> GpuChannel::CreateImageForGpuMemoryBuffer(
+    gfx::GpuMemoryBufferHandle handle,
+    const gfx::Size& size,
+    gfx::BufferFormat format,
+    gfx::BufferPlane plane,
+    SurfaceHandle surface_handle) {
+  GpuChannelManager* manager = gpu_channel_manager();
+  if (!manager->gpu_memory_buffer_factory())
+    return nullptr;
+
+  // TODO(b/220336463): plumb the right color space.
+  return manager->gpu_memory_buffer_factory()
+      ->AsImageFactory()
+      ->CreateImageForGpuMemoryBuffer(std::move(handle), size, format,
+                                      gfx::ColorSpace(), plane, client_id_,
+                                      surface_handle);
+}
+
 }  // namespace gpu
index 49f643b..c877b7b 100644 (file)
@@ -36,6 +36,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_image.h"
 #include "ui/gl/gl_share_group.h"
 #include "ui/gl/gpu_preference.h"
 
@@ -104,6 +105,8 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener,
 
   SyncPointManager* sync_point_manager() const { return sync_point_manager_; }
 
+  gles2::ImageManager* image_manager() const { return image_manager_.get(); }
+
   const scoped_refptr<base::SingleThreadTaskRunner>& task_runner() const {
     return task_runner_;
   }
@@ -155,6 +158,13 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener,
 
   uint64_t GetMemoryUsage() const;
 
+  scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer(
+      gfx::GpuMemoryBufferHandle handle,
+      const gfx::Size& size,
+      gfx::BufferFormat format,
+      gfx::BufferPlane plane,
+      SurfaceHandle surface_handle);
+
   // Executes a DeferredRequest that was previously received and has now been
   // scheduled by the scheduler.
   void ExecuteDeferredRequest(mojom::DeferredRequestParamsPtr params);
@@ -285,6 +295,7 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener,
   // process use.
   scoped_refptr<gl::GLShareGroup> share_group_;
 
+  std::unique_ptr<gles2::ImageManager> image_manager_;
   std::unique_ptr<SharedImageStub> shared_image_stub_;
 
   const bool is_gpu_host_;
index 18834f4..fca4990 100644 (file)
@@ -67,6 +67,12 @@ bool GLImage::BindTexImage(unsigned target) {
   return false;
 }
 
+bool GLImage::BindTexImageWithInternalformat(unsigned target,
+                                             unsigned internalformat) {
+  NOTREACHED();
+  return false;
+}
+
 void GLImage::ReleaseTexImage(unsigned target) {
   NOTREACHED();
 }
index c7b3d98..1c65bcb 100644 (file)
@@ -73,6 +73,13 @@ class GL_EXPORT GLImage : public base::RefCounted<GLImage> {
   // It is valid for an implementation to always return false.
   virtual bool BindTexImage(unsigned target);
 
+  // Bind image to texture currently bound to |target|, forcing the texture's
+  // internal format to the specified one. This is a feature not available on
+  // all platforms. Returns true on success.  It is valid for an implementation
+  // to always return false.
+  virtual bool BindTexImageWithInternalformat(unsigned target,
+                                              unsigned internalformat);
+
   // Release image from texture currently bound to |target|.
   virtual void ReleaseTexImage(unsigned target);