blob: be36ec404086c3fbdaddaa6672acb4522b1a1604 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
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
Vadim Caenb79f4e32024-08-30 16:35:33 +020018#include <chrono>
19
Jan Sebechlebskyb8282672024-05-22 10:43:37 +020020#include "utils/Timers.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010021#define LOG_TAG "EglSurfaceTexture"
22
Jim Shargo2e0202f2024-07-30 19:54:43 +000023#include <GLES/gl.h>
24#include <com_android_graphics_libgui_flags.h>
25#include <gui/BufferQueue.h>
26#include <gui/GLConsumer.h>
27#include <gui/IGraphicBufferProducer.h>
28#include <hardware/gralloc.h>
29
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010030#include <cstdint>
31
32#include "EglSurfaceTexture.h"
33#include "EglUtil.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010034
35namespace android {
36namespace companion {
37namespace virtualcamera {
Jan Sebechlebsky759f0a82024-07-02 15:33:16 +020038namespace {
39
40// Maximal number of buffers producer can dequeue without blocking.
41constexpr int kBufferProducerMaxDequeueBufferCount = 64;
42
43} // namespace
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010044
45EglSurfaceTexture::EglSurfaceTexture(const uint32_t width, const uint32_t height)
46 : mWidth(width), mHeight(height) {
47 glGenTextures(1, &mTextureId);
48 if (checkEglError("EglSurfaceTexture(): glGenTextures")) {
49 ALOGE("Failed to generate texture");
50 return;
51 }
Jim Shargo2e0202f2024-07-30 19:54:43 +000052
53#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
54 mGlConsumer = sp<GLConsumer>::make(mTextureId, GLConsumer::TEXTURE_EXTERNAL,
55 false, false);
56 mGlConsumer->setName(String8("VirtualCameraEglSurfaceTexture"));
57 mGlConsumer->setDefaultBufferSize(mWidth, mHeight);
58 mGlConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_TEXTURE);
59 mGlConsumer->setDefaultBufferFormat(AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420);
60
61 mSurface = mGlConsumer->getSurface();
62 mSurface->setMaxDequeuedBufferCount(kBufferProducerMaxDequeueBufferCount);
63#else
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010064 BufferQueue::createBufferQueue(&mBufferProducer, &mBufferConsumer);
Jan Sebechlebsky759f0a82024-07-02 15:33:16 +020065 // Set max dequeue buffer count for producer to maximal value to prevent
66 // blocking when dequeuing input buffers.
67 mBufferProducer->setMaxDequeuedBufferCount(
68 kBufferProducerMaxDequeueBufferCount);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010069 mGlConsumer = sp<GLConsumer>::make(
70 mBufferConsumer, mTextureId, GLConsumer::TEXTURE_EXTERNAL, false, false);
71 mGlConsumer->setName(String8("VirtualCameraEglSurfaceTexture"));
72 mGlConsumer->setDefaultBufferSize(mWidth, mHeight);
73 mGlConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_TEXTURE);
74 mGlConsumer->setDefaultBufferFormat(AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420);
75
76 mSurface = sp<Surface>::make(mBufferProducer);
Jim Shargo2e0202f2024-07-30 19:54:43 +000077#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010078}
79
80EglSurfaceTexture::~EglSurfaceTexture() {
81 if (mTextureId != 0) {
82 glDeleteTextures(1, &mTextureId);
83 }
84}
85
86sp<Surface> EglSurfaceTexture::getSurface() {
87 return mSurface;
88}
89
90sp<GraphicBuffer> EglSurfaceTexture::getCurrentBuffer() {
91 return mGlConsumer->getCurrentBuffer();
92}
93
Jan Sebechlebsky18ac32c2024-06-07 09:53:53 +020094void EglSurfaceTexture::setFrameAvailableListener(
95 const wp<ConsumerBase::FrameAvailableListener>& listener) {
96 mGlConsumer->setFrameAvailableListener(listener);
97}
98
Jan Sebechlebskyb8282672024-05-22 10:43:37 +020099bool EglSurfaceTexture::waitForNextFrame(const std::chrono::nanoseconds timeout) {
100 return mSurface->waitForNextFrame(mGlConsumer->getFrameNumber(),
101 static_cast<nsecs_t>(timeout.count()));
102}
103
Vadim Caenb79f4e32024-08-30 16:35:33 +0200104std::chrono::nanoseconds EglSurfaceTexture::getTimestamp() {
105 return std::chrono::nanoseconds(mGlConsumer->getTimestamp());
106}
107
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100108GLuint EglSurfaceTexture::updateTexture() {
Jan Sebechlebsky759f0a82024-07-02 15:33:16 +0200109 int previousFrameId;
110 int framesAdvance = 0;
111 // Consume buffers one at the time.
112 // Contrary to the code comments in GLConsumer, the GLConsumer acquires
113 // next queued buffer (not the most recently queued buffer).
114 while (true) {
115 previousFrameId = mGlConsumer->getFrameNumber();
116 mGlConsumer->updateTexImage();
117 int currentFrameId = mGlConsumer->getFrameNumber();
118 if (previousFrameId == currentFrameId) {
119 // Frame number didn't change after updating the texture,
120 // this means we're at the end of the queue and current attached
121 // buffer is the most recent buffer.
122 break;
123 }
124
125 framesAdvance++;
126 previousFrameId = currentFrameId;
127 }
128 ALOGV("%s: Advanced %d frames", __func__, framesAdvance);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100129 return mTextureId;
130}
131
Jan Sebechlebsky99492e32023-12-20 09:49:45 +0100132GLuint EglSurfaceTexture::getTextureId() const {
133 return mTextureId;
134}
135
136std::array<float, 16> EglSurfaceTexture::getTransformMatrix() {
137 std::array<float, 16> matrix;
138 mGlConsumer->getTransformMatrix(matrix.data());
139 return matrix;
140}
141
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100142uint32_t EglSurfaceTexture::getWidth() const {
143 return mWidth;
144}
145
146uint32_t EglSurfaceTexture::getHeight() const {
147 return mHeight;
148}
149
150} // namespace virtualcamera
151} // namespace companion
152} // namespace android