summarylogtreecommitdiffstats
path: root/3304.patch
blob: 84b0406cc690cfaa6745675839a919376bd8a704 (plain)
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
From 8428900e23d0b2637fc2e67eb28810da93e87545 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Wed, 20 Sep 2023 19:31:35 +0800
Subject: [PATCH 1/9] onscreen/native: Fall back to gbm_surface_create without
 flags

The Nvidia driver will return ENOSYS if any flags are used(!?)
---
 src/backends/native/meta-onscreen-native.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index e315a9b5f03..6a086e59121 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -2122,6 +2122,15 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative         *renderer_nat
                                     width, height,
                                     format,
                                     GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+  if (!gbm_surface)
+    {
+      gbm_surface = gbm_surface_create (gbm_device,
+                                        width, height,
+                                        format,
+                                        0);
+    }
+
   if (!gbm_surface)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-- 
GitLab


From 95007a86edb2b65f656f43916ce381e3578f5e05 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 3 Oct 2023 17:38:47 +0800
Subject: [PATCH 2/9] egl: Add function: meta_egl_query_string

---
 src/backends/meta-egl.c | 8 ++++++++
 src/backends/meta-egl.h | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
index ac19828c4cd..c468c6f970c 100644
--- a/src/backends/meta-egl.c
+++ b/src/backends/meta-egl.c
@@ -238,6 +238,14 @@ meta_egl_has_extensions (MetaEgl      *egl,
   return has_extensions;
 }
 
