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.");