From d3644c0193273f708634389d6b47e18c1c8a0c24 Mon Sep 17 00:00:00 2001 From: uzair Date: Thu, 5 Jan 2023 13:31:55 +0530 Subject: [PATCH] [PDNCF] Backport ImageManager class and its dependencies 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 --- gpu/GLES2/gl2chromium_autogen.h | 4 + gpu/GLES2/gl2extchromium.h | 37 +++++++ gpu/command_buffer/build_gles2_cmd_buffer.py | 15 +++ gpu/command_buffer/client/gles2_c_lib_autogen.h | 26 +++++ .../client/gles2_cmd_helper_autogen.h | 26 +++++ .../client/gles2_implementation_autogen.h | 8 ++ .../client/gles2_implementation_impl_autogen.h | 34 ++++++ .../client/gles2_implementation_unittest_autogen.h | 33 ++++++ .../client/gles2_interface_autogen.h | 5 + .../client/gles2_interface_stub_autogen.h | 5 + .../client/gles2_interface_stub_impl_autogen.h | 8 ++ .../client/gles2_trace_implementation_autogen.h | 5 + .../gles2_trace_implementation_impl_autogen.h | 22 ++++ .../common/gles2_cmd_format_autogen.h | 120 ++++++++++++++++++++ .../common/gles2_cmd_format_test_autogen.h | 41 +++++++ gpu/command_buffer/common/gles2_cmd_ids_autogen.h | 73 ++++++------ gpu/command_buffer/gles2_cmd_buffer_functions.txt | 3 + gpu/command_buffer/service/BUILD.gn | 2 + .../service/command_buffer_task_executor.h | 4 + gpu/command_buffer/service/context_group.cc | 2 + gpu/command_buffer/service/context_group.h | 6 + gpu/command_buffer/service/gles2_cmd_decoder.cc | 122 +++++++++++++++++++++ gpu/command_buffer/service/gles2_cmd_decoder.h | 1 + .../service/gles2_cmd_decoder_autogen.h | 58 ++++++++++ .../service/gles2_cmd_decoder_passthrough.cc | 46 ++++++++ .../service/gles2_cmd_decoder_passthrough.h | 5 + ...gles2_cmd_decoder_passthrough_doer_prototypes.h | 5 + .../service/gles2_cmd_decoder_passthrough_doers.cc | 49 +++++++++ ...es2_cmd_decoder_passthrough_handlers_autogen.cc | 48 ++++++++ gpu/command_buffer/service/image_manager.cc | 38 +++++++ gpu/command_buffer/service/image_manager.h | 42 +++++++ gpu/gles2_conform_support/egl/context.cc | 4 +- gpu/gles2_conform_support/egl/context.h | 2 + gpu/ipc/common/gpu_channel.mojom | 20 ++++ gpu/ipc/in_process_command_buffer.cc | 6 +- gpu/ipc/service/command_buffer_stub.cc | 8 ++ gpu/ipc/service/command_buffer_stub.h | 2 + gpu/ipc/service/gles2_command_buffer_stub.cc | 65 ++++++++++- gpu/ipc/service/gles2_command_buffer_stub.h | 3 + gpu/ipc/service/gpu_channel.cc | 21 ++++ gpu/ipc/service/gpu_channel.h | 11 ++ ui/gl/gl_image.cc | 6 + ui/gl/gl_image.h | 7 ++ 43 files changed, 1007 insertions(+), 41 deletions(-) create mode 100644 gpu/command_buffer/service/image_manager.cc create mode 100644 gpu/command_buffer/service/image_manager.h diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index f0b3a3d..efcb0d37 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -330,6 +330,10 @@ #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) diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index da4583a..44036b8 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h @@ -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 diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 453d713..b8bef5e 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -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', diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 161c43e..7114150 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -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(glBindUniformLocationCHROMIUM), }, { + "glBindTexImage2DCHROMIUM", + reinterpret_cast(glBindTexImage2DCHROMIUM), + }, + { + "glBindTexImage2DWithInternalformatCHROMIUM", + reinterpret_cast( + glBindTexImage2DWithInternalformatCHROMIUM), + }, + { + "glReleaseTexImage2DCHROMIUM", + reinterpret_cast(glReleaseTexImage2DCHROMIUM), + }, + { "glTraceBeginCHROMIUM", reinterpret_cast(glTraceBeginCHROMIUM), }, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 7676f76..1de1be1 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -2923,6 +2923,32 @@ void BindUniformLocationCHROMIUMBucket(GLuint program, } } +void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { + gles2::cmds::BindTexImage2DCHROMIUM* c = + GetCmdSpace(); + if (c) { + c->Init(target, imageId); + } +} + +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) { + gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM* c = + GetCmdSpace(); + if (c) { + c->Init(target, internalformat, imageId); + } +} + +void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { + gles2::cmds::ReleaseTexImage2DCHROMIUM* c = + GetCmdSpace(); + if (c) { + c->Init(target, imageId); + } +} + void TraceBeginCHROMIUM(GLuint category_bucket_id, GLuint name_bucket_id) { gles2::cmds::TraceBeginCHROMIUM* c = GetCmdSpace(); diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index b556b23..f1c6a51 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -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; diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index a8586eb..1b945f0 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -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) { diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 6f17bb34..c2d65f1 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -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 { diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 9867b5d..d24bf67 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -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; diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 0127a24..c799d22 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -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; diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 7d3af70..0dc071a 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -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() {} diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 9c075c5..2103e9e 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -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; diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 071fc7c..e22cb21 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -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"); diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 0c8b458..c6e3715 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -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(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd(); } + + void Init(GLenum _target, GLint _imageId) { + SetHeader(); + target = _target; + imageId = _imageId; + } + + void* Set(void* cmd, GLenum _target, GLint _imageId) { + static_cast(cmd)->Init(_target, _imageId); + return NextCmdAddress(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(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd(); } + + 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(cmd)->Init(_target, _internalformat, _imageId); + return NextCmdAddress(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(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd(); } + + void Init(GLenum _target, GLint _imageId) { + SetHeader(); + target = _target; + imageId = _imageId; + } + + void* Set(void* cmd, GLenum _target, GLint _imageId) { + static_cast(cmd)->Init(_target, _imageId); + return NextCmdAddress(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; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 5f45c44..d4b335c 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -4795,6 +4795,47 @@ TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUMBucket) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindTexImage2DCHROMIUM) { + cmds::BindTexImage2DCHROMIUM& cmd = + *GetBufferAs(); + void* next_cmd = + cmd.Set(&cmd, static_cast(11), static_cast(12)); + EXPECT_EQ(static_cast(cmds::BindTexImage2DCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast(11), cmd.target); + EXPECT_EQ(static_cast(12), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, BindTexImage2DWithInternalformatCHROMIUM) { + cmds::BindTexImage2DWithInternalformatCHROMIUM& cmd = + *GetBufferAs(); + void* next_cmd = cmd.Set(&cmd, static_cast(11), + static_cast(12), static_cast(13)); + EXPECT_EQ(static_cast( + cmds::BindTexImage2DWithInternalformatCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast(11), cmd.target); + EXPECT_EQ(static_cast(12), cmd.internalformat); + EXPECT_EQ(static_cast(13), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, ReleaseTexImage2DCHROMIUM) { + cmds::ReleaseTexImage2DCHROMIUM& cmd = + *GetBufferAs(); + void* next_cmd = + cmd.Set(&cmd, static_cast(11), static_cast(12)); + EXPECT_EQ(static_cast(cmds::ReleaseTexImage2DCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast(11), cmd.target); + EXPECT_EQ(static_cast(12), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, TraceBeginCHROMIUM) { cmds::TraceBeginCHROMIUM& cmd = *GetBufferAs(); void* next_cmd = diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 4a47970..430f843 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -301,41 +301,44 @@ 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 = diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index 590507a..a2801cd 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt @@ -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); diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 4632c26..a03eceb 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn @@ -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", diff --git a/gpu/command_buffer/service/command_buffer_task_executor.h b/gpu/command_buffer/service/command_buffer_task_executor.h index 56f94e7..b01d55f 100644 --- a/gpu/command_buffer/service/command_buffer_task_executor.h +++ b/gpu/command_buffer/service/command_buffer_task_executor.h @@ -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 owned_program_cache_; raw_ptr program_cache_; + gles2::ImageManager image_manager_; ServiceDiscardableManager discardable_manager_; PassthroughDiscardableManager passthrough_discardable_manager_; gles2::ShaderTranslatorCache shader_translator_cache_; diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 0638760..b714271 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -76,6 +76,7 @@ ContextGroup::ContextGroup( FramebufferCompletenessCache* framebuffer_completeness_cache, const scoped_refptr& 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), diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 0aaaf27..6760a38 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -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 { FramebufferCompletenessCache* framebuffer_completeness_cache, const scoped_refptr& 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 { 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 { scoped_refptr feature_info_; + raw_ptr image_manager_; + raw_ptr image_factory_; std::vector> decoders_; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0f2c253..43e00a8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -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) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index dc7f727..62bf9e9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -46,6 +46,7 @@ class CopyTexImageResourceManager; class CopyTextureCHROMIUMResourceManager; class FramebufferManager; class GLES2Util; +class ImageManager; class Logger; class Outputter; class ShaderTranslatorInterface; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index c07937b..e45bf73 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -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( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(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(cmd_data); + GLenum target = static_cast(c.target); + GLenum internalformat = static_cast(c.internalformat); + GLint imageId = static_cast(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( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(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) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index ab2f90a..c716981 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc @@ -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(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 texture) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index e46b8ae..2e791c8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h @@ -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; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 3a96342..cd4a3e0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h @@ -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(); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 9b09ddf..9b51b08 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc @@ -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(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) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 09295b0..e52e094 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc @@ -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( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(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(cmd_data); + GLenum target = static_cast(c.target); + GLenum internalformat = static_cast(c.internalformat); + GLint imageId = static_cast(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( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(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 index 0000000..d7ca6d0 --- /dev/null +++ b/gpu/command_buffer/service/image_manager.cc @@ -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 + +#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 index 0000000..8397eee --- /dev/null +++ b/gpu/command_buffer/service/image_manager.h @@ -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 + +#include + +#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> GLImageMap; + GLImageMap images_; +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_ diff --git a/gpu/gles2_conform_support/egl/context.cc b/gpu/gles2_conform_support/egl/context.cc index 35fe874..9dfd81f 100644 --- a/gpu/gles2_conform_support/egl/context.cc +++ b/gpu/gles2_conform_support/egl/context.cc @@ -255,8 +255,8 @@ bool Context::CreateService(gl::GLSurface* gl_surface) { scoped_refptr 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(); diff --git a/gpu/gles2_conform_support/egl/context.h b/gpu/gles2_conform_support/egl/context.h index f8d0b38..54dbc99 100644 --- a/gpu/gles2_conform_support/egl/context.h +++ b/gpu/gles2_conform_support/egl/context.h @@ -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, 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_; diff --git a/gpu/ipc/common/gpu_channel.mojom b/gpu/ipc/common/gpu_channel.mojom index 717c9f0..e83f981 100644 --- a/gpu/ipc/common/gpu_channel.mojom +++ b/gpu/ipc/common/gpu_channel.mojom @@ -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. diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 0d9a6b3..8bf1b65 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc @@ -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()); diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index 88de4e9..8c87d63 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc @@ -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"); diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h index 9089132..2d1b5cd 100644 --- a/gpu/ipc/service/command_buffer_stub.h +++ b/gpu/ipc/service/command_buffer_stub.h @@ -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, diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc index be556d7..cd81adc 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/gpu/ipc/service/gles2_command_buffer_stub.cc @@ -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 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 diff --git a/gpu/ipc/service/gles2_command_buffer_stub.h b/gpu/ipc/service/gles2_command_buffer_stub.h index 4568fe5..973134f 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.h +++ b/gpu/ipc/service/gles2_command_buffer_stub.h @@ -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. diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index 11b35bf..b00928a 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc @@ -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( this, @@ -1078,4 +1081,22 @@ uint64_t GpuChannel::GetMemoryUsage() const { return size; } +scoped_refptr 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 diff --git a/gpu/ipc/service/gpu_channel.h b/gpu/ipc/service/gpu_channel.h index 49f643b..c877b7b 100644 --- a/gpu/ipc/service/gpu_channel.h +++ b/gpu/ipc/service/gpu_channel.h @@ -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& 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 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 share_group_; + std::unique_ptr image_manager_; std::unique_ptr shared_image_stub_; const bool is_gpu_host_; diff --git a/ui/gl/gl_image.cc b/ui/gl/gl_image.cc index 18834f4..fca4990 100644 --- a/ui/gl/gl_image.cc +++ b/ui/gl/gl_image.cc @@ -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(); } diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index c7b3d98..1c65bcb 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -73,6 +73,13 @@ class GL_EXPORT GLImage : public base::RefCounted { // 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); -- 2.7.4