blob: c8f61f4386052b9001839312e9c544865a70ca29 [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#ifndef ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H
18#define ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H
19
20#include <deque>
21#include <future>
22#include <memory>
23#include <thread>
24
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010025#include "VirtualCameraDevice.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010026#include "VirtualCameraSessionContext.h"
27#include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010028#include "android/binder_auto_utils.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010029#include "util/EglDisplayContext.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010030#include "util/EglFramebuffer.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010031#include "util/EglProgram.h"
32#include "util/EglSurfaceTexture.h"
33
34namespace android {
35namespace companion {
36namespace virtualcamera {
37
38// Represents single output buffer of capture request.
39class CaptureRequestBuffer {
40 public:
41 CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
42
43 int getStreamId() const;
44 int getBufferId() const;
45 sp<Fence> getFence() const;
46
47 private:
48 const int mStreamId;
49 const int mBufferId;
50 const sp<Fence> mFence;
51};
52
53// Represents single capture request to fill set of buffers.
54class ProcessCaptureRequestTask {
55 public:
56 ProcessCaptureRequestTask(
57 int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers);
58
59 // Returns frame number corresponding to the request.
60 int getFrameNumber() const;
61
62 // Get reference to vector describing output buffers corresponding
63 // to this request.
64 //
65 // Note that the vector is owned by the ProcessCaptureRequestTask instance,
66 // so it cannot be access outside of its lifetime.
67 const std::vector<CaptureRequestBuffer>& getBuffers() const;
68
69 private:
70 const int mFrameNumber;
71 const std::vector<CaptureRequestBuffer> mBuffers;
72};
73
74// Wraps dedicated rendering thread and rendering business with corresponding
75// input surface.
76class VirtualCameraRenderThread {
77 public:
78 // Create VirtualCameraRenderThread instance:
79 // * sessionContext - VirtualCameraSessionContext reference for shared access
80 // to mapped buffers.
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010081 // * inputSurfaceSize - requested size of input surface.
82 // * reportedSensorSize - reported static sensor size of virtual camera.
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010083 // * cameraDeviceCallback - callback for corresponding camera instance
84 // * testMode - when set to true, test pattern is rendered to input surface
85 // before each capture request is processed to simulate client input.
86 VirtualCameraRenderThread(
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010087 VirtualCameraSessionContext& sessionContext, Resolution inputSurfaceSize,
88 Resolution reportedSensorSize,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010089 std::shared_ptr<
90 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
91 cameraDeviceCallback,
92 bool testMode = false);
93
94 ~VirtualCameraRenderThread();
95
96 // Start rendering thread.
97 void start();
98 // Stop rendering thread.
99 void stop();
100
101 // Equeue capture task for processing on render thread.
102 void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
103 EXCLUDES(mLock);
104
105 // Flush all in-flight requests.
106 void flush() EXCLUDES(mLock);
107
108 // Returns input surface corresponding to "virtual camera sensor".
109 sp<Surface> getInputSurface();
110
111 private:
112 std::unique_ptr<ProcessCaptureRequestTask> dequeueTask() EXCLUDES(mLock);
113
114 // Rendering thread entry point.
115 void threadLoop();
116
117 // Process single capture request task (always called on render thread).
118 void processCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
119
120 // Flush single capture request task returning the error status immediately.
121 void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
122
123 // TODO(b/301023410) - Refactor the actual rendering logic off this class for
124 // easier testability.
125
126 // Render current image to the BLOB buffer.
127 // If fence is specified, this function will block until the fence is cleared
128 // before writing to the buffer.
129 // Always called on render thread.
130 ndk::ScopedAStatus renderIntoBlobStreamBuffer(const int streamId,
131 const int bufferId,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100132 sp<Fence> fence = nullptr);
133
134 // Render current image to the YCbCr buffer.
135 // If fence is specified, this function will block until the fence is cleared
136 // before writing to the buffer.
137 // Always called on render thread.
138 ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
139 sp<Fence> fence = nullptr);
140
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100141 // Render current image into provided EglFramebuffer.
142 // If fence is specified, this function will block until the fence is cleared
143 // before writing to the buffer.
144 // Always called on the render thread.
145 ndk::ScopedAStatus renderIntoEglFramebuffer(EglFrameBuffer& framebuffer,
146 sp<Fence> fence = nullptr);
147
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100148 // Camera callback
149 const std::shared_ptr<
150 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
151 mCameraDeviceCallback;
152
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100153 const Resolution mInputSurfaceSize;
154 const Resolution mReportedSensorSize;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100155 const int mTestMode;
156
157 VirtualCameraSessionContext& mSessionContext;
158
159 std::thread mThread;
160
161 // Blocking queue implementation.
162 std::mutex mLock;
163 std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
164 std::condition_variable mCondVar;
165 volatile bool mPendingExit GUARDED_BY(mLock);
166
167 // EGL helpers - constructed and accessed only from rendering thread.
168 std::unique_ptr<EglDisplayContext> mEglDisplayContext;
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100169 std::unique_ptr<EglTextureProgram> mEglTextureYuvProgram;
170 std::unique_ptr<EglTextureProgram> mEglTextureRgbProgram;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100171 std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
172
173 std::promise<sp<Surface>> mInputSurfacePromise;
174};
175
176} // namespace virtualcamera
177} // namespace companion
178} // namespace android
179
180#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H