• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <iostream>
7 #include <cutils/log.h>
8 
9 #include "drm_fourcc.h"
10 #include "TestingAndroidWsi.h"
11 
12 namespace gfxstream {
13 
14 static constexpr int numFds = 0;
15 static constexpr int numInts = 1;
16 
GlFormatToDrmFormat(uint32_t glFormat)17 std::optional<uint32_t> GlFormatToDrmFormat(uint32_t glFormat) {
18     switch (glFormat) {
19         case kGlRGB:
20             return DRM_FORMAT_BGR888;
21         case kGlRGB565:
22             return DRM_FORMAT_BGR565;
23         case kGlRGBA:
24             return DRM_FORMAT_ABGR8888;
25     }
26     return std::nullopt;
27 }
28 
DrmToVirglFormat(uint32_t drmFormat)29 std::optional<uint32_t> DrmToVirglFormat(uint32_t drmFormat) {
30     switch (drmFormat) {
31         case DRM_FORMAT_ABGR8888:
32             return VIRGL_FORMAT_B8G8R8A8_UNORM;
33         case DRM_FORMAT_BGR888:
34             return VIRGL_FORMAT_R8G8B8_UNORM;
35         case DRM_FORMAT_BGR565:
36             return VIRGL_FORMAT_B5G6R5_UNORM;
37     }
38     return std::nullopt;
39 }
40 
TestingAHardwareBuffer(uint32_t width,uint32_t height,VirtGpuBlobPtr resource)41 TestingAHardwareBuffer::TestingAHardwareBuffer(
42         uint32_t width,
43         uint32_t height,
44         VirtGpuBlobPtr resource)
45     : mWidth(width),
46       mHeight(height),
47       mResource(resource) {
48     mHandle = native_handle_create(numFds, numInts);
49     mHandle->data[0] = mResource->getResourceHandle();
50 }
51 
~TestingAHardwareBuffer()52 TestingAHardwareBuffer::~TestingAHardwareBuffer() {
53     native_handle_close(mHandle);
54 }
55 
getResourceId() const56 uint32_t TestingAHardwareBuffer::getResourceId() const {
57     return mResource->getResourceHandle();
58 }
59 
getWidth() const60 uint32_t TestingAHardwareBuffer::getWidth() const {
61     return mWidth;
62 }
63 
getHeight() const64 uint32_t TestingAHardwareBuffer::getHeight() const {
65     return mHeight;
66 }
67 
getAndroidFormat() const68 int TestingAHardwareBuffer::getAndroidFormat() const {
69     return /*AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM=*/1;
70 }
71 
getDrmFormat() const72 uint32_t TestingAHardwareBuffer::getDrmFormat() const {
73     return DRM_FORMAT_ABGR8888;
74 }
75 
asAHardwareBuffer()76 AHardwareBuffer* TestingAHardwareBuffer::asAHardwareBuffer() {
77     return reinterpret_cast<AHardwareBuffer*>(this);
78 }
79 
asBufferHandle()80 buffer_handle_t TestingAHardwareBuffer::asBufferHandle() {
81     return reinterpret_cast<buffer_handle_t>(mHandle);
82 }
83 
asEglClientBuffer()84 EGLClientBuffer TestingAHardwareBuffer::asEglClientBuffer() {
85     return reinterpret_cast<EGLClientBuffer>(this);
86 }
87 
TestingVirtGpuGralloc()88 TestingVirtGpuGralloc::TestingVirtGpuGralloc() {}
89 
createColorBuffer(void *,int width,int height,uint32_t glFormat)90 uint32_t TestingVirtGpuGralloc::createColorBuffer(
91         void*,
92         int width,
93         int height,
94         uint32_t glFormat) {
95     auto drmFormat = GlFormatToDrmFormat(glFormat);
96     if (!drmFormat) {
97         ALOGE("Unhandled format");
98     }
99 
100     auto ahb = allocate(width, height, *drmFormat);
101 
102     uint32_t hostHandle = ahb->getResourceId();
103     mAllocatedColorBuffers.emplace(hostHandle, std::move(ahb));
104     return hostHandle;
105 }
106 
allocate(uint32_t width,uint32_t height,uint32_t format,uint64_t usage,AHardwareBuffer ** outputAhb)107 int TestingVirtGpuGralloc::allocate(
108         uint32_t width,
109         uint32_t height,
110         uint32_t format,
111         uint64_t usage,
112         AHardwareBuffer** outputAhb) {
113     (void)width;
114     (void)height;
115     (void)format;
116     (void)usage;
117     (void)outputAhb;
118 
119     // TODO: support export flow?
120     ALOGE("Unimplemented");
121 
122     return 0;
123 }
124 
allocate(uint32_t width,uint32_t height,uint32_t format)125 std::unique_ptr<TestingAHardwareBuffer> TestingVirtGpuGralloc::allocate(
126         uint32_t width,
127         uint32_t height,
128         uint32_t format) {
129     ALOGE("Allocating AHB w:%u, h:%u, format %u", width, height, format);
130 
131     auto device = VirtGpuDevice::getInstance();
132     if (!device) {
133         ALOGE("Failed to allocate: no virtio gpu device.");
134         return nullptr;
135     }
136 
137     auto virglFormat = DrmToVirglFormat(format);
138     if (!virglFormat) {
139         std::cout << "Unhandled DRM format:" << format;
140         return nullptr;
141     }
142 
143     auto resource = device->createVirglBlob(width, height, *virglFormat);
144     if (!resource) {
145         ALOGE("Failed to allocate: failed to create virtio resource.");
146         return nullptr;
147     }
148 
149     resource->wait();
150 
151     return std::make_unique<TestingAHardwareBuffer>(width, height, std::move(resource));
152 }
153 
acquire(AHardwareBuffer * ahb)154 void TestingVirtGpuGralloc::acquire(AHardwareBuffer* ahb) {
155     // TODO
156 }
157 
release(AHardwareBuffer * ahb)158 void TestingVirtGpuGralloc::release(AHardwareBuffer* ahb) {
159     // TODO
160 }
161 
getHostHandle(const native_handle_t * handle)162 uint32_t TestingVirtGpuGralloc::getHostHandle(const native_handle_t* handle) {
163     const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle);
164     return ahb->getResourceId();
165 }
166 
getHostHandle(const AHardwareBuffer * handle)167 uint32_t TestingVirtGpuGralloc::getHostHandle(const AHardwareBuffer* handle) {
168     const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle);
169     return ahb->getResourceId();
170 }
171 
getFormat(const native_handle_t * handle)172 int TestingVirtGpuGralloc::getFormat(const native_handle_t* handle) {
173     const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle);
174     return ahb->getAndroidFormat();
175 }
176 
getFormat(const AHardwareBuffer * handle)177 int TestingVirtGpuGralloc::getFormat(const AHardwareBuffer* handle) {
178     const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle);
179     return ahb->getAndroidFormat();
180 }
181 
getFormatDrmFourcc(const AHardwareBuffer * handle)182 uint32_t TestingVirtGpuGralloc::getFormatDrmFourcc(const AHardwareBuffer* handle) {
183     const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle);
184     return ahb->getDrmFormat();
185 }
186 
getAllocatedSize(const native_handle_t *)187 size_t TestingVirtGpuGralloc::getAllocatedSize(const native_handle_t*) {
188     ALOGE("Unimplemented.");
189     return 0;
190 }
191 
getAllocatedSize(const AHardwareBuffer *)192 size_t TestingVirtGpuGralloc::getAllocatedSize(const AHardwareBuffer*) {
193     ALOGE("Unimplemented.");
194     return 0;
195 }
196 
TestingANativeWindow(uint32_t width,uint32_t height,uint32_t format,std::vector<std::unique_ptr<TestingAHardwareBuffer>> buffers)197 TestingANativeWindow::TestingANativeWindow(
198         uint32_t width,
199         uint32_t height,
200         uint32_t format,
201         std::vector<std::unique_ptr<TestingAHardwareBuffer>> buffers)
202     : mWidth(width),
203       mHeight(height),
204       mFormat(format),
205       mBuffers(std::move(buffers)) {
206     for (auto& buffer : mBuffers) {
207         mBufferQueue.push_back(QueuedAHB{
208             .ahb = buffer.get(),
209             .fence = -1,
210         });
211     }
212 }
213 
asEglNativeWindowType()214 EGLNativeWindowType TestingANativeWindow::asEglNativeWindowType() {
215     return reinterpret_cast<EGLNativeWindowType>(this);
216 }
217 
getWidth() const218 uint32_t TestingANativeWindow::getWidth() const {
219     return mWidth;
220 }
221 
getHeight() const222 uint32_t TestingANativeWindow::getHeight() const {
223     return mHeight;
224 }
225 
getFormat() const226 int TestingANativeWindow::getFormat() const {
227     return mFormat;
228 }
229 
queueBuffer(EGLClientBuffer buffer,int fence)230 int TestingANativeWindow::queueBuffer(EGLClientBuffer buffer, int fence) {
231     auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer);
232 
233     mBufferQueue.push_back(QueuedAHB{
234         .ahb = ahb,
235         .fence = fence,
236     });
237 
238     return 0;
239 }
240 
dequeueBuffer(EGLClientBuffer * buffer,int * fence)241 int TestingANativeWindow::dequeueBuffer(EGLClientBuffer* buffer, int* fence) {
242     auto queuedAhb = mBufferQueue.front();
243     mBufferQueue.pop_front();
244 
245     *buffer = queuedAhb.ahb->asEglClientBuffer();
246     *fence = queuedAhb.fence;
247     return 0;
248 }
249 
cancelBuffer(EGLClientBuffer buffer)250 int TestingANativeWindow::cancelBuffer(EGLClientBuffer buffer) {
251     auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer);
252 
253     mBufferQueue.push_back(QueuedAHB{
254         .ahb = ahb,
255         .fence = -1,
256     });
257 
258     return 0;
259 }
260 
isValid(EGLNativeWindowType window)261 bool TestingVirtGpuANativeWindowHelper::isValid(EGLNativeWindowType window) {
262     // TODO: maybe a registry of valid TestingANativeWindow-s?
263     return true;
264 }
265 
isValid(EGLClientBuffer buffer)266 bool TestingVirtGpuANativeWindowHelper::isValid(EGLClientBuffer buffer) {
267     // TODO: maybe a registry of valid TestingAHardwareBuffer-s?
268     return true;
269 }
270 
acquire(EGLNativeWindowType window)271 void TestingVirtGpuANativeWindowHelper::acquire(EGLNativeWindowType window) {
272     // TODO: maybe a registry of valid TestingANativeWindow-s?
273 }
274 
release(EGLNativeWindowType window)275 void TestingVirtGpuANativeWindowHelper::release(EGLNativeWindowType window) {
276     // TODO: maybe a registry of valid TestingANativeWindow-s?
277 }
278 
acquire(EGLClientBuffer buffer)279 void TestingVirtGpuANativeWindowHelper::acquire(EGLClientBuffer buffer) {
280     // TODO: maybe a registry of valid TestingAHardwareBuffer-s?
281 }
282 
release(EGLClientBuffer buffer)283 void TestingVirtGpuANativeWindowHelper::release(EGLClientBuffer buffer) {
284     // TODO: maybe a registry of valid TestingAHardwareBuffer-s?
285 }
286 
getConsumerUsage(EGLNativeWindowType window,int * usage)287 int TestingVirtGpuANativeWindowHelper::getConsumerUsage(EGLNativeWindowType window, int* usage) {
288     (void)window;
289     (void)usage;
290     return 0;
291 }
setUsage(EGLNativeWindowType window,int usage)292 void TestingVirtGpuANativeWindowHelper::setUsage(EGLNativeWindowType window, int usage) {
293     (void)window;
294     (void)usage;
295 }
296 
getWidth(EGLNativeWindowType window)297 int TestingVirtGpuANativeWindowHelper::getWidth(EGLNativeWindowType window) {
298     auto anw = reinterpret_cast<TestingANativeWindow*>(window);
299     return anw->getWidth();
300 }
301 
getHeight(EGLNativeWindowType window)302 int TestingVirtGpuANativeWindowHelper::getHeight(EGLNativeWindowType window) {
303     auto anw = reinterpret_cast<TestingANativeWindow*>(window);
304     return anw->getHeight();
305 }
306 
getWidth(EGLClientBuffer buffer)307 int TestingVirtGpuANativeWindowHelper::getWidth(EGLClientBuffer buffer) {
308     auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer);
309     return ahb->getWidth();
310 }
311 
getHeight(EGLClientBuffer buffer)312 int TestingVirtGpuANativeWindowHelper::getHeight(EGLClientBuffer buffer) {
313     auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer);
314     return ahb->getHeight();
315 }
316 
getFormat(EGLClientBuffer buffer,Gralloc * helper)317 int TestingVirtGpuANativeWindowHelper::getFormat(EGLClientBuffer buffer, Gralloc* helper) {
318     auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer);
319     return ahb->getAndroidFormat();
320 }
321 
setSwapInterval(EGLNativeWindowType window,int interval)322 void TestingVirtGpuANativeWindowHelper::setSwapInterval(EGLNativeWindowType window, int interval) {
323     ALOGE("Unimplemented");
324 }
325 
queueBuffer(EGLNativeWindowType window,EGLClientBuffer buffer,int fence)326 int TestingVirtGpuANativeWindowHelper::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) {
327     auto anw = reinterpret_cast<TestingANativeWindow*>(window);
328     return anw->queueBuffer(buffer, fence);
329 }
330 
dequeueBuffer(EGLNativeWindowType window,EGLClientBuffer * buffer,int * fence)331 int TestingVirtGpuANativeWindowHelper::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) {
332     auto anw = reinterpret_cast<TestingANativeWindow*>(window);
333     return anw->dequeueBuffer(buffer, fence);
334 }
335 
cancelBuffer(EGLNativeWindowType window,EGLClientBuffer buffer)336 int TestingVirtGpuANativeWindowHelper::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) {
337     auto anw = reinterpret_cast<TestingANativeWindow*>(window);
338     return anw->cancelBuffer(buffer);
339 }
340 
getHostHandle(EGLClientBuffer buffer,Gralloc *)341 int TestingVirtGpuANativeWindowHelper::getHostHandle(EGLClientBuffer buffer, Gralloc*) {
342     auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer);
343     return ahb->getResourceId();
344 }
345 
346 }  // namespace gfxstream
347