0048-gbm-add-pbuffer-support.patch 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. From e98ab37481eb89284b95a84bdb01a43262841cce Mon Sep 17 00:00:00 2001
  2. From: Brendan King <Brendan.King@imgtec.com>
  3. Date: Fri, 21 Aug 2020 12:13:28 +0100
  4. Subject: [PATCH] gbm: add pbuffer support
  5. The EGL backend GLX provider for XWayland may get the EGL configs it
  6. uses to generate the GLX ones from GBM. That platform doesn't support
  7. pbuffers. When the client tries to match GLX configs with the DRI ones,
  8. a mismatch in the pbuffer attributes will result in the GLX config
  9. being rejected.
  10. Although support for creating pbuffers has been added, this isn't
  11. required when using the EGL backend GLX provider, as indirect GLX
  12. isn't supported.
  13. ---
  14. src/egl/drivers/dri2/egl_dri2.h | 3 +
  15. src/egl/drivers/dri2/platform_drm.c | 110 +++++++++++++++++++++++++---
  16. 2 files changed, 103 insertions(+), 10 deletions(-)
  17. diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
  18. index 27beae5..f8792ea 100644
  19. --- a/src/egl/drivers/dri2/egl_dri2.h
  20. +++ b/src/egl/drivers/dri2/egl_dri2.h
  21. @@ -468,6 +468,9 @@ struct dri2_egl_surface
  22. /* surfaceless and device */
  23. __DRIimage *front;
  24. unsigned int visual;
  25. +#ifdef HAVE_DRM_PLATFORM
  26. + struct gbm_bo *front_bo;
  27. +#endif
  28. #ifdef HAVE_WAYLAND_PLATFORM
  29. void *swrast_front;
  30. diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
  31. index 2b32943..258e8b6 100644
  32. --- a/src/egl/drivers/dri2/platform_drm.c
  33. +++ b/src/egl/drivers/dri2/platform_drm.c
  34. @@ -41,6 +41,38 @@
  35. #include "egl_dri2.h"
  36. #include "loader.h"
  37. +static bool
  38. +dri2_drm_alloc_front_image(struct dri2_egl_surface *dri2_surf)
  39. +{
  40. + if (!dri2_surf->front_bo) {
  41. + struct dri2_egl_display *dri2_dpy =
  42. + dri2_egl_display(dri2_surf->base.Resource.Display);
  43. +
  44. + struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
  45. +
  46. + dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
  47. + surf->base.v0.width,
  48. + surf->base.v0.height,
  49. + surf->base.v0.format,
  50. + surf->base.v0.flags);
  51. + if (!dri2_surf->front_bo) {
  52. + _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
  53. + return false;
  54. + }
  55. + }
  56. +
  57. + return true;
  58. +}
  59. +
  60. +static void
  61. +dri2_drm_free_front_image(struct dri2_egl_surface *dri2_surf)
  62. +{
  63. + if (dri2_surf->front_bo) {
  64. + gbm_bo_destroy(dri2_surf->front_bo);
  65. + dri2_surf->front_bo = NULL;
  66. + }
  67. +}
  68. +
  69. static struct gbm_bo *
  70. lock_front_buffer(struct gbm_surface *_surf)
  71. {
  72. @@ -138,8 +170,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
  73. }
  74. static _EGLSurface *
  75. -dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
  76. - void *native_surface, const EGLint *attrib_list)
  77. +dri2_drm_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
  78. + void *native_surface, const EGLint *attrib_list)
  79. {
  80. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  81. struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
  82. @@ -154,11 +186,25 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
  83. return NULL;
  84. }
  85. - if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
  86. + if (!dri2_init_surface(&dri2_surf->base, disp, type, conf,
  87. attrib_list, false, native_surface))
  88. goto cleanup_surf;
  89. - config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
  90. + if (type == EGL_PBUFFER_BIT) {
  91. + struct gbm_device *gbm = disp->PlatformDisplay;
  92. + _EGLSurface *surf = &dri2_surf->base;
  93. +
  94. + assert(!surface);
  95. +
  96. + surface = gbm_surface_create(gbm, surf->Width, surf->Height,
  97. + conf->NativeVisualID, GBM_BO_USE_RENDERING);
  98. + if (!surface) {
  99. + _eglError(EGL_BAD_ALLOC, "Failed to allocate pbuffer GBM surface");
  100. + goto cleanup_surf;
  101. + }
  102. + }
  103. +
  104. + config = dri2_get_dri_config(dri2_conf, type,
  105. dri2_surf->base.GLColorspace);
  106. if (!config) {
  107. @@ -183,11 +229,22 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
  108. return &dri2_surf->base;
  109. cleanup_surf:
  110. + if (type == EGL_PBUFFER_BIT && surface != NULL)
  111. + gbm_surface_destroy(surface);
  112. +
  113. free(dri2_surf);
  114. return NULL;
  115. }
  116. +static _EGLSurface *
  117. +dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
  118. + void *native_surface, const EGLint *attrib_list)
  119. +{
  120. + return dri2_drm_create_surface(disp, EGL_WINDOW_BIT, conf,
  121. + native_surface, attrib_list);
  122. +}
  123. +
  124. static _EGLSurface *
  125. dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
  126. void *native_window, const EGLint *attrib_list)
  127. @@ -202,6 +259,14 @@ dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
  128. return NULL;
  129. }
  130. +static _EGLSurface *
  131. +dri2_drm_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
  132. + const EGLint *attrib_list)
  133. +{
  134. + return dri2_drm_create_surface(disp, EGL_PBUFFER_BIT, conf,
  135. + NULL, attrib_list);
  136. +}
  137. +
  138. static EGLBoolean
  139. dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
  140. {
  141. @@ -217,6 +282,11 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
  142. dri2_egl_surface_free_local_buffers(dri2_surf);
  143. + dri2_drm_free_front_image(dri2_surf);
  144. +
  145. + if (surf->Type == EGL_PBUFFER_BIT)
  146. + gbm_surface_destroy(&dri2_surf->gbm_surf->base);
  147. +
  148. dri2_fini_surface(surf);
  149. free(surf);
  150. @@ -402,12 +472,27 @@ dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
  151. struct dri2_egl_surface *dri2_surf = loaderPrivate;
  152. struct gbm_dri_bo *bo;
  153. - if (get_back_bo(dri2_surf) < 0)
  154. - return 0;
  155. + buffers->image_mask = 0;
  156. + buffers->front = NULL;
  157. + buffers->back = NULL;
  158. - bo = gbm_dri_bo(dri2_surf->back->bo);
  159. - buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
  160. - buffers->back = bo->image;
  161. + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
  162. + if (!dri2_drm_alloc_front_image(dri2_surf))
  163. + return 0;
  164. +
  165. + bo = gbm_dri_bo(dri2_surf->front_bo);
  166. + buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
  167. + buffers->front = bo->image;
  168. + }
  169. +
  170. + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
  171. + if (get_back_bo(dri2_surf) < 0)
  172. + return 0;
  173. +
  174. + bo = gbm_dri_bo(dri2_surf->back->bo);
  175. + buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
  176. + buffers->back = bo->image;
  177. + }
  178. return 1;
  179. }
  180. @@ -425,6 +510,9 @@ dri2_drm_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
  181. struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  182. struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  183. + if (dri2_surf->base.Type != EGL_WINDOW_BIT)
  184. + return EGL_TRUE;
  185. +
  186. if (!dri2_dpy->flush) {
  187. dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
  188. return EGL_TRUE;
  189. @@ -648,7 +736,8 @@ drm_add_configs_for_visuals(_EGLDisplay *disp)
  190. };
  191. dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
  192. - config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
  193. + config_count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
  194. + attr_list, NULL, NULL);
  195. if (dri2_conf) {
  196. if (dri2_conf->base.ConfigID == config_count + 1)
  197. config_count++;
  198. @@ -672,6 +761,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
  199. .authenticate = dri2_drm_authenticate,
  200. .create_window_surface = dri2_drm_create_window_surface,
  201. .create_pixmap_surface = dri2_drm_create_pixmap_surface,
  202. + .create_pbuffer_surface = dri2_drm_create_pbuffer_surface,
  203. .destroy_surface = dri2_drm_destroy_surface,
  204. .create_image = dri2_drm_create_image_khr,
  205. .swap_buffers = dri2_drm_swap_buffers,