Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

platform_android.c 51KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  1. /*
  2. * Mesa 3-D graphics library
  3. *
  4. * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
  5. * Copyright (C) 2010-2011 LunarG Inc.
  6. *
  7. * Based on platform_x11, which has
  8. *
  9. * Copyright © 2011 Intel Corporation
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a
  12. * copy of this software and associated documentation files (the "Software"),
  13. * to deal in the Software without restriction, including without limitation
  14. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  15. * and/or sell copies of the Software, and to permit persons to whom the
  16. * Software is furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included
  19. * in all copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  24. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  26. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  27. * DEALINGS IN THE SOFTWARE.
  28. */
  29. #include <cutils/properties.h>
  30. #include <errno.h>
  31. #include <dirent.h>
  32. #include <dlfcn.h>
  33. #include <fcntl.h>
  34. #include <xf86drm.h>
  35. #include <stdbool.h>
  36. #include <stdio.h>
  37. #include <sync/sync.h>
  38. #include <sys/types.h>
  39. #include "loader.h"
  40. #include "egl_dri2.h"
  41. #include "egl_dri2_fallbacks.h"
  42. #ifdef HAVE_DRM_GRALLOC
  43. #include <gralloc_drm_handle.h>
  44. #include "gralloc_drm.h"
  45. #endif /* HAVE_DRM_GRALLOC */
  46. #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
  47. enum chroma_order {
  48. YCbCr,
  49. YCrCb,
  50. };
  51. struct droid_yuv_format {
  52. /* Lookup keys */
  53. int native; /* HAL_PIXEL_FORMAT_ */
  54. enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */
  55. int chroma_step; /* Distance in bytes between subsequent chroma pixels. */
  56. /* Result */
  57. int fourcc; /* __DRI_IMAGE_FOURCC_ */
  58. };
  59. /* The following table is used to look up a DRI image FourCC based
  60. * on native format and information contained in android_ycbcr struct. */
  61. static const struct droid_yuv_format droid_yuv_formats[] = {
  62. /* Native format, YCrCb, Chroma step, DRI image FourCC */
  63. { HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 2, __DRI_IMAGE_FOURCC_NV12 },
  64. { HAL_PIXEL_FORMAT_YCbCr_420_888, YCbCr, 1, __DRI_IMAGE_FOURCC_YUV420 },
  65. { HAL_PIXEL_FORMAT_YCbCr_420_888, YCrCb, 1, __DRI_IMAGE_FOURCC_YVU420 },
  66. { HAL_PIXEL_FORMAT_YV12, YCrCb, 1, __DRI_IMAGE_FOURCC_YVU420 },
  67. /* HACK: See droid_create_image_from_prime_fd() and
  68. * https://issuetracker.google.com/32077885. */
  69. { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 2, __DRI_IMAGE_FOURCC_NV12 },
  70. { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCbCr, 1, __DRI_IMAGE_FOURCC_YUV420 },
  71. { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, __DRI_IMAGE_FOURCC_YVU420 },
  72. { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, __DRI_IMAGE_FOURCC_AYUV },
  73. { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, YCrCb, 1, __DRI_IMAGE_FOURCC_XYUV8888 },
  74. };
  75. static int
  76. get_fourcc_yuv(int native, enum chroma_order chroma_order, int chroma_step)
  77. {
  78. for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i)
  79. if (droid_yuv_formats[i].native == native &&
  80. droid_yuv_formats[i].chroma_order == chroma_order &&
  81. droid_yuv_formats[i].chroma_step == chroma_step)
  82. return droid_yuv_formats[i].fourcc;
  83. return -1;
  84. }
  85. static bool
  86. is_yuv(int native)
  87. {
  88. for (int i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i)
  89. if (droid_yuv_formats[i].native == native)
  90. return true;
  91. return false;
  92. }
  93. static int
  94. get_format_bpp(int native)
  95. {
  96. int bpp;
  97. switch (native) {
  98. case HAL_PIXEL_FORMAT_RGBA_8888:
  99. case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
  100. /*
  101. * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack.
  102. * TODO: Remove this once https://issuetracker.google.com/32077885 is fixed.
  103. */
  104. case HAL_PIXEL_FORMAT_RGBX_8888:
  105. case HAL_PIXEL_FORMAT_BGRA_8888:
  106. bpp = 4;
  107. break;
  108. case HAL_PIXEL_FORMAT_RGB_565:
  109. bpp = 2;
  110. break;
  111. default:
  112. bpp = 0;
  113. break;
  114. }
  115. return bpp;
  116. }
  117. /* createImageFromFds requires fourcc format */
  118. static int get_fourcc(int native)
  119. {
  120. switch (native) {
  121. case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FOURCC_RGB565;
  122. case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FOURCC_ARGB8888;
  123. case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FOURCC_ABGR8888;
  124. case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
  125. /*
  126. * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack.
  127. * TODO: Remove this once https://issuetracker.google.com/32077885 is fixed.
  128. */
  129. case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FOURCC_XBGR8888;
  130. default:
  131. _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", native);
  132. }
  133. return -1;
  134. }
  135. static int get_format(int format)
  136. {
  137. switch (format) {
  138. case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FORMAT_ARGB8888;
  139. case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FORMAT_RGB565;
  140. case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FORMAT_ABGR8888;
  141. case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
  142. /*
  143. * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack.
  144. * TODO: Revert this once https://issuetracker.google.com/32077885 is fixed.
  145. */
  146. case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FORMAT_XBGR8888;
  147. default:
  148. _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", format);
  149. }
  150. return -1;
  151. }
  152. static int
  153. get_native_buffer_fd(struct ANativeWindowBuffer *buf)
  154. {
  155. native_handle_t *handle = (native_handle_t *)buf->handle;
  156. /*
  157. * Various gralloc implementations exist, but the dma-buf fd tends
  158. * to be first. Access it directly to avoid a dependency on specific
  159. * gralloc versions.
  160. */
  161. return (handle && handle->numFds) ? handle->data[0] : -1;
  162. }
  163. #ifdef HAVE_DRM_GRALLOC
  164. static int
  165. get_native_buffer_name(struct ANativeWindowBuffer *buf)
  166. {
  167. return gralloc_drm_get_gem_handle(buf->handle);
  168. }
  169. #endif /* HAVE_DRM_GRALLOC */
  170. static EGLBoolean
  171. droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
  172. {
  173. int fence_fd;
  174. if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer,
  175. &fence_fd))
  176. return EGL_FALSE;
  177. /* If access to the buffer is controlled by a sync fence, then block on the
  178. * fence.
  179. *
  180. * It may be more performant to postpone blocking until there is an
  181. * immediate need to write to the buffer. But doing so would require adding
  182. * hooks to the DRI2 loader.
  183. *
  184. * From the ANativeWindow::dequeueBuffer documentation:
  185. *
  186. * The libsync fence file descriptor returned in the int pointed to by
  187. * the fenceFd argument will refer to the fence that must signal
  188. * before the dequeued buffer may be written to. A value of -1
  189. * indicates that the caller may access the buffer immediately without
  190. * waiting on a fence. If a valid file descriptor is returned (i.e.
  191. * any value except -1) then the caller is responsible for closing the
  192. * file descriptor.
  193. */
  194. if (fence_fd >= 0) {
  195. /* From the SYNC_IOC_WAIT documentation in <linux/sync.h>:
  196. *
  197. * Waits indefinitely if timeout < 0.
  198. */
  199. int timeout = -1;
  200. sync_wait(fence_fd, timeout);
  201. close(fence_fd);
  202. }
  203. dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common);
  204. /* Record all the buffers created by ANativeWindow and update back buffer
  205. * for updating buffer's age in swap_buffers.
  206. */
  207. EGLBoolean updated = EGL_FALSE;
  208. for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  209. if (!dri2_surf->color_buffers[i].buffer) {
  210. dri2_surf->color_buffers[i].buffer = dri2_surf->buffer;
  211. }
  212. if (dri2_surf->color_buffers[i].buffer == dri2_surf->buffer) {
  213. dri2_surf->back = &dri2_surf->color_buffers[i];
  214. updated = EGL_TRUE;
  215. break;
  216. }
  217. }
  218. if (!updated) {
  219. /* In case of all the buffers were recreated by ANativeWindow, reset
  220. * the color_buffers
  221. */
  222. for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  223. dri2_surf->color_buffers[i].buffer = NULL;
  224. dri2_surf->color_buffers[i].age = 0;
  225. }
  226. dri2_surf->color_buffers[0].buffer = dri2_surf->buffer;
  227. dri2_surf->back = &dri2_surf->color_buffers[0];
  228. }
  229. return EGL_TRUE;
  230. }
  231. static EGLBoolean
  232. droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf)
  233. {
  234. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  235. /* To avoid blocking other EGL calls, release the display mutex before
  236. * we enter droid_window_enqueue_buffer() and re-acquire the mutex upon
  237. * return.
  238. */
  239. mtx_unlock(&disp->Mutex);
  240. /* Queue the buffer with stored out fence fd. The ANativeWindow or buffer
  241. * consumer may choose to wait for the fence to signal before accessing
  242. * it. If fence fd value is -1, buffer can be accessed by consumer
  243. * immediately. Consumer or application shouldn't rely on timestamp
  244. * associated with fence if the fence fd is -1.
  245. *
  246. * Ownership of fd is transferred to consumer after queueBuffer and the
  247. * consumer is responsible for closing it. Caller must not use the fd
  248. * after passing it to queueBuffer.
  249. */
  250. int fence_fd = dri2_surf->out_fence_fd;
  251. dri2_surf->out_fence_fd = -1;
  252. dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer,
  253. fence_fd);
  254. dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common);
  255. dri2_surf->buffer = NULL;
  256. dri2_surf->back = NULL;
  257. mtx_lock(&disp->Mutex);
  258. if (dri2_surf->dri_image_back) {
  259. dri2_dpy->image->destroyImage(dri2_surf->dri_image_back);
  260. dri2_surf->dri_image_back = NULL;
  261. }
  262. return EGL_TRUE;
  263. }
  264. static void
  265. droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf)
  266. {
  267. int ret;
  268. int fence_fd = dri2_surf->out_fence_fd;
  269. dri2_surf->out_fence_fd = -1;
  270. ret = dri2_surf->window->cancelBuffer(dri2_surf->window,
  271. dri2_surf->buffer, fence_fd);
  272. if (ret < 0) {
  273. _eglLog(_EGL_WARNING, "ANativeWindow::cancelBuffer failed");
  274. dri2_surf->base.Lost = EGL_TRUE;
  275. }
  276. }
  277. static bool
  278. droid_set_shared_buffer_mode(_EGLDisplay *disp, _EGLSurface *surf, bool mode)
  279. {
  280. #if ANDROID_API_LEVEL >= 24
  281. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  282. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  283. struct ANativeWindow *window = dri2_surf->window;
  284. assert(surf->Type == EGL_WINDOW_BIT);
  285. assert(_eglSurfaceHasMutableRenderBuffer(&dri2_surf->base));
  286. _eglLog(_EGL_DEBUG, "%s: mode=%d", __func__, mode);
  287. if (native_window_set_shared_buffer_mode(window, mode)) {
  288. _eglLog(_EGL_WARNING, "failed native_window_set_shared_buffer_mode"
  289. "(window=%p, mode=%d)", window, mode);
  290. return false;
  291. }
  292. return true;
  293. #else
  294. _eglLog(_EGL_FATAL, "%s:%d: internal error: unreachable", __FILE__, __LINE__);
  295. return false;
  296. #endif
  297. }
  298. static _EGLSurface *
  299. droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
  300. _EGLConfig *conf, void *native_window,
  301. const EGLint *attrib_list)
  302. {
  303. __DRIcreateNewDrawableFunc createNewDrawable;
  304. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  305. struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
  306. struct dri2_egl_surface *dri2_surf;
  307. struct ANativeWindow *window = native_window;
  308. const __DRIconfig *config;
  309. dri2_surf = calloc(1, sizeof *dri2_surf);
  310. if (!dri2_surf) {
  311. _eglError(EGL_BAD_ALLOC, "droid_create_surface");
  312. return NULL;
  313. }
  314. if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, true))
  315. goto cleanup_surface;
  316. if (type == EGL_WINDOW_BIT) {
  317. int format;
  318. if (window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
  319. _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
  320. goto cleanup_surface;
  321. }
  322. if (window->query(window, NATIVE_WINDOW_FORMAT, &format)) {
  323. _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
  324. goto cleanup_surface;
  325. }
  326. if (format != dri2_conf->base.NativeVisualID) {
  327. _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x",
  328. format, dri2_conf->base.NativeVisualID);
  329. }
  330. window->query(window, NATIVE_WINDOW_WIDTH, &dri2_surf->base.Width);
  331. window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height);
  332. }
  333. config = dri2_get_dri_config(dri2_conf, type,
  334. dri2_surf->base.GLColorspace);
  335. if (!config) {
  336. _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
  337. goto cleanup_surface;
  338. }
  339. if (dri2_dpy->image_driver)
  340. createNewDrawable = dri2_dpy->image_driver->createNewDrawable;
  341. else
  342. createNewDrawable = dri2_dpy->dri2->createNewDrawable;
  343. dri2_surf->dri_drawable = (*createNewDrawable)(dri2_dpy->dri_screen, config,
  344. dri2_surf);
  345. if (dri2_surf->dri_drawable == NULL) {
  346. _eglError(EGL_BAD_ALLOC, "createNewDrawable");
  347. goto cleanup_surface;
  348. }
  349. if (window) {
  350. window->common.incRef(&window->common);
  351. dri2_surf->window = window;
  352. }
  353. return &dri2_surf->base;
  354. cleanup_surface:
  355. free(dri2_surf);
  356. return NULL;
  357. }
  358. static _EGLSurface *
  359. droid_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
  360. _EGLConfig *conf, void *native_window,
  361. const EGLint *attrib_list)
  362. {
  363. return droid_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
  364. native_window, attrib_list);
  365. }
  366. static _EGLSurface *
  367. droid_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
  368. _EGLConfig *conf, const EGLint *attrib_list)
  369. {
  370. return droid_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
  371. NULL, attrib_list);
  372. }
  373. static EGLBoolean
  374. droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
  375. {
  376. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  377. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  378. dri2_egl_surface_free_local_buffers(dri2_surf);
  379. if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  380. if (dri2_surf->buffer)
  381. droid_window_cancel_buffer(dri2_surf);
  382. dri2_surf->window->common.decRef(&dri2_surf->window->common);
  383. }
  384. if (dri2_surf->dri_image_back) {
  385. _eglLog(_EGL_DEBUG, "%s : %d : destroy dri_image_back", __func__, __LINE__);
  386. dri2_dpy->image->destroyImage(dri2_surf->dri_image_back);
  387. dri2_surf->dri_image_back = NULL;
  388. }
  389. if (dri2_surf->dri_image_front) {
  390. _eglLog(_EGL_DEBUG, "%s : %d : destroy dri_image_front", __func__, __LINE__);
  391. dri2_dpy->image->destroyImage(dri2_surf->dri_image_front);
  392. dri2_surf->dri_image_front = NULL;
  393. }
  394. dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
  395. dri2_fini_surface(surf);
  396. free(dri2_surf);
  397. return EGL_TRUE;
  398. }
  399. static EGLBoolean
  400. droid_swap_interval(_EGLDriver *drv, _EGLDisplay *disp,
  401. _EGLSurface *surf, EGLint interval)
  402. {
  403. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  404. struct ANativeWindow *window = dri2_surf->window;
  405. if (window->setSwapInterval(window, interval))
  406. return EGL_FALSE;
  407. surf->SwapInterval = interval;
  408. return EGL_TRUE;
  409. }
  410. static int
  411. update_buffers(struct dri2_egl_surface *dri2_surf)
  412. {
  413. if (dri2_surf->base.Lost)
  414. return -1;
  415. if (dri2_surf->base.Type != EGL_WINDOW_BIT)
  416. return 0;
  417. /* try to dequeue the next back buffer */
  418. if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) {
  419. _eglLog(_EGL_WARNING, "Could not dequeue buffer from native window");
  420. dri2_surf->base.Lost = EGL_TRUE;
  421. return -1;
  422. }
  423. /* free outdated buffers and update the surface size */
  424. if (dri2_surf->base.Width != dri2_surf->buffer->width ||
  425. dri2_surf->base.Height != dri2_surf->buffer->height) {
  426. dri2_egl_surface_free_local_buffers(dri2_surf);
  427. dri2_surf->base.Width = dri2_surf->buffer->width;
  428. dri2_surf->base.Height = dri2_surf->buffer->height;
  429. }
  430. return 0;
  431. }
  432. static int
  433. get_front_bo(struct dri2_egl_surface *dri2_surf, unsigned int format)
  434. {
  435. struct dri2_egl_display *dri2_dpy =
  436. dri2_egl_display(dri2_surf->base.Resource.Display);
  437. if (dri2_surf->dri_image_front)
  438. return 0;
  439. if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  440. /* According current EGL spec, front buffer rendering
  441. * for window surface is not supported now.
  442. * and mesa doesn't have the implementation of this case.
  443. * Add warning message, but not treat it as error.
  444. */
  445. _eglLog(_EGL_DEBUG, "DRI driver requested unsupported front buffer for window surface");
  446. } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) {
  447. dri2_surf->dri_image_front =
  448. dri2_dpy->image->createImage(dri2_dpy->dri_screen,
  449. dri2_surf->base.Width,
  450. dri2_surf->base.Height,
  451. format,
  452. 0,
  453. dri2_surf);
  454. if (!dri2_surf->dri_image_front) {
  455. _eglLog(_EGL_WARNING, "dri2_image_front allocation failed");
  456. return -1;
  457. }
  458. }
  459. return 0;
  460. }
  461. static int
  462. get_back_bo(struct dri2_egl_surface *dri2_surf)
  463. {
  464. struct dri2_egl_display *dri2_dpy =
  465. dri2_egl_display(dri2_surf->base.Resource.Display);
  466. int fourcc, pitch;
  467. int offset = 0, fd;
  468. if (dri2_surf->dri_image_back)
  469. return 0;
  470. if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  471. if (!dri2_surf->buffer) {
  472. _eglLog(_EGL_WARNING, "Could not get native buffer");
  473. return -1;
  474. }
  475. fd = get_native_buffer_fd(dri2_surf->buffer);
  476. if (fd < 0) {
  477. _eglLog(_EGL_WARNING, "Could not get native buffer FD");
  478. return -1;
  479. }
  480. fourcc = get_fourcc(dri2_surf->buffer->format);
  481. pitch = dri2_surf->buffer->stride *
  482. get_format_bpp(dri2_surf->buffer->format);
  483. if (fourcc == -1 || pitch == 0) {
  484. _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)",
  485. fourcc, pitch);
  486. return -1;
  487. }
  488. dri2_surf->dri_image_back =
  489. dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
  490. dri2_surf->base.Width,
  491. dri2_surf->base.Height,
  492. fourcc,
  493. &fd,
  494. 1,
  495. &pitch,
  496. &offset,
  497. dri2_surf);
  498. if (!dri2_surf->dri_image_back) {
  499. _eglLog(_EGL_WARNING, "failed to create DRI image from FD");
  500. return -1;
  501. }
  502. } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) {
  503. /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically,
  504. * the spec states that they have a back buffer but no front buffer, in
  505. * contrast to pixmaps, which have a front buffer but no back buffer.
  506. *
  507. * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate
  508. * from the spec, following the precedent of Mesa's EGL X11 platform. The
  509. * X11 platform correctly assigns pbuffers to single-buffered configs, but
  510. * assigns the pbuffer a front buffer instead of a back buffer.
  511. *
  512. * Pbuffers in the X11 platform mostly work today, so let's just copy its
  513. * behavior instead of trying to fix (and hence potentially breaking) the
  514. * world.
  515. */
  516. _eglLog(_EGL_DEBUG, "DRI driver requested unsupported back buffer for pbuffer surface");
  517. }
  518. return 0;
  519. }
  520. /* Some drivers will pass multiple bits in buffer_mask.
  521. * For such case, will go through all the bits, and
  522. * will not return error when unsupported buffer is requested, only
  523. * return error when the allocation for supported buffer failed.
  524. */
  525. static int
  526. droid_image_get_buffers(__DRIdrawable *driDrawable,
  527. unsigned int format,
  528. uint32_t *stamp,
  529. void *loaderPrivate,
  530. uint32_t buffer_mask,
  531. struct __DRIimageList *images)
  532. {
  533. struct dri2_egl_surface *dri2_surf = loaderPrivate;
  534. images->image_mask = 0;
  535. images->front = NULL;
  536. images->back = NULL;
  537. if (update_buffers(dri2_surf) < 0)
  538. return 0;
  539. if (_eglSurfaceInSharedBufferMode(&dri2_surf->base)) {
  540. if (get_back_bo(dri2_surf) < 0)
  541. return 0;
  542. /* We have dri_image_back because this is a window surface and
  543. * get_back_bo() succeeded.
  544. */
  545. assert(dri2_surf->dri_image_back);
  546. images->back = dri2_surf->dri_image_back;
  547. images->image_mask |= __DRI_IMAGE_BUFFER_SHARED;
  548. /* There exists no accompanying back nor front buffer. */
  549. return 1;
  550. }
  551. if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
  552. if (get_front_bo(dri2_surf, format) < 0)
  553. return 0;
  554. if (dri2_surf->dri_image_front) {
  555. images->front = dri2_surf->dri_image_front;
  556. images->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
  557. }
  558. }
  559. if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
  560. if (get_back_bo(dri2_surf) < 0)
  561. return 0;
  562. if (dri2_surf->dri_image_back) {
  563. images->back = dri2_surf->dri_image_back;
  564. images->image_mask |= __DRI_IMAGE_BUFFER_BACK;
  565. }
  566. }
  567. return 1;
  568. }
  569. static EGLint
  570. droid_query_buffer_age(_EGLDriver *drv,
  571. _EGLDisplay *disp, _EGLSurface *surface)
  572. {
  573. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
  574. if (update_buffers(dri2_surf) < 0) {
  575. _eglError(EGL_BAD_ALLOC, "droid_query_buffer_age");
  576. return -1;
  577. }
  578. return dri2_surf->back ? dri2_surf->back->age : 0;
  579. }
  580. static EGLBoolean
  581. droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
  582. {
  583. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  584. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  585. const bool has_mutable_rb = _eglSurfaceHasMutableRenderBuffer(draw);
  586. /* From the EGL_KHR_mutable_render_buffer spec (v12):
  587. *
  588. * If surface is a single-buffered window, pixmap, or pbuffer surface
  589. * for which there is no pending change to the EGL_RENDER_BUFFER
  590. * attribute, eglSwapBuffers has no effect.
  591. */
  592. if (has_mutable_rb &&
  593. draw->RequestedRenderBuffer == EGL_SINGLE_BUFFER &&
  594. draw->ActiveRenderBuffer == EGL_SINGLE_BUFFER) {
  595. _eglLog(_EGL_DEBUG, "%s: remain in shared buffer mode", __func__);
  596. return EGL_TRUE;
  597. }
  598. for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  599. if (dri2_surf->color_buffers[i].age > 0)
  600. dri2_surf->color_buffers[i].age++;
  601. }
  602. /* "XXX: we don't use get_back_bo() since it causes regressions in
  603. * several dEQP tests.
  604. */
  605. if (dri2_surf->back)
  606. dri2_surf->back->age = 1;
  607. dri2_flush_drawable_for_swapbuffers(disp, draw);
  608. /* dri2_surf->buffer can be null even when no error has occured. For
  609. * example, if the user has called no GL rendering commands since the
  610. * previous eglSwapBuffers, then the driver may have not triggered
  611. * a callback to ANativeWindow::dequeueBuffer, in which case
  612. * dri2_surf->buffer remains null.
  613. */
  614. if (dri2_surf->buffer)
  615. droid_window_enqueue_buffer(disp, dri2_surf);
  616. dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
  617. /* Update the shared buffer mode */
  618. if (has_mutable_rb &&
  619. draw->ActiveRenderBuffer != draw->RequestedRenderBuffer) {
  620. bool mode = (draw->RequestedRenderBuffer == EGL_SINGLE_BUFFER);
  621. _eglLog(_EGL_DEBUG, "%s: change to shared buffer mode %d",
  622. __func__, mode);
  623. if (!droid_set_shared_buffer_mode(disp, draw, mode))
  624. return EGL_FALSE;
  625. draw->ActiveRenderBuffer = draw->RequestedRenderBuffer;
  626. }
  627. return EGL_TRUE;
  628. }
  629. #if ANDROID_API_LEVEL >= 23
  630. static EGLBoolean
  631. droid_set_damage_region(_EGLDriver *drv,
  632. _EGLDisplay *disp,
  633. _EGLSurface *draw, const EGLint* rects, EGLint n_rects)
  634. {
  635. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  636. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  637. android_native_rect_t* droid_rects = NULL;
  638. int ret;
  639. if (n_rects == 0)
  640. return EGL_TRUE;
  641. droid_rects = malloc(n_rects * sizeof(android_native_rect_t));
  642. if (droid_rects == NULL)
  643. return _eglError(EGL_BAD_ALLOC, "eglSetDamageRegionKHR");
  644. for (EGLint num_drects = 0; num_drects < n_rects; num_drects++) {
  645. EGLint i = num_drects * 4;
  646. droid_rects[num_drects].left = rects[i];
  647. droid_rects[num_drects].bottom = rects[i + 1];
  648. droid_rects[num_drects].right = rects[i] + rects[i + 2];
  649. droid_rects[num_drects].top = rects[i + 1] + rects[i + 3];
  650. }
  651. /*
  652. * XXX/TODO: Need to check for other return values
  653. */
  654. ret = native_window_set_surface_damage(dri2_surf->window, droid_rects, n_rects);
  655. free(droid_rects);
  656. return ret == 0 ? EGL_TRUE : EGL_FALSE;
  657. }
  658. #endif
  659. static _EGLImage *
  660. droid_create_image_from_prime_fd_yuv(_EGLDisplay *disp, _EGLContext *ctx,
  661. struct ANativeWindowBuffer *buf, int fd)
  662. {
  663. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  664. struct android_ycbcr ycbcr;
  665. size_t offsets[3];
  666. size_t pitches[3];
  667. enum chroma_order chroma_order;
  668. int fourcc;
  669. int ret;
  670. if (!dri2_dpy->gralloc->lock_ycbcr) {
  671. _eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
  672. return NULL;
  673. }
  674. memset(&ycbcr, 0, sizeof(ycbcr));
  675. ret = dri2_dpy->gralloc->lock_ycbcr(dri2_dpy->gralloc, buf->handle,
  676. 0, 0, 0, 0, 0, &ycbcr);
  677. if (ret) {
  678. /* HACK: See droid_create_image_from_prime_fd() and
  679. * https://issuetracker.google.com/32077885.*/
  680. if (buf->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
  681. return NULL;
  682. _eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret);
  683. return NULL;
  684. }
  685. dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, buf->handle);
  686. /* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
  687. * it will return the .y/.cb/.cr pointers based on a NULL pointer,
  688. * so they can be interpreted as offsets. */
  689. offsets[0] = (size_t)ycbcr.y;
  690. /* We assume here that all the planes are located in one DMA-buf. */
  691. if ((size_t)ycbcr.cr < (size_t)ycbcr.cb) {
  692. chroma_order = YCrCb;
  693. offsets[1] = (size_t)ycbcr.cr;
  694. offsets[2] = (size_t)ycbcr.cb;
  695. } else {
  696. chroma_order = YCbCr;
  697. offsets[1] = (size_t)ycbcr.cb;
  698. offsets[2] = (size_t)ycbcr.cr;
  699. }
  700. /* .ystride is the line length (in bytes) of the Y plane,
  701. * .cstride is the line length (in bytes) of any of the remaining
  702. * Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully
  703. * planar formats. */
  704. pitches[0] = ycbcr.ystride;
  705. pitches[1] = pitches[2] = ycbcr.cstride;
  706. /* .chroma_step is the byte distance between the same chroma channel
  707. * values of subsequent pixels, assumed to be the same for Cb and Cr. */
  708. fourcc = get_fourcc_yuv(buf->format, chroma_order, ycbcr.chroma_step);
  709. if (fourcc == -1) {
  710. _eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = %d",
  711. buf->format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", ycbcr.chroma_step);
  712. return NULL;
  713. }
  714. if (ycbcr.chroma_step == 2) {
  715. /* Semi-planar Y + CbCr or Y + CrCb format. */
  716. const EGLint attr_list_2plane[] = {
  717. EGL_WIDTH, buf->width,
  718. EGL_HEIGHT, buf->height,
  719. EGL_LINUX_DRM_FOURCC_EXT, fourcc,
  720. EGL_DMA_BUF_PLANE0_FD_EXT, fd,
  721. EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
  722. EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
  723. EGL_DMA_BUF_PLANE1_FD_EXT, fd,
  724. EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
  725. EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
  726. EGL_NONE, 0
  727. };
  728. return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_2plane);
  729. } else {
  730. /* Fully planar Y + Cb + Cr or Y + Cr + Cb format. */
  731. const EGLint attr_list_3plane[] = {
  732. EGL_WIDTH, buf->width,
  733. EGL_HEIGHT, buf->height,
  734. EGL_LINUX_DRM_FOURCC_EXT, fourcc,
  735. EGL_DMA_BUF_PLANE0_FD_EXT, fd,
  736. EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
  737. EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
  738. EGL_DMA_BUF_PLANE1_FD_EXT, fd,
  739. EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
  740. EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
  741. EGL_DMA_BUF_PLANE2_FD_EXT, fd,
  742. EGL_DMA_BUF_PLANE2_PITCH_EXT, pitches[2],
  743. EGL_DMA_BUF_PLANE2_OFFSET_EXT, offsets[2],
  744. EGL_NONE, 0
  745. };
  746. return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_3plane);
  747. }
  748. }
  749. static _EGLImage *
  750. droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx,
  751. struct ANativeWindowBuffer *buf, int fd)
  752. {
  753. unsigned int pitch;
  754. if (is_yuv(buf->format)) {
  755. _EGLImage *image;
  756. image = droid_create_image_from_prime_fd_yuv(disp, ctx, buf, fd);
  757. /*
  758. * HACK: https://issuetracker.google.com/32077885
  759. * There is no API available to properly query the IMPLEMENTATION_DEFINED
  760. * format. As a workaround we rely here on gralloc allocating either
  761. * an arbitrary YCbCr 4:2:0 or RGBX_8888, with the latter being recognized
  762. * by lock_ycbcr failing.
  763. */
  764. if (image || buf->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
  765. return image;
  766. }
  767. const int fourcc = get_fourcc(buf->format);
  768. if (fourcc == -1) {
  769. _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
  770. return NULL;
  771. }
  772. pitch = buf->stride * get_format_bpp(buf->format);
  773. if (pitch == 0) {
  774. _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
  775. return NULL;
  776. }
  777. const EGLint attr_list[] = {
  778. EGL_WIDTH, buf->width,
  779. EGL_HEIGHT, buf->height,
  780. EGL_LINUX_DRM_FOURCC_EXT, fourcc,
  781. EGL_DMA_BUF_PLANE0_FD_EXT, fd,
  782. EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
  783. EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
  784. EGL_NONE, 0
  785. };
  786. return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
  787. }
  788. #ifdef HAVE_DRM_GRALLOC
  789. static _EGLImage *
  790. droid_create_image_from_name(_EGLDisplay *disp, _EGLContext *ctx,
  791. struct ANativeWindowBuffer *buf)
  792. {
  793. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  794. struct dri2_egl_image *dri2_img;
  795. int name;
  796. int format;
  797. name = get_native_buffer_name(buf);
  798. if (!name) {
  799. _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
  800. return NULL;
  801. }
  802. format = get_format(buf->format);
  803. if (format == -1)
  804. return NULL;
  805. dri2_img = calloc(1, sizeof(*dri2_img));
  806. if (!dri2_img) {
  807. _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
  808. return NULL;
  809. }
  810. _eglInitImage(&dri2_img->base, disp);
  811. dri2_img->dri_image =
  812. dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
  813. buf->width,
  814. buf->height,
  815. format,
  816. name,
  817. buf->stride,
  818. dri2_img);
  819. if (!dri2_img->dri_image) {
  820. free(dri2_img);
  821. _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
  822. return NULL;
  823. }
  824. return &dri2_img->base;
  825. }
  826. #endif /* HAVE_DRM_GRALLOC */
  827. static EGLBoolean
  828. droid_query_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
  829. EGLint attribute, EGLint *value)
  830. {
  831. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  832. switch (attribute) {
  833. case EGL_WIDTH:
  834. if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) {
  835. dri2_surf->window->query(dri2_surf->window,
  836. NATIVE_WINDOW_DEFAULT_WIDTH, value);
  837. return EGL_TRUE;
  838. }
  839. break;
  840. case EGL_HEIGHT:
  841. if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) {
  842. dri2_surf->window->query(dri2_surf->window,
  843. NATIVE_WINDOW_DEFAULT_HEIGHT, value);
  844. return EGL_TRUE;
  845. }
  846. break;
  847. default:
  848. break;
  849. }
  850. return _eglQuerySurface(drv, disp, surf, attribute, value);
  851. }
  852. static _EGLImage *
  853. dri2_create_image_android_native_buffer(_EGLDisplay *disp,
  854. _EGLContext *ctx,
  855. struct ANativeWindowBuffer *buf)
  856. {
  857. int fd;
  858. if (ctx != NULL) {
  859. /* From the EGL_ANDROID_image_native_buffer spec:
  860. *
  861. * * If <target> is EGL_NATIVE_BUFFER_ANDROID and <ctx> is not
  862. * EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated.
  863. */
  864. _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for "
  865. "EGL_NATIVE_BUFFER_ANDROID, the context must be "
  866. "EGL_NO_CONTEXT");
  867. return NULL;
  868. }
  869. if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
  870. buf->common.version != sizeof(*buf)) {
  871. _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
  872. return NULL;
  873. }
  874. fd = get_native_buffer_fd(buf);
  875. if (fd >= 0)
  876. return droid_create_image_from_prime_fd(disp, ctx, buf, fd);
  877. #ifdef HAVE_DRM_GRALLOC
  878. return droid_create_image_from_name(disp, ctx, buf);
  879. #else
  880. return NULL;
  881. #endif
  882. }
  883. static _EGLImage *
  884. droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
  885. _EGLContext *ctx, EGLenum target,
  886. EGLClientBuffer buffer, const EGLint *attr_list)
  887. {
  888. switch (target) {
  889. case EGL_NATIVE_BUFFER_ANDROID:
  890. return dri2_create_image_android_native_buffer(disp, ctx,
  891. (struct ANativeWindowBuffer *) buffer);
  892. default:
  893. return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
  894. }
  895. }
  896. static void
  897. droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
  898. {
  899. }
  900. #ifdef HAVE_DRM_GRALLOC
  901. static int
  902. droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf,
  903. unsigned int *attachments, int count)
  904. {
  905. int num_buffers = 0;
  906. /* fill dri2_surf->buffers */
  907. for (int i = 0; i < count * 2; i += 2) {
  908. __DRIbuffer *buf, *local;
  909. assert(num_buffers < ARRAY_SIZE(dri2_surf->buffers));
  910. buf = &dri2_surf->buffers[num_buffers];
  911. switch (attachments[i]) {
  912. case __DRI_BUFFER_BACK_LEFT:
  913. if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  914. buf->attachment = attachments[i];
  915. buf->name = get_native_buffer_name(dri2_surf->buffer);
  916. buf->cpp = get_format_bpp(dri2_surf->buffer->format);
  917. buf->pitch = dri2_surf->buffer->stride * buf->cpp;
  918. buf->flags = 0;
  919. if (buf->name)
  920. num_buffers++;
  921. break;
  922. }
  923. /* fall through for pbuffers */
  924. case __DRI_BUFFER_DEPTH:
  925. case __DRI_BUFFER_STENCIL:
  926. case __DRI_BUFFER_ACCUM:
  927. case __DRI_BUFFER_DEPTH_STENCIL:
  928. case __DRI_BUFFER_HIZ:
  929. local = dri2_egl_surface_alloc_local_buffer(dri2_surf,
  930. attachments[i], attachments[i + 1]);
  931. if (local) {
  932. *buf = *local;
  933. num_buffers++;
  934. }
  935. break;
  936. case __DRI_BUFFER_FRONT_LEFT:
  937. case __DRI_BUFFER_FRONT_RIGHT:
  938. case __DRI_BUFFER_FAKE_FRONT_LEFT:
  939. case __DRI_BUFFER_FAKE_FRONT_RIGHT:
  940. case __DRI_BUFFER_BACK_RIGHT:
  941. default:
  942. /* no front or right buffers */
  943. break;
  944. }
  945. }
  946. return num_buffers;
  947. }
  948. static __DRIbuffer *
  949. droid_get_buffers_with_format(__DRIdrawable * driDrawable,
  950. int *width, int *height,
  951. unsigned int *attachments, int count,
  952. int *out_count, void *loaderPrivate)
  953. {
  954. struct dri2_egl_surface *dri2_surf = loaderPrivate;
  955. if (update_buffers(dri2_surf) < 0)
  956. return NULL;
  957. *out_count = droid_get_buffers_parse_attachments(dri2_surf, attachments, count);
  958. if (width)
  959. *width = dri2_surf->base.Width;
  960. if (height)
  961. *height = dri2_surf->base.Height;
  962. return dri2_surf->buffers;
  963. }
  964. #endif /* HAVE_DRM_GRALLOC */
  965. static unsigned
  966. droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
  967. {
  968. /* Note: loaderPrivate is _EGLDisplay* */
  969. switch (cap) {
  970. case DRI_LOADER_CAP_RGBA_ORDERING:
  971. return 1;
  972. default:
  973. return 0;
  974. }
  975. }
  976. static EGLBoolean
  977. droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
  978. {
  979. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  980. static const struct {
  981. int format;
  982. unsigned int rgba_masks[4];
  983. } visuals[] = {
  984. { HAL_PIXEL_FORMAT_RGBA_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 } },
  985. { HAL_PIXEL_FORMAT_RGBX_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 } },
  986. { HAL_PIXEL_FORMAT_RGB_565, { 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 } },
  987. { HAL_PIXEL_FORMAT_BGRA_8888, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 } },
  988. };
  989. unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
  990. int config_count = 0;
  991. /* The nesting of loops is significant here. Also significant is the order
  992. * of the HAL pixel formats. Many Android apps (such as Google's official
  993. * NDK GLES2 example app), and even portions the core framework code (such
  994. * as SystemServiceManager in Nougat), incorrectly choose their EGLConfig.
  995. * They neglect to match the EGLConfig's EGL_NATIVE_VISUAL_ID against the
  996. * window's native format, and instead choose the first EGLConfig whose
  997. * channel sizes match those of the native window format while ignoring the
  998. * channel *ordering*.
  999. *
  1000. * We can detect such buggy clients in logcat when they call
  1001. * eglCreateSurface, by detecting the mismatch between the EGLConfig's
  1002. * format and the window's format.
  1003. *
  1004. * As a workaround, we generate EGLConfigs such that all EGLConfigs for HAL
  1005. * pixel format i precede those for HAL pixel format i+1. In my
  1006. * (chadversary) testing on Android Nougat, this was good enough to pacify
  1007. * the buggy clients.
  1008. */
  1009. for (int i = 0; i < ARRAY_SIZE(visuals); i++) {
  1010. for (int j = 0; dri2_dpy->driver_configs[j]; j++) {
  1011. const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
  1012. const EGLint config_attrs[] = {
  1013. EGL_NATIVE_VISUAL_ID, visuals[i].format,
  1014. EGL_NATIVE_VISUAL_TYPE, visuals[i].format,
  1015. EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE,
  1016. EGL_RECORDABLE_ANDROID, EGL_TRUE,
  1017. EGL_NONE
  1018. };
  1019. struct dri2_egl_config *dri2_conf =
  1020. dri2_add_config(disp, dri2_dpy->driver_configs[j],
  1021. config_count + 1, surface_type, config_attrs,
  1022. visuals[i].rgba_masks);
  1023. if (dri2_conf) {
  1024. if (dri2_conf->base.ConfigID == config_count + 1)
  1025. config_count++;
  1026. format_count[i]++;
  1027. }
  1028. }
  1029. }
  1030. for (int i = 0; i < ARRAY_SIZE(format_count); i++) {
  1031. if (!format_count[i]) {
  1032. _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x",
  1033. visuals[i].format);
  1034. }
  1035. }
  1036. return (config_count != 0);
  1037. }
  1038. static EGLBoolean
  1039. droid_probe_device(_EGLDisplay *disp);
  1040. #ifdef HAVE_DRM_GRALLOC
  1041. static EGLBoolean
  1042. droid_open_device_drm_gralloc(_EGLDisplay *disp)
  1043. {
  1044. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  1045. int fd = -1, err = -EINVAL;
  1046. if (dri2_dpy->gralloc->perform)
  1047. err = dri2_dpy->gralloc->perform(dri2_dpy->gralloc,
  1048. GRALLOC_MODULE_PERFORM_GET_DRM_FD,
  1049. &fd);
  1050. if (err || fd < 0) {
  1051. _eglLog(_EGL_WARNING, "fail to get drm fd");
  1052. return EGL_FALSE;
  1053. }
  1054. dri2_dpy->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
  1055. if (dri2_dpy->fd < 0)
  1056. return EGL_FALSE;
  1057. return droid_probe_device(disp);
  1058. }
  1059. #endif /* HAVE_DRM_GRALLOC */
  1060. static const struct dri2_egl_display_vtbl droid_display_vtbl = {
  1061. .authenticate = NULL,
  1062. .create_window_surface = droid_create_window_surface,
  1063. .create_pixmap_surface = dri2_fallback_create_pixmap_surface,
  1064. .create_pbuffer_surface = droid_create_pbuffer_surface,
  1065. .destroy_surface = droid_destroy_surface,
  1066. .create_image = droid_create_image_khr,
  1067. .swap_buffers = droid_swap_buffers,
  1068. .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage, /* Android implements the function */
  1069. .swap_buffers_region = dri2_fallback_swap_buffers_region,
  1070. .swap_interval = droid_swap_interval,
  1071. #if ANDROID_API_LEVEL >= 23
  1072. .set_damage_region = droid_set_damage_region,
  1073. #else
  1074. .set_damage_region = dri2_fallback_set_damage_region,
  1075. #endif
  1076. .post_sub_buffer = dri2_fallback_post_sub_buffer,
  1077. .copy_buffers = dri2_fallback_copy_buffers,
  1078. .query_buffer_age = droid_query_buffer_age,
  1079. .query_surface = droid_query_surface,
  1080. .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
  1081. .get_sync_values = dri2_fallback_get_sync_values,
  1082. .get_dri_drawable = dri2_surface_get_dri_drawable,
  1083. .set_shared_buffer_mode = droid_set_shared_buffer_mode,
  1084. };
  1085. #ifdef HAVE_DRM_GRALLOC
  1086. static const __DRIdri2LoaderExtension droid_dri2_loader_extension = {
  1087. .base = { __DRI_DRI2_LOADER, 4 },
  1088. .getBuffers = NULL,
  1089. .flushFrontBuffer = droid_flush_front_buffer,
  1090. .getBuffersWithFormat = droid_get_buffers_with_format,
  1091. .getCapability = droid_get_capability,
  1092. };
  1093. #endif /* HAVE_DRM_GRALLOC */
  1094. static const __DRIimageLoaderExtension droid_image_loader_extension = {
  1095. .base = { __DRI_IMAGE_LOADER, 2 },
  1096. .getBuffers = droid_image_get_buffers,
  1097. .flushFrontBuffer = droid_flush_front_buffer,
  1098. .getCapability = droid_get_capability,
  1099. };
  1100. #ifdef HAVE_DRM_GRALLOC
  1101. static const __DRIextension *droid_dri2_loader_extensions[] = {
  1102. &droid_dri2_loader_extension.base,
  1103. &image_lookup_extension.base,
  1104. &use_invalidate.base,
  1105. /* No __DRI_MUTABLE_RENDER_BUFFER_LOADER because it requires
  1106. * __DRI_IMAGE_LOADER.
  1107. */
  1108. NULL,
  1109. };
  1110. #endif /* HAVE_DRM_GRALLOC */
  1111. static void
  1112. droid_display_shared_buffer(__DRIdrawable *driDrawable, int fence_fd,
  1113. void *loaderPrivate)
  1114. {
  1115. struct dri2_egl_surface *dri2_surf = loaderPrivate;
  1116. struct ANativeWindowBuffer *old_buffer UNUSED = dri2_surf->buffer;
  1117. if (!_eglSurfaceInSharedBufferMode(&dri2_surf->base)) {
  1118. _eglLog(_EGL_WARNING, "%s: internal error: buffer is not shared",
  1119. __func__);
  1120. return;
  1121. }
  1122. if (fence_fd >= 0) {
  1123. /* The driver's fence is more recent than the surface's out fence, if it
  1124. * exists at all. So use the driver's fence.
  1125. */
  1126. if (dri2_surf->out_fence_fd >= 0) {
  1127. close(dri2_surf->out_fence_fd);
  1128. dri2_surf->out_fence_fd = -1;
  1129. }
  1130. } else if (dri2_surf->out_fence_fd >= 0) {
  1131. fence_fd = dri2_surf->out_fence_fd;
  1132. dri2_surf->out_fence_fd = -1;
  1133. }
  1134. if (dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer,
  1135. fence_fd)) {
  1136. _eglLog(_EGL_WARNING, "%s: ANativeWindow::queueBuffer failed", __func__);
  1137. close(fence_fd);
  1138. return;
  1139. }
  1140. fence_fd = -1;
  1141. if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer,
  1142. &fence_fd)) {
  1143. /* Tear down the surface because it no longer has a back buffer. */
  1144. struct dri2_egl_display *dri2_dpy =
  1145. dri2_egl_display(dri2_surf->base.Resource.Display);
  1146. _eglLog(_EGL_WARNING, "%s: ANativeWindow::dequeueBuffer failed", __func__);
  1147. dri2_surf->base.Lost = true;
  1148. dri2_surf->buffer = NULL;
  1149. dri2_surf->back = NULL;
  1150. if (dri2_surf->dri_image_back) {
  1151. dri2_dpy->image->destroyImage(dri2_surf->dri_image_back);
  1152. dri2_surf->dri_image_back = NULL;
  1153. }
  1154. dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
  1155. return;
  1156. }
  1157. if (fence_fd < 0)
  1158. return;
  1159. /* Access to the buffer is controlled by a sync fence. Block on it.
  1160. *
  1161. * Ideally, we would submit the fence to the driver, and the driver would
  1162. * postpone command execution until it signalled. But DRI lacks API for
  1163. * that (as of 2018-04-11).
  1164. *
  1165. * SYNC_IOC_WAIT waits forever if timeout < 0
  1166. */
  1167. sync_wait(fence_fd, -1);
  1168. close(fence_fd);
  1169. }
  1170. static const __DRImutableRenderBufferLoaderExtension droid_mutable_render_buffer_extension = {
  1171. .base = { __DRI_MUTABLE_RENDER_BUFFER_LOADER, 1 },
  1172. .displaySharedBuffer = droid_display_shared_buffer,
  1173. };
  1174. static const __DRIextension *droid_image_loader_extensions[] = {
  1175. &droid_image_loader_extension.base,
  1176. &image_lookup_extension.base,
  1177. &use_invalidate.base,
  1178. &droid_mutable_render_buffer_extension.base,
  1179. NULL,
  1180. };
  1181. static EGLBoolean
  1182. droid_load_driver(_EGLDisplay *disp)
  1183. {
  1184. struct dri2_egl_display *dri2_dpy = disp->DriverData;
  1185. const char *err;
  1186. dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
  1187. if (dri2_dpy->driver_name == NULL)
  1188. return false;
  1189. dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
  1190. if (!dri2_dpy->is_render_node) {
  1191. #ifdef HAVE_DRM_GRALLOC
  1192. /* Handle control nodes using __DRI_DRI2_LOADER extension and GEM names
  1193. * for backwards compatibility with drm_gralloc. (Do not use on new
  1194. * systems.) */
  1195. dri2_dpy->loader_extensions = droid_dri2_loader_extensions;
  1196. if (!dri2_load_driver(disp)) {
  1197. err = "DRI2: failed to load driver";
  1198. goto error;
  1199. }
  1200. #else
  1201. err = "DRI2: handle is not for a render node";
  1202. goto error;
  1203. #endif
  1204. } else {
  1205. dri2_dpy->loader_extensions = droid_image_loader_extensions;
  1206. if (!dri2_load_driver_dri3(disp)) {
  1207. err = "DRI3: failed to load driver";
  1208. goto error;
  1209. }
  1210. }
  1211. return true;
  1212. error:
  1213. free(dri2_dpy->driver_name);
  1214. dri2_dpy->driver_name = NULL;
  1215. return false;
  1216. }
  1217. static void
  1218. droid_unload_driver(_EGLDisplay *disp)
  1219. {
  1220. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  1221. dlclose(dri2_dpy->driver);
  1222. dri2_dpy->driver = NULL;
  1223. free(dri2_dpy->driver_name);
  1224. dri2_dpy->driver_name = NULL;
  1225. }
  1226. static int
  1227. droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor)
  1228. {
  1229. drmVersionPtr ver = drmGetVersion(fd);
  1230. if (!ver)
  1231. return -1;
  1232. if (strcmp(vendor, ver->name) != 0) {
  1233. drmFreeVersion(ver);
  1234. return -1;
  1235. }
  1236. drmFreeVersion(ver);
  1237. return 0;
  1238. }
  1239. static EGLBoolean
  1240. droid_probe_device(_EGLDisplay *disp)
  1241. {
  1242. /* Check that the device is supported, by attempting to:
  1243. * - load the dri module
  1244. * - and, create a screen
  1245. */
  1246. if (!droid_load_driver(disp))
  1247. return EGL_FALSE;
  1248. if (!dri2_create_screen(disp)) {
  1249. _eglLog(_EGL_WARNING, "DRI2: failed to create screen");
  1250. droid_unload_driver(disp);
  1251. return EGL_FALSE;
  1252. }
  1253. return EGL_TRUE;
  1254. }
  1255. static EGLBoolean
  1256. droid_open_device(_EGLDisplay *disp)
  1257. {
  1258. #define MAX_DRM_DEVICES 64
  1259. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  1260. drmDevicePtr device, devices[MAX_DRM_DEVICES] = { NULL };
  1261. int num_devices;
  1262. char *vendor_name = NULL;
  1263. char vendor_buf[PROPERTY_VALUE_MAX];
  1264. if (property_get("drm.gpu.vendor_name", vendor_buf, NULL) > 0)
  1265. vendor_name = vendor_buf;
  1266. num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
  1267. if (num_devices < 0)
  1268. return EGL_FALSE;
  1269. for (int i = 0; i < num_devices; i++) {
  1270. device = devices[i];
  1271. if (!(device->available_nodes & (1 << DRM_NODE_RENDER)))
  1272. continue;
  1273. dri2_dpy->fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
  1274. if (dri2_dpy->fd < 0) {
  1275. _eglLog(_EGL_WARNING, "%s() Failed to open DRM device %s",
  1276. __func__, device->nodes[DRM_NODE_RENDER]);
  1277. continue;
  1278. }
  1279. /* If a vendor is explicitly provided, we use only that.
  1280. * Otherwise we fall-back the first device that is supported.
  1281. */
  1282. if (vendor_name) {
  1283. if (droid_filter_device(disp, dri2_dpy->fd, vendor_name)) {
  1284. /* Device does not match - try next device */
  1285. close(dri2_dpy->fd);
  1286. dri2_dpy->fd = -1;
  1287. continue;
  1288. }
  1289. /* If the requested device matches - use it. Regardless if
  1290. * init fails, do not fall-back to any other device.
  1291. */
  1292. if (!droid_probe_device(disp)) {
  1293. close(dri2_dpy->fd);
  1294. dri2_dpy->fd = -1;
  1295. }
  1296. break;
  1297. }
  1298. if (droid_probe_device(disp))
  1299. break;
  1300. /* No explicit request - attempt the next device */
  1301. close(dri2_dpy->fd);
  1302. dri2_dpy->fd = -1;
  1303. }
  1304. drmFreeDevices(devices, num_devices);
  1305. if (dri2_dpy->fd < 0) {
  1306. _eglLog(_EGL_WARNING, "Failed to open %s DRM device",
  1307. vendor_name ? "desired": "any");
  1308. return EGL_FALSE;
  1309. }
  1310. return EGL_TRUE;
  1311. #undef MAX_DRM_DEVICES
  1312. }
  1313. EGLBoolean
  1314. dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
  1315. {
  1316. _EGLDevice *dev;
  1317. struct dri2_egl_display *dri2_dpy;
  1318. const char *err;
  1319. int ret;
  1320. /* Not supported yet */
  1321. if (disp->Options.ForceSoftware)
  1322. return EGL_FALSE;
  1323. dri2_dpy = calloc(1, sizeof(*dri2_dpy));
  1324. if (!dri2_dpy)
  1325. return _eglError(EGL_BAD_ALLOC, "eglInitialize");
  1326. dri2_dpy->fd = -1;
  1327. ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
  1328. (const hw_module_t **)&dri2_dpy->gralloc);
  1329. if (ret) {
  1330. err = "DRI2: failed to get gralloc module";
  1331. goto cleanup;
  1332. }
  1333. disp->DriverData = (void *) dri2_dpy;
  1334. #ifdef HAVE_DRM_GRALLOC
  1335. if (!droid_open_device_drm_gralloc(disp)) {
  1336. #else
  1337. if (!droid_open_device(disp)) {
  1338. #endif
  1339. err = "DRI2: failed to open device";
  1340. goto cleanup;
  1341. }
  1342. dev = _eglAddDevice(dri2_dpy->fd, false);
  1343. if (!dev) {
  1344. err = "DRI2: failed to find EGLDevice";
  1345. goto cleanup;
  1346. }
  1347. disp->Device = dev;
  1348. if (!dri2_setup_extensions(disp)) {
  1349. err = "DRI2: failed to setup extensions";
  1350. goto cleanup;
  1351. }
  1352. dri2_setup_screen(disp);
  1353. /* We set the maximum swap interval as 1 for Android platform, since it is
  1354. * the maximum value supported by Android according to the value of
  1355. * ANativeWindow::maxSwapInterval.
  1356. */
  1357. dri2_setup_swap_interval(disp, 1);
  1358. disp->Extensions.ANDROID_framebuffer_target = EGL_TRUE;
  1359. disp->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
  1360. disp->Extensions.ANDROID_recordable = EGL_TRUE;
  1361. disp->Extensions.EXT_buffer_age = EGL_TRUE;
  1362. #if ANDROID_API_LEVEL >= 23
  1363. disp->Extensions.KHR_partial_update = EGL_TRUE;
  1364. #endif
  1365. disp->Extensions.KHR_image = EGL_TRUE;
  1366. #if ANDROID_API_LEVEL >= 24
  1367. if (dri2_dpy->mutable_render_buffer &&
  1368. dri2_dpy->loader_extensions == droid_image_loader_extensions) {
  1369. disp->Extensions.KHR_mutable_render_buffer = EGL_TRUE;
  1370. }
  1371. #endif
  1372. /* Create configs *after* enabling extensions because presence of DRI
  1373. * driver extensions can affect the capabilities of EGLConfigs.
  1374. */
  1375. if (!droid_add_configs_for_visuals(drv, disp)) {
  1376. err = "DRI2: failed to add configs";
  1377. goto cleanup;
  1378. }
  1379. /* Fill vtbl last to prevent accidentally calling virtual function during
  1380. * initialization.
  1381. */
  1382. dri2_dpy->vtbl = &droid_display_vtbl;
  1383. return EGL_TRUE;
  1384. cleanup:
  1385. dri2_display_destroy(disp);
  1386. return _eglError(EGL_NOT_INITIALIZED, err);
  1387. }