Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec79adf2 authored by Ján Sebechlebský's avatar Ján Sebechlebský Committed by Android (Google) Code Review
Browse files

Merge changes I081c12fe,Ib7fd2bb0 into main

* changes:
  Cache handles to attributes & uniforms for texture shader
  Apply transformation matrix to texture coordinates.
parents 22439d24 ca2d7970
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -542,8 +542,12 @@ ndk::ScopedAStatus VirtualCameraRenderThread::renderIntoEglFramebuffer(
  } else {
    const bool renderSuccess =
        isYuvFormat(static_cast<PixelFormat>(textureBuffer->getPixelFormat()))
            ? mEglTextureYuvProgram->draw(mEglSurfaceTexture->updateTexture())
            : mEglTextureRgbProgram->draw(mEglSurfaceTexture->updateTexture());
            ? mEglTextureYuvProgram->draw(
                  mEglSurfaceTexture->getTextureId(),
                  mEglSurfaceTexture->getTransformMatrix())
            : mEglTextureRgbProgram->draw(
                  mEglSurfaceTexture->getTextureId(),
                  mEglSurfaceTexture->getTransformMatrix());
    if (!renderSuccess) {
      ALOGE("%s: Failed to render texture", __func__);
      return cameraStatus(Status::INTERNAL_ERROR);
+40 −19
Original line number Diff line number Diff line
@@ -68,12 +68,13 @@ constexpr char kJuliaFractalFragmentShader[] = R"(
    })";

constexpr char kExternalTextureVertexShader[] = R"(#version 300 es
  uniform mat4 aTextureTransformMatrix; // Transform matrix given by surface texture.
  in vec4 aPosition;
  in vec2 aTextureCoord;
  out vec2 vTextureCoord;
  void main() {
    gl_Position = aPosition;
    vTextureCoord = aTextureCoord;
    vTextureCoord = (aTextureTransformMatrix * vec4(aTextureCoord, 0.0, 1.0)).xy;
  })";

constexpr char kExternalYuvTextureFragmentShader[] = R"(#version 300 es
@@ -100,10 +101,12 @@ constexpr char kExternalRgbaTextureFragmentShader[] = R"(#version 300 es
    })";

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
                                              1.0f, -1.f, 0.0f,  // bottom right
                                              1.0f, 1.0f, 0.0f};  // top right

constexpr std::array<float, 12> kSquareCoords{
    -1.f, -1.0f, 0.0f,   // top left
    -1.f, 1.f,   0.0f,   // bottom left
    1.0f, 1.f,   0.0f,   // bottom right
    1.0f, -1.0f, 0.0f};  // top right

constexpr std::array<float, 8> kTextureCoords{0.0f, 1.0f,   // top left
                                              0.0f, 0.0f,   // bottom left
@@ -265,32 +268,50 @@ EglTextureProgram::EglTextureProgram(const TextureFormat textureFormat) {
  } else {
    ALOGE("External texture EGL shader program initialization failed.");
  }

  // Lookup and cache handles to uniforms & attributes.
  mPositionHandle = glGetAttribLocation(mProgram, "aPosition");
  mTextureCoordHandle = glGetAttribLocation(mProgram, "aTextureCoord");
  mTransformMatrixHandle =
      glGetUniformLocation(mProgram, "aTextureTransformMatrix");
  mTextureHandle = glGetUniformLocation(mProgram, "uTexture");

  // Pass vertex array to the shader.
  glEnableVertexAttribArray(mPositionHandle);
  glVertexAttribPointer(mPositionHandle, kCoordsPerVertex, GL_FLOAT, false,
                        kSquareCoords.size(), kSquareCoords.data());

  // Pass texture coordinates corresponding to vertex array to the shader.
  glEnableVertexAttribArray(mTextureCoordHandle);
  glVertexAttribPointer(mTextureCoordHandle, 2, GL_FLOAT, false,
                        kTextureCoords.size(), kTextureCoords.data());
}

