0018-egl-add-Tizen-platform-support.patch 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634
  1. From 70abef4d4511b1e25ab3b4746644e5324140d9d7 Mon Sep 17 00:00:00 2001
  2. From: Frank Binns <frank.binns@imgtec.com>
  3. Date: Fri, 6 Jan 2017 16:35:00 +0000
  4. Subject: [PATCH] egl: add Tizen platform support
  5. Add a new "tizen" platform to support drm/gbm and Wayland on Tizen.
  6. The platform can be enabled by passing "-Dplatforms=tizen" to Meson.
  7. ---
  8. meson.build | 25 +-
  9. meson_options.txt | 2 +-
  10. src/egl/drivers/dri2/egl_dri2.c | 182 ++++-
  11. src/egl/drivers/dri2/egl_dri2.h | 59 +-
  12. src/egl/drivers/dri2/platform_tizen.c | 980 ++++++++++++++++++++++++++
  13. src/egl/main/eglapi.c | 7 +
  14. src/egl/main/egldisplay.c | 32 +-
  15. src/egl/main/egldisplay.h | 7 +
  16. src/egl/main/egllog.c | 27 +-
  17. src/egl/meson.build | 7 +-
  18. 10 files changed, 1313 insertions(+), 15 deletions(-)
  19. create mode 100644 src/egl/drivers/dri2/platform_tizen.c
  20. diff --git a/meson.build b/meson.build
  21. index 968b4f5..3d9d345 100644
  22. --- a/meson.build
  23. +++ b/meson.build
  24. @@ -358,6 +358,11 @@ with_platform_x11 = _platforms.contains('x11')
  25. with_platform_wayland = _platforms.contains('wayland')
  26. with_platform_haiku = _platforms.contains('haiku')
  27. with_platform_windows = _platforms.contains('windows')
  28. +with_platform_tizen = _platforms.contains('tizen')
  29. +
  30. +if with_platform_tizen and _platforms.length() != 1
  31. + error('tizen cannot be enabled at the same time as other platforms')
  32. +endif
  33. with_glx = get_option('glx')
  34. if with_glx == 'auto'
  35. @@ -910,7 +915,7 @@ else
  36. pre_args += '-DEGL_NO_X11'
  37. gl_pkgconfig_c_flags += '-DEGL_NO_X11'
  38. endif
  39. -if with_gbm and not with_platform_android
  40. +if with_gbm and not with_platform_android and not with_platform_tizen
  41. pre_args += '-DHAVE_DRM_PLATFORM'
  42. endif
  43. @@ -944,6 +949,15 @@ endif
  44. if with_platform_haiku
  45. pre_args += '-DHAVE_HAIKU_PLATFORM'
  46. endif
  47. +if with_platform_tizen
  48. + dep_dlog = dependency('dlog')
  49. + dep_tizen = [
  50. + dep_dlog,
  51. + dependency('libtbm'),
  52. + dependency('tpl-egl'),
  53. + ]
  54. + pre_args += '-DHAVE_TIZEN_PLATFORM'
  55. +endif
  56. prog_python = import('python').find_installation('python3')
  57. has_mako = run_command(
  58. @@ -1568,7 +1582,8 @@ with_gallium_drisw_kms = false
  59. dep_libdrm = dependency(
  60. 'libdrm', version : '>=' + _drm_ver,
  61. # GNU/Hurd includes egl_dri2, without drm.
  62. - required : (with_dri2 and host_machine.system() != 'gnu') or with_dri3
  63. + required : (with_dri2 and host_machine.system() != 'gnu') or with_dri3 or
  64. + with_platform_tizen
  65. )
  66. if dep_libdrm.found()
  67. pre_args += '-DHAVE_LIBDRM'
  68. @@ -2187,8 +2202,10 @@ if with_egl
  69. lines += 'EGL drivers: ' + ' '.join(egl_drivers)
  70. endif
  71. if with_egl or with_any_vk
  72. - _platforms += 'surfaceless'
  73. - if with_gbm and not with_platform_android
  74. + if not with_platform_tizen
  75. + _platforms += 'surfaceless'
  76. + endif
  77. + if with_gbm and not with_platform_android and not with_platform_tizen
  78. _platforms += 'drm'
  79. endif
  80. lines += 'EGL/Vulkan/VL platforms: ' + ' '.join(_platforms)
  81. diff --git a/meson_options.txt b/meson_options.txt
  82. index dac7910..8230db9 100644
  83. --- a/meson_options.txt
  84. +++ b/meson_options.txt
  85. @@ -23,7 +23,7 @@ option(
  86. type : 'array',
  87. value : ['auto'],
  88. choices : [
  89. - 'auto', 'x11', 'wayland', 'haiku', 'android', 'windows',
  90. + 'auto', 'x11', 'wayland', 'haiku', 'android', 'windows', 'tizen',
  91. ],
  92. description : 'window systems to support. If this is set to `auto`, all platforms applicable will be enabled.'
  93. )
  94. diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
  95. index dea5899..6d34395 100644
  96. --- a/src/egl/drivers/dri2/egl_dri2.c
  97. +++ b/src/egl/drivers/dri2/egl_dri2.c
  98. @@ -1179,6 +1179,11 @@ dri2_initialize(_EGLDisplay *disp)
  99. case _EGL_PLATFORM_ANDROID:
  100. ret = dri2_initialize_android(disp);
  101. break;
  102. +#ifdef HAVE_TIZEN_PLATFORM
  103. + case _EGL_PLATFORM_TIZEN:
  104. + ret = dri2_initialize_tizen(disp);
  105. + break;
  106. +#endif
  107. default:
  108. unreachable("Callers ensure we cannot get here.");
  109. return EGL_FALSE;
  110. @@ -1253,6 +1258,12 @@ dri2_display_destroy(_EGLDisplay *disp)
  111. case _EGL_PLATFORM_WAYLAND:
  112. dri2_teardown_wayland(dri2_dpy);
  113. break;
  114. +#ifdef HAVE_TIZEN_PLATFORM
  115. + case _EGL_PLATFORM_TIZEN:
  116. + if (dri2_dpy->tpl_dpy)
  117. + tpl_object_unreference((tpl_object_t *) dri2_dpy->tpl_dpy);
  118. + break;
  119. +#endif
  120. default:
  121. /* TODO: add teardown for other platforms */
  122. break;
  123. @@ -2293,8 +2304,96 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
  124. return dri2_create_image_from_dri(disp, dri_image);
  125. }
  126. -#ifdef HAVE_WAYLAND_PLATFORM
  127. +#ifdef HAVE_TIZEN_PLATFORM
  128. +int
  129. +dri2_fourcc_from_tbm_format(tbm_format format)
  130. +{
  131. + switch (format) {
  132. + case TBM_FORMAT_ARGB8888:
  133. + return DRM_FORMAT_ARGB8888;
  134. + case TBM_FORMAT_XRGB8888:
  135. + return DRM_FORMAT_XRGB8888;
  136. + case TBM_FORMAT_RGB565:
  137. + return DRM_FORMAT_RGB565;
  138. + default:
  139. + _eglLog(_EGL_DEBUG, "%s: unsupported tbm format %#x", __func__, format);
  140. + return 0;
  141. + }
  142. +}
  143. +static _EGLImage *
  144. +dri2_create_image_wayland_wl_buffer_tizen(_EGLDisplay *disp, _EGLContext *ctx,
  145. + EGLClientBuffer _buffer,
  146. + const EGLint *attr_list)
  147. +{
  148. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  149. + __DRIimage *dri_image;
  150. + _EGLImageAttribs attrs;
  151. + tbm_surface_h tbm_surf;
  152. + tbm_bo tbm_buf;
  153. + tbm_surface_info_s info;
  154. + int fourcc, fd, pitch, offset;
  155. +
  156. + tbm_surf = tpl_display_get_buffer_from_native_pixmap(dri2_dpy->tpl_dpy,
  157. + (tpl_handle_t) _buffer);
  158. + if (!tbm_surf) {
  159. + _eglError(EGL_BAD_PARAMETER, "tpl_display_get_buffer_from_native_pixmap");
  160. + return NULL;
  161. + }
  162. +
  163. + if (!_eglParseImageAttribList(&attrs, disp, attr_list)) {
  164. + _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer_tizen");
  165. + return NULL;
  166. + }
  167. +
  168. + if (tbm_surface_get_info(tbm_surf, &info)) {
  169. + _eglError(EGL_BAD_PARAMETER, "tbm_surface_get_info");
  170. + return NULL;
  171. + }
  172. +
  173. + if (info.num_planes > 1) {
  174. + _eglError(EGL_BAD_PARAMETER,
  175. + "dri2_create_image_wayland_wl_buffer_tizen (multi-plane format)");
  176. + return NULL;
  177. + }
  178. +
  179. + if (attrs.PlaneWL < 0 || attrs.PlaneWL >= info.num_planes) {
  180. + _eglError(EGL_BAD_PARAMETER,
  181. + "dri2_create_image_wayland_wl_buffer_tizen (plane out of bounds)");
  182. + return NULL;
  183. + }
  184. +
  185. + tbm_buf = tbm_surface_internal_get_bo(tbm_surf, attrs.PlaneWL);
  186. + if (!tbm_buf) {
  187. + _eglError(EGL_BAD_PARAMETER, "tbm_surface_internal_get_bo");
  188. + return NULL;
  189. + }
  190. +
  191. + fourcc = dri2_fourcc_from_tbm_format(info.format);
  192. + pitch = info.planes[attrs.PlaneWL].stride;
  193. + offset = info.planes[attrs.PlaneWL].offset;
  194. + fd = tbm_bo_export_fd(tbm_buf);
  195. +
  196. + dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
  197. + info.width,
  198. + info.height,
  199. + fourcc,
  200. + &fd,
  201. + 1,
  202. + &pitch,
  203. + &offset,
  204. + tbm_surf);
  205. + close(fd);
  206. + if (dri_image == NULL) {
  207. + _eglError(EGL_BAD_PARAMETER, "createImageFromFds");
  208. + return NULL;
  209. + }
  210. +
  211. + return dri2_create_image_from_dri(disp, dri_image);
  212. +}
  213. +#endif
  214. +
  215. +#ifdef HAVE_WAYLAND_PLATFORM
  216. /* This structure describes how a wl_buffer maps to one or more
  217. * __DRIimages. A wl_drm_buffer stores the wl_drm format code and the
  218. * offsets and strides of the planes in the buffer. This table maps a
  219. @@ -3193,6 +3292,10 @@ dri2_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
  220. #ifdef HAVE_WAYLAND_PLATFORM
  221. case EGL_WAYLAND_BUFFER_WL:
  222. return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
  223. +#endif
  224. +#ifdef HAVE_TIZEN_PLATFORM
  225. + case EGL_WAYLAND_BUFFER_WL:
  226. + return dri2_create_image_wayland_wl_buffer_tizen(disp, ctx, buffer, attr_list);
  227. #endif
  228. case EGL_CL_IMAGE_IMG:
  229. return dri2_create_image_img_buffer(disp, ctx, target, buffer, attr_list);
  230. @@ -3214,6 +3317,78 @@ dri2_destroy_image_khr(_EGLDisplay *disp, _EGLImage *image)
  231. return EGL_TRUE;
  232. }
  233. +#ifdef HAVE_TIZEN_PLATFORM
  234. +
  235. +static EGLint get_texture_format_from_gbm_format(tbm_format format)
  236. +{
  237. + switch (format) {
  238. + case TBM_FORMAT_ARGB8888:
  239. + return EGL_TEXTURE_RGBA;
  240. + default:
  241. + _eglLog(_EGL_DEBUG, "%s: unsupported tbm format %#x", __func__, format);
  242. + return 0;
  243. + }
  244. +}
  245. +
  246. +static EGLBoolean
  247. +dri2_bind_wayland_display_wl_tizen(_EGLDisplay *disp, struct wl_display *wl_dpy)
  248. +{
  249. + (void) disp;
  250. + (void) wl_dpy;
  251. +
  252. + return EGL_TRUE;
  253. +}
  254. +
  255. +static EGLBoolean
  256. +dri2_unbind_wayland_display_wl_tizen(_EGLDisplay *disp,
  257. + struct wl_display *wl_dpy)
  258. +{
  259. + (void) disp;
  260. + (void) wl_dpy;
  261. +
  262. + return EGL_TRUE;
  263. +}
  264. +
  265. +static EGLBoolean
  266. +dri2_query_wayland_buffer_wl_tizen(_EGLDisplay *disp,
  267. + struct wl_resource *buffer_resource,
  268. + EGLint attribute, EGLint *value)
  269. +{
  270. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  271. + tpl_handle_t pixmap = (tpl_handle_t) buffer_resource;
  272. + tbm_surface_h tbm_surf;
  273. + tbm_format format;
  274. + EGLint tex_format;
  275. +
  276. + tbm_surf = tpl_display_get_buffer_from_native_pixmap(dri2_dpy->tpl_dpy,
  277. + pixmap);
  278. + if (!tbm_surf)
  279. + return EGL_FALSE;
  280. +
  281. + switch (attribute) {
  282. + case EGL_TEXTURE_FORMAT:
  283. + format = tbm_surface_get_format(tbm_surf);
  284. + tex_format = get_texture_format_from_gbm_format(format);
  285. + if (!tex_format)
  286. + return EGL_FALSE;
  287. +
  288. + *value = tex_format;
  289. + break;
  290. + case EGL_WIDTH:
  291. + *value = tbm_surface_get_width(tbm_surf);
  292. + break;
  293. + case EGL_HEIGHT:
  294. + *value = tbm_surface_get_height(tbm_surf);
  295. + break;
  296. + default:
  297. + return EGL_FALSE;
  298. + }
  299. +
  300. + return EGL_TRUE;
  301. +}
  302. +
  303. +#endif
  304. +
  305. #ifdef HAVE_WAYLAND_PLATFORM
  306. static void
  307. @@ -3755,6 +3930,11 @@ const _EGLDriver _eglDriver = {
  308. .BindWaylandDisplayWL = dri2_bind_wayland_display_wl,
  309. .UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl,
  310. .QueryWaylandBufferWL = dri2_query_wayland_buffer_wl,
  311. +#endif
  312. +#ifdef HAVE_TIZEN_PLATFORM
  313. + .BindWaylandDisplayWL = dri2_bind_wayland_display_wl_tizen,
  314. + .UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl_tizen,
  315. + .QueryWaylandBufferWL = dri2_query_wayland_buffer_wl_tizen,
  316. #endif
  317. .GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium,
  318. .CreateSyncKHR = dri2_create_sync,
  319. diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
  320. index 6a7eede..a8bfe45 100644
  321. --- a/src/egl/drivers/dri2/egl_dri2.h
  322. +++ b/src/egl/drivers/dri2/egl_dri2.h
  323. @@ -62,9 +62,9 @@ struct zwp_linux_dmabuf_v1;
  324. #include <gbm_driint.h>
  325. #endif
  326. -#ifdef HAVE_ANDROID_PLATFORM
  327. #define LOG_TAG "EGL-DRI2"
  328. +#ifdef HAVE_ANDROID_PLATFORM
  329. #include <hardware/gralloc.h>
  330. #if ANDROID_API_LEVEL >= 26
  331. @@ -75,6 +75,12 @@ struct zwp_linux_dmabuf_v1;
  332. #endif /* HAVE_ANDROID_PLATFORM */
  333. +#ifdef HAVE_TIZEN_PLATFORM
  334. +#include <pthread.h>
  335. +#include <tpl.h>
  336. +#include <tbm_surface_internal.h>
  337. +#endif
  338. +
  339. #include "eglconfig.h"
  340. #include "eglcontext.h"
  341. #include "egldevice.h"
  342. @@ -259,6 +265,10 @@ struct dri2_egl_display
  343. bool is_render_node;
  344. bool is_different_gpu;
  345. +
  346. +#ifdef HAVE_TIZEN_PLATFORM
  347. + tpl_display_t *tpl_dpy;
  348. +#endif
  349. };
  350. struct dri2_egl_context
  351. @@ -276,6 +286,18 @@ enum wayland_buffer_type {
  352. };
  353. #endif
  354. +#define DRI2_SURFACE_NUM_COLOR_BUFFERS 4
  355. +
  356. +#ifdef HAVE_TIZEN_PLATFORM
  357. +struct tpl_swap_queue_elem
  358. +{
  359. + tbm_surface_h tbm_surf;
  360. + EGLint *rects;
  361. + EGLint n_rects_max;
  362. + EGLint n_rects;
  363. +};
  364. +#endif
  365. +
  366. struct dri2_egl_surface
  367. {
  368. _EGLSurface base;
  369. @@ -308,15 +330,33 @@ struct dri2_egl_surface
  370. struct gbm_dri_surface *gbm_surf;
  371. #endif
  372. +#ifdef HAVE_TIZEN_PLATFORM
  373. + tpl_surface_t *tpl_surf;
  374. + bool reset;
  375. + /*
  376. + * Protects swap_queue_idx_head, swap_queue_idx_tail and
  377. + * color_buffers.locked.
  378. + */
  379. + pthread_mutex_t mutex;
  380. + pthread_cond_t swap_queue_cond;
  381. + struct tpl_swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
  382. + int swap_queue_idx_head;
  383. + int swap_queue_idx_tail;
  384. + pthread_t swap_queue_processor;
  385. +#endif
  386. +
  387. /* EGL-owned buffers */
  388. __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT];
  389. -#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
  390. +#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) || \
  391. + defined(HAVE_TIZEN_PLATFORM)
  392. struct {
  393. +#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_TIZEN_PLATFORM)
  394. + __DRIimage *dri_image;
  395. +#endif
  396. #ifdef HAVE_WAYLAND_PLATFORM
  397. struct wl_buffer *wl_buffer;
  398. bool wl_release;
  399. - __DRIimage *dri_image;
  400. /* for is_different_gpu case. NULL else */
  401. __DRIimage *linear_copy;
  402. /* for swrast */
  403. @@ -325,6 +365,9 @@ struct dri2_egl_surface
  404. #endif
  405. #ifdef HAVE_DRM_PLATFORM
  406. struct gbm_bo *bo;
  407. +#endif
  408. +#ifdef HAVE_TIZEN_PLATFORM
  409. + tbm_surface_h tbm_surf;
  410. #endif
  411. bool locked;
  412. int age;
  413. @@ -525,6 +568,11 @@ dri2_initialize_android(_EGLDisplay *disp)
  414. EGLBoolean
  415. dri2_initialize_surfaceless(_EGLDisplay *disp);
  416. +#ifdef HAVE_TIZEN_PLATFORM
  417. +EGLBoolean
  418. +dri2_initialize_tizen(_EGLDisplay *disp);
  419. +#endif
  420. +
  421. EGLBoolean
  422. dri2_initialize_device(_EGLDisplay *disp);
  423. static inline void
  424. @@ -559,6 +607,11 @@ dri2_set_WL_bind_wayland_display(_EGLDisplay *disp)
  425. #endif
  426. }
  427. +#ifdef HAVE_TIZEN_PLATFORM
  428. +int
  429. +dri2_fourcc_from_tbm_format(tbm_format format);
  430. +#endif
  431. +
  432. void
  433. dri2_display_destroy(_EGLDisplay *disp);
  434. diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
  435. new file mode 100644
  436. index 0000000..a08bc8c
  437. --- /dev/null
  438. +++ b/src/egl/drivers/dri2/platform_tizen.c
  439. @@ -0,0 +1,980 @@
  440. +/*
  441. + * Mesa 3-D graphics library
  442. + *
  443. + * Copyright (c) Imagination Technologies Ltd.
  444. + * Copyright © 2011 Intel Corporation
  445. + *
  446. + * Permission is hereby granted, free of charge, to any person obtaining a
  447. + * copy of this software and associated documentation files (the "Software"),
  448. + * to deal in the Software without restriction, including without limitation
  449. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  450. + * and/or sell copies of the Software, and to permit persons to whom the
  451. + * Software is furnished to do so, subject to the following conditions:
  452. + *
  453. + * The above copyright notice and this permission notice shall be included
  454. + * in all copies or substantial portions of the Software.
  455. + *
  456. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  457. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  458. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  459. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  460. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  461. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  462. + * DEALINGS IN THE SOFTWARE.
  463. + */
  464. +
  465. +#include <dlfcn.h>
  466. +#include <pthread.h>
  467. +#include <stdio.h>
  468. +#include <string.h>
  469. +#include <tpl.h>
  470. +#include <xf86drm.h>
  471. +
  472. +#include "egl_dri2.h"
  473. +#include "loader.h"
  474. +
  475. +#define TIZEN_DRM_RENDER_MINOR_START 128
  476. +#define TIZEN_DRM_RENDER_MINOR_MAX 191
  477. +
  478. +#define TIZEN_SWAP_N_RECTS_MIN 32
  479. +
  480. +struct rgba_shifts_and_sizes {
  481. + int shifts[4];
  482. + unsigned int sizes[4];
  483. +};
  484. +
  485. +static void *swap_queue_processor_worker(void *data)
  486. +{
  487. + struct dri2_egl_surface *dri2_surf = data;
  488. +
  489. + pthread_mutex_lock(&dri2_surf->mutex);
  490. + while (1) {
  491. + struct tpl_swap_queue_elem *queue_elem;
  492. + int i;
  493. + tpl_result_t res;
  494. +
  495. + if (dri2_surf->swap_queue_idx_head == dri2_surf->swap_queue_idx_tail) {
  496. + /* Wait for new swaps to be added to the queue */
  497. + pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex);
  498. + continue;
  499. + }
  500. +
  501. + queue_elem = &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_head];
  502. + pthread_mutex_unlock(&dri2_surf->mutex);
  503. +
  504. + res = tpl_surface_enqueue_buffer_with_damage(dri2_surf->tpl_surf,
  505. + queue_elem->tbm_surf,
  506. + queue_elem->n_rects,
  507. + queue_elem->rects);
  508. + if (res != TPL_ERROR_NONE)
  509. + return NULL;
  510. +
  511. + pthread_mutex_lock(&dri2_surf->mutex);
  512. + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  513. + if (dri2_surf->color_buffers[i].tbm_surf == queue_elem->tbm_surf) {
  514. + dri2_surf->color_buffers[i].locked = false;
  515. + break;
  516. + }
  517. + }
  518. +
  519. + dri2_surf->swap_queue_idx_head++;
  520. + dri2_surf->swap_queue_idx_head %= ARRAY_SIZE(dri2_surf->swap_queue);
  521. +
  522. + /*
  523. + * Notify get_back_bo that a buffer has become available, reset_surface_cb
  524. + * that it may be able to reset the surface or dri2_tizen_destroy_surface
  525. + * that it may be able to proceed with surface destruction.
  526. + */
  527. + pthread_cond_signal(&dri2_surf->swap_queue_cond);
  528. + }
  529. + pthread_mutex_unlock(&dri2_surf->mutex);
  530. +
  531. + return NULL;
  532. +}
  533. +
  534. +static __DRIimage *
  535. +create_image_from_native(struct dri2_egl_surface *dri2_surf,
  536. + tbm_surface_h tbm_surf,
  537. + int *width, int *height,
  538. + void *loaderPrivate)
  539. +{
  540. + _EGLSurface *surf = &dri2_surf->base;
  541. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(surf->Resource.Display);
  542. + tbm_bo tbm_buf;
  543. + tbm_surface_info_s info;
  544. + int fd, fourcc, offset, pitch;
  545. + __DRIimage *dri_image;
  546. +
  547. + tbm_buf = tbm_surface_internal_get_bo(tbm_surf, 0);
  548. + if (!tbm_buf) {
  549. + _eglLog(_EGL_DEBUG, "%s: failed to get bo for tbm surface", __func__);
  550. + return NULL;
  551. + }
  552. +
  553. + if (tbm_surface_get_info(tbm_surf, &info)) {
  554. + _eglLog(_EGL_DEBUG, "%s: failed to get tbm surface info", __func__);
  555. + return NULL;
  556. + }
  557. +
  558. + fd = tbm_bo_export_fd(tbm_buf);
  559. + fourcc = dri2_fourcc_from_tbm_format(info.format);
  560. + offset = info.planes[0].offset;
  561. + pitch = info.planes[0].stride;
  562. +
  563. + dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
  564. + info.width,
  565. + info.height,
  566. + fourcc,
  567. + &fd,
  568. + 1,
  569. + &pitch,
  570. + &offset,
  571. + loaderPrivate);
  572. + close(fd);
  573. +
  574. + if (!dri_image) {
  575. + _eglLog(_EGL_DEBUG, "%s: failed to create dri image from tbm bo", __func__);
  576. + return NULL;
  577. + }
  578. +
  579. + if (width)
  580. + *width = info.width;
  581. +
  582. + if (height)
  583. + *height = info.height;
  584. +
  585. + return dri_image;
  586. +}
  587. +
  588. +static int
  589. +get_back_bo(struct dri2_egl_surface *dri2_surf, bool allow_update)
  590. +{
  591. + struct dri2_egl_display *dri2_dpy =
  592. + dri2_egl_display(dri2_surf->base.Resource.Display);
  593. + tbm_surface_h tbm_surf;
  594. + tpl_bool_t tpl_surf_valid;
  595. + int i;
  596. +
  597. + if (dri2_surf->base.Type == EGL_PIXMAP_BIT) {
  598. + _eglLog(_EGL_DEBUG, "%s: can't get back bo for pixmap surface", __func__);
  599. + return -1;
  600. + }
  601. +
  602. + if (dri2_surf->back && !allow_update)
  603. + return 0;
  604. +
  605. + /*
  606. + * If the tpl surface is no longer valid, e.g. it has been resized, then
  607. + * we should get a new back buffer.
  608. + */
  609. + tpl_surf_valid = tpl_surface_validate(dri2_surf->tpl_surf);
  610. + if (dri2_surf->back && tpl_surf_valid == TPL_TRUE)
  611. + return 0;
  612. +
  613. + tbm_surf = tpl_surface_dequeue_buffer(dri2_surf->tpl_surf);
  614. + if (!tbm_surf) {
  615. + _eglLog(_EGL_DEBUG, "%s: surface buffer dequeue failed", __func__);
  616. + return -1;
  617. + }
  618. +
  619. + pthread_mutex_lock(&dri2_surf->mutex);
  620. + /*
  621. + * If the tpl surface is no longer valid, e.g. it has been resized, then the
  622. + * call to tpl_surface should've resulted in a call to reset_surface_cb,
  623. + * which sets the dri2_surf reset flag. In this case we need to reset the
  624. + * color_buffer state.
  625. + *
  626. + * Note: we can't rely on the return value of tpl_surface_validate
  627. + * since the surface may have become invalid between this call and
  628. + * tpl_surface_dequeue_buffer.
  629. + */
  630. + if (dri2_surf->reset) {
  631. + /* Wait for any outstanding swaps to complete */
  632. + while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
  633. + pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex);
  634. +
  635. + /* Cancel the old back buffer */
  636. + if (dri2_surf->back) {
  637. + tbm_surface_internal_unref(dri2_surf->back->tbm_surf);
  638. + dri2_surf->back->locked = false;
  639. + dri2_surf->back = NULL;
  640. + }
  641. +
  642. + /* Reset the color buffers */
  643. + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  644. + assert(!dri2_surf->color_buffers[i].locked);
  645. +
  646. + if (dri2_surf->color_buffers[i].dri_image) {
  647. + dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
  648. + dri2_surf->color_buffers[i].dri_image = NULL;
  649. + }
  650. +
  651. + dri2_surf->color_buffers[i].tbm_surf = NULL;
  652. + dri2_surf->color_buffers[i].age = 0;
  653. + }
  654. +
  655. + dri2_surf->back = NULL;
  656. + dri2_surf->current = NULL;
  657. + dri2_surf->reset = false;
  658. + }
  659. +
  660. + assert(!dri2_surf->back);
  661. +
  662. + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  663. + if (dri2_surf->color_buffers[i].tbm_surf == tbm_surf) {
  664. + dri2_surf->back = &dri2_surf->color_buffers[i];
  665. + assert(!dri2_surf->back->locked);
  666. + break;
  667. + }
  668. + }
  669. +
  670. + while (!dri2_surf->back) {
  671. + int age;
  672. +
  673. + /*
  674. + * Search for a free color buffer. Free the oldest buffer if one
  675. + * cannot be found.
  676. + */
  677. + for (i = 0, age = -1; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  678. + if (dri2_surf->color_buffers[i].locked)
  679. + continue;
  680. + if (!dri2_surf->color_buffers[i].dri_image) {
  681. + dri2_surf->back = &dri2_surf->color_buffers[i];
  682. + break;
  683. + }
  684. +
  685. + if (dri2_surf->color_buffers[i].age > age) {
  686. + dri2_surf->back = &dri2_surf->color_buffers[i];
  687. + age = dri2_surf->color_buffers[i].age;
  688. + }
  689. + }
  690. +
  691. + if (!dri2_surf->back) {
  692. + /*
  693. + * There aren't any available back buffers so wait for
  694. + * swap_queue_processor_worker to make one available.
  695. + */
  696. + pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex);
  697. + continue;
  698. + }
  699. +
  700. + if (dri2_surf->back->dri_image)
  701. + dri2_dpy->image->destroyImage(dri2_surf->back->dri_image);
  702. +
  703. + dri2_surf->back->dri_image =
  704. + create_image_from_native(dri2_surf, tbm_surf,
  705. + &dri2_surf->base.Width,
  706. + &dri2_surf->base.Height,
  707. + dri2_surf);
  708. + if (!dri2_surf->back->dri_image) {
  709. + dri2_surf->back = NULL;
  710. + pthread_mutex_unlock(&dri2_surf->mutex);
  711. + return -1;
  712. + }
  713. + }
  714. +
  715. + dri2_surf->back->tbm_surf = tbm_surf;
  716. + dri2_surf->back->locked = true;
  717. +
  718. + if (dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED &&
  719. + dri2_surf->current) {
  720. + _EGLContext *ctx = _eglGetCurrentContext();
  721. + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
  722. +
  723. + if (dri2_ctx)
  724. + {
  725. + dri2_dpy->image->blitImage(dri2_ctx->dri_context,
  726. + dri2_surf->back->dri_image,
  727. + dri2_surf->current->dri_image,
  728. + 0, 0, dri2_surf->base.Width,
  729. + dri2_surf->base.Height,
  730. + 0, 0, dri2_surf->base.Width,
  731. + dri2_surf->base.Height,
  732. + __BLIT_FLAG_FLUSH);
  733. + }
  734. + }
  735. +
  736. + pthread_mutex_unlock(&dri2_surf->mutex);
  737. +
  738. + return 0;
  739. +}
  740. +
  741. +static int
  742. +get_front_bo(struct dri2_egl_surface *dri2_surf)
  743. +{
  744. + struct dri2_egl_display *dri2_dpy =
  745. + dri2_egl_display(dri2_surf->base.Resource.Display);
  746. +
  747. + if (dri2_surf->front)
  748. + return 0;
  749. +
  750. + if (dri2_surf->base.Type == EGL_PIXMAP_BIT) {
  751. + tbm_surface_h tbm_surf;
  752. +
  753. + tbm_surf = tpl_surface_dequeue_buffer(dri2_surf->tpl_surf);
  754. + if (!tbm_surf)
  755. + return -1;
  756. +
  757. + dri2_surf->front = create_image_from_native(dri2_surf, tbm_surf,
  758. + &dri2_surf->base.Width,
  759. + &dri2_surf->base.Height,
  760. + dri2_surf);
  761. + } else {
  762. + dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen,
  763. + dri2_surf->base.Width,
  764. + dri2_surf->base.Height,
  765. + dri2_surf->visual,
  766. + 0,
  767. + dri2_surf);
  768. + }
  769. +
  770. + return dri2_surf->front ? 0 : -1;
  771. +}
  772. +
  773. +static _EGLSurface *
  774. +create_surface(_EGLDisplay *dpy, _EGLConfig *config, EGLint type,
  775. + const EGLint *attrib_list)
  776. +{
  777. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
  778. + struct dri2_egl_config *dri2_config = dri2_egl_config(config);
  779. + struct dri2_egl_surface *dri2_surf;
  780. + const __DRIconfig *dri_config;
  781. +
  782. + dri2_surf = calloc(1, sizeof(*dri2_surf));
  783. + if (!dri2_surf) {
  784. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to create surface");
  785. + return NULL;
  786. + }
  787. +
  788. + if (!dri2_init_surface(&dri2_surf->base, dpy, type, config, attrib_list,
  789. + false, NULL))
  790. + goto err_free_surface;
  791. +
  792. + dri_config = dri2_get_dri_config(dri2_config, type,
  793. + dri2_surf->base.GLColorspace);
  794. + if (!dri_config) {
  795. + _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
  796. + goto err_free_surface;
  797. + }
  798. +
  799. + dri2_surf->dri_drawable =
  800. + dri2_dpy->image_driver->createNewDrawable(dri2_dpy->dri_screen,
  801. + dri_config, dri2_surf);
  802. + if (!dri2_surf->dri_drawable) {
  803. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to create drawable");
  804. + goto err_free_surface;
  805. + }
  806. +
  807. + pthread_mutex_init(&dri2_surf->mutex, NULL);
  808. + pthread_cond_init(&dri2_surf->swap_queue_cond, NULL);
  809. +
  810. + return &dri2_surf->base;
  811. +
  812. +err_free_surface:
  813. + free(dri2_surf);
  814. + return NULL;
  815. +}
  816. +
  817. +static void
  818. +destroy_surface(_EGLSurface *surf)
  819. +{
  820. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(surf->Resource.Display);
  821. + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  822. +
  823. + pthread_cond_destroy(&dri2_surf->swap_queue_cond);
  824. + pthread_mutex_destroy(&dri2_surf->mutex);
  825. + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
  826. + free(dri2_surf);
  827. +}
  828. +
  829. +static void
  830. +reset_surface_cb(void *data)
  831. +{
  832. + struct dri2_egl_surface *dri2_surf = data;
  833. +
  834. + dri2_surf->reset = true;
  835. +}
  836. +
  837. +static _EGLSurface *
  838. +dri2_tizen_create_window_surface(_EGLDisplay *dpy, _EGLConfig *config,
  839. + void *native_window, const EGLint *attrib_list)
  840. +{
  841. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
  842. + struct dri2_egl_surface *dri2_surf;
  843. + _EGLSurface *surf;
  844. + int width, height;
  845. + tbm_format format;
  846. + tpl_result_t res;
  847. + int err;
  848. +
  849. + surf = create_surface(dpy, config, EGL_WINDOW_BIT, attrib_list);
  850. + if (!surf)
  851. + return NULL;
  852. +
  853. + res = tpl_display_get_native_window_info(dri2_dpy->tpl_dpy, native_window,
  854. + &width, &height, &format,
  855. + config->RedSize +
  856. + config->GreenSize +
  857. + config->BlueSize +
  858. + config->AlphaSize,
  859. + config->AlphaSize);
  860. + if (res != TPL_ERROR_NONE) {
  861. + _eglError(EGL_BAD_NATIVE_WINDOW, "DRI2: failed to get window info");
  862. + goto err_destroy_surface;
  863. + }
  864. +
  865. + dri2_surf = dri2_egl_surface(surf);
  866. + dri2_surf->base.Width = width;
  867. + dri2_surf->base.Height = height;
  868. +
  869. + dri2_surf->tpl_surf = tpl_surface_create(dri2_dpy->tpl_dpy, native_window,
  870. + TPL_SURFACE_TYPE_WINDOW, format);
  871. + if (!dri2_surf->tpl_surf) {
  872. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to create TPL window surface");
  873. + goto err_destroy_surface;
  874. + }
  875. +
  876. + res = tpl_surface_set_reset_cb(dri2_surf->tpl_surf, dri2_surf,
  877. + reset_surface_cb);
  878. + if (res != TPL_ERROR_NONE) {
  879. + _eglError(EGL_BAD_NATIVE_WINDOW,
  880. + "DRI2: failed to register TPL window surface reset callback");
  881. + goto err_tpl_surface_destroy;
  882. + }
  883. +
  884. + err = pthread_create(&dri2_surf->swap_queue_processor, NULL,
  885. + swap_queue_processor_worker, dri2_surf);
  886. + if (err) {
  887. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to create TPL window thread");
  888. + goto err_tpl_surface_destroy;
  889. + }
  890. +
  891. + return surf;
  892. +
  893. +err_tpl_surface_destroy:
  894. + tpl_object_unreference((tpl_object_t *) dri2_surf->tpl_surf);
  895. +err_destroy_surface:
  896. + destroy_surface(surf);
  897. + return NULL;
  898. +}
  899. +
  900. +static _EGLSurface *
  901. +dri2_tizen_create_pixmap_surface(_EGLDisplay *dpy, _EGLConfig *config,
  902. + void *native_pixmap, const EGLint *attrib_list)
  903. +{
  904. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
  905. + struct dri2_egl_surface *dri2_surf;
  906. + _EGLSurface *surf;
  907. + int width, height;
  908. + tbm_format format;
  909. + tpl_result_t res;
  910. +
  911. + surf = create_surface(dpy, config, EGL_PIXMAP_BIT, attrib_list);
  912. + if (!surf)
  913. + return NULL;
  914. +
  915. + res = tpl_display_get_native_pixmap_info(dri2_dpy->tpl_dpy, native_pixmap,
  916. + &width, &height, &format);
  917. + if (res != TPL_ERROR_NONE) {
  918. + _eglError(EGL_BAD_NATIVE_PIXMAP, "DRI2: failed to get pixmap info");
  919. + goto err_destroy_surface;
  920. + }
  921. +
  922. + dri2_surf = dri2_egl_surface(surf);
  923. + dri2_surf->base.Width = width;
  924. + dri2_surf->base.Height = height;
  925. +
  926. + dri2_surf->tpl_surf = tpl_surface_create(dri2_dpy->tpl_dpy, native_pixmap,
  927. + TPL_SURFACE_TYPE_PIXMAP, format);
  928. + if (!dri2_surf->tpl_surf) {
  929. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to create TPL pixmap surface");
  930. + goto err_destroy_surface;
  931. + }
  932. +
  933. + return surf;
  934. +
  935. +err_destroy_surface:
  936. + destroy_surface(surf);
  937. + return NULL;
  938. +}
  939. +
  940. +static _EGLSurface *
  941. +dri2_tizen_create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *config,
  942. + const EGLint *attrib_list)
  943. +{
  944. + struct dri2_egl_surface *dri2_surf;
  945. + _EGLSurface *surf;
  946. +
  947. + surf = create_surface(dpy, config, EGL_PBUFFER_BIT, attrib_list);
  948. + if (!surf)
  949. + return NULL;
  950. +
  951. + dri2_surf = dri2_egl_surface(surf);
  952. +
  953. + if (config->RedSize == 5)
  954. + dri2_surf->visual = __DRI_IMAGE_FORMAT_RGB565;
  955. + else if (config->AlphaSize)
  956. + dri2_surf->visual = __DRI_IMAGE_FORMAT_ARGB8888;
  957. + else
  958. + dri2_surf->visual = __DRI_IMAGE_FORMAT_XRGB8888;
  959. +
  960. + return surf;
  961. +}
  962. +
  963. +static EGLBoolean
  964. +dri2_tizen_destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
  965. +{
  966. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
  967. + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  968. + int i;
  969. +
  970. + if (dri2_surf->swap_queue_processor) {
  971. + /* Wait for any outstanding swaps to complete */
  972. + pthread_mutex_lock(&dri2_surf->mutex);
  973. + while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
  974. + pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex);
  975. + pthread_mutex_unlock(&dri2_surf->mutex);
  976. +
  977. + pthread_cancel(dri2_surf->swap_queue_processor);
  978. + pthread_join(dri2_surf->swap_queue_processor, NULL);
  979. + }
  980. +
  981. + for (i = 0; i < ARRAY_SIZE(dri2_surf->swap_queue); i++)
  982. + free(dri2_surf->swap_queue[i].rects);
  983. +
  984. + if (dri2_surf->front)
  985. + dri2_dpy->image->destroyImage(dri2_surf->front);
  986. +
  987. + if (dri2_surf->back) {
  988. + tbm_surface_internal_unref(dri2_surf->back->tbm_surf);
  989. + dri2_surf->back->locked = false;
  990. + }
  991. +
  992. + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  993. + if (dri2_surf->color_buffers[i].dri_image)
  994. + dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
  995. + assert(!dri2_surf->color_buffers[i].locked);
  996. + }
  997. +
  998. + if (dri2_surf->tpl_surf)
  999. + tpl_object_unreference((tpl_object_t *) dri2_surf->tpl_surf);
  1000. +
  1001. + destroy_surface(surf);
  1002. +
  1003. + return EGL_TRUE;
  1004. +}
  1005. +
  1006. +static EGLBoolean
  1007. +dri2_tizen_swap_interval(_EGLDisplay *dpy, _EGLSurface *surf, EGLint interval)
  1008. +{
  1009. + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  1010. + tpl_result_t res;
  1011. +
  1012. + if (interval > surf->Config->MaxSwapInterval)
  1013. + interval = surf->Config->MaxSwapInterval;
  1014. + else if (interval < surf->Config->MinSwapInterval)
  1015. + interval = surf->Config->MinSwapInterval;
  1016. +
  1017. + if (interval == surf->SwapInterval)
  1018. + return EGL_TRUE;
  1019. +
  1020. + res = tpl_surface_set_post_interval(dri2_surf->tpl_surf, interval);
  1021. + if (res == TPL_ERROR_NONE) {
  1022. + surf->SwapInterval = interval;
  1023. + return EGL_TRUE;
  1024. + }
  1025. +
  1026. + return EGL_FALSE;
  1027. +}
  1028. +
  1029. +static EGLBoolean
  1030. +dri2_tizen_swap_buffers_with_damage(_EGLDisplay *dpy, _EGLSurface *draw,
  1031. + const EGLint *rects, EGLint n_rects)
  1032. +{
  1033. + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  1034. + struct tpl_swap_queue_elem *queue_elem;
  1035. + int i;
  1036. +
  1037. + if (dri2_surf->base.Type != EGL_WINDOW_BIT)
  1038. + return EGL_TRUE;
  1039. +
  1040. + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  1041. + if (draw->SwapBehavior == EGL_BUFFER_PRESERVED)
  1042. + dri2_surf->color_buffers[i].age = 1;
  1043. + else if (dri2_surf->color_buffers[i].age > 0)
  1044. + dri2_surf->color_buffers[i].age++;
  1045. + }
  1046. +
  1047. + /*
  1048. + * Make sure we have a back buffer in case we're swapping without ever
  1049. + * rendering.
  1050. + */
  1051. + if (get_back_bo(dri2_surf, false) < 0) {
  1052. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to get back buffer");
  1053. + return EGL_FALSE;
  1054. + }
  1055. +
  1056. + dri2_flush_drawable_for_swapbuffers(dpy, draw);
  1057. +
  1058. + pthread_mutex_lock(&dri2_surf->mutex);
  1059. + queue_elem =
  1060. + &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_tail];
  1061. +
  1062. + queue_elem->tbm_surf = dri2_surf->back->tbm_surf;
  1063. +
  1064. + /* Allocate space for damage rectangles in swap queue element if necessary */
  1065. + if (queue_elem->n_rects_max < n_rects) {
  1066. + free(queue_elem->rects);
  1067. +
  1068. + if (!queue_elem->n_rects_max)
  1069. + queue_elem->n_rects_max = TIZEN_SWAP_N_RECTS_MIN;
  1070. +
  1071. + while (queue_elem->n_rects_max <= n_rects)
  1072. + queue_elem->n_rects_max *= 2;
  1073. +
  1074. + queue_elem->rects =
  1075. + malloc(sizeof(*queue_elem->rects) * queue_elem->n_rects_max);
  1076. + if (!queue_elem->rects) {
  1077. + _eglError(EGL_BAD_ALLOC,
  1078. + "DRI2: failed to allocate space for damage rects");
  1079. + queue_elem->n_rects_max = 0;
  1080. + pthread_mutex_unlock(&dri2_surf->mutex);
  1081. + return EGL_FALSE;
  1082. + }
  1083. + }
  1084. +
  1085. + /* Copy damage rectangles into swap queue element */
  1086. + STATIC_ASSERT(sizeof(*queue_elem->rects) == sizeof(*rects));
  1087. + memcpy(&queue_elem->rects[0], &rects[0], sizeof(*rects) * n_rects);
  1088. + queue_elem->n_rects = n_rects;
  1089. +
  1090. + dri2_surf->swap_queue_idx_tail++;
  1091. + dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->color_buffers);
  1092. +
  1093. + /* Notify swap_queue_processor_worker that there's new work */
  1094. + pthread_cond_signal(&dri2_surf->swap_queue_cond);
  1095. + pthread_mutex_unlock(&dri2_surf->mutex);
  1096. +
  1097. + dri2_surf->back->age = 1;
  1098. + dri2_surf->current = dri2_surf->back;
  1099. + dri2_surf->back = NULL;
  1100. +
  1101. + return EGL_TRUE;
  1102. +}
  1103. +
  1104. +static EGLBoolean
  1105. +dri2_tizen_swap_buffers(_EGLDisplay *dpy, _EGLSurface *draw)
  1106. +{
  1107. + return dri2_tizen_swap_buffers_with_damage(dpy, draw, NULL, 0);
  1108. +}
  1109. +
  1110. +static EGLint
  1111. +dri2_tizen_query_buffer_age(_EGLDisplay *dpy, _EGLSurface *surface)
  1112. +{
  1113. + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
  1114. +
  1115. + if (get_back_bo(dri2_surf, false) < 0) {
  1116. + _eglError(EGL_BAD_ALLOC, "DRI2: failed to get back buffer");
  1117. + return -1;
  1118. + }
  1119. +
  1120. + return dri2_surf->back->age;
  1121. +}
  1122. +
  1123. +
  1124. +static EGLBoolean
  1125. +dri2_tizen_query_surface(_EGLDisplay *dpy, _EGLSurface *surf,
  1126. + EGLint attribute, EGLint *value)
  1127. +{
  1128. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
  1129. + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  1130. +
  1131. + switch (attribute) {
  1132. + case EGL_WIDTH:
  1133. + case EGL_HEIGHT:
  1134. + if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  1135. + tpl_handle_t window;
  1136. + int width, height;
  1137. + tbm_format format;
  1138. + tpl_result_t res;
  1139. +
  1140. + window = tpl_surface_get_native_handle(dri2_surf->tpl_surf);
  1141. +
  1142. + res = tpl_display_get_native_window_info(dri2_dpy->tpl_dpy, window,
  1143. + &width, &height, &format,
  1144. + surf->Config->RedSize +
  1145. + surf->Config->GreenSize +
  1146. + surf->Config->BlueSize +
  1147. + surf->Config->AlphaSize,
  1148. + surf->Config->AlphaSize);
  1149. + if (res == TPL_ERROR_NONE) {
  1150. + surf->Width = width;
  1151. + surf->Height = height;
  1152. + }
  1153. + }
  1154. + break;
  1155. + default:
  1156. + break;
  1157. + }
  1158. +
  1159. + return _eglQuerySurface(dpy, surf, attribute, value);
  1160. +}
  1161. +
  1162. +
  1163. +static struct dri2_egl_display_vtbl dri2_tizen_display_vtbl = {
  1164. + .create_window_surface = dri2_tizen_create_window_surface,
  1165. + .create_pixmap_surface = dri2_tizen_create_pixmap_surface,
  1166. + .create_pbuffer_surface = dri2_tizen_create_pbuffer_surface,
  1167. + .destroy_surface = dri2_tizen_destroy_surface,
  1168. + .create_image = dri2_create_image_khr,
  1169. + .swap_interval = dri2_tizen_swap_interval,
  1170. + .swap_buffers = dri2_tizen_swap_buffers,
  1171. + .swap_buffers_with_damage = dri2_tizen_swap_buffers_with_damage,
  1172. + .query_buffer_age = dri2_tizen_query_buffer_age,
  1173. + .query_surface = dri2_tizen_query_surface,
  1174. + .get_dri_drawable = dri2_surface_get_dri_drawable,
  1175. +};
  1176. +
  1177. +static int
  1178. +dri2_tizen_get_buffers(__DRIdrawable *driDrawable,
  1179. + unsigned int format,
  1180. + uint32_t *stamp,
  1181. + void *loaderPrivate,
  1182. + uint32_t buffer_mask,
  1183. + struct __DRIimageList *buffers)
  1184. +{
  1185. + struct dri2_egl_surface *dri2_surf = loaderPrivate;
  1186. +
  1187. + buffers->image_mask = 0;
  1188. + buffers->front = NULL;
  1189. + buffers->back = NULL;
  1190. +
  1191. + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT)
  1192. + if (get_front_bo(dri2_surf) < 0)
  1193. + return 0;
  1194. +
  1195. + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK)
  1196. + if (get_back_bo(dri2_surf, true) < 0)
  1197. + return 0;
  1198. +
  1199. + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
  1200. + buffers->front = dri2_surf->front;
  1201. + buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
  1202. + }
  1203. +
  1204. + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
  1205. + buffers->back = dri2_surf->back->dri_image;
  1206. + buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
  1207. + }
  1208. +
  1209. + return 1;
  1210. +}
  1211. +
  1212. +static void
  1213. +dri2_tizen_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
  1214. +{
  1215. +}
  1216. +
  1217. +static const __DRIimageLoaderExtension tizen_image_loader_extension = {
  1218. + .base = { __DRI_IMAGE_LOADER, 1 },
  1219. + .getBuffers = dri2_tizen_get_buffers,
  1220. + .flushFrontBuffer = dri2_tizen_flush_front_buffer,
  1221. +};
  1222. +
  1223. +static const __DRIextension *image_loader_extensions[] = {
  1224. + &tizen_image_loader_extension.base,
  1225. + &image_lookup_extension.base,
  1226. + NULL,
  1227. +};
  1228. +
  1229. +static EGLBoolean
  1230. +dri2_tizen_add_configs(_EGLDisplay *dpy)
  1231. +{
  1232. + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
  1233. + int count = 0;
  1234. +
  1235. + for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
  1236. + static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
  1237. + {
  1238. + /* ARGB8888 */
  1239. + { 16, 8, 0, 24 },
  1240. + { 8, 8, 8, 8 },
  1241. + },
  1242. + {
  1243. + /* RGB888 */
  1244. + { 16, 8, 0, -1 },
  1245. + { 8, 8, 8, 0 },
  1246. + },
  1247. + {
  1248. + /* RGB565 */
  1249. + { 11, 5, 0, -1 },
  1250. + { 5, 6, 5, 0 },
  1251. + },
  1252. + };
  1253. + struct dri2_egl_config *dri2_cfg;
  1254. + int shifts[4];
  1255. + unsigned int sizes[4];
  1256. + unsigned int caveat = 0;
  1257. + int surface_type = 0;
  1258. + tpl_bool_t is_slow;
  1259. + EGLint attr_list[] = {
  1260. + EGL_NATIVE_VISUAL_ID, 0,
  1261. + EGL_CONFIG_CAVEAT, EGL_NONE,
  1262. + EGL_NONE,
  1263. + };
  1264. + tpl_result_t res;
  1265. +
  1266. + dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
  1267. + shifts, sizes);
  1268. +
  1269. + dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
  1270. + __DRI_ATTRIB_BUFFER_SIZE, &depth);
  1271. +
  1272. + dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
  1273. + __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
  1274. +
  1275. + res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_WINDOW,
  1276. + sizes[0], sizes[1], sizes[2], sizes[3],
  1277. + depth, &attr_list[1], &is_slow);
  1278. + if (res != TPL_ERROR_NONE)
  1279. + continue;
  1280. + surface_type |= EGL_WINDOW_BIT;
  1281. +
  1282. + if (is_slow)
  1283. + caveat |= __DRI_ATTRIB_SLOW_BIT;
  1284. +
  1285. + res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_PIXMAP,
  1286. + sizes[0], sizes[1], sizes[2], sizes[3],
  1287. + depth, NULL, &is_slow);
  1288. + if (res == TPL_ERROR_NONE) {
  1289. + surface_type |= EGL_PIXMAP_BIT;
  1290. +
  1291. + if (is_slow)
  1292. + caveat |= __DRI_ATTRIB_SLOW_BIT;
  1293. + }
  1294. +
  1295. + for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
  1296. + const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
  1297. +
  1298. + if (shifts[0] == pbuffer_sas->shifts[0] &&
  1299. + shifts[1] == pbuffer_sas->shifts[1] &&
  1300. + shifts[2] == pbuffer_sas->shifts[2] &&
  1301. + shifts[3] == pbuffer_sas->shifts[3] &&
  1302. + sizes[0] == pbuffer_sas->sizes[0] &&
  1303. + sizes[1] == pbuffer_sas->sizes[1] &&
  1304. + sizes[2] == pbuffer_sas->sizes[2] &&
  1305. + sizes[3] == pbuffer_sas->sizes[3]) {
  1306. + surface_type |= EGL_PBUFFER_BIT;
  1307. + break;
  1308. + }
  1309. + }
  1310. +
  1311. + if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
  1312. + surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
  1313. +
  1314. + if (caveat & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
  1315. + attr_list[3] = EGL_NON_CONFORMANT_CONFIG;
  1316. + else if (caveat & __DRI_ATTRIB_SLOW_BIT)
  1317. + attr_list[3] = EGL_SLOW_CONFIG;
  1318. +
  1319. + dri2_cfg = dri2_add_config(dpy, dri2_dpy->driver_configs[i], count + 1,
  1320. + surface_type, &attr_list[0], NULL, NULL);
  1321. + if (dri2_cfg)
  1322. + count++;
  1323. + }
  1324. +
  1325. + return count != 0;
  1326. +}
  1327. +
  1328. +EGLBoolean
  1329. +dri2_initialize_tizen(_EGLDisplay *dpy)
  1330. +{
  1331. + struct dri2_egl_display *dri2_dpy;
  1332. + int i;
  1333. +
  1334. + dri2_dpy = calloc(1, sizeof(*dri2_dpy));
  1335. + if (!dri2_dpy)
  1336. + return _eglError(EGL_BAD_ALLOC, "DRI2: failed to create display");
  1337. +
  1338. + dpy->DriverData = (void *) dri2_dpy;
  1339. + dri2_dpy->fd = -1;
  1340. +
  1341. + dri2_dpy->tpl_dpy =
  1342. + tpl_display_create(TPL_BACKEND_UNKNOWN, dpy->PlatformDisplay);
  1343. + if (!dri2_dpy->tpl_dpy) {
  1344. + _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to create tpl display");
  1345. + goto cleanup;
  1346. + }
  1347. +
  1348. + for (i = TIZEN_DRM_RENDER_MINOR_START; i <= TIZEN_DRM_RENDER_MINOR_MAX; i++) {
  1349. + char *render_path;
  1350. +
  1351. + if (asprintf(&render_path, DRM_RENDER_DEV_NAME, DRM_DIR_NAME, i) < 0)
  1352. + continue;
  1353. +
  1354. + dri2_dpy->fd = loader_open_device(render_path);
  1355. + free(render_path);
  1356. + if (dri2_dpy->fd < 0)
  1357. + continue;
  1358. +
  1359. + dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
  1360. + if (dri2_dpy->driver_name) {
  1361. + if (dri2_load_driver_dri3(dpy)) {
  1362. + _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
  1363. + if (!dev) {
  1364. + dlclose(dri2_dpy->driver);
  1365. + _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
  1366. + } else {
  1367. + dri2_dpy->own_device = 1;
  1368. + dpy->Device = dev;
  1369. + break;
  1370. + }
  1371. + }
  1372. +
  1373. + free(dri2_dpy->driver_name);
  1374. + dri2_dpy->driver_name = NULL;
  1375. + }
  1376. +
  1377. + close(dri2_dpy->fd);
  1378. + dri2_dpy->fd = -1;
  1379. + }
  1380. +
  1381. + if (dri2_dpy->fd < 0) {
  1382. + _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to load driver");
  1383. + goto cleanup;
  1384. + }
  1385. +
  1386. + dri2_dpy->loader_extensions = &image_loader_extensions[0];
  1387. +
  1388. + if (!dri2_create_screen(dpy)) {
  1389. + _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to create screen");
  1390. + goto cleanup;
  1391. + }
  1392. +
  1393. + if (!dri2_setup_extensions(dpy))
  1394. + goto cleanup;
  1395. +
  1396. + dri2_setup_screen(dpy);
  1397. +
  1398. + if (!dri2_tizen_add_configs(dpy)) {
  1399. + _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
  1400. + goto cleanup;
  1401. + }
  1402. +
  1403. + dpy->Extensions.EXT_buffer_age = EGL_TRUE;
  1404. + dpy->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
  1405. + dpy->Extensions.KHR_image_base = EGL_TRUE;
  1406. + dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
  1407. +
  1408. + /*
  1409. + * Fill vtbl last to prevent accidentally calling virtual function during
  1410. + * initialization.
  1411. + */
  1412. + dri2_dpy->vtbl = &dri2_tizen_display_vtbl;
  1413. +
  1414. + return EGL_TRUE;
  1415. +
  1416. +cleanup:
  1417. + dri2_display_destroy(dpy);
  1418. + return EGL_FALSE;
  1419. +}
  1420. diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
  1421. index 234449a..43c7b91 100644
  1422. --- a/src/egl/main/eglapi.c
  1423. +++ b/src/egl/main/eglapi.c
  1424. @@ -416,6 +416,13 @@ _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
  1425. case EGL_PLATFORM_DEVICE_EXT:
  1426. disp = _eglGetDeviceDisplay(native_display, attrib_list);
  1427. break;
  1428. +#ifdef HAVE_TIZEN_PLATFORM
  1429. + case EGL_PLATFORM_GBM_MESA:
  1430. + case EGL_PLATFORM_WAYLAND_EXT:
  1431. + disp = _eglGetTizenDisplay((struct gbm_device*) native_display,
  1432. + attrib_list);
  1433. + break;
  1434. +#endif
  1435. default:
  1436. RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
  1437. }
  1438. diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
  1439. index 765618f..486ac3b 100644
  1440. --- a/src/egl/main/egldisplay.c
  1441. +++ b/src/egl/main/egldisplay.c
  1442. @@ -77,6 +77,7 @@ static const struct {
  1443. { _EGL_PLATFORM_HAIKU, "haiku" },
  1444. { _EGL_PLATFORM_SURFACELESS, "surfaceless" },
  1445. { _EGL_PLATFORM_DEVICE, "device" },
  1446. + { _EGL_PLATFORM_TIZEN, "tizen" },
  1447. };
  1448. @@ -107,6 +108,17 @@ _eglGetNativePlatformFromEnv(void)
  1449. }
  1450. }
  1451. +#ifdef HAVE_TIZEN_PLATFORM
  1452. + switch (plat) {
  1453. + case _EGL_PLATFORM_DRM:
  1454. + case _EGL_PLATFORM_WAYLAND:
  1455. + plat = _EGL_PLATFORM_TIZEN;
  1456. + break;
  1457. + default:
  1458. + break;
  1459. + }
  1460. +#endif
  1461. +
  1462. if (plat == _EGL_INVALID_PLATFORM)
  1463. _eglLog(_EGL_WARNING, "invalid EGL_PLATFORM given");
  1464. @@ -120,6 +132,7 @@ _eglGetNativePlatformFromEnv(void)
  1465. static _EGLPlatformType
  1466. _eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
  1467. {
  1468. +#ifndef HAVE_TIZEN_PLATFORM
  1469. if (nativeDisplay == EGL_DEFAULT_DISPLAY)
  1470. return _EGL_INVALID_PLATFORM;
  1471. @@ -141,7 +154,7 @@ _eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
  1472. return _EGL_PLATFORM_DRM;
  1473. #endif
  1474. }
  1475. -
  1476. +#endif
  1477. return _EGL_INVALID_PLATFORM;
  1478. }
  1479. @@ -595,6 +608,23 @@ _eglGetAndroidDisplay(void *native_display,
  1480. }
  1481. #endif /* HAVE_ANDROID_PLATFORM */
  1482. +#ifdef HAVE_TIZEN_PLATFORM
  1483. +_EGLDisplay*
  1484. +_eglGetTizenDisplay(void *native_display,
  1485. + const EGLint *attrib_list)
  1486. +{
  1487. + /* EGL_MESA_platform_gbm and EGL_EXT_platform_wayland recognizes no
  1488. + * attributes. */
  1489. + if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
  1490. + _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
  1491. + return NULL;
  1492. + }
  1493. +
  1494. + return _eglFindDisplay(_EGL_PLATFORM_TIZEN, native_display,
  1495. + attrib_list);
  1496. +}
  1497. +#endif /* HAVE_TIZEN_PLATFORM */
  1498. +
  1499. _EGLDisplay*
  1500. _eglGetDeviceDisplay(void *native_display,
  1501. const EGLAttrib *attrib_list)
  1502. diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
  1503. index 5b05dcc..cbb0983 100644
  1504. --- a/src/egl/main/egldisplay.h
  1505. +++ b/src/egl/main/egldisplay.h
  1506. @@ -52,6 +52,7 @@ enum _egl_platform_type {
  1507. _EGL_PLATFORM_HAIKU,
  1508. _EGL_PLATFORM_SURFACELESS,
  1509. _EGL_PLATFORM_DEVICE,
  1510. + _EGL_PLATFORM_TIZEN,
  1511. _EGL_NUM_PLATFORMS,
  1512. _EGL_INVALID_PLATFORM = -1
  1513. @@ -329,6 +330,12 @@ _eglGetAndroidDisplay(void *native_display,
  1514. const EGLAttrib *attrib_list);
  1515. #endif
  1516. +#ifdef HAVE_TIZEN_PLATFORM
  1517. +_EGLDisplay*
  1518. +_eglGetTizenDisplay(void *native_display,
  1519. + const EGLint *attrib_list);
  1520. +#endif
  1521. +
  1522. _EGLDisplay*
  1523. _eglGetDeviceDisplay(void *native_display,
  1524. const EGLAttrib *attrib_list);
  1525. diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c
  1526. index 6a91952..973b760 100644
  1527. --- a/src/egl/main/egllog.c
  1528. +++ b/src/egl/main/egllog.c
  1529. @@ -46,15 +46,17 @@
  1530. #include "egllog.h"
  1531. -#ifdef HAVE_ANDROID_PLATFORM
  1532. #define LOG_TAG "EGL-MAIN"
  1533. +
  1534. +#ifdef HAVE_ANDROID_PLATFORM
  1535. #if ANDROID_API_LEVEL >= 26
  1536. #include <log/log.h>
  1537. #else
  1538. #include <cutils/log.h>
  1539. #endif /* use log/log.h start from android 8 major version */
  1540. -
  1541. -#endif /* HAVE_ANDROID_PLATFORM */
  1542. +#elif defined(HAVE_TIZEN_PLATFORM)
  1543. +#include <dlog.h>
  1544. +#endif /* HAVE_TIZEN_PLATFORM */
  1545. #define MAXSTRING 1000
  1546. #define FALLBACK_LOG_LEVEL _EGL_WARNING
  1547. @@ -93,9 +95,26 @@ _eglDefaultLogger(EGLint level, const char *msg)
  1548. [_EGL_DEBUG] = ANDROID_LOG_DEBUG,
  1549. };
  1550. LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg);
  1551. +#elif defined(HAVE_TIZEN_PLATFORM)
  1552. + switch (level) {
  1553. + case _EGL_DEBUG:
  1554. + LOGD("%s", msg);
  1555. + break;
  1556. + case _EGL_INFO:
  1557. + LOGI("%s", msg);
  1558. + break;
  1559. + case _EGL_WARNING:
  1560. + LOGW("%s", msg);
  1561. + break;
  1562. + case _EGL_FATAL:
  1563. + LOGF("%s", msg);
  1564. + break;
  1565. + default:
  1566. + break;
  1567. + }
  1568. #else
  1569. fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
  1570. -#endif /* HAVE_ANDROID_PLATFORM */
  1571. +#endif /* HAVE_TIZEN_PLATFORM */
  1572. }
  1573. diff --git a/src/egl/meson.build b/src/egl/meson.build
  1574. index ab8f4e1..5749ec8 100644
  1575. --- a/src/egl/meson.build
  1576. +++ b/src/egl/meson.build
  1577. @@ -106,7 +106,7 @@ if with_dri2
  1578. endif
  1579. deps_for_egl += [dep_x11_xcb, dep_xcb_dri2, dep_xcb_xfixes]
  1580. endif
  1581. - if with_gbm and not with_platform_android
  1582. + if with_gbm and not with_platform_android and not with_platform_tizen
  1583. files_egl += files('drivers/dri2/platform_drm.c')
  1584. link_for_egl += libgbm
  1585. incs_for_egl += [inc_gbm, include_directories('../gbm/main')]
  1586. @@ -141,6 +141,11 @@ elif with_platform_haiku
  1587. link_for_egl += libgl
  1588. deps_for_egl += cpp.find_library('be')
  1589. endif
  1590. +if with_platform_tizen
  1591. + files_egl += files('drivers/dri2/platform_tizen.c')
  1592. + incs_for_egl += [inc_loader]
  1593. + deps_for_egl += [dep_tizen, dep_libdrm]
  1594. +endif
  1595. if cc.has_function('mincore')
  1596. c_args_for_egl += '-DHAVE_MINCORE'