1 /*
2 * Copyright 2024 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "ANativeWindowEmulated.h"
7
8 #include "util/log.h"
9
10 namespace gfxstream {
11
EmulatedANativeWindow(uint32_t width,uint32_t height,uint32_t format,std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers)12 EmulatedANativeWindow::EmulatedANativeWindow(
13 uint32_t width, uint32_t height, uint32_t format,
14 std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers)
15 : mRefCount(1), mWidth(width), mHeight(height), mFormat(format), mBuffers(std::move(buffers)) {
16 for (auto& buffer : mBuffers) {
17 mBufferQueue.push_back(QueuedAHB{
18 .ahb = buffer.get(),
19 .fence = -1,
20 });
21 }
22 }
23
asEglNativeWindowType()24 EGLNativeWindowType EmulatedANativeWindow::asEglNativeWindowType() {
25 return reinterpret_cast<EGLNativeWindowType>(this);
26 }
27
getWidth() const28 uint32_t EmulatedANativeWindow::getWidth() const { return mWidth; }
29
getHeight() const30 uint32_t EmulatedANativeWindow::getHeight() const { return mHeight; }
31
getFormat() const32 int EmulatedANativeWindow::getFormat() const { return mFormat; }
33
queueBuffer(EGLClientBuffer buffer,int fence)34 int EmulatedANativeWindow::queueBuffer(EGLClientBuffer buffer, int fence) {
35 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
36
37 mBufferQueue.push_back(QueuedAHB{
38 .ahb = ahb,
39 .fence = fence,
40 });
41
42 return 0;
43 }
44
dequeueBuffer(EGLClientBuffer * buffer,int * fence)45 int EmulatedANativeWindow::dequeueBuffer(EGLClientBuffer* buffer, int* fence) {
46 auto queuedAhb = mBufferQueue.front();
47 mBufferQueue.pop_front();
48
49 *buffer = queuedAhb.ahb->asEglClientBuffer();
50 *fence = queuedAhb.fence;
51 return 0;
52 }
53
cancelBuffer(EGLClientBuffer buffer)54 int EmulatedANativeWindow::cancelBuffer(EGLClientBuffer buffer) {
55 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
56
57 mBufferQueue.push_back(QueuedAHB{
58 .ahb = ahb,
59 .fence = -1,
60 });
61
62 return 0;
63 }
64
acquire()65 void EmulatedANativeWindow::acquire() { ++mRefCount; }
66
release()67 void EmulatedANativeWindow::release() {
68 --mRefCount;
69 if (mRefCount == 0) {
70 delete this;
71 }
72 }
73
isValid(EGLNativeWindowType window)74 bool EmulatedANativeWindowHelper::isValid(EGLNativeWindowType window) {
75 // TODO: maybe a registry of valid EmulatedANativeWindow-s?
76 (void)window;
77 return true;
78 }
79
isValid(EGLClientBuffer buffer)80 bool EmulatedANativeWindowHelper::isValid(EGLClientBuffer buffer) {
81 // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s?
82 (void)buffer;
83 return true;
84 }
85
acquire(EGLNativeWindowType window)86 void EmulatedANativeWindowHelper::acquire(EGLNativeWindowType window) {
87 auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window);
88 anw->acquire();
89 }
90
release(EGLNativeWindowType window)91 void EmulatedANativeWindowHelper::release(EGLNativeWindowType window) {
92 auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window);
93 anw->release();
94 }
95
acquire(EGLClientBuffer buffer)96 void EmulatedANativeWindowHelper::acquire(EGLClientBuffer buffer) {
97 // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s?
98 (void)buffer;
99 }
100
release(EGLClientBuffer buffer)101 void EmulatedANativeWindowHelper::release(EGLClientBuffer buffer) { (void)buffer; }
102
getConsumerUsage(EGLNativeWindowType window,int * usage)103 int EmulatedANativeWindowHelper::getConsumerUsage(EGLNativeWindowType window, int* usage) {
104 (void)window;
105 (void)usage;
106 return 0;
107 }
setUsage(EGLNativeWindowType window,int usage)108 void EmulatedANativeWindowHelper::setUsage(EGLNativeWindowType window, int usage) {
109 (void)window;
110 (void)usage;
111 }
112
getWidth(EGLNativeWindowType window)113 int EmulatedANativeWindowHelper::getWidth(EGLNativeWindowType window) {
114 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
115 return anw->getWidth();
116 }
117
getHeight(EGLNativeWindowType window)118 int EmulatedANativeWindowHelper::getHeight(EGLNativeWindowType window) {
119 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
120 return anw->getHeight();
121 }
122
getWidth(EGLClientBuffer buffer)123 int EmulatedANativeWindowHelper::getWidth(EGLClientBuffer buffer) {
124 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
125 return ahb->getWidth();
126 }
127
getHeight(EGLClientBuffer buffer)128 int EmulatedANativeWindowHelper::getHeight(EGLClientBuffer buffer) {
129 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
130 return ahb->getHeight();
131 }
132
getFormat(EGLClientBuffer buffer,Gralloc * helper)133 int EmulatedANativeWindowHelper::getFormat(EGLClientBuffer buffer, Gralloc* helper) {
134 (void)helper;
135
136 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
137 return ahb->getAndroidFormat();
138 }
139
setSwapInterval(EGLNativeWindowType window,int interval)140 void EmulatedANativeWindowHelper::setSwapInterval(EGLNativeWindowType window, int interval) {
141 mesa_loge("Unimplemented");
142 (void)window;
143 (void)interval;
144 }
145
queueBuffer(EGLNativeWindowType window,EGLClientBuffer buffer,int fence)146 int EmulatedANativeWindowHelper::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer,
147 int fence) {
148 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
149 return anw->queueBuffer(buffer, fence);
150 }
151
dequeueBuffer(EGLNativeWindowType window,EGLClientBuffer * buffer,int * fence)152 int EmulatedANativeWindowHelper::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer,
153 int* fence) {
154 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
155 return anw->dequeueBuffer(buffer, fence);
156 }
157
cancelBuffer(EGLNativeWindowType window,EGLClientBuffer buffer)158 int EmulatedANativeWindowHelper::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) {
159 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
160 return anw->cancelBuffer(buffer);
161 }
162
getHostHandle(EGLClientBuffer buffer,Gralloc *)163 int EmulatedANativeWindowHelper::getHostHandle(EGLClientBuffer buffer, Gralloc*) {
164 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
165 return ahb->getResourceId();
166 }
167
createNativeWindowForTesting(Gralloc * gralloc,uint32_t width,uint32_t height)168 EGLNativeWindowType EmulatedANativeWindowHelper::createNativeWindowForTesting(Gralloc* gralloc,
169 uint32_t width,
170 uint32_t height) {
171 std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers;
172 for (int i = 0; i < 3; i++) {
173 AHardwareBuffer* ahb = nullptr;
174 if (gralloc->allocate(width, height, GFXSTREAM_AHB_FORMAT_R8G8B8A8_UNORM, -1, &ahb) != 0) {
175 mesa_loge("Failed to allocate gralloc buffer.");
176 return nullptr;
177 }
178 buffers.emplace_back(reinterpret_cast<EmulatedAHardwareBuffer*>(ahb));
179 }
180 return reinterpret_cast<EGLNativeWindowType>(
181 new EmulatedANativeWindow(width, height, GFXSTREAM_AHB_FORMAT_R8G8B8A8_UNORM, std::move(buffers)));
182 }
183
createPlatformANativeWindowHelper()184 ANativeWindowHelper* createPlatformANativeWindowHelper() {
185 return new EmulatedANativeWindowHelper();
186 }
187
188 } // namespace gfxstream
189