diff --git a/mediapipe/gpu/gl_texture_buffer.cc b/mediapipe/gpu/gl_texture_buffer.cc index 48afbd219..da2533f1c 100644 --- a/mediapipe/gpu/gl_texture_buffer.cc +++ b/mediapipe/gpu/gl_texture_buffer.cc @@ -14,6 +14,8 @@ #include "mediapipe/gpu/gl_texture_buffer.h" +#include + #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "mediapipe/framework/formats/image_frame.h" @@ -131,6 +133,12 @@ bool GlTextureBuffer::CreateInternal(const void* data, int alignment) { SymbolAvailable(&glTexStorage2D)) { ABSL_CHECK(data == nullptr) << "unimplemented"; glTexStorage2D(target_, 1, info.gl_internal_format, width_, height_); + } else if (info.immutable) { + ABSL_CHECK(SymbolAvailable(&glTexStorage2D) && + context->GetGlVersion() != GlVersion::kGLES2) + << "Immutable GpuBuffer format requested is not supported in this " + << "GLContext. Format was " << static_cast(format_); + glTexStorage2D(target_, 1, info.gl_internal_format, width_, height_); } else { glTexImage2D(target_, 0 /* level */, info.gl_internal_format, width_, height_, 0 /* border */, info.gl_format, info.gl_type, data); diff --git a/mediapipe/gpu/gpu_buffer_format.cc b/mediapipe/gpu/gpu_buffer_format.cc index 646fb383f..930bad735 100644 --- a/mediapipe/gpu/gpu_buffer_format.cc +++ b/mediapipe/gpu/gpu_buffer_format.cc @@ -163,6 +163,14 @@ const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format, { {GL_RGBA32F, GL_RGBA, GL_FLOAT, 1}, }}, + {GpuBufferFormat::kImmutableRGBAFloat128, + { + {GL_RGBA32F, GL_RGBA, GL_FLOAT, 1, true /* immutable */}, + }}, + {GpuBufferFormat::kImmutableRGBA32, + { + {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, true /* immutable */}, + }}, }}; static const auto* gles2_format_info = ([] { @@ -206,6 +214,7 @@ const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format, ImageFormat::Format ImageFormatForGpuBufferFormat(GpuBufferFormat format) { switch (format) { + case GpuBufferFormat::kImmutableRGBA32: case GpuBufferFormat::kBGRA32: // TODO: verify we are handling order of channels correctly. return ImageFormat::SRGBA; @@ -221,6 +230,7 @@ ImageFormat::Format ImageFormatForGpuBufferFormat(GpuBufferFormat format) { return ImageFormat::SRGB; case GpuBufferFormat::kTwoComponentFloat32: return ImageFormat::VEC32F2; + case GpuBufferFormat::kImmutableRGBAFloat128: case GpuBufferFormat::kRGBAFloat128: return ImageFormat::VEC32F4; case GpuBufferFormat::kRGBA32: diff --git a/mediapipe/gpu/gpu_buffer_format.h b/mediapipe/gpu/gpu_buffer_format.h index 06eabda77..0b6badfb5 100644 --- a/mediapipe/gpu/gpu_buffer_format.h +++ b/mediapipe/gpu/gpu_buffer_format.h @@ -53,6 +53,10 @@ enum class GpuBufferFormat : uint32_t { kRGB24 = 0x00000018, // Note: prefer BGRA32 whenever possible. kRGBAHalf64 = MEDIAPIPE_FOURCC('R', 'G', 'h', 'A'), kRGBAFloat128 = MEDIAPIPE_FOURCC('R', 'G', 'f', 'A'), + // Immutable version of kRGBA32 + kImmutableRGBA32 = MEDIAPIPE_FOURCC('4', 'C', 'I', '8'), + // Immutable version of kRGBAFloat128 + kImmutableRGBAFloat128 = MEDIAPIPE_FOURCC('4', 'C', 'I', 'f'), // 8-bit Y plane + interleaved 8-bit U/V plane with 2x2 subsampling. kNV12 = MEDIAPIPE_FOURCC('N', 'V', '1', '2'), // 8-bit Y plane + interleaved 8-bit V/U plane with 2x2 subsampling. @@ -78,6 +82,9 @@ struct GlTextureInfo { // For multiplane buffers, this represents how many times smaller than // the nominal image size a plane is. int downscale; + // For GLES3.1+ compute shaders, users may explicitly request immutable + // textures + bool immutable = false; }; const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format, @@ -121,6 +128,8 @@ inline OSType CVPixelFormatForGpuBufferFormat(GpuBufferFormat format) { return kCVPixelFormatType_64RGBAHalf; case GpuBufferFormat::kRGBAFloat128: return kCVPixelFormatType_128RGBAFloat; + case GpuBufferFormat::kImmutableRGBA32: + case GpuBufferFormat::kImmutableRGBAFloat128: case GpuBufferFormat::kNV12: case GpuBufferFormat::kNV21: case GpuBufferFormat::kI420: