mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
ui/spice: support multi plane dmabuf scanout
We need spice version >= 0.15.3 which has spice_qxl_gl_scanout2 API for multi plane scanout support. v2: * use new dmabuf API and check length * check spice_qxl_gl_scanout2 present instead of bump spice version dependency Signed-off-by: Qiang Yu <yuq825@gmail.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Tested-by: Marc-André Lureau <marcandre.lureau@redhat.com> [ Fix style ] Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20250327025848.46962-7-yuq825@gmail.com>
This commit is contained in:
parent
10aaad0edc
commit
98a050ca93
2 changed files with 69 additions and 34 deletions
|
@ -3168,6 +3168,11 @@ if host_os == 'windows'
|
|||
}''', name: '_lock_file and _unlock_file'))
|
||||
endif
|
||||
|
||||
if spice.found()
|
||||
config_host_data.set('HAVE_SPICE_QXL_GL_SCANOUT2',
|
||||
cc.has_function('spice_qxl_gl_scanout2', dependencies: spice))
|
||||
endif
|
||||
|
||||
if host_os == 'windows'
|
||||
mingw_has_setjmp_longjmp = cc.links('''
|
||||
#include <setjmp.h>
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "ui/spice-display.h"
|
||||
|
||||
#include "standard-headers/drm/drm_fourcc.h"
|
||||
|
||||
bool spice_opengl;
|
||||
|
||||
int qemu_spice_rect_is_empty(const QXLRect* r)
|
||||
|
@ -872,6 +874,26 @@ static void spice_gl_update(DisplayChangeListener *dcl,
|
|||
ssd->gl_updates++;
|
||||
}
|
||||
|
||||
static void spice_server_gl_scanout(QXLInstance *qxl,
|
||||
const int *fd,
|
||||
uint32_t width, uint32_t height,
|
||||
const uint32_t *offset,
|
||||
const uint32_t *stride,
|
||||
uint32_t num_planes, uint32_t format,
|
||||
uint64_t modifier, int y_0_top)
|
||||
{
|
||||
#ifdef HAVE_SPICE_QXL_GL_SCANOUT2
|
||||
spice_qxl_gl_scanout2(qxl, fd, width, height, offset, stride,
|
||||
num_planes, format, modifier, y_0_top);
|
||||
#else
|
||||
if (num_planes <= 1) {
|
||||
spice_qxl_gl_scanout(qxl, fd[0], width, height, stride[0], format, y_0_top);
|
||||
} else {
|
||||
error_report("SPICE server does not support multi plane GL scanout");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void spice_gl_switch(DisplayChangeListener *dcl,
|
||||
struct DisplaySurface *new_surface)
|
||||
{
|
||||
|
@ -884,16 +906,16 @@ static void spice_gl_switch(DisplayChangeListener *dcl,
|
|||
if (ssd->ds) {
|
||||
uint32_t offset[DMABUF_MAX_PLANES], stride[DMABUF_MAX_PLANES];
|
||||
int fd[DMABUF_MAX_PLANES], num_planes, fourcc;
|
||||
uint64_t modifier;
|
||||
|
||||
surface_gl_create_texture(ssd->gls, ssd->ds);
|
||||
if (!egl_dmabuf_export_texture(ssd->ds->texture, fd, (EGLint *)offset,
|
||||
(EGLint *)stride, &fourcc, &num_planes, NULL)) {
|
||||
surface_gl_destroy_texture(ssd->gls, ssd->ds);
|
||||
return;
|
||||
}
|
||||
|
||||
if (num_planes > 1) {
|
||||
fprintf(stderr, "%s: does not support multi-plane texture\n", __func__);
|
||||
if (!egl_dmabuf_export_texture(ssd->ds->texture,
|
||||
fd,
|
||||
(EGLint *)offset,
|
||||
(EGLint *)stride,
|
||||
&fourcc,
|
||||
&num_planes,
|
||||
&modifier)) {
|
||||
surface_gl_destroy_texture(ssd->gls, ssd->ds);
|
||||
return;
|
||||
}
|
||||
|
@ -904,10 +926,11 @@ static void spice_gl_switch(DisplayChangeListener *dcl,
|
|||
fourcc);
|
||||
|
||||
/* note: spice server will close the fd */
|
||||
spice_qxl_gl_scanout(&ssd->qxl, fd[0],
|
||||
surface_width(ssd->ds),
|
||||
surface_height(ssd->ds),
|
||||
stride[0], fourcc, false);
|
||||
spice_server_gl_scanout(&ssd->qxl, fd,
|
||||
surface_width(ssd->ds),
|
||||
surface_height(ssd->ds),
|
||||
offset, stride, num_planes,
|
||||
fourcc, modifier, false);
|
||||
ssd->have_surface = true;
|
||||
ssd->have_scanout = false;
|
||||
|
||||
|
@ -930,7 +953,8 @@ static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)
|
|||
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
|
||||
|
||||
trace_qemu_spice_gl_scanout_disable(ssd->qxl.id);
|
||||
spice_qxl_gl_scanout(&ssd->qxl, -1, 0, 0, 0, 0, false);
|
||||
spice_server_gl_scanout(&ssd->qxl, NULL, 0, 0, NULL, NULL, 0, DRM_FORMAT_INVALID,
|
||||
DRM_FORMAT_MOD_INVALID, false);
|
||||
qemu_spice_gl_monitor_config(ssd, 0, 0, 0, 0);
|
||||
ssd->have_surface = false;
|
||||
ssd->have_scanout = false;
|
||||
|
@ -948,22 +972,21 @@ static void qemu_spice_gl_scanout_texture(DisplayChangeListener *dcl,
|
|||
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
|
||||
EGLint offset[DMABUF_MAX_PLANES], stride[DMABUF_MAX_PLANES], fourcc = 0;
|
||||
int fd[DMABUF_MAX_PLANES], num_planes;
|
||||
uint64_t modifier;
|
||||
|
||||
assert(tex_id);
|
||||
if (!egl_dmabuf_export_texture(tex_id, fd, offset, stride, &fourcc,
|
||||
&num_planes, NULL)) {
|
||||
&num_planes, &modifier)) {
|
||||
fprintf(stderr, "%s: failed to export dmabuf for texture\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (num_planes > 1) {
|
||||
fprintf(stderr, "%s: does not support multi-plane dmabuf\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_qemu_spice_gl_scanout_texture(ssd->qxl.id, w, h, fourcc);
|
||||
|
||||
/* note: spice server will close the fd */
|
||||
spice_qxl_gl_scanout(&ssd->qxl, fd[0], backing_width, backing_height,
|
||||
stride[0], fourcc, y_0_top);
|
||||
spice_server_gl_scanout(&ssd->qxl, fd, backing_width, backing_height,
|
||||
(uint32_t *)offset, (uint32_t *)stride, num_planes,
|
||||
fourcc, modifier, y_0_top);
|
||||
qemu_spice_gl_monitor_config(ssd, x, y, w, h);
|
||||
ssd->have_surface = false;
|
||||
ssd->have_scanout = true;
|
||||
|
@ -1034,11 +1057,10 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
|
|||
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||
{
|
||||
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
|
||||
EGLint stride = 0, fourcc = 0;
|
||||
EGLint fourcc = 0;
|
||||
bool render_cursor = false;
|
||||
bool y_0_top = false; /* FIXME */
|
||||
uint64_t cookie;
|
||||
int fd;
|
||||
uint32_t width, height, texture;
|
||||
|
||||
if (!ssd->have_scanout) {
|
||||
|
@ -1075,6 +1097,7 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
|
|||
ssd->blit_fb.height != height) {
|
||||
int fds[DMABUF_MAX_PLANES], num_planes;
|
||||
uint32_t offsets[DMABUF_MAX_PLANES], strides[DMABUF_MAX_PLANES];
|
||||
uint64_t modifier;
|
||||
|
||||
trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, width,
|
||||
height);
|
||||
|
@ -1083,29 +1106,36 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
|
|||
width, height);
|
||||
if (!egl_dmabuf_export_texture(ssd->blit_fb.texture, fds,
|
||||
(EGLint *)offsets, (EGLint *)strides,
|
||||
&fourcc, &num_planes, NULL)) {
|
||||
&fourcc, &num_planes, &modifier)) {
|
||||
fprintf(stderr,
|
||||
"%s: failed to export dmabuf for texture\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (num_planes > 1) {
|
||||
fprintf(stderr,
|
||||
"%s: does not support multi-plane dmabuf\n", __func__);
|
||||
return;
|
||||
}
|
||||
spice_qxl_gl_scanout(&ssd->qxl, fds[0], width, height,
|
||||
strides[0], fourcc, false);
|
||||
|
||||
spice_server_gl_scanout(&ssd->qxl, fds, width, height, offsets, strides,
|
||||
num_planes, fourcc, modifier, false);
|
||||
}
|
||||
} else {
|
||||
stride = qemu_dmabuf_get_strides(dmabuf, NULL)[0];
|
||||
int fds[DMABUF_MAX_PLANES];
|
||||
int noffsets, nstrides;
|
||||
const uint32_t *offsets = qemu_dmabuf_get_offsets(dmabuf, &noffsets);
|
||||
const uint32_t *strides = qemu_dmabuf_get_strides(dmabuf, &nstrides);
|
||||
uint32_t num_planes = qemu_dmabuf_get_num_planes(dmabuf);
|
||||
|
||||
assert(noffsets >= num_planes);
|
||||
assert(nstrides >= num_planes);
|
||||
|
||||
fourcc = qemu_dmabuf_get_fourcc(dmabuf);
|
||||
y_0_top = qemu_dmabuf_get_y0_top(dmabuf);
|
||||
qemu_dmabuf_dup_fds(dmabuf, &fd, 1);
|
||||
qemu_dmabuf_dup_fds(dmabuf, fds, DMABUF_MAX_PLANES);
|
||||
|
||||
trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id, width, height);
|
||||
/* note: spice server will close the fd, so hand over a dup */
|
||||
spice_qxl_gl_scanout(&ssd->qxl, fd, width, height,
|
||||
stride, fourcc, y_0_top);
|
||||
spice_server_gl_scanout(&ssd->qxl, fds, width, height,
|
||||
offsets, strides, num_planes,
|
||||
fourcc,
|
||||
qemu_dmabuf_get_modifier(dmabuf),
|
||||
y_0_top);
|
||||
}
|
||||
qemu_spice_gl_monitor_config(ssd, 0, 0, width, height);
|
||||
ssd->guest_dmabuf_refresh = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue