1 // Copyright 2024 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "ANativeWindowEmulated.h"
16
17 #include <log/log.h>
18
19 namespace gfxstream {
20
EmulatedANativeWindow(uint32_t width,uint32_t height,uint32_t format,std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers)21 EmulatedANativeWindow::EmulatedANativeWindow(
22 uint32_t width, uint32_t height, uint32_t format,
23 std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers)
24 : mRefCount(1), mWidth(width), mHeight(height), mFormat(format), mBuffers(std::move(buffers)) {
25 for (auto& buffer : mBuffers) {
26 mBufferQueue.push_back(QueuedAHB{
27 .ahb = buffer.get(),
28 .fence = -1,
29 });
30 }
31 }
32
asEglNativeWindowType()33 EGLNativeWindowType EmulatedANativeWindow::asEglNativeWindowType() {
34 return reinterpret_cast<EGLNativeWindowType>(this);
35 }
36
getWidth() const37 uint32_t EmulatedANativeWindow::getWidth() const { return mWidth; }
38
getHeight() const39 uint32_t EmulatedANativeWindow::getHeight() const { return mHeight; }
40
getFormat() const41 int EmulatedANativeWindow::getFormat() const { return mFormat; }
42
queueBuffer(EGLClientBuffer buffer,int fence)43 int EmulatedANativeWindow::queueBuffer(EGLClientBuffer buffer, int fence) {
44 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
45
46 mBufferQueue.push_back(QueuedAHB{
47 .ahb = ahb,
48 .fence = fence,
49 });
50
51 return 0;
52 }
53
dequeueBuffer(EGLClientBuffer * buffer,int * fence)54 int EmulatedANativeWindow::dequeueBuffer(EGLClientBuffer* buffer, int* fence) {
55 auto queuedAhb = mBufferQueue.front();
56 mBufferQueue.pop_front();
57
58 *buffer = queuedAhb.ahb->asEglClientBuffer();
59 *fence = queuedAhb.fence;
60 return 0;
61 }
62
cancelBuffer(EGLClientBuffer buffer)63 int EmulatedANativeWindow::cancelBuffer(EGLClientBuffer buffer) {
64 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
65
66 mBufferQueue.push_back(QueuedAHB{
67 .ahb = ahb,
68 .fence = -1,
69 });
70
71 return 0;
72 }
73
acquire()74 void EmulatedANativeWindow::acquire() { ++mRefCount; }
75
release()76 void EmulatedANativeWindow::release() {
77 --mRefCount;
78 if (mRefCount == 0) {
79 delete this;
80 }
81 }
82
isValid(EGLNativeWindowType window)83 bool EmulatedANativeWindowHelper::isValid(EGLNativeWindowType window) {
84 // TODO: maybe a registry of valid EmulatedANativeWindow-s?
85 (void)window;
86 return true;
87 }
88
isValid(EGLClientBuffer buffer)89 bool EmulatedANativeWindowHelper::isValid(EGLClientBuffer buffer) {
90 // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s?
91 (void)buffer;
92 return true;
93 }
94
acquire(EGLNativeWindowType window)95 void EmulatedANativeWindowHelper::acquire(EGLNativeWindowType window) {
96 auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window);
97 anw->acquire();
98 }
99
release(EGLNativeWindowType window)100 void EmulatedANativeWindowHelper::release(EGLNativeWindowType window) {
101 auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window);
102 anw->release();
103 }
104
acquire(EGLClientBuffer buffer)105 void EmulatedANativeWindowHelper::acquire(EGLClientBuffer buffer) {
106 // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s?
107 (void)buffer;
108 }
109
release(EGLClientBuffer buffer)110 void EmulatedANativeWindowHelper::release(EGLClientBuffer buffer) { (void)buffer; }
111
getConsumerUsage(EGLNativeWindowType window,int * usage)112 int EmulatedANativeWindowHelper::getConsumerUsage(EGLNativeWindowType window, int* usage) {
113 (void)window;
114 (void)usage;
115 return 0;
116 }
setUsage(EGLNativeWindowType window,int usage)117 void EmulatedANativeWindowHelper::setUsage(EGLNativeWindowType window, int usage) {
118 (void)window;
119 (void)usage;
120 }
121
getWidth(EGLNativeWindowType window)122 int EmulatedANativeWindowHelper::getWidth(EGLNativeWindowType window) {
123 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
124 return anw->getWidth();
125 }
126
getHeight(EGLNativeWindowType window)127 int EmulatedANativeWindowHelper::getHeight(EGLNativeWindowType window) {
128 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
129 return anw->getHeight();
130 }
131
getWidth(EGLClientBuffer buffer)132 int EmulatedANativeWindowHelper::getWidth(EGLClientBuffer buffer) {
133 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
134 return ahb->getWidth();
135 }
136
getHeight(EGLClientBuffer buffer)137 int EmulatedANativeWindowHelper::getHeight(EGLClientBuffer buffer) {
138 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
139 return ahb->getHeight();
140 }
141
getFormat(EGLClientBuffer buffer,Gralloc * helper)142 int EmulatedANativeWindowHelper::getFormat(EGLClientBuffer buffer, Gralloc* helper) {
143 (void)helper;
144
145 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
146 return ahb->getAndroidFormat();
147 }
148
setSwapInterval(EGLNativeWindowType window,int interval)149 void EmulatedANativeWindowHelper::setSwapInterval(EGLNativeWindowType window, int interval) {
150 ALOGE("Unimplemented");
151 (void)window;
152 (void)interval;
153 }
154
queueBuffer(EGLNativeWindowType window,EGLClientBuffer buffer,int fence)155 int EmulatedANativeWindowHelper::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer,
156 int fence) {
157 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
158 return anw->queueBuffer(buffer, fence);
159 }
160
dequeueBuffer(EGLNativeWindowType window,EGLClientBuffer * buffer,int * fence)161 int EmulatedANativeWindowHelper::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer,
162 int* fence) {
163 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
164 return anw->dequeueBuffer(buffer, fence);
165 }
166
cancelBuffer(EGLNativeWindowType window,EGLClientBuffer buffer)167 int EmulatedANativeWindowHelper::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) {
168 auto anw = reinterpret_cast<EmulatedANativeWindow*>(window);
169 return anw->cancelBuffer(buffer);
170 }
171
getHostHandle(EGLClientBuffer buffer,Gralloc *)172 int EmulatedANativeWindowHelper::getHostHandle(EGLClientBuffer buffer, Gralloc*) {
173 auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer);
174 return ahb->getResourceId();
175 }
176
createNativeWindowForTesting(Gralloc * gralloc,uint32_t width,uint32_t height)177 EGLNativeWindowType EmulatedANativeWindowHelper::createNativeWindowForTesting(Gralloc* gralloc,
178 uint32_t width,
179 uint32_t height) {
180 std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers;
181 for (int i = 0; i < 3; i++) {
182 AHardwareBuffer* ahb = nullptr;
183 if (gralloc->allocate(width, height, GFXSTREAM_AHB_FORMAT_R8G8B8A8_UNORM, -1, &ahb) != 0) {
184 ALOGE("Failed to allocate gralloc buffer.");
185 return nullptr;
186 }
187 buffers.emplace_back(reinterpret_cast<EmulatedAHardwareBuffer*>(ahb));
188 }
189 return reinterpret_cast<EGLNativeWindowType>(
190 new EmulatedANativeWindow(width, height, GFXSTREAM_AHB_FORMAT_R8G8B8A8_UNORM, std::move(buffers)));
191 }
192
createPlatformANativeWindowHelper()193 ANativeWindowHelper* createPlatformANativeWindowHelper() {
194 return new EmulatedANativeWindowHelper();
195 }
196
197 } // namespace gfxstream
198