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