Support RGBA input buffers.
This change adds separate EGL shader for RGBA->YUV conversion
and modifies the JPEG compression to render input texture
into temporary framebuffer (doing the compression if necessary).
Bug: 301023410
Test: atest virtual_camera_tests
Test: atest VirtualCameraTest
Change-Id: Id3bd19d4c364691e2b1554fcf78d5f9940754314
diff --git a/services/camera/virtualcamera/util/EglProgram.cc b/services/camera/virtualcamera/util/EglProgram.cc
index c468d39..510fd33 100644
--- a/services/camera/virtualcamera/util/EglProgram.cc
+++ b/services/camera/virtualcamera/util/EglProgram.cc
@@ -76,17 +76,29 @@
vTextureCoord = aTextureCoord;
})";
-constexpr char kExternalTextureFragmentShader[] = R"(#version 300 es
+constexpr char kExternalYuvTextureFragmentShader[] = R"(#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
#extension GL_EXT_YUV_target : require
precision mediump float;
in vec2 vTextureCoord;
- out vec4 fragColor;
+ layout (yuv) out vec4 fragColor;
uniform __samplerExternal2DY2YEXT uTexture;
void main() {
fragColor = texture(uTexture, vTextureCoord);
})";
+constexpr char kExternalRgbaTextureFragmentShader[] = R"(#version 300 es
+ #extension GL_OES_EGL_image_external : require
+ #extension GL_EXT_YUV_target : require
+ precision mediump float;
+ in vec2 vTextureCoord;
+ layout (yuv) out vec4 fragColor;
+ uniform samplerExternalOES uTexture;
+ void main() {
+ vec4 rgbaColor = texture(uTexture, vTextureCoord);
+ fragColor = vec4(rgb_2_yuv(rgbaColor.xyz, itu_601_full_range), 0.0);
+ })";
+
constexpr int kCoordsPerVertex = 3;
constexpr std::array<float, 12> kSquareCoords{-1.f, 1.0f, 0.0f, // top left
-1.f, -1.f, 0.0f, // bottom left
@@ -237,7 +249,7 @@
return true;
}
-EglTextureProgram::EglTextureProgram() {
+EglTextureProgram::EglTextureProgram(const TextureFormat textureFormat) {
if (!isGlExtensionSupported(kGlExtYuvTarget)) {
ALOGE(
"Cannot initialize external texture program due to missing "
@@ -245,7 +257,10 @@
return;
}
- if (initialize(kExternalTextureVertexShader, kExternalTextureFragmentShader)) {
+ const char* fragmentShaderSrc = textureFormat == TextureFormat::YUV
+ ? kExternalYuvTextureFragmentShader
+ : kExternalRgbaTextureFragmentShader;
+ if (initialize(kExternalTextureVertexShader, fragmentShaderSrc)) {
ALOGV("Successfully initialized EGL shaders for external texture program.");
} else {
ALOGE("External texture EGL shader program initialization failed.");