+const char *
+meta_egl_query_string (MetaEgl    *egl,
+                       EGLDisplay  display,
+                       EGLint      name)
+{
+  return eglQueryString (display, name);
+}
+
 gboolean
 meta_egl_initialize (MetaEgl   *egl,
                      EGLDisplay display,
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
index 4ed54a53997..55976bfdb15 100644
--- a/src/backends/meta-egl.h
+++ b/src/backends/meta-egl.h
@@ -47,6 +47,10 @@ gboolean meta_egl_has_extensions (MetaEgl      *egl,
                                   const char   *first_extension,
                                   ...);
 
+const char * meta_egl_query_string (MetaEgl    *egl,
+                                    EGLDisplay  display,
+                                    EGLint      name);
+
 gboolean meta_egl_initialize (MetaEgl   *egl,
                               EGLDisplay display,
                               GError   **error);
-- 
GitLab


From 28664e0556612fe01b6144547f0db7afe603e5af Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 3 Oct 2023 17:39:49 +0800
Subject: [PATCH 3/9] renderer/native: Flag when explicit sync between GPUs is
 required

---
 src/backends/native/meta-renderer-native-private.h | 1 +
 src/backends/native/meta-renderer-native.c         | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/src/backends/native/meta-renderer-native-private.h b/src/backends/native/meta-renderer-native-private.h
index 66b987a5c0c..1a4ee2c8106 100644
--- a/src/backends/native/meta-renderer-native-private.h
+++ b/src/backends/native/meta-renderer-native-private.h
@@ -60,6 +60,7 @@ typedef struct _MetaRendererNativeGpuData
   struct {
     MetaSharedFramebufferCopyMode copy_mode;
     gboolean has_EGL_EXT_image_dma_buf_import_modifiers;
+    gboolean needs_explicit_sync;
 
     /* For GPU blit mode */
     EGLContext egl_context;
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index dc08824c181..85a7e656300 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1757,6 +1757,7 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
   CoglContext *cogl_context;
   CoglDisplay *cogl_display;
   const char **missing_gl_extensions;
+  const char *egl_vendor;
 
   egl_display = meta_render_device_get_egl_display (render_device);
   if (egl_display == EGL_NO_DISPLAY)
@@ -1823,6 +1824,11 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
     meta_egl_has_extensions (egl, egl_display, NULL,
                              "EGL_EXT_image_dma_buf_import_modifiers",
                              NULL);
+
+  egl_vendor = meta_egl_query_string (egl, egl_display, EGL_VENDOR);
+  if (!g_strcmp0 (egl_vendor, "NVIDIA"))
+    renderer_gpu_data->secondary.needs_explicit_sync = TRUE;
+
   ret = TRUE;
 out:
   maybe_restore_cogl_egl_api (renderer_native);
-- 
GitLab


From 2bd5da67bfe3303d09e36e457e6e7976962ec83c Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Fri, 29 Sep 2023 18:38:26 +0800
Subject: [PATCH 4/9] onscreen/native: Finish primary GPU rendering before
 copying to secondary

As mentioned in the OES_EGL_image_external spec, there is no implicit
sync between the EGLImage producer and consumer. And in this code path
we don't have meta_drm_buffer_gbm_new_lock_front on the primary GPU to
do it for us either. So synchronization has to be done manually or else
the secondary GPU is likely to get an unfinished image.

This problem has only been observed when the secondary GPU is using the
Nvidia proprietary driver.
---
 src/backends/native/meta-onscreen-native.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index 6a086e59121..54f23b08e24 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -620,6 +620,9 @@ copy_shared_framebuffer_gpu (CoglOnscreen                        *onscreen,
   COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu,
                            "copy_shared_framebuffer_gpu()");
 
+  if (renderer_gpu_data->secondary.needs_explicit_sync)
+    cogl_framebuffer_finish (COGL_FRAMEBUFFER (onscreen));
+
   render_device = renderer_gpu_data->render_device;
   egl_display = meta_render_device_get_egl_display (render_device);
 
-- 
GitLab


From 2952fe89b195ebb74fa37b19c6cf9ac4e112bd99 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Fri, 29 Sep 2023 17:19:16 +0800
Subject: [PATCH 5/9] renderer/native-gles3: Remember to set the glViewport

This is a critical part of any OpenGL program. Mesa allowed us to get
away without it and provided a sane default of the full buffer, but
Nvidia seems to default to an empty/zero viewport so would refuse to
paint any pixels.

In the OpenGL ES 2.0 spec this is ambiguous:

> In the initial state, w and h are set to the width and height,
> respectively, of the window into which the GL is to do its rendering.

because the first "window" used is EGL_NO_SURFACE in
init_secondary_gpu_data_gpu. It has no width or height.

In the OpenGL ES 3.0 spec the ambiguity is somewhat resolved:

> If the default framebuffer is bound but no default framebuffer is
> associated with the GL context (see chapter 4), then w and h are
> initially set to zero.

but not entirely resolved because neither spec says whether
EGL_NO_SURFACE should be treated as zero dimensions (Nvidia) or ignored
and not counted as the first "window" (Mesa).
---
 src/backends/native/meta-renderer-native-gles3.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c
index cf27ba8d461..b1c4a0de919 100644
--- a/src/backends/native/meta-renderer-native-gles3.c
+++ b/src/backends/native/meta-renderer-native-gles3.c
@@ -54,6 +54,8 @@ paint_egl_image (MetaGles3   *gles3,
 
   meta_gles3_clear_error (gles3);
 
+  GLBAS (gles3, glViewport, (0, 0, width, height));
+
   GLBAS (gles3, glGenFramebuffers, (1, &framebuffer));
   GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer));
 
-- 
GitLab


From 96d6fd5b85b9febeae9367ecbd409cec44264b23 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Thu, 21 Sep 2023 18:35:24 +0800
Subject: [PATCH 6/9] renderer/native-gles3: Use GL_OES_EGL_image_external, not
 GL_OES_EGL_image

Although MetaRendererNative checks for the GL_OES_EGL_image_external
extension, paint_egl_image was implemented to use GL_OES_EGL_image.
That was a problem because:

 1. Nvidia only knows how to import buffers from Mesa using
    GL_OES_EGL_image_external.
 2. GL_OES_EGL_image_external doesn't support GL_TEXTURE_2D.
 3. glFramebufferTexture2D doesn't support GL_TEXTURE_EXTERNAL_OES.

So we're left with only one option to use GL_OES_EGL_image_external and
GL_TEXTURE_EXTERNAL_OES. This means we can't use glFramebufferTexture2D
anymore, which means we can't use glBlitFramebuffer anymore. We're
resigned to implementing a traditional shader.

As a bonus, this makes us OpenGL ES 2.0 compliant because we've removed
the code that required ES 3.0 (GL_READ_FRAMEBUFFER and glBlitFramebuffer).

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6221,
        https://gitlab.gnome.org/GNOME/mutter/-/issues/2247,
        https://launchpad.net/bugs/1970291
---
 .../native/meta-renderer-native-gles3.c       | 156 +++++++++++++++---
 1 file changed, 135 insertions(+), 21 deletions(-)

diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c
index b1c4a0de919..bbc6b287dd4 100644
--- a/src/backends/native/meta-renderer-native-gles3.c
+++ b/src/backends/native/meta-renderer-native-gles3.c
@@ -3,6 +3,7 @@
 /*
  * Copyright (C) 2017 Red Hat
  * Copyright (c) 2018 DisplayLink (UK) Ltd.
+ * Copyright (c) 2023 Canonical Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -43,6 +44,127 @@
 #error "Somehow included OpenGL headers when we shouldn't have"
 #endif
 
+static GQuark
+get_quark_for_egl_context (EGLContext egl_context)
+{
+  char key[128];
+
+  g_snprintf (key, sizeof key, "EGLContext %p", egl_context);
+
+  return g_quark_from_string (key);
+}
+
+static GLuint
+load_shader (const char *src,
+             GLenum      type)
+{
+  GLuint shader = glCreateShader (type);
+
+  if (shader)
+    {
+      GLint compiled;
+
+      glShaderSource (shader, 1, &src, NULL);
+      glCompileShader (shader);
+      glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
+      if (!compiled)
+        {
+          GLchar log[1024];
+
+          glGetShaderInfoLog (shader, sizeof (log) - 1, NULL, log);
+          log[sizeof (log) - 1] = '\0';
+          g_warning ("load_shader compile failed: %s", log);
+          glDeleteShader (shader);
+          shader = 0;
+        }
+    }
+
+  return shader;
+}
+
+static void
+ensure_shader_program (MetaGles3 *gles3)
+{
+  static const char vertex_shader_source[] =
+    "#version 100\n"
+    "attribute vec2 position;\n"
+    "attribute vec2 texcoord;\n"
+    "varying vec2 v_texcoord;\n"
+    "\n"
+    "void main()\n"
+    "{\n"
+    "  gl_Position = vec4(position, 0.0, 1.0);\n"
+    "  v_texcoord = texcoord;\n"
+    "}\n";
+
+  static const char fragment_shader_source[] =
+    "#version 100\n"
+    "#extension GL_OES_EGL_image_external : require\n"
+    "precision mediump float;\n"
+    "uniform samplerExternalOES s_texture;\n"
+    "varying vec2 v_texcoord;\n"
+    "\n"
+    " void main()\n"
+    "{\n"
+    "  gl_FragColor = texture2D(s_texture, v_texcoord);\n"
+    "}\n";
+
+  static const GLfloat box[] =
+  { /* position    texcoord */
+    -1.0f, +1.0f, 0.0f, 0.0f,
+    +1.0f, +1.0f, 1.0f, 0.0f,
+    +1.0f, -1.0f, 1.0f, 1.0f,
+    -1.0f, -1.0f, 0.0f, 1.0f,
+  };
+  GLint linked;
+  GLuint vertex_shader, fragment_shader;
+  GLint position_attrib, texcoord_attrib;
+  GQuark shader_program_quark;
+  GLuint shader_program;
+
+  shader_program_quark = get_quark_for_egl_context (eglGetCurrentContext ());
+  if (g_object_get_qdata (G_OBJECT (gles3), shader_program_quark))
+    return;
+
+  shader_program = glCreateProgram ();
+  g_return_if_fail (shader_program);
+  g_object_set_qdata_full (G_OBJECT (gles3),
+                           shader_program_quark,
+                           GUINT_TO_POINTER (shader_program),
+                           NULL);
+
+  vertex_shader = load_shader (vertex_shader_source, GL_VERTEX_SHADER);
+  g_return_if_fail (vertex_shader);
+  fragment_shader = load_shader (fragment_shader_source, GL_FRAGMENT_SHADER);
+  g_return_if_fail (fragment_shader);
+
+  GLBAS (gles3, glAttachShader, (shader_program, vertex_shader));
+  GLBAS (gles3, glAttachShader, (shader_program, fragment_shader));
+  GLBAS (gles3, glLinkProgram, (shader_program));
+  GLBAS (gles3, glGetProgramiv, (shader_program, GL_LINK_STATUS, &linked));
+  if (!linked)
+    {
+      GLchar log[1024];
+
+      glGetProgramInfoLog (shader_program, sizeof (log) - 1, NULL, log);
+      log[sizeof (log) - 1] = '\0';
+      g_warning ("Link failed: %s", log);
+      return;
+    }
+
+  GLBAS (gles3, glUseProgram, (shader_program));
+
+  position_attrib = glGetAttribLocation (shader_program, "position");
+  GLBAS (gles3, glEnableVertexAttribArray, (position_attrib));
+  GLBAS (gles3, glVertexAttribPointer,
+         (position_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box));
+
+  texcoord_attrib = glGetAttribLocation (shader_program, "texcoord");
+  GLBAS (gles3, glEnableVertexAttribArray, (texcoord_attrib));
+  GLBAS (gles3, glVertexAttribPointer,
+         (texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box + 2));
+}
+
 static void
 paint_egl_image (MetaGles3   *gles3,
                  EGLImageKHR  egl_image,
@@ -50,41 +172,33 @@ paint_egl_image (MetaGles3   *gles3,
                  int          height)
 {
   GLuint texture;
-  GLuint framebuffer;
 
   meta_gles3_clear_error (gles3);
+  ensure_shader_program (gles3);
 
   GLBAS (gles3, glViewport, (0, 0, width, height));
 
-  GLBAS (gles3, glGenFramebuffers, (1, &framebuffer));
-  GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer));
-
   GLBAS (gles3, glActiveTexture, (GL_TEXTURE0));
   GLBAS (gles3, glGenTextures, (1, &texture));
