TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / graphics / emugl / RenderControl.cpp
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "anbox/graphics/emugl/RenderControl.h"
18 #include "anbox/graphics/emugl/DispatchTables.h"
19 #include "anbox/graphics/emugl/DisplayManager.h"
20 #include "anbox/graphics/emugl/RenderThreadInfo.h"
21 #include "anbox/graphics/emugl/Renderer.h"
22 #include "anbox/graphics/emugl/RendererConfig.h"
23 #include "anbox/graphics/layer_composer.h"
24 #include "anbox/logger.h"
25
26 #include "external/android-emugl/shared/OpenglCodecCommon/ChecksumCalculatorThreadInfo.h"
27 #include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h"
28
29 #include <map>
30 #include <string>
31 #include <sstream>
32
33 static const GLint rendererVersion = 1;
34 static std::shared_ptr<anbox::graphics::LayerComposer> composer;
35 static std::shared_ptr<Renderer> renderer;
36
37 void registerLayerComposer(
38     const std::shared_ptr<anbox::graphics::LayerComposer> &c) {
39   composer = c;
40 }
41
42 void registerRenderer(const std::shared_ptr<Renderer> &r) {
43   renderer = r;
44 }
45
46 static GLint rcGetRendererVersion() { return rendererVersion; }
47
48 static EGLint rcGetEGLVersion(EGLint *major, EGLint *minor) {
49   if (!renderer)
50     return EGL_FALSE;
51
52   *major = static_cast<EGLint>(renderer->getCaps().eglMajor);
53   *minor = static_cast<EGLint>(renderer->getCaps().eglMinor);
54
55   return EGL_TRUE;
56 }
57
58 static std::string filter_extensions(const std::string& extensions, const std::vector<std::string>& whitelist) {
59   std::stringstream approved_extensions;
60   auto extension_list = anbox::utils::string_split(extensions, ' ');
61   for (const auto& ext : extension_list) {
62     if (std::find(whitelist.begin(), whitelist.end(), ext) == whitelist.end())
63       continue;
64
65     if (approved_extensions.tellp() > 0)
66       approved_extensions << " ";
67
68     approved_extensions << ext;
69   }
70   return approved_extensions.str();
71 }
72
73 static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize) {
74   if (!renderer)
75     return 0;
76
77   std::string result = s_egl.eglQueryString(renderer->getDisplay(), name);
78   if (result.empty())
79     return 0;
80
81   if (name == EGL_EXTENSIONS) {
82     // We need to drop a few extensions from the list reported by the driver
83     // as not all are well enough support by our EGL implementation.
84     std::vector<std::string> whitelisted_extensions = {
85       "EGL_KHR_image_base",
86       "EGL_KHR_gl_texture_2D_image",
87     };
88     result = filter_extensions(result, whitelisted_extensions);
89   }
90
91   int len = result.length() + 1;
92   if (!buffer || len > bufferSize) {
93     return -len;
94   }
95
96   strcpy(static_cast<char*>(buffer), result.c_str());
97   return len;
98 }
99
100 static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) {
101   RenderThreadInfo* tInfo = RenderThreadInfo::get();
102   std::string result;
103
104   if (tInfo && tInfo->currContext) {
105     const char* str = nullptr;
106     if (tInfo->currContext->isGL2())
107       str = reinterpret_cast<const char*>(s_gles2.glGetString(name));
108     else
109       str = reinterpret_cast<const char*>(s_gles1.glGetString(name));
110
111     if (str)
112       result += str;
113   }
114
115   // We're forcing version 2.0 no matter what the host provides as
116   // our emulation layer isn't prepared for anything newer (yet).
117   // This goes in parallel with filtering the extension set for
118   // any unwanted extensions. If we don't force the right version
119   // here certain parts of the system will assume API conditions
120   // which aren't met.
121   if (name == GL_VERSION)
122     result = "OpenGL ES 2.0";
123   else if (name == GL_EXTENSIONS) {
124     // We need to drop a few extensions from the list reported by the driver
125     // as not all are well enough support by our GL implementation.
126     std::vector<std::string> whitelisted_extensions = {
127       "GL_OES_EGL_image",
128       "GL_OES_EGL_image_external",
129       "GL_OES_depth24",
130       "GL_OES_depth32",
131       "GL_OES_element_index_uint",
132       "GL_OES_texture_float",
133       "GL_OES_texture_float_linear",
134       "GL_OES_compressed_paletted_texture",
135       "GL_OES_compressed_ETC1_RGB8_texture",
136       "GL_OES_depth_texture",
137       "GL_OES_texture_half_float",
138       "GL_OES_texture_half_float_linear",
139       "GL_OES_packed_depth_stencil",
140       "GL_OES_vertex_half_float",
141       "GL_OES_standard_derivatives",
142       "GL_OES_texture_npot",
143       "GL_OES_rgb8_rgba8",
144     };
145
146     result = filter_extensions(result, whitelisted_extensions);
147   }
148
149   int nextBufferSize = result.size() + 1;
150
151   if (!buffer || nextBufferSize > bufferSize)
152     return -nextBufferSize;
153
154   snprintf(static_cast<char*>(buffer), nextBufferSize, "%s", result.c_str());
155   return nextBufferSize;
156 }
157
158 static EGLint rcGetNumConfigs(uint32_t *p_numAttribs) {
159   int numConfigs = 0, numAttribs = 0;
160
161   renderer->getConfigs()->getPackInfo(&numConfigs, &numAttribs);
162   if (p_numAttribs) {
163     *p_numAttribs = static_cast<uint32_t>(numAttribs);
164   }
165   return numConfigs;
166 }
167
168 static EGLint rcGetConfigs(uint32_t bufSize, GLuint *buffer) {
169   GLuint bufferSize = static_cast<GLuint>(bufSize);
170   return renderer->getConfigs()->packConfigs(bufferSize, buffer);
171 }
172
173 static EGLint rcChooseConfig(EGLint *attribs, uint32_t attribs_size,
174                              uint32_t *configs, uint32_t configs_size) {
175   if (!renderer || attribs_size == 0)
176     return 0;
177
178   return renderer->getConfigs()->chooseConfig(attribs, reinterpret_cast<EGLint *>(configs),
179                                               static_cast<EGLint>(configs_size));
180 }
181
182 static EGLint rcGetFBParam(EGLint param) {
183   if (!renderer)
184     return 0;
185
186   EGLint ret = 0;
187
188   switch (param) {
189     case FB_WIDTH:
190       ret = static_cast<EGLint>(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution());
191       break;
192     case FB_HEIGHT:
193       ret = static_cast<EGLint>(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution());
194       break;
195     case FB_XDPI:
196       ret = 72;  // XXX: should be implemented
197       break;
198     case FB_YDPI:
199       ret = 72;  // XXX: should be implemented
200       break;
201     case FB_FPS:
202       ret = 60;
203       break;
204     case FB_MIN_SWAP_INTERVAL:
205       ret = 1;  // XXX: should be implemented
206       break;
207     case FB_MAX_SWAP_INTERVAL:
208       ret = 1;  // XXX: should be implemented
209       break;
210     default:
211       break;
212   }
213
214   return ret;
215 }
216
217 static uint32_t rcCreateContext(uint32_t config, uint32_t share,
218                                 uint32_t glVersion) {
219   if (!renderer)
220     return 0;
221
222   // To make it consistent with the guest, create GLES2 context when GL
223   // version==2 or 3
224   HandleType ret =
225       renderer->createRenderContext(config, share, glVersion == 2 || glVersion == 3);
226   return ret;
227 }
228
229 static void rcDestroyContext(uint32_t context) {
230   if (!renderer)
231     return;
232
233   renderer->DestroyRenderContext(context);
234 }
235
236 static uint32_t rcCreateWindowSurface(uint32_t config, uint32_t width,
237                                       uint32_t height) {
238   if (!renderer)
239     return 0;
240
241   return renderer->createWindowSurface(config, width, height);
242 }
243
244 static void rcDestroyWindowSurface(uint32_t windowSurface) {
245   if (!renderer)
246     return;
247
248   renderer->DestroyWindowSurface(windowSurface);
249 }
250
251 static uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height,
252                                     GLenum internalFormat) {
253   if (!renderer)
254     return 0;
255
256   return renderer->createColorBuffer(width, height, internalFormat);
257 }
258
259 static int rcOpenColorBuffer2(uint32_t colorbuffer) {
260   if (!renderer)
261     return -1;
262
263   return renderer->openColorBuffer(colorbuffer);
264 }
265
266 // Deprecated, kept for compatibility with old system images only.
267 // Use rcOpenColorBuffer2 instead.
268 static void rcOpenColorBuffer(uint32_t colorbuffer) {
269   (void)rcOpenColorBuffer2(colorbuffer);
270 }
271
272 static void rcCloseColorBuffer(uint32_t colorbuffer) {
273   if (!renderer)
274     return;
275
276   renderer->closeColorBuffer(colorbuffer);
277 }
278
279 static int rcFlushWindowColorBuffer(uint32_t windowSurface) {
280   if (!renderer)
281     return -1;
282
283   if (!renderer->flushWindowSurfaceColorBuffer(windowSurface))
284     return -1;
285
286   return 0;
287 }
288
289 static void rcSetWindowColorBuffer(uint32_t windowSurface,
290                                    uint32_t colorBuffer) {
291   if (!renderer)
292     return;
293
294   renderer->setWindowSurfaceColorBuffer(windowSurface, colorBuffer);
295 }
296
297 static EGLint rcMakeCurrent(uint32_t context, uint32_t drawSurf,
298                             uint32_t readSurf) {
299   if (!renderer)
300     return EGL_FALSE;
301
302   bool ret = renderer->bindContext(context, drawSurf, readSurf);
303
304   return (ret ? EGL_TRUE : EGL_FALSE);
305 }
306
307 static void rcFBPost(uint32_t) { WARNING("Not implemented"); }
308
309 static void rcFBSetSwapInterval(EGLint) {
310   // XXX: TBD - should be implemented
311 }
312
313 static void rcBindTexture(uint32_t colorBuffer) {
314   if (!renderer)
315     return;
316
317   renderer->bindColorBufferToTexture(colorBuffer);
318 }
319
320 static void rcBindRenderbuffer(uint32_t colorBuffer) {
321   if (!renderer)
322     return;
323
324   renderer->bindColorBufferToRenderbuffer(colorBuffer);
325 }
326
327 static EGLint rcColorBufferCacheFlush(uint32_t, EGLint, 
328                                       int) {
329   // XXX: TBD - should be implemented
330   return 0;
331 }
332
333 static void rcReadColorBuffer(uint32_t colorBuffer, GLint x, GLint y,
334                               GLint width, GLint height, GLenum format,
335                               GLenum type, void *pixels) {
336   if (!renderer)
337     return;
338
339   renderer->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
340 }
341
342 static int rcUpdateColorBuffer(uint32_t colorBuffer, GLint x, GLint y,
343                                GLint width, GLint height, GLenum format,
344                                GLenum type, void *pixels) {
345   if (!renderer)
346     return -1;
347
348   renderer->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
349   return 0;
350 }
351
352 static uint32_t rcCreateClientImage(uint32_t context, EGLenum target,
353                                     GLuint buffer) {
354   if (!renderer)
355     return 0;
356
357   return renderer->createClientImage(context, target, buffer);
358 }
359
360 static int rcDestroyClientImage(uint32_t image) {
361   if (!renderer)
362     return 0;
363
364   return renderer->destroyClientImage(image);
365 }
366
367 static void rcSelectChecksumCalculator(uint32_t protocol, uint32_t) {
368   ChecksumCalculatorThreadInfo::setVersion(protocol);
369 }
370
371 int rcGetNumDisplays() {
372   // For now we only support a single display but that single display
373   // will contain more than one display so that we simply spawn up a big
374   // virtual display which should match the real display arrangement
375   // in most cases.
376   return 1;
377 }
378
379 int rcGetDisplayWidth(uint32_t display_id) {
380   (void)display_id;
381   return static_cast<int>(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution());
382 }
383
384 int rcGetDisplayHeight(uint32_t display_id) {
385   (void)display_id;
386   return static_cast<int>(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution());
387 }
388
389 int rcGetDisplayDpiX(uint32_t display_id) {
390   (void)display_id;
391   return 120;
392 }
393
394 int rcGetDisplayDpiY(uint32_t display_id) {
395   (void)display_id;
396   return 120;
397 }
398
399 int rcGetDisplayVsyncPeriod(uint32_t display_id) {
400   (void)display_id;
401   return 1;
402 }
403
404 static std::vector<Renderable> frame_layers;
405
406 bool is_layer_blacklisted(const std::string &name) {
407   static std::vector<std::string> blacklist = {
408       // The 'Sprite' layer is the mouse cursor Android uses as soon
409       // as it has a pointer input device available. We don't want to
410       // display this layer at all but don't have a good way of disabling
411       // the cursor on the Android side yet.
412       "Sprite",
413   };
414   return std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end();
415 }
416
417 void rcPostLayer(const char *name, uint32_t color_buffer, float alpha,
418                  int32_t sourceCropLeft, int32_t sourceCropTop,
419                  int32_t sourceCropRight, int32_t sourceCropBottom,
420                  int32_t displayFrameLeft, int32_t displayFrameTop,
421                  int32_t displayFrameRight, int32_t displayFrameBottom) {
422   Renderable r{
423       name,
424       color_buffer,
425       alpha,
426       {displayFrameLeft, displayFrameTop, displayFrameRight, displayFrameBottom},
427       {sourceCropLeft, sourceCropTop, sourceCropRight, sourceCropBottom}};
428   frame_layers.push_back(r);
429 }
430
431 void rcPostAllLayersDone() {
432   if (composer) composer->submit_layers(frame_layers);
433
434   frame_layers.clear();
435 }
436
437 void initRenderControlContext(renderControl_decoder_context_t *dec) {
438   dec->rcGetRendererVersion = rcGetRendererVersion;
439   dec->rcGetEGLVersion = rcGetEGLVersion;
440   dec->rcQueryEGLString = rcQueryEGLString;
441   dec->rcGetGLString = rcGetGLString;
442   dec->rcGetNumConfigs = rcGetNumConfigs;
443   dec->rcGetConfigs = rcGetConfigs;
444   dec->rcChooseConfig = rcChooseConfig;
445   dec->rcGetFBParam = rcGetFBParam;
446   dec->rcCreateContext = rcCreateContext;
447   dec->rcDestroyContext = rcDestroyContext;
448   dec->rcCreateWindowSurface = rcCreateWindowSurface;
449   dec->rcDestroyWindowSurface = rcDestroyWindowSurface;
450   dec->rcCreateColorBuffer = rcCreateColorBuffer;
451   dec->rcOpenColorBuffer = rcOpenColorBuffer;
452   dec->rcCloseColorBuffer = rcCloseColorBuffer;
453   dec->rcSetWindowColorBuffer = rcSetWindowColorBuffer;
454   dec->rcFlushWindowColorBuffer = rcFlushWindowColorBuffer;
455   dec->rcMakeCurrent = rcMakeCurrent;
456   dec->rcFBPost = rcFBPost;
457   dec->rcFBSetSwapInterval = rcFBSetSwapInterval;
458   dec->rcBindTexture = rcBindTexture;
459   dec->rcBindRenderbuffer = rcBindRenderbuffer;
460   dec->rcColorBufferCacheFlush = rcColorBufferCacheFlush;
461   dec->rcReadColorBuffer = rcReadColorBuffer;
462   dec->rcUpdateColorBuffer = rcUpdateColorBuffer;
463   dec->rcOpenColorBuffer2 = rcOpenColorBuffer2;
464   dec->rcCreateClientImage = rcCreateClientImage;
465   dec->rcDestroyClientImage = rcDestroyClientImage;
466   dec->rcSelectChecksumCalculator = rcSelectChecksumCalculator;
467   dec->rcGetNumDisplays = rcGetNumDisplays;
468   dec->rcGetDisplayWidth = rcGetDisplayWidth;
469   dec->rcGetDisplayHeight = rcGetDisplayHeight;
470   dec->rcGetDisplayDpiX = rcGetDisplayDpiX;
471   dec->rcGetDisplayDpiY = rcGetDisplayDpiY;
472   dec->rcGetDisplayVsyncPeriod = rcGetDisplayVsyncPeriod;
473   dec->rcPostLayer = rcPostLayer;
474   dec->rcPostAllLayersDone = rcPostAllLayersDone;
475 }