blob: 30de7c2e4c68e2643dc9d16ef9f3bb9c3542cfb6 [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
25#include "VirtualCameraSessionContext.h"
26#include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h"
27#include "util/EglDisplayContext.h"
28#include "util/EglProgram.h"
29#include "util/EglSurfaceTexture.h"
30
31namespace android {
32namespace companion {
33namespace virtualcamera {
34
35// Represents single output buffer of capture request.
36class CaptureRequestBuffer {
37 public:
38 CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
39
40 int getStreamId() const;
41 int getBufferId() const;
42 sp<Fence> getFence() const;
43
44 private:
45 const int mStreamId;
46 const int mBufferId;
47 const sp<Fence> mFence;
48};
49
50// Represents single capture request to fill set of buffers.
51class ProcessCaptureRequestTask {
52 public:
53 ProcessCaptureRequestTask(
54 int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers);
55
56 // Returns frame number corresponding to the request.
57 int getFrameNumber() const;
58
59 // Get reference to vector describing output buffers corresponding
60 // to this request.
61 //
62 // Note that the vector is owned by the ProcessCaptureRequestTask instance,
63 // so it cannot be access outside of its lifetime.
64 const std::vector<CaptureRequestBuffer>& getBuffers() const;
65
66 private:
67 const int mFrameNumber;
68 const std::vector<CaptureRequestBuffer> mBuffers;
69};
70
71// Wraps dedicated rendering thread and rendering business with corresponding
72// input surface.
73class VirtualCameraRenderThread {
74 public:
75 // Create VirtualCameraRenderThread instance:
76 // * sessionContext - VirtualCameraSessionContext reference for shared access
77 // to mapped buffers.
78 // * inputWidth - requested width of input surface ("virtual camera sensor")
79 // * inputHeight - requested height of input surface ("virtual camera sensor")
80 // * cameraDeviceCallback - callback for corresponding camera instance
81 // * testMode - when set to true, test pattern is rendered to input surface
82 // before each capture request is processed to simulate client input.
83 VirtualCameraRenderThread(
84 VirtualCameraSessionContext& sessionContext, int inputWidth,
85 int inputHeight,
86 std::shared_ptr<
87 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
88 cameraDeviceCallback,
89 bool testMode = false);
90
91 ~VirtualCameraRenderThread();
92
93 // Start rendering thread.
94 void start();
95 // Stop rendering thread.
96 void stop();
97
98 // Equeue capture task for processing on render thread.
99 void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
100 EXCLUDES(mLock);
101
102 // Flush all in-flight requests.
103 void flush() EXCLUDES(mLock);
104
105 // Returns input surface corresponding to "virtual camera sensor".
106 sp<Surface> getInputSurface();
107
108 private:
109 std::unique_ptr<ProcessCaptureRequestTask> dequeueTask() EXCLUDES(mLock);
110
111 // Rendering thread entry point.
112 void threadLoop();
113
114 // Process single capture request task (always called on render thread).
115 void processCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
116
117 // Flush single capture request task returning the error status immediately.
118 void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
119
120 // TODO(b/301023410) - Refactor the actual rendering logic off this class for
121 // easier testability.
122
123 // Render current image to the BLOB buffer.
124 // If fence is specified, this function will block until the fence is cleared
125 // before writing to the buffer.
126 // Always called on render thread.
127 ndk::ScopedAStatus renderIntoBlobStreamBuffer(const int streamId,
128 const int bufferId,
129 const size_t bufferSize,
130 sp<Fence> fence = nullptr);
131
132 // Render current image to the YCbCr buffer.
133 // If fence is specified, this function will block until the fence is cleared
134 // before writing to the buffer.
135 // Always called on render thread.
136 ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
137 sp<Fence> fence = nullptr);
138
139 // Camera callback
140 const std::shared_ptr<
141 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
142 mCameraDeviceCallback;
143
144 const int mInputSurfaceWidth;
145 const int mInputSurfaceHeight;
146 const int mTestMode;
147
148 VirtualCameraSessionContext& mSessionContext;
149
150 std::thread mThread;
151
152 // Blocking queue implementation.
153 std::mutex mLock;
154 std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
155 std::condition_variable mCondVar;
156 volatile bool mPendingExit GUARDED_BY(mLock);
157
158 // EGL helpers - constructed and accessed only from rendering thread.
159 std::unique_ptr<EglDisplayContext> mEglDisplayContext;
160 std::unique_ptr<EglTextureProgram> mEglTextureProgram;
161 std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
162
163 std::promise<sp<Surface>> mInputSurfacePromise;
164};
165
166} // namespace virtualcamera
167} // namespace companion
168} // namespace android
169
170#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H