-  GLBAS (gles3, glBindTexture, (GL_TEXTURE_2D, texture));
-  GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_2D, egl_image));
-  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+  GLBAS (gles3, glBindTexture, (GL_TEXTURE_EXTERNAL_OES, texture));
+  GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_EXTERNAL_OES,
+                                               egl_image));
+  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES,
+                                  GL_TEXTURE_MAG_FILTER,
                                   GL_NEAREST));
-  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES,
+                                  GL_TEXTURE_MIN_FILTER,
                                   GL_NEAREST));
-  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES,
+                                  GL_TEXTURE_WRAP_S,
                                   GL_CLAMP_TO_EDGE));
-  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES,
+                                  GL_TEXTURE_WRAP_T,
                                   GL_CLAMP_TO_EDGE));
-  GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES,
-                                  GL_CLAMP_TO_EDGE));
-
-  GLBAS (gles3, glFramebufferTexture2D, (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                         GL_TEXTURE_2D, texture, 0));
 
-  GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer));
-  GLBAS (gles3, glBlitFramebuffer, (0, height, width, 0,
-                                    0, 0, width, height,
-                                    GL_COLOR_BUFFER_BIT,
-                                    GL_NEAREST));
+  GLBAS (gles3, glDrawArrays, (GL_TRIANGLE_FAN, 0, 4));
 
   GLBAS (gles3, glDeleteTextures, (1, &texture));