bool EglTextureProgram::draw(GLuint textureId) {
EglTextureProgram::~EglTextureProgram() {
  if (mPositionHandle != -1) {
    glDisableVertexAttribArray(mPositionHandle);
  }
  if (mTextureCoordHandle != -1) {
    glDisableVertexAttribArray(mTextureCoordHandle);
  }
}

bool EglTextureProgram::draw(GLuint textureId,
                             const std::array<float, 16>& transformMatrix) {
  // Load compiled shader.
  glUseProgram(mProgram);
  if (checkEglError("glUseProgram")) {
    return false;
  }

  // Pass vertex array to the shader.
  int positionHandle = glGetAttribLocation(mProgram, "aPosition");
  glEnableVertexAttribArray(positionHandle);
  glVertexAttribPointer(positionHandle, kCoordsPerVertex, GL_FLOAT, false,
                        kSquareCoords.size(), kSquareCoords.data());

  // Pass texture coordinates corresponding to vertex array to the shader.
  int textureCoordHandle = glGetAttribLocation(mProgram, "aTextureCoord");
  glEnableVertexAttribArray(textureCoordHandle);
  glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, false,
                        kTextureCoords.size(), kTextureCoords.data());
  // Pass transformation matrix for the texture coordinates.
  glUniformMatrix4fv(mTextureCoordHandle, 1, /*transpose=*/GL_FALSE,
                     transformMatrix.data());

  // Configure texture for the shader.
  int textureHandle = glGetUniformLocation(mProgram, "uTexture");
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
  glUniform1i(textureHandle, 0);
  glUniform1i(mTextureHandle, 0);

  // Draw triangle strip forming a square filling the viewport.
  glDrawElements(GL_TRIANGLES, kDrawOrder.size(), GL_UNSIGNED_BYTE,
+18 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#ifndef ANDROID_COMPANION_VIRTUALCAMERA_EGLPROGRAM_H
#define ANDROID_COMPANION_VIRTUALCAMERA_EGLPROGRAM_H

#include <array>

#include "GLES/gl.h"

namespace android {
@@ -58,8 +60,23 @@ class EglTextureProgram : public EglProgram {
  enum class TextureFormat { RGBA, YUV };

  EglTextureProgram(TextureFormat textureFormat = TextureFormat::YUV);
  virtual ~EglTextureProgram();

  // Draw texture over whole viewport, applying transformMatrix to texture
  // coordinates.
  //
  // Transform matrix is 4x4 matrix represented in column-major order and is
  // applied to texture coordinates in (s,t,0,1), s,t from <0,1> range prior to
  // sampling:
  //
  // textureCoord = transformMatrix * vec4(s,t,0,1).xy
  bool draw(GLuint textureId, const std::array<float, 16>& transformMatrix);

  bool draw(GLuint textureId);
 private:
  int mPositionHandle = -1;
  int mTextureCoordHandle = -1;
  int mTransformMatrixHandle = -1;
  int mTextureHandle = -1;
};

}  // namespace virtualcamera
+10 −0
Original line number Diff line number Diff line
@@ -68,6 +68,16 @@ GLuint EglSurfaceTexture::updateTexture() {
  return mTextureId;
}

GLuint EglSurfaceTexture::getTextureId() const {
  return mTextureId;
}

std::array<float, 16> EglSurfaceTexture::getTransformMatrix() {
  std::array<float, 16> matrix;
  mGlConsumer->getTransformMatrix(matrix.data());
  return matrix;
}

uint32_t EglSurfaceTexture::getWidth() const {
  return mWidth;
}
+11 −0
Original line number Diff line number Diff line
@@ -57,6 +57,17 @@ class EglSurfaceTexture {
  // Returns EGL texture id of the texture.
  GLuint updateTexture();

  // Returns EGL texture id of the underlying texture.
  GLuint getTextureId() const;

  // Returns 4x4 transformation matrix in column-major order,
  // which should be applied to EGL texture coordinates
  // before sampling from the texture backed by android native buffer,
  // so the corresponding region of the underlying buffer is sampled.
  //
  // See SurfaceTexture.getTransformMatrix for more details.
  std::array<float, 16> getTransformMatrix();

 private:
  sp<IGraphicBufferProducer> mBufferProducer;
  sp<IGraphicBufferConsumer> mBufferConsumer;