• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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.#pragma once
14 #include "AndroidWindow.h"
15 
16 #include "AndroidHostCommon.h"
17 
18 #include <errno.h>
19 #include <hardware/gralloc.h>
20 #include <stdio.h>
21 #include <cassert>
22 
23 #define AW_DEBUG 1
24 
25 #define E(fmt,...) \
26     fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
27 
28 #if AW_DEBUG
29 #define D(fmt,...) \
30     fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
31 
32 #else
33 #define D(fmt,...)
34 #endif
35 
36 namespace aemu {
37 
38 // Declarations for the ANativeWindow implementation.
39 
40 static int hook_setSwapInterval(struct ANativeWindow* window, int interval);
41 static int hook_dequeueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer);
42 static int hook_lockBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
43 static int hook_queueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
44 static int hook_query(const struct ANativeWindow* window, int what, int* value);
45 static int hook_perform(struct ANativeWindow* window, int operation, ... );
46 static int hook_cancelBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
47 static int hook_dequeueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer, int* fenceFd);
48 static int hook_queueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd);
49 static int hook_cancelBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd);
50 static void hook_incRef(struct android_native_base_t* common);
51 static void hook_decRef(struct android_native_base_t* common);
52 
AndroidWindow(int _width,int _height)53 AndroidWindow::AndroidWindow(int _width, int _height)
54     : width(_width), height(_height) {
55     // Initialize the ANativeWindow function pointers.
56     ANativeWindow::setSwapInterval = hook_setSwapInterval;
57     ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
58     ANativeWindow::cancelBuffer = hook_cancelBuffer;
59     ANativeWindow::queueBuffer = hook_queueBuffer;
60     ANativeWindow::query = hook_query;
61     ANativeWindow::perform = hook_perform;
62 
63     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
64     ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
65     ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
66     ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
67 
68     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
69     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
70 
71     common.incRef = hook_incRef;
72     common.decRef = hook_decRef;
73 }
74 
setProducer(AndroidBufferQueue * _fromProducer,AndroidBufferQueue * _toProducer)75 void AndroidWindow::setProducer(AndroidBufferQueue* _fromProducer,
76                                 AndroidBufferQueue* _toProducer) {
77     fromProducer = _fromProducer;
78     toProducer = _toProducer;
79 }
80 
dequeueBuffer(ANativeWindowBuffer ** buffer,int * fenceFd)81 int AndroidWindow::dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd) {
82     assert(fromProducer);
83     AndroidBufferQueue::Item item;
84     fromProducer->dequeueBuffer(&item);
85     *buffer = item.buffer;
86     if (fenceFd)
87         *fenceFd = item.fenceFd;
88     return 0;
89 }
90 
queueBuffer(ANativeWindowBuffer * buffer,int fenceFd)91 int AndroidWindow::queueBuffer(ANativeWindowBuffer* buffer, int fenceFd) {
92     assert(toProducer);
93     toProducer->queueBuffer({buffer, fenceFd});
94     return 0;
95 }
96 
cancelBuffer(ANativeWindowBuffer * buffer,int fenceFd)97 int AndroidWindow::cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd) {
98     assert(toProducer);
99     fromProducer->cancelBuffer({buffer, fenceFd});
100     return 0;
101 }
102 
query(int what,int * value) const103 int AndroidWindow::query(int what, int* value) const {
104     switch (what) {
105         case ANATIVEWINDOW_QUERY_DEFAULT_WIDTH:
106         case NATIVE_WINDOW_WIDTH:
107             *value = width;
108             break;
109         case ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT:
110         case NATIVE_WINDOW_HEIGHT:
111             *value = height;
112             break;
113         case NATIVE_WINDOW_FORMAT:
114             *value = HAL_PIXEL_FORMAT_RGBA_8888;
115             break;
116         case NATIVE_WINDOW_TRANSFORM_HINT:
117             *value = 0;
118             break;
119         case NATIVE_WINDOW_MAX_BUFFER_COUNT:
120             *value = 2;
121             break;
122         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
123             *value = 2;
124             break;
125 
126         case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
127         case NATIVE_WINDOW_CONCRETE_TYPE:
128         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
129         case NATIVE_WINDOW_BUFFER_AGE:
130         case NATIVE_WINDOW_LAST_DEQUEUE_DURATION:
131         case NATIVE_WINDOW_LAST_QUEUE_DURATION:
132         case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT:
133         case NATIVE_WINDOW_IS_VALID:
134         case NATIVE_WINDOW_DATASPACE:
135         default:
136             E("Unknown query 0x%x, not implemented.", what);
137             return -EINVAL;
138     }
139     return 0;
140 }
141 
perform(int operation,va_list args)142 int AndroidWindow::perform(int operation, va_list args)
143 {
144     int res = 0;
145     switch (operation) {
146     case NATIVE_WINDOW_CONNECT:
147         // deprecated. must return NO_ERROR.
148         break;
149     case NATIVE_WINDOW_DISCONNECT:
150         // deprecated. must return NO_ERROR.
151         break;
152     case NATIVE_WINDOW_GET_CONSUMER_USAGE64: {
153         uint64_t* usage = va_arg(args, uint64_t*);
154         *usage =
155             GRALLOC_USAGE_HW_TEXTURE |
156             GRALLOC_USAGE_HW_RENDER;
157         va_end(args);
158         break;
159     }
160     case NATIVE_WINDOW_API_CONNECT:
161     case NATIVE_WINDOW_API_DISCONNECT: {
162         break;
163     }
164     case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT: {
165         bool* outSupport = va_arg(args, bool*);
166         *outSupport = false;
167         va_end(args);
168         break;
169     }
170     case NATIVE_WINDOW_SET_BUFFER_COUNT: {
171         size_t bufferCount = va_arg(args, size_t);
172         va_end(args);
173         break;
174     }
175     case NATIVE_WINDOW_SET_AUTO_REFRESH:
176     case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
177     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
178     case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
179     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
180     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
181     case NATIVE_WINDOW_SET_SCALING_MODE:
182     case NATIVE_WINDOW_SET_USAGE:
183     case NATIVE_WINDOW_SET_USAGE64:
184     case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION:
185     case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
186         break;
187     case NATIVE_WINDOW_SET_CROP:
188     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
189     case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
190     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
191     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
192     case NATIVE_WINDOW_LOCK:
193     case NATIVE_WINDOW_UNLOCK_AND_POST:
194     case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
195     case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA:
196     case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
197     // case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
198     case NATIVE_WINDOW_GET_NEXT_FRAME_ID:
199     case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS:
200     case NATIVE_WINDOW_GET_COMPOSITOR_TIMING:
201     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
202     case NATIVE_WINDOW_GET_HDR_SUPPORT:
203 
204     default:
205         E("Unknown perform 0x%x, not implemented.", operation);
206         res = -EINVAL;
207         break;
208     }
209     return res;
210 }
211 
212 // Android native window implementation
hook_setSwapInterval(struct ANativeWindow * window,int interval)213 static int hook_setSwapInterval(struct ANativeWindow* window, int interval) {
214     AndroidWindow* aw = AndroidWindow::getSelf(window);
215     aw->swapInterval = interval;
216     return 0;
217 }
218 
hook_dequeueBuffer_DEPRECATED(struct ANativeWindow * window,struct ANativeWindowBuffer ** buffer)219 static int hook_dequeueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer) {
220     AndroidWindow* aw = AndroidWindow::getSelf(window);
221     return aw->dequeueBuffer(buffer, nullptr);
222 }
223 
hook_lockBuffer_DEPRECATED(struct ANativeWindow * window,struct ANativeWindowBuffer * buffer)224 static int hook_lockBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer) {
225     E("Not implemented");
226     return 0;
227 }
228 
hook_queueBuffer_DEPRECATED(struct ANativeWindow * window,struct ANativeWindowBuffer * buffer)229 static int hook_queueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer) {
230     E("Not implemented");
231     return 0;
232 }
233 
hook_query(const struct ANativeWindow * window,int what,int * value)234 static int hook_query(const struct ANativeWindow* window, int what, int* value) {
235     const AndroidWindow* aw = AndroidWindow::getSelfConst(window);
236     return aw->query(what, value);
237 }
238 
hook_perform(struct ANativeWindow * window,int operation,...)239 static int hook_perform(struct ANativeWindow* window, int operation, ... ) {
240     va_list args;
241     va_start(args, operation);
242     AndroidWindow* w = AndroidWindow::getSelf(window);
243     int result = w->perform(operation, args);
244     va_end(args);
245     return result;
246 }
247 
hook_cancelBuffer_DEPRECATED(struct ANativeWindow * window,struct ANativeWindowBuffer * buffer)248 static int hook_cancelBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer) {
249     E("Not implemented");
250     return 0;
251 }
252 
hook_dequeueBuffer(struct ANativeWindow * window,struct ANativeWindowBuffer ** buffer,int * fenceFd)253 static int hook_dequeueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer, int* fenceFd) {
254     AndroidWindow* aw = AndroidWindow::getSelf(window);
255     return aw->dequeueBuffer(buffer, fenceFd);
256 }
257 
hook_queueBuffer(struct ANativeWindow * window,struct ANativeWindowBuffer * buffer,int fenceFd)258 static int hook_queueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd) {
259     AndroidWindow* aw = AndroidWindow::getSelf(window);
260     return aw->queueBuffer(buffer, fenceFd);
261 }
262 
hook_cancelBuffer(struct ANativeWindow * window,struct ANativeWindowBuffer * buffer,int fenceFd)263 static int hook_cancelBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd) {
264     AndroidWindow* aw = AndroidWindow::getSelf(window);
265     return aw->cancelBuffer(buffer, fenceFd);
266 }
267 
hook_incRef(struct android_native_base_t * common)268 static void hook_incRef(struct android_native_base_t* common) {
269 }
270 
hook_decRef(struct android_native_base_t * common)271 static void hook_decRef(struct android_native_base_t* common) {
272 }
273 
274 } // namespace aemu
275 
276 extern "C" {
277 
create_host_anativewindow(int width,int height)278 EXPORT ANativeWindow* create_host_anativewindow(int width, int height) {
279     aemu::AndroidWindow* res =
280         new aemu::AndroidWindow(width, height);
281 
282     return (ANativeWindow*)res;
283 }
284 
destroy_host_anativewindow(ANativeWindow * window)285 EXPORT void destroy_host_anativewindow(ANativeWindow* window) {
286     delete aemu::AndroidWindow::getSelf(window);
287 }
288 
289 } // extern "C"
290