-  GLBAS (gles3, glDeleteFramebuffers, (1, &framebuffer));
 }
 
 gboolean
-- 
GitLab


From d55b2925c858694bed0979c6661b590887200c4d Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Wed, 10 Jan 2024 15:35:03 +0800
Subject: [PATCH 7/9] renderer/native-gles3: Fix up function parameter
 alignment

check-code-style was complaining about this.
---
 src/backends/native/meta-renderer-native-gles3.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/backends/native/meta-renderer-native-gles3.h b/src/backends/native/meta-renderer-native-gles3.h
index 591ff82e174..569e99f23c2 100644
--- a/src/backends/native/meta-renderer-native-gles3.h
+++ b/src/backends/native/meta-renderer-native-gles3.h
@@ -26,10 +26,10 @@
 #include "backends/meta-egl.h"
 #include "backends/meta-gles3.h"
 
-gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl       *egl,
-                                                    MetaGles3     *gles3,
-                                                    EGLDisplay     egl_display,
-                                                    EGLContext     egl_context,
-                                                    EGLSurface     egl_surface,
-                                                    struct gbm_bo *shared_bo,
-                                                    GError       **error);
+gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl        *egl,
+                                                    MetaGles3      *gles3,
+                                                    EGLDisplay      egl_display,
+                                                    EGLContext      egl_context,
+                                                    EGLSurface      egl_surface,
+                                                    struct gbm_bo  *shared_bo,
+                                                    GError        **error);
-- 
GitLab


