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