27
27
* Benjamin Franzke <benjaminfranzke@googlemail.com>
30
34
#include <stdint.h>
31
35
#include <stdlib.h>
32
36
#include <string.h>
36
37
#include <unistd.h>
37
#include <vulkan/vulkan_core.h>
38
#include <vulkan/vulkan_wayland.h>
40
38
#include <xf86drm.h>
41
39
#include "drm-uapi/drm_fourcc.h"
42
40
#include <sys/mman.h>
41
#include <vulkan/vulkan_core.h>
42
#include <vulkan/vulkan_wayland.h>
44
#include "util/anon_file.h"
45
#include "util/u_vector.h"
44
46
#include "egl_dri2.h"
45
#include "loader_dri_helper.h"
47
#include "util/u_vector.h"
48
#include "util/anon_file.h"
49
47
#include "eglglobals.h"
50
48
#include "kopper_interface.h"
50
#include "loader_dri_helper.h"
52
#include "linux-dmabuf-unstable-v1-client-protocol.h"
53
#include "wayland-drm-client-protocol.h"
54
#include <wayland-client.h>
52
55
#include <wayland-egl-backend.h>
53
#include <wayland-client.h>
54
#include "wayland-drm-client-protocol.h"
55
#include "linux-dmabuf-unstable-v1-client-protocol.h"
58
58
* The index of entries in this table is used as a bitmask in
78
78
} dri2_wl_visuals[] = {
81
WL_DRM_FORMAT_ABGR16F, WL_SHM_FORMAT_ABGR16161616F,
82
__DRI_IMAGE_FORMAT_ABGR16161616F, 0, 64,
81
WL_DRM_FORMAT_ABGR16F,
82
WL_SHM_FORMAT_ABGR16161616F,
83
__DRI_IMAGE_FORMAT_ABGR16161616F,
88
WL_DRM_FORMAT_XBGR16F, WL_SHM_FORMAT_XBGR16161616F,
89
__DRI_IMAGE_FORMAT_XBGR16161616F, 0, 64,
91
WL_DRM_FORMAT_XBGR16F,
92
WL_SHM_FORMAT_XBGR16161616F,
93
__DRI_IMAGE_FORMAT_XBGR16161616F,
95
WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
96
__DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 32,
101
WL_DRM_FORMAT_XRGB2101010,
102
WL_SHM_FORMAT_XRGB2101010,
103
__DRI_IMAGE_FORMAT_XRGB2101010,
104
__DRI_IMAGE_FORMAT_XBGR2101010,
102
WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
103
__DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 32,
111
WL_DRM_FORMAT_ARGB2101010,
112
WL_SHM_FORMAT_ARGB2101010,
113
__DRI_IMAGE_FORMAT_ARGB2101010,
114
__DRI_IMAGE_FORMAT_ABGR2101010,
109
WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
110
__DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 32,
121
WL_DRM_FORMAT_XBGR2101010,
122
WL_SHM_FORMAT_XBGR2101010,
123
__DRI_IMAGE_FORMAT_XBGR2101010,
124
__DRI_IMAGE_FORMAT_XRGB2101010,
116
WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
117
__DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 32,
131
WL_DRM_FORMAT_ABGR2101010,
132
WL_SHM_FORMAT_ABGR2101010,
133
__DRI_IMAGE_FORMAT_ABGR2101010,
134
__DRI_IMAGE_FORMAT_ARGB2101010,
123
WL_DRM_FORMAT_XRGB8888, WL_SHM_FORMAT_XRGB8888,
124
__DRI_IMAGE_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_NONE, 32,
141
WL_DRM_FORMAT_XRGB8888,
142
WL_SHM_FORMAT_XRGB8888,
143
__DRI_IMAGE_FORMAT_XRGB8888,
144
__DRI_IMAGE_FORMAT_NONE,
130
WL_DRM_FORMAT_ARGB8888, WL_SHM_FORMAT_ARGB8888,
131
__DRI_IMAGE_FORMAT_ARGB8888, __DRI_IMAGE_FORMAT_NONE, 32,
151
WL_DRM_FORMAT_ARGB8888,
152
WL_SHM_FORMAT_ARGB8888,
153
__DRI_IMAGE_FORMAT_ARGB8888,
154
__DRI_IMAGE_FORMAT_NONE,
137
WL_DRM_FORMAT_ABGR8888, WL_SHM_FORMAT_ABGR8888,
138
__DRI_IMAGE_FORMAT_ABGR8888, __DRI_IMAGE_FORMAT_NONE, 32,
161
WL_DRM_FORMAT_ABGR8888,
162
WL_SHM_FORMAT_ABGR8888,
163
__DRI_IMAGE_FORMAT_ABGR8888,
164
__DRI_IMAGE_FORMAT_NONE,
144
WL_DRM_FORMAT_XBGR8888, WL_SHM_FORMAT_XBGR8888,
145
__DRI_IMAGE_FORMAT_XBGR8888, __DRI_IMAGE_FORMAT_NONE, 32,
171
WL_DRM_FORMAT_XBGR8888,
172
WL_SHM_FORMAT_XBGR8888,
173
__DRI_IMAGE_FORMAT_XBGR8888,
174
__DRI_IMAGE_FORMAT_NONE,
151
WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
152
__DRI_IMAGE_FORMAT_RGB565, __DRI_IMAGE_FORMAT_NONE, 16,
181
WL_DRM_FORMAT_RGB565,
182
WL_SHM_FORMAT_RGB565,
183
__DRI_IMAGE_FORMAT_RGB565,
184
__DRI_IMAGE_FORMAT_NONE,
159
192
dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy,
160
const __DRIconfig *config,
193
const __DRIconfig *config, bool force_opaque)
164
196
unsigned int sizes[4];
417
450
static struct wl_surface *
418
451
get_wl_surface_proxy(struct wl_egl_window *window)
420
/* Version 3 of wl_egl_window introduced a version field at the same
421
* location where a pointer to wl_surface was stored. Thus, if
422
* window->version is dereferenceable, we've been given an older version of
423
* wl_egl_window, and window->version points to wl_surface */
424
if (_eglPointerIsDereferencable((void *)(window->version))) {
453
/* Version 3 of wl_egl_window introduced a version field at the same
454
* location where a pointer to wl_surface was stored. Thus, if
455
* window->version is dereferenceable, we've been given an older version of
456
* wl_egl_window, and window->version points to wl_surface */
457
if (_eglPointerIsDereferenceable((void *)(window->version))) {
425
458
return wl_proxy_create_wrapper((void *)(window->version));
427
460
return wl_proxy_create_wrapper(window->surface);
431
surface_dmabuf_feedback_format_table(void *data,
432
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
433
int32_t fd, uint32_t size)
464
surface_dmabuf_feedback_format_table(
466
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
467
int32_t fd, uint32_t size)
435
469
struct dri2_egl_surface *dri2_surf = data;
436
470
struct dmabuf_feedback *feedback = &dri2_surf->pending_dmabuf_feedback;
438
472
feedback->format_table.size = size;
439
feedback->format_table.data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
473
feedback->format_table.data =
474
mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
445
surface_dmabuf_feedback_main_device(void *data,
446
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
447
struct wl_array *device)
480
surface_dmabuf_feedback_main_device(
481
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
482
struct wl_array *device)
449
484
struct dri2_egl_surface *dri2_surf = data;
450
485
struct dmabuf_feedback *feedback = &dri2_surf->pending_dmabuf_feedback;
504
539
/* Compositor may advertise or not a format table. If it does, we use it.
505
* Otherwise, we steal the most recent advertised format table. If we don't have
506
* a most recent advertised format table, compositor did something wrong. */
540
* Otherwise, we steal the most recent advertised format table. If we don't
541
* have a most recent advertised format table, compositor did something
507
543
if (feedback->format_table.data == NULL) {
508
544
feedback->format_table = dri2_surf->dmabuf_feedback.format_table;
509
dmabuf_feedback_format_table_init(&dri2_surf->dmabuf_feedback.format_table);
545
dmabuf_feedback_format_table_init(
546
&dri2_surf->dmabuf_feedback.format_table);
511
548
if (feedback->format_table.data == MAP_FAILED) {
512
549
_eglLog(_EGL_WARNING, "wayland-egl: we could not map the format table "
577
615
static const struct zwp_linux_dmabuf_feedback_v1_listener
578
surface_dmabuf_feedback_listener = {
579
.format_table = surface_dmabuf_feedback_format_table,
580
.main_device = surface_dmabuf_feedback_main_device,
581
.tranche_target_device = surface_dmabuf_feedback_tranche_target_device,
582
.tranche_flags = surface_dmabuf_feedback_tranche_flags,
583
.tranche_formats = surface_dmabuf_feedback_tranche_formats,
584
.tranche_done = surface_dmabuf_feedback_tranche_done,
585
.done = surface_dmabuf_feedback_done,
616
surface_dmabuf_feedback_listener = {
617
.format_table = surface_dmabuf_feedback_format_table,
618
.main_device = surface_dmabuf_feedback_main_device,
619
.tranche_target_device = surface_dmabuf_feedback_tranche_target_device,
620
.tranche_flags = surface_dmabuf_feedback_tranche_flags,
621
.tranche_formats = surface_dmabuf_feedback_tranche_formats,
622
.tranche_done = surface_dmabuf_feedback_tranche_done,
623
.done = surface_dmabuf_feedback_done,
651
int cmp_rgb_shifts = memcmp(transparent_visual->rgba_shifts,
652
opaque_visual->rgba_shifts,
653
3 * sizeof(opaque_visual->rgba_shifts[0]));
654
int cmp_rgb_sizes = memcmp(transparent_visual->rgba_sizes,
655
opaque_visual->rgba_sizes,
656
3 * sizeof(opaque_visual->rgba_sizes[0]));
691
memcmp(transparent_visual->rgba_shifts, opaque_visual->rgba_shifts,
692
3 * sizeof(opaque_visual->rgba_shifts[0]));
694
memcmp(transparent_visual->rgba_sizes, opaque_visual->rgba_sizes,
695
3 * sizeof(opaque_visual->rgba_sizes[0]));
658
697
if (cmp_rgb_shifts == 0 && cmp_rgb_sizes == 0) {
659
698
found_opaque_equivalent = true;
718
758
wl_proxy_set_queue((struct wl_proxy *)dmabuf_wrapper,
719
759
dri2_surf->wl_queue);
720
dri2_surf->wl_dmabuf_feedback =
721
zwp_linux_dmabuf_v1_get_surface_feedback(dmabuf_wrapper,
722
dri2_surf->wl_surface_wrapper);
760
dri2_surf->wl_dmabuf_feedback = zwp_linux_dmabuf_v1_get_surface_feedback(
761
dmabuf_wrapper, dri2_surf->wl_surface_wrapper);
723
762
wl_proxy_wrapper_destroy(dmabuf_wrapper);
725
zwp_linux_dmabuf_feedback_v1_add_listener(dri2_surf->wl_dmabuf_feedback,
726
&surface_dmabuf_feedback_listener,
764
zwp_linux_dmabuf_feedback_v1_add_listener(
765
dri2_surf->wl_dmabuf_feedback, &surface_dmabuf_feedback_listener,
729
768
if (dmabuf_feedback_init(&dri2_surf->pending_dmabuf_feedback) < 0) {
730
769
zwp_linux_dmabuf_feedback_v1_destroy(dri2_surf->wl_dmabuf_feedback);
747
786
dri2_surf->wl_win->resize_callback = resize_callback;
749
788
if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf))
750
goto cleanup_dmabuf_feedback;
789
goto cleanup_dmabuf_feedback;
752
791
dri2_surf->base.SwapInterval = dri2_dpy->default_swap_interval;
754
793
return &dri2_surf->base;
756
cleanup_dmabuf_feedback:
795
cleanup_dmabuf_feedback:
757
796
if (dri2_surf->wl_dmabuf_feedback) {
758
797
zwp_linux_dmabuf_feedback_v1_destroy(dri2_surf->wl_dmabuf_feedback);
759
798
dmabuf_feedback_fini(&dri2_surf->dmabuf_feedback);
760
799
dmabuf_feedback_fini(&dri2_surf->pending_dmabuf_feedback);
762
cleanup_surf_wrapper:
801
cleanup_surf_wrapper:
763
802
wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
765
804
wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
767
806
if (dri2_surf->wl_drm_wrapper)
768
807
wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper);
770
809
wl_event_queue_destroy(dri2_surf->wl_queue);
934
974
if (tranche->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT)
935
975
flags |= __DRI_IMAGE_USE_SCANOUT;
937
dri2_surf->back->dri_image =
938
loader_dri_create_image(dri2_dpy->dri_screen_render_gpu, dri2_dpy->image,
939
dri2_surf->base.Width,
940
dri2_surf->base.Height,
942
(dri2_dpy->fd_render_gpu != dri2_dpy->fd_display_gpu) ? 0 : flags,
943
modifiers, num_modifiers, NULL);
977
dri2_surf->back->dri_image = loader_dri_create_image(
978
dri2_dpy->dri_screen_render_gpu, dri2_dpy->image,
979
dri2_surf->base.Width, dri2_surf->base.Height, dri_image_format,
980
(dri2_dpy->fd_render_gpu != dri2_dpy->fd_display_gpu) ? 0 : flags,
981
modifiers, num_modifiers, NULL);
945
983
if (dri2_surf->back->dri_image)
972
1010
/* If our DRIImage implementation does not support createImageWithModifiers,
973
1011
* then fall back to the old createImage, and hope it allocates an image
974
1012
* which is acceptable to the winsys. */
975
dri2_surf->back->dri_image =
976
loader_dri_create_image(dri2_dpy->dri_screen_render_gpu, dri2_dpy->image,
977
dri2_surf->base.Width,
978
dri2_surf->base.Height,
980
(dri2_dpy->fd_render_gpu != dri2_dpy->fd_display_gpu) ? 0 : use_flags,
981
modifiers, num_modifiers, NULL);
1013
dri2_surf->back->dri_image = loader_dri_create_image(
1014
dri2_dpy->dri_screen_render_gpu, dri2_dpy->image, dri2_surf->base.Width,
1015
dri2_surf->base.Height, dri_image_format,
1016
(dri2_dpy->fd_render_gpu != dri2_dpy->fd_display_gpu) ? 0 : use_flags,
1017
modifiers, num_modifiers, NULL);
999
1035
/* Substitute dri image format if server does not support original format */
1000
1036
if (!BITSET_TEST(dri2_dpy->formats.formats_bitmap, visual_idx))
1001
linear_dri_image_format = dri2_wl_visuals[visual_idx].alt_dri_image_format;
1037
linear_dri_image_format =
1038
dri2_wl_visuals[visual_idx].alt_dri_image_format;
1003
1040
/* These asserts hold, as long as dri2_wl_visuals[] is self-consistent and
1004
1041
* the PRIME substitution logic in dri2_wl_add_configs_for_visuals() is free
1007
1044
assert(linear_dri_image_format != __DRI_IMAGE_FORMAT_NONE);
1008
assert(BITSET_TEST(dri2_dpy->formats.formats_bitmap,
1009
dri2_wl_visual_idx_from_dri_image_format(linear_dri_image_format)));
1046
dri2_dpy->formats.formats_bitmap,
1047
dri2_wl_visual_idx_from_dri_image_format(linear_dri_image_format)));
1011
1049
/* There might be a buffer release already queued that wasn't processed */
1012
1050
wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue);
1111
1145
/* The linear buffer was created in the display GPU's vram, so we
1112
1146
* need to make it visible to render GPU
1114
dri2_surf->back->linear_copy =
1115
dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen_render_gpu,
1116
dri2_surf->base.Width,
1117
dri2_surf->base.Height,
1118
loader_image_format_to_fourcc(
1119
linear_dri_image_format),
1120
&buffer_fds[0], num_planes,
1148
dri2_surf->back->linear_copy = dri2_dpy->image->createImageFromFds(
1149
dri2_dpy->dri_screen_render_gpu, dri2_surf->base.Width,
1150
dri2_surf->base.Height,
1151
loader_image_format_to_fourcc(linear_dri_image_format),
1152
&buffer_fds[0], num_planes, &strides[0], &offsets[0],
1124
1154
for (i = 0; i < num_planes; ++i) {
1125
1155
if (buffer_fds[i] != -1)
1126
1156
close(buffer_fds[i]);
1310
1337
for (int i = 0; i < count; ++i) {
1311
attachments_with_format[2*i] = attachments[i];
1312
attachments_with_format[2*i + 1] = dri2_wl_visuals[visual_idx].bpp;
1338
attachments_with_format[2 * i] = attachments[i];
1339
attachments_with_format[2 * i + 1] = dri2_wl_visuals[visual_idx].bpp;
1316
dri2_wl_get_buffers_with_format(driDrawable,
1318
attachments_with_format, count,
1319
out_count, loaderPrivate);
1342
buffer = dri2_wl_get_buffers_with_format(driDrawable, width, height,
1343
attachments_with_format, count,
1344
out_count, loaderPrivate);
1321
1346
free(attachments_with_format);
1365
1387
static const __DRIdri2LoaderExtension dri2_loader_extension = {
1366
.base = { __DRI_DRI2_LOADER, 4 },
1388
.base = {__DRI_DRI2_LOADER, 4},
1368
.getBuffers = dri2_wl_get_buffers,
1369
.flushFrontBuffer = dri2_wl_flush_front_buffer,
1390
.getBuffers = dri2_wl_get_buffers,
1391
.flushFrontBuffer = dri2_wl_flush_front_buffer,
1370
1392
.getBuffersWithFormat = dri2_wl_get_buffers_with_format,
1371
.getCapability = dri2_wl_get_capability,
1393
.getCapability = dri2_wl_get_capability,
1374
1396
static const __DRIimageLoaderExtension image_loader_extension = {
1375
.base = { __DRI_IMAGE_LOADER, 2 },
1397
.base = {__DRI_IMAGE_LOADER, 2},
1377
.getBuffers = image_get_buffers,
1378
.flushFrontBuffer = dri2_wl_flush_front_buffer,
1379
.getCapability = dri2_wl_get_capability,
1399
.getBuffers = image_get_buffers,
1400
.flushFrontBuffer = dri2_wl_flush_front_buffer,
1401
.getCapability = dri2_wl_get_capability,
1383
wayland_throttle_callback(void *data,
1384
struct wl_callback *callback,
1405
wayland_throttle_callback(void *data, struct wl_callback *callback,
1387
1408
struct dri2_egl_surface *dri2_surf = data;
1445
1463
if (dri2_dpy->image->base.version >= 15) {
1446
1464
int mod_hi, mod_lo;
1448
query = dri2_dpy->image->queryImage(image,
1449
__DRI_IMAGE_ATTRIB_MODIFIER_UPPER,
1451
query &= dri2_dpy->image->queryImage(image,
1452
__DRI_IMAGE_ATTRIB_MODIFIER_LOWER,
1466
query = dri2_dpy->image->queryImage(
1467
image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, &mod_hi);
1468
query &= dri2_dpy->image->queryImage(
1469
image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, &mod_lo);
1455
1471
modifier = combine_u32_into_u64(mod_hi, mod_lo);
1502
1519
p_image = image;
1505
query = dri2_dpy->image->queryImage(p_image,
1506
__DRI_IMAGE_ATTRIB_FD,
1508
query &= dri2_dpy->image->queryImage(p_image,
1509
__DRI_IMAGE_ATTRIB_STRIDE,
1511
query &= dri2_dpy->image->queryImage(p_image,
1512
__DRI_IMAGE_ATTRIB_OFFSET,
1523
dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_FD, &fd);
1524
query &= dri2_dpy->image->queryImage(
1525
p_image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
1526
query &= dri2_dpy->image->queryImage(
1527
p_image, __DRI_IMAGE_ATTRIB_OFFSET, &offset);
1514
1528
if (image != p_image)
1515
1529
dri2_dpy->image->destroyImage(p_image);
1556
1571
static EGLBoolean
1557
try_damage_buffer(struct dri2_egl_surface *dri2_surf,
1558
const EGLint *rects,
1572
try_damage_buffer(struct dri2_egl_surface *dri2_surf, const EGLint *rects,
1559
1573
EGLint n_rects)
1561
if (wl_proxy_get_version((struct wl_proxy *) dri2_surf->wl_surface_wrapper)
1562
< WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
1575
if (wl_proxy_get_version((struct wl_proxy *)dri2_surf->wl_surface_wrapper) <
1576
WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
1563
1577
return EGL_FALSE;
1565
1579
for (int i = 0; i < n_rects; i++) {
1566
1580
const int *rect = &rects[i * 4];
1568
wl_surface_damage_buffer(dri2_surf->wl_surface_wrapper,
1582
wl_surface_damage_buffer(dri2_surf->wl_surface_wrapper, rect[0],
1570
1583
dri2_surf->base.Height - rect[1] - rect[3],
1571
1584
rect[2], rect[3]);
1640
1651
dri2_surf->current->wl_release = false;
1642
wl_buffer_add_listener(dri2_surf->current->wl_buffer,
1643
&wl_buffer_listener, dri2_surf);
1653
wl_buffer_add_listener(dri2_surf->current->wl_buffer, &wl_buffer_listener,
1646
1657
wl_surface_attach(dri2_surf->wl_surface_wrapper,
1647
dri2_surf->current->wl_buffer,
1648
dri2_surf->dx, dri2_surf->dy);
1658
dri2_surf->current->wl_buffer, dri2_surf->dx,
1650
dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
1661
dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
1651
1662
dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
1652
1663
/* reset resize growing parameters */
1653
1664
dri2_surf->dx = 0;
1657
1668
* ignore the damage region and post maximum damage, due to
1658
1669
* https://bugs.freedesktop.org/78190 */
1659
1670
if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
1660
wl_surface_damage(dri2_surf->wl_surface_wrapper,
1661
0, 0, INT32_MAX, INT32_MAX);
1671
wl_surface_damage(dri2_surf->wl_surface_wrapper, 0, 0, INT32_MAX,
1663
1674
if (dri2_dpy->fd_render_gpu != dri2_dpy->fd_display_gpu) {
1664
1675
_EGLContext *ctx = _eglGetCurrentContext();
1665
1676
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
1666
dri2_dpy->image->blitImage(dri2_ctx->dri_context,
1667
dri2_surf->current->linear_copy,
1668
dri2_surf->current->dri_image,
1669
0, 0, dri2_surf->base.Width,
1670
dri2_surf->base.Height,
1671
0, 0, dri2_surf->base.Width,
1672
dri2_surf->base.Height, 0);
1677
dri2_dpy->image->blitImage(
1678
dri2_ctx->dri_context, dri2_surf->current->linear_copy,
1679
dri2_surf->current->dri_image, 0, 0, dri2_surf->base.Width,
1680
dri2_surf->base.Height, 0, 0, dri2_surf->base.Width,
1681
dri2_surf->base.Height, 0);
1675
1684
wl_surface_commit(dri2_surf->wl_surface_wrapper);
1880
1889
wl_drm_bind(struct dri2_egl_display *dri2_dpy)
1882
dri2_dpy->wl_drm = wl_registry_bind(dri2_dpy->wl_registry, dri2_dpy->wl_drm_name,
1883
&wl_drm_interface, dri2_dpy->wl_drm_version);
1892
wl_registry_bind(dri2_dpy->wl_registry, dri2_dpy->wl_drm_name,
1893
&wl_drm_interface, dri2_dpy->wl_drm_version);
1884
1894
wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
1888
default_dmabuf_feedback_format_table(void *data,
1889
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
1890
int32_t fd, uint32_t size)
1898
default_dmabuf_feedback_format_table(
1900
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
1901
int32_t fd, uint32_t size)
1892
1903
struct dri2_egl_display *dri2_dpy = data;
1894
1905
dri2_dpy->format_table.size = size;
1895
dri2_dpy->format_table.data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
1906
dri2_dpy->format_table.data =
1907
mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
1901
default_dmabuf_feedback_main_device(void *data,
1902
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1903
struct wl_array *device)
1913
default_dmabuf_feedback_main_device(
1914
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1915
struct wl_array *device)
1905
1917
struct dri2_egl_display *dri2_dpy = data;
1927
default_dmabuf_feedback_tranche_target_device(void *data,
1928
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1929
struct wl_array *device)
1931
/* ignore this event */
1935
default_dmabuf_feedback_tranche_flags(void *data,
1936
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1939
/* ignore this event */
1943
default_dmabuf_feedback_tranche_formats(void *data,
1944
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1945
struct wl_array *indices)
1939
default_dmabuf_feedback_tranche_target_device(
1940
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1941
struct wl_array *device)
1943
/* ignore this event */
1947
default_dmabuf_feedback_tranche_flags(
1948
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1951
/* ignore this event */
1955
default_dmabuf_feedback_tranche_formats(
1956
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
1957
struct wl_array *indices)
1947
1959
struct dri2_egl_display *dri2_dpy = data;
1948
1960
uint64_t *modifier_ptr, modifier;
1983
default_dmabuf_feedback_tranche_done(void *data,
1984
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
1996
default_dmabuf_feedback_tranche_done(
1997
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
1986
1999
/* ignore this event */
1990
default_dmabuf_feedback_done(void *data,
1991
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
2003
default_dmabuf_feedback_done(
2004
void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
1993
2006
/* ignore this event */
1996
2009
static const struct zwp_linux_dmabuf_feedback_v1_listener
1997
dmabuf_feedback_listener = {
1998
.format_table = default_dmabuf_feedback_format_table,
1999
.main_device = default_dmabuf_feedback_main_device,
2000
.tranche_target_device = default_dmabuf_feedback_tranche_target_device,
2001
.tranche_flags = default_dmabuf_feedback_tranche_flags,
2002
.tranche_formats = default_dmabuf_feedback_tranche_formats,
2003
.tranche_done = default_dmabuf_feedback_tranche_done,
2004
.done = default_dmabuf_feedback_done,
2010
dmabuf_feedback_listener = {
2011
.format_table = default_dmabuf_feedback_format_table,
2012
.main_device = default_dmabuf_feedback_main_device,
2013
.tranche_target_device = default_dmabuf_feedback_tranche_target_device,
2014
.tranche_flags = default_dmabuf_feedback_tranche_flags,
2015
.tranche_formats = default_dmabuf_feedback_tranche_formats,
2016
.tranche_done = default_dmabuf_feedback_tranche_done,
2017
.done = default_dmabuf_feedback_done,
2014
2027
if (strcmp(interface, wl_drm_interface.name) == 0) {
2015
2028
dri2_dpy->wl_drm_version = MIN2(version, 2);
2016
2029
dri2_dpy->wl_drm_name = name;
2017
} else if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0 && version >= 3) {
2018
dri2_dpy->wl_dmabuf =
2019
wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface,
2020
MIN2(version, ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION));
2030
} else if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0 &&
2032
dri2_dpy->wl_dmabuf = wl_registry_bind(
2033
registry, name, &zwp_linux_dmabuf_v1_interface,
2034
MIN2(version, ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION));
2021
2035
zwp_linux_dmabuf_v1_add_listener(dri2_dpy->wl_dmabuf, &dmabuf_listener,
2124
2138
* by our client gpu during PRIME blitImage conversion to a linear
2125
2139
* wl_buffer, so add visual c as supported by the client renderer.
2127
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
2128
count + 1, EGL_WINDOW_BIT, NULL,
2129
dri2_wl_visuals[c].rgba_shifts,
2130
dri2_wl_visuals[c].rgba_sizes);
2141
dri2_conf = dri2_add_config(
2142
disp, dri2_dpy->driver_configs[i], count + 1, EGL_WINDOW_BIT, NULL,
2143
dri2_wl_visuals[c].rgba_shifts, dri2_wl_visuals[c].rgba_sizes);
2131
2144
if (dri2_conf) {
2132
2145
if (dri2_conf->base.ConfigID == count + 1)
2134
2147
format_count[c]++;
2135
2148
if (format_count[c] == 1)
2136
_eglLog(_EGL_DEBUG, "Client format %s to server format %s via "
2137
"PRIME blitImage.", dri2_wl_visuals[c].format_name,
2150
"Client format %s to server format %s via "
2152
dri2_wl_visuals[c].format_name,
2138
2153
dri2_wl_visuals[s].format_name);
2182
2197
if (dri2_dpy->wl_dpy_wrapper == NULL)
2185
wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_dpy_wrapper,
2200
wl_proxy_set_queue((struct wl_proxy *)dri2_dpy->wl_dpy_wrapper,
2186
2201
dri2_dpy->wl_queue);
2188
2203
if (dri2_dpy->own_device)
2189
2204
wl_display_dispatch_pending(dri2_dpy->wl_dpy);
2191
2206
dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy_wrapper);
2192
wl_registry_add_listener(dri2_dpy->wl_registry,
2193
®istry_listener_drm, dri2_dpy);
2207
wl_registry_add_listener(dri2_dpy->wl_registry, ®istry_listener_drm,
2195
2210
if (roundtrip(dri2_dpy) < 0)
2198
2213
/* Get default dma-buf feedback */
2199
if (dri2_dpy->wl_dmabuf && zwp_linux_dmabuf_v1_get_version(dri2_dpy->wl_dmabuf) >=
2200
ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION) {
2214
if (dri2_dpy->wl_dmabuf &&
2215
zwp_linux_dmabuf_v1_get_version(dri2_dpy->wl_dmabuf) >=
2216
ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION) {
2201
2217
dmabuf_feedback_format_table_init(&dri2_dpy->format_table);
2202
2218
dri2_dpy->wl_dmabuf_feedback =
2203
2219
zwp_linux_dmabuf_v1_get_default_feedback(dri2_dpy->wl_dmabuf);
2204
zwp_linux_dmabuf_feedback_v1_add_listener(dri2_dpy->wl_dmabuf_feedback,
2205
&dmabuf_feedback_listener, dri2_dpy);
2220
zwp_linux_dmabuf_feedback_v1_add_listener(
2221
dri2_dpy->wl_dmabuf_feedback, &dmabuf_feedback_listener, dri2_dpy);
2208
2224
if (roundtrip(dri2_dpy) < 0)
2438
2456
/* else choose any another free location */
2439
if (!dri2_surf->back) {
2457
while (!dri2_surf->back) {
2440
2458
for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
2441
2459
if (!dri2_surf->color_buffers[i].locked) {
2442
dri2_surf->back = &dri2_surf->color_buffers[i];
2445
if (!dri2_wl_swrast_allocate_buffer(dri2_surf,
2447
dri2_surf->base.Width,
2448
dri2_surf->base.Height,
2449
&dri2_surf->back->data,
2450
&dri2_surf->back->data_size,
2451
&dri2_surf->back->wl_buffer)) {
2452
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
2455
wl_buffer_add_listener(dri2_surf->back->wl_buffer,
2456
&wl_buffer_listener, dri2_surf);
2460
dri2_surf->back = &dri2_surf->color_buffers[i];
2463
if (!dri2_wl_swrast_allocate_buffer(
2464
dri2_surf, dri2_surf->format, dri2_surf->base.Width,
2465
dri2_surf->base.Height, &dri2_surf->back->data,
2466
&dri2_surf->back->data_size, &dri2_surf->back->wl_buffer)) {
2467
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
2470
wl_buffer_add_listener(dri2_surf->back->wl_buffer,
2471
&wl_buffer_listener, dri2_surf);
2462
if (!dri2_surf->back) {
2463
_eglError(EGL_BAD_ALLOC, "failed to find free buffer");
2476
/* wait for the compositor to release a buffer */
2477
if (!dri2_surf->back) {
2478
if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_surf->wl_queue) ==
2480
_eglError(EGL_BAD_ALLOC, "waiting for a free buffer failed");
2467
2486
dri2_surf->back->locked = true;
2510
2529
dri2_wl_swrast_commit_backbuffer(struct dri2_egl_surface *dri2_surf)
2512
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
2531
struct dri2_egl_display *dri2_dpy =
2532
dri2_egl_display(dri2_surf->base.Resource.Display);
2514
2534
while (dri2_surf->throttle_callback != NULL)
2515
if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
2516
dri2_surf->wl_queue) == -1)
2535
if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_surf->wl_queue) ==
2519
2539
if (dri2_surf->base.SwapInterval > 0) {
2520
2540
dri2_surf->throttle_callback =
2521
2541
wl_surface_frame(dri2_surf->wl_surface_wrapper);
2522
wl_callback_add_listener(dri2_surf->throttle_callback,
2523
&throttle_listener, dri2_surf);
2542
wl_callback_add_listener(dri2_surf->throttle_callback, &throttle_listener,
2526
2546
dri2_surf->current = dri2_surf->back;
2527
2547
dri2_surf->back = NULL;
2529
2549
wl_surface_attach(dri2_surf->wl_surface_wrapper,
2530
dri2_surf->current->wl_buffer,
2531
dri2_surf->dx, dri2_surf->dy);
2550
dri2_surf->current->wl_buffer, dri2_surf->dx,
2533
dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
2553
dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
2534
2554
dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
2535
2555
/* reset resize growing parameters */
2536
2556
dri2_surf->dx = 0;
2537
2557
dri2_surf->dy = 0;
2539
wl_surface_damage(dri2_surf->wl_surface_wrapper,
2540
0, 0, INT32_MAX, INT32_MAX);
2559
wl_surface_damage(dri2_surf->wl_surface_wrapper, 0, 0, INT32_MAX, INT32_MAX);
2541
2560
wl_surface_commit(dri2_surf->wl_surface_wrapper);
2543
2562
/* If we're not waiting for a frame callback then we'll at least throttle
2547
2566
if (dri2_surf->throttle_callback == NULL) {
2548
2567
dri2_surf->throttle_callback = wl_display_sync(dri2_surf->wl_dpy_wrapper);
2549
wl_callback_add_listener(dri2_surf->throttle_callback,
2550
&throttle_listener, dri2_surf);
2568
wl_callback_add_listener(dri2_surf->throttle_callback, &throttle_listener,
2553
2572
wl_display_flush(dri2_dpy->wl_dpy);
2557
dri2_wl_swrast_get_drawable_info(__DRIdrawable * draw,
2558
int *x, int *y, int *w, int *h,
2559
void *loaderPrivate)
2576
dri2_wl_swrast_get_drawable_info(__DRIdrawable *draw, int *x, int *y, int *w,
2577
int *h, void *loaderPrivate)
2561
2579
struct dri2_egl_surface *dri2_surf = loaderPrivate;
2563
(void) swrast_update_buffers(dri2_surf);
2581
(void)swrast_update_buffers(dri2_surf);
2566
2584
*w = dri2_surf->base.Width;
2571
dri2_wl_swrast_get_image(__DRIdrawable * read,
2572
int x, int y, int w, int h,
2589
dri2_wl_swrast_get_image(__DRIdrawable *read, int x, int y, int w, int h,
2573
2590
char *data, void *loaderPrivate)
2575
2592
struct dri2_egl_surface *dri2_surf = loaderPrivate;
2576
2593
int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
2577
2594
int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x);
2578
int src_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width);
2595
int src_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format,
2596
dri2_surf->base.Width);
2579
2597
int dst_stride = copy_width;
2580
2598
char *src, *dst;
2608
dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
2609
int x, int y, int w, int h, int stride,
2610
char *data, void *loaderPrivate)
2626
dri2_wl_swrast_put_image2(__DRIdrawable *draw, int op, int x, int y, int w,
2627
int h, int stride, char *data, void *loaderPrivate)
2612
2629
struct dri2_egl_surface *dri2_surf = loaderPrivate;
2613
2630
int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
2614
int dst_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width);
2631
int dst_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format,
2632
dri2_surf->base.Width);
2615
2633
int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x);
2616
2634
char *src, *dst;
2618
2636
assert(copy_width <= stride);
2620
(void) swrast_update_buffers(dri2_surf);
2638
(void)swrast_update_buffers(dri2_surf);
2621
2639
dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
2623
2641
/* partial copy, copy old content */
2624
2642
if (copy_width < dst_stride)
2625
dri2_wl_swrast_get_image(draw, 0, 0,
2626
dri2_surf->base.Width, dri2_surf->base.Height,
2627
dst, loaderPrivate);
2643
dri2_wl_swrast_get_image(draw, 0, 0, dri2_surf->base.Width,
2644
dri2_surf->base.Height, dst, loaderPrivate);
2629
2646
dst += x_offset;
2630
2647
dst += y * dst_stride;
2649
dri2_wl_swrast_put_image(__DRIdrawable * draw, int op,
2650
int x, int y, int w, int h,
2651
char *data, void *loaderPrivate)
2666
dri2_wl_swrast_put_image(__DRIdrawable *draw, int op, int x, int y, int w,
2667
int h, char *data, void *loaderPrivate)
2653
2669
struct dri2_egl_surface *dri2_surf = loaderPrivate;
2656
2672
stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
2657
dri2_wl_swrast_put_image2(draw, op, x, y, w, h,
2658
stride, data, loaderPrivate);
2673
dri2_wl_swrast_put_image2(draw, op, x, y, w, h, stride, data, loaderPrivate);
2661
2676
static EGLBoolean
2699
2714
struct dri2_egl_display *dri2_dpy = data;
2701
2716
if (strcmp(interface, wl_shm_interface.name) == 0) {
2703
wl_registry_bind(registry, name, &wl_shm_interface, 1);
2717
dri2_dpy->wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
2704
2718
wl_shm_add_listener(dri2_dpy->wl_shm, &shm_listener, dri2_dpy);
2708
2722
static const struct wl_registry_listener registry_listener_swrast = {
2709
2723
.global = registry_handle_global_swrast,
2710
.global_remove = registry_handle_global_remove
2724
.global_remove = registry_handle_global_remove,
2713
2727
static const struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
2723
2737
static const __DRIswrastLoaderExtension swrast_loader_extension = {
2724
.base = { __DRI_SWRAST_LOADER, 2 },
2738
.base = {__DRI_SWRAST_LOADER, 2},
2726
2740
.getDrawableInfo = dri2_wl_swrast_get_drawable_info,
2727
.putImage = dri2_wl_swrast_put_image,
2728
.getImage = dri2_wl_swrast_get_image,
2729
.putImage2 = dri2_wl_swrast_put_image2,
2741
.putImage = dri2_wl_swrast_put_image,
2742
.getImage = dri2_wl_swrast_get_image,
2743
.putImage2 = dri2_wl_swrast_put_image2,
2732
static_assert(sizeof(struct kopper_vk_surface_create_storage) >= sizeof(VkWaylandSurfaceCreateInfoKHR), "");
2746
static_assert(sizeof(struct kopper_vk_surface_create_storage) >=
2747
sizeof(VkWaylandSurfaceCreateInfoKHR),
2735
2751
kopperSetSurfaceCreateInfo(void *_draw, struct kopper_loader_info *out)
2737
struct dri2_egl_surface *dri2_surf = _draw;
2738
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
2739
VkWaylandSurfaceCreateInfoKHR *wlsci = (VkWaylandSurfaceCreateInfoKHR *)&out->bos;
2753
struct dri2_egl_surface *dri2_surf = _draw;
2754
struct dri2_egl_display *dri2_dpy =
2755
dri2_egl_display(dri2_surf->base.Resource.Display);
2756
VkWaylandSurfaceCreateInfoKHR *wlsci =
2757
(VkWaylandSurfaceCreateInfoKHR *)&out->bos;
2741
wlsci->sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
2742
wlsci->pNext = NULL;
2744
wlsci->display = dri2_dpy->wl_dpy;
2745
wlsci->surface = dri2_surf->wl_surface_wrapper;
2759
wlsci->sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
2760
wlsci->pNext = NULL;
2762
wlsci->display = dri2_dpy->wl_dpy;
2763
wlsci->surface = dri2_surf->wl_surface_wrapper;
2748
2766
static const __DRIkopperLoaderExtension kopper_loader_extension = {
2749
.base = { __DRI_KOPPER_LOADER, 1 },
2767
.base = {__DRI_KOPPER_LOADER, 1},
2751
.SetSurfaceCreateInfo = kopperSetSurfaceCreateInfo,
2769
.SetSurfaceCreateInfo = kopperSetSurfaceCreateInfo,
2753
2771
static const __DRIextension *swrast_loader_extensions[] = {
2754
2772
&swrast_loader_extension.base,
2796
2815
if (dri2_dpy->wl_dpy_wrapper == NULL)
2799
wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_dpy_wrapper,
2818
wl_proxy_set_queue((struct wl_proxy *)dri2_dpy->wl_dpy_wrapper,
2800
2819
dri2_dpy->wl_queue);
2802
2821
if (dri2_dpy->own_device)
2803
2822
wl_display_dispatch_pending(dri2_dpy->wl_dpy);
2805
2824
dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy_wrapper);
2806
wl_registry_add_listener(dri2_dpy->wl_registry,
2807
®istry_listener_swrast, dri2_dpy);
2825
wl_registry_add_listener(dri2_dpy->wl_registry, ®istry_listener_swrast,
2809
2828
if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_shm == NULL)
2812
if (roundtrip(dri2_dpy) < 0 || !BITSET_TEST_RANGE(dri2_dpy->formats.formats_bitmap,
2813
0, dri2_dpy->formats.num_formats))
2831
if (roundtrip(dri2_dpy) < 0 ||
2832
!BITSET_TEST_RANGE(dri2_dpy->formats.formats_bitmap, 0,
2833
dri2_dpy->formats.num_formats))
2816
2836
dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast");