1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // #define LOG_NDEBUG 0
18 #include "utils/Timers.h"
19 #define LOG_TAG "EglSurfaceTexture"
20 
21 #include <cstdint>
22 
23 #include "EglSurfaceTexture.h"
24 #include "EglUtil.h"
25 #include "GLES/gl.h"
26 #include "gui/BufferQueue.h"
27 #include "gui/GLConsumer.h"
28 #include "gui/IGraphicBufferProducer.h"
29 #include "hardware/gralloc.h"
30 
31 namespace android {
32 namespace companion {
33 namespace virtualcamera {
34 
EglSurfaceTexture(const uint32_t width,const uint32_t height)35 EglSurfaceTexture::EglSurfaceTexture(const uint32_t width, const uint32_t height)
36     : mWidth(width), mHeight(height) {
37   glGenTextures(1, &mTextureId);
38   if (checkEglError("EglSurfaceTexture(): glGenTextures")) {
39     ALOGE("Failed to generate texture");
40     return;
41   }
42   BufferQueue::createBufferQueue(&mBufferProducer, &mBufferConsumer);
43   mGlConsumer = sp<GLConsumer>::make(
44       mBufferConsumer, mTextureId, GLConsumer::TEXTURE_EXTERNAL, false, false);
45   mGlConsumer->setName(String8("VirtualCameraEglSurfaceTexture"));
46   mGlConsumer->setDefaultBufferSize(mWidth, mHeight);
47   mGlConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_TEXTURE);
48   mGlConsumer->setDefaultBufferFormat(AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420);
49 
50   mSurface = sp<Surface>::make(mBufferProducer);
51 }
52 
~EglSurfaceTexture()53 EglSurfaceTexture::~EglSurfaceTexture() {
54   if (mTextureId != 0) {
55     glDeleteTextures(1, &mTextureId);
56   }
57 }
58 
getSurface()59 sp<Surface> EglSurfaceTexture::getSurface() {
60   return mSurface;
61 }
62 
getCurrentBuffer()63 sp<GraphicBuffer> EglSurfaceTexture::getCurrentBuffer() {
64   return mGlConsumer->getCurrentBuffer();
65 }
66 
setFrameAvailableListener(const wp<ConsumerBase::FrameAvailableListener> & listener)67 void EglSurfaceTexture::setFrameAvailableListener(
68     const wp<ConsumerBase::FrameAvailableListener>& listener) {
69   mGlConsumer->setFrameAvailableListener(listener);
70 }
71 
waitForNextFrame(const std::chrono::nanoseconds timeout)72 bool EglSurfaceTexture::waitForNextFrame(const std::chrono::nanoseconds timeout) {
73   return mSurface->waitForNextFrame(mGlConsumer->getFrameNumber(),
74                                     static_cast<nsecs_t>(timeout.count()));
75 }
76 
updateTexture()77 GLuint EglSurfaceTexture::updateTexture() {
78   mGlConsumer->updateTexImage();
79   return mTextureId;
80 }
81 
getTextureId() const82 GLuint EglSurfaceTexture::getTextureId() const {
83   return mTextureId;
84 }
85 
getTransformMatrix()86 std::array<float, 16> EglSurfaceTexture::getTransformMatrix() {
87   std::array<float, 16> matrix;
88   mGlConsumer->getTransformMatrix(matrix.data());
89   return matrix;
90 }
91 
getWidth() const92 uint32_t EglSurfaceTexture::getWidth() const {
93   return mWidth;
94 }
95 
getHeight() const96 uint32_t EglSurfaceTexture::getHeight() const {
97   return mHeight;
98 }
99 
100 }  // namespace virtualcamera
101 }  // namespace companion
102 }  // namespace android
103