From 66315ab449f26de6ec10040139f660488f9ad7e3 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 9 Jan 2024 18:03:51 +0800
Subject: [PATCH 8/9] renderer/native: Remove cached program ID when EGLContext
 destroyed

In the rare event that hotplugs destroy and then create a new EGLContext
with the exactly the same ID, this ensures we will forget the old program
which presumably wouldn't work in the new context. It will be recreated.
---
 src/backends/native/meta-renderer-native-gles3.c | 9 +++++++++
 src/backends/native/meta-renderer-native-gles3.h | 3 +++
 src/backends/native/meta-renderer-native.c       | 4 ++++
 3 files changed, 16 insertions(+)

diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c
index bbc6b287dd4..693db0ad8c8 100644
--- a/src/backends/native/meta-renderer-native-gles3.c
+++ b/src/backends/native/meta-renderer-native-gles3.c
@@ -272,3 +272,12 @@ meta_renderer_native_gles3_blit_shared_bo (MetaEgl        *egl,
 
   return TRUE;
 }
+
+void
+meta_renderer_native_gles3_forget_context (MetaGles3  *gles3,
+                                           EGLContext  egl_context)
+{
+  GQuark shader_program_quark = get_quark_for_egl_context (egl_context);
+
+  g_object_set_qdata (G_OBJECT (gles3), shader_program_quark, NULL);
+}
diff --git a/src/backends/native/meta-renderer-native-gles3.h b/src/backends/native/meta-renderer-native-gles3.h
index 569e99f23c2..f5791a171fe 100644
--- a/src/backends/native/meta-renderer-native-gles3.h
+++ b/src/backends/native/meta-renderer-native-gles3.h
@@ -33,3 +33,6 @@ gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl        *egl,
                                                     EGLSurface      egl_surface,
                                                     struct gbm_bo  *shared_bo,
                                                     GError        **error);
+
+void meta_renderer_native_gles3_forget_context (MetaGles3  *gles3,
+                                                EGLContext  egl_context);
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 85a7e656300..1ac95569ca5 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -62,6 +62,7 @@
 #include "backends/native/meta-output-kms.h"
 #include "backends/native/meta-render-device-gbm.h"
 #include "backends/native/meta-render-device-surfaceless.h"
+#include "backends/native/meta-renderer-native-gles3.h"
 #include "backends/native/meta-renderer-native-private.h"
 #include "backends/native/meta-renderer-view-native.h"
 #include "cogl/cogl.h"
@@ -135,6 +136,9 @@ meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data
       MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
       MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
 
+      meta_renderer_native_gles3_forget_context (renderer_native->gles3,
+                                                 renderer_gpu_data->secondary.egl_context);
+
       meta_egl_destroy_context (egl,
                                 egl_display,
                                 renderer_gpu_data->secondary.egl_context,
-- 
GitLab


From 48ca241a070a6d6a757a7f4745fef6ef15a28234 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 24 Oct 2023 16:26:57 +0800
Subject: [PATCH 9/9] onscreen/native: Don't refuse primary GPU copy support
 based on egl_surface

Because that egl_surface is only used for secondary GPU copying, which
isn't relevant to primary GPU copies.

This is a partial revert of 41bfabad96 which is no longer required since
the previous commits have enabled secondary GPU copy support for nvidia-drm.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2551
---
 src/backends/native/meta-onscreen-native.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index 54f23b08e24..7dd79e61566 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -729,8 +729,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen                        *onscre
   COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu,
                            "copy_shared_framebuffer_primary_gpu()");
 
-  if (!secondary_gpu_state ||
-      secondary_gpu_state->egl_surface == EGL_NO_SURFACE)
+  if (!secondary_gpu_state)
     return NULL;
 
   primary_gpu = meta_renderer_native_get_primary_gpu (renderer_native);
-- 
GitLab