* [Qemu-devel] [PULL 01/10] ui: Support non-zero minimum values for absolute input axes
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 02/10] ui: input-linux: Add absolute event support Gerd Hoffmann
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Voinov, Gerd Hoffmann, Michael S. Tsirkin, Peter Maydell
From: Philippe Voinov <philippevoinov@gmail.com>
This patch refactors ui/input.c to support absolute axis
minimum values other than 0. All dependent calls to qemu_input_queue_abs
have been updated to explicitly supply 0 as the axis minimum value.
Signed-off-by: Philippe Voinov <philippevoinov@gmail.com>
Message-id: 20170505133952.29885-1-philippevoinov@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/input.h | 11 +++++++----
hw/input/virtio-input-hid.c | 6 ++++--
ui/gtk.c | 4 ++--
ui/input.c | 31 ++++++++++++++++++++++---------
ui/sdl.c | 4 ++--
ui/sdl2.c | 4 ++--
ui/spice-input.c | 4 ++--
ui/vnc.c | 4 ++--
ui/cocoa.m | 4 ++--
9 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/include/ui/input.h b/include/ui/input.h
index d06a12dd4c..3cfd0f3363 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -8,7 +8,8 @@
#define INPUT_EVENT_MASK_REL (1<<INPUT_EVENT_KIND_REL)
#define INPUT_EVENT_MASK_ABS (1<<INPUT_EVENT_KIND_ABS)
-#define INPUT_EVENT_ABS_SIZE 0x8000
+#define INPUT_EVENT_ABS_MIN 0x0000
+#define INPUT_EVENT_ABS_MAX 0x7FFF
typedef struct QemuInputHandler QemuInputHandler;
typedef struct QemuInputHandlerState QemuInputHandlerState;
@@ -54,12 +55,14 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
uint32_t button_old, uint32_t button_new);
bool qemu_input_is_absolute(void);
-int qemu_input_scale_axis(int value, int size_in, int size_out);
+int qemu_input_scale_axis(int value,
+ int min_in, int max_in,
+ int min_out, int max_out);
InputEvent *qemu_input_event_new_move(InputEventKind kind,
InputAxis axis, int value);
void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value);
-void qemu_input_queue_abs(QemuConsole *src, InputAxis axis,
- int value, int size);
+void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value,
+ int min_in, int max_in);
void qemu_input_check_mode_change(void);
void qemu_add_mouse_mode_change_notifier(Notifier *notify);
diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c
index 3ee0c1814a..46c038110c 100644
--- a/hw/input/virtio-input-hid.c
+++ b/hw/input/virtio-input-hid.c
@@ -484,12 +484,14 @@ static struct virtio_input_config virtio_tablet_config[] = {
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_X,
.size = sizeof(virtio_input_absinfo),
- .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
+ .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
},{
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_Y,
.size = sizeof(virtio_input_absinfo),
- .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
+ .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
},
{ /* end of list */ },
};
diff --git a/ui/gtk.c b/ui/gtk.c
index 7479ceef35..0213ad0efc 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -912,9 +912,9 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
return TRUE;
}
qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
- surface_width(vc->gfx.ds));
+ 0, surface_width(vc->gfx.ds));
qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
- surface_height(vc->gfx.ds));
+ 0, surface_height(vc->gfx.ds));
qemu_input_event_sync();
} else if (s->last_set && s->ptr_owner == vc) {
qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
diff --git a/ui/input.c b/ui/input.c
index 830f912f99..290ca9f54d 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -166,6 +166,11 @@ void qmp_input_send_event(bool has_device, const char *device,
qemu_input_event_sync();
}
+static int qemu_input_transform_invert_abs_value(int value)
+{
+ return (int64_t)INPUT_EVENT_ABS_MAX - value + INPUT_EVENT_ABS_MIN;
+}
+
static void qemu_input_transform_abs_rotate(InputEvent *evt)
{
InputMoveEvent *move = evt->u.abs.data;
@@ -175,16 +180,16 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt)
move->axis = INPUT_AXIS_Y;
} else if (move->axis == INPUT_AXIS_Y) {
move->axis = INPUT_AXIS_X;
- move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
+ move->value = qemu_input_transform_invert_abs_value(move->value);
}
break;
case 180:
- move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
+ move->value = qemu_input_transform_invert_abs_value(move->value);
break;
case 270:
if (move->axis == INPUT_AXIS_X) {
move->axis = INPUT_AXIS_Y;
- move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
+ move->value = qemu_input_transform_invert_abs_value(move->value);
} else if (move->axis == INPUT_AXIS_Y) {
move->axis = INPUT_AXIS_X;
}
@@ -467,12 +472,17 @@ bool qemu_input_is_absolute(void)
return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS);
}
-int qemu_input_scale_axis(int value, int size_in, int size_out)
+int qemu_input_scale_axis(int value,
+ int min_in, int max_in,
+ int min_out, int max_out)
{
- if (size_in < 2) {
- return size_out / 2;
+ int64_t range_in = (int64_t)max_in - min_in;
+ int64_t range_out = (int64_t)max_out - min_out;
+
+ if (range_in < 1) {
+ return min_out + range_out / 2;
}
- return (int64_t)value * (size_out - 1) / (size_in - 1);
+ return ((int64_t)value - min_in) * range_out / range_in + min_out;
}
InputEvent *qemu_input_event_new_move(InputEventKind kind,
@@ -496,10 +506,13 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
qapi_free_InputEvent(evt);
}
-void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
+void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value,
+ int min_in, int max_in)
{
InputEvent *evt;
- int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
+ int scaled = qemu_input_scale_axis(value, min_in, max_in,
+ INPUT_EVENT_ABS_MIN,
+ INPUT_EVENT_ABS_MAX);
evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
qemu_input_event_send(src, evt);
qapi_free_InputEvent(evt);
diff --git a/ui/sdl.c b/ui/sdl.c
index 37c21a00fb..b35a67855f 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -490,9 +490,9 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
if (qemu_input_is_absolute()) {
qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x,
- real_screen->w);
+ 0, real_screen->w);
qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y,
- real_screen->h);
+ 0, real_screen->h);
} else {
if (guest_cursor) {
x -= guest_x;
diff --git a/ui/sdl2.c b/ui/sdl2.c
index faf9bdff5c..21de05200e 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -298,8 +298,8 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
}
}
}
- qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
- qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
+ qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, 0, max_w);
+ qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, 0, max_h);
} else {
if (guest_cursor) {
x -= guest_x;
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 8eeebdbb2e..86293dd2ce 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -172,8 +172,8 @@ static void tablet_position(SpiceTabletInstance* sin, int x, int y,
QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
spice_update_buttons(pointer, 0, buttons_state);
- qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, pointer->width);
- qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, pointer->height);
+ qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, 0, pointer->width);
+ qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, 0, pointer->height);
qemu_input_event_sync();
}
diff --git a/ui/vnc.c b/ui/vnc.c
index 9c4edcdbf5..601f9ec539 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1556,8 +1556,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
}
if (vs->absolute) {
- qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
- qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
+ qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
+ qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
} else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 207555edf7..3a9bc4da5f 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -749,8 +749,8 @@ QemuCocoaView *cocoaView;
* clicks in the titlebar.
*/
if ([self screenContainsPoint:p]) {
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width);
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, screen.height);
+ qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, 0, screen.width);
+ qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, 0, screen.height);
}
} else {
qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 02/10] ui: input-linux: Add absolute event support
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 01/10] ui: Support non-zero minimum values for absolute input axes Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 03/10] virtio-gpu: move virtio_gpu_gl_block Gerd Hoffmann
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Voinov, Gerd Hoffmann
From: Philippe Voinov <philippevoinov@gmail.com>
This patch adds support for absolute pointer events to the input-linux
subsystem. This support was omitted from the original input-linux patch,
however most of the code required for it is already in place.
Support for absolute events is especially useful for guests with vga
passthrough. Since they have a physical monitor, none of normal channels
for sending video output (vnc, etc) are used, meaning they also can't be
used to send absolute input events. This leaves QMP as the only option
to send absolute input into vga passthrough guests, which is not its
intended use and is not efficient.
This patch allows, for example, uinput to be used to create virtual
absolute input devices. This lets you build external systems which share
physical input devices between guests. Without absolute input
capability, such external systems can't seamlessly share pointer devices
between guests.
Signed-off-by: Philippe Voinov <philippevoinov@gmail.com>
Message-id: 20170505134231.30210-1-philippevoinov@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/input-linux.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/ui/input-linux.c b/ui/input-linux.c
index dc0613ca1f..49d52a69cc 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -169,6 +169,10 @@ struct InputLinux {
bool has_abs_x;
int num_keys;
int num_btns;
+ int abs_x_min;
+ int abs_x_max;
+ int abs_y_min;
+ int abs_y_max;
struct input_event event;
int read_offset;
@@ -314,6 +318,18 @@ static void input_linux_handle_mouse(InputLinux *il, struct input_event *event)
break;
}
break;
+ case EV_ABS:
+ switch (event->code) {
+ case ABS_X:
+ qemu_input_queue_abs(NULL, INPUT_AXIS_X, event->value,
+ il->abs_x_min, il->abs_x_max);
+ break;
+ case ABS_Y:
+ qemu_input_queue_abs(NULL, INPUT_AXIS_Y, event->value,
+ il->abs_y_min, il->abs_y_max);
+ break;
+ }
+ break;
case EV_SYN:
qemu_input_event_sync();
if (il->wheel != 0) {
@@ -351,7 +367,7 @@ static void input_linux_event(void *opaque)
if (il->num_keys) {
input_linux_handle_keyboard(il, &il->event);
}
- if (il->has_rel_x && il->num_btns) {
+ if ((il->has_rel_x || il->has_abs_x) && il->num_btns) {
input_linux_handle_mouse(il, &il->event);
}
}
@@ -364,6 +380,7 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
uint8_t keymap[KEY_CNT / 8], keystate[KEY_CNT / 8];
unsigned int i;
int rc, ver;
+ struct input_absinfo absinfo;
if (!il->evdev) {
error_setg(errp, "no input device specified");
@@ -402,6 +419,12 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
rc = ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
if (absmap & (1 << ABS_X)) {
il->has_abs_x = true;
+ rc = ioctl(il->fd, EVIOCGABS(ABS_X), &absinfo);
+ il->abs_x_min = absinfo.minimum;
+ il->abs_x_max = absinfo.maximum;
+ rc = ioctl(il->fd, EVIOCGABS(ABS_Y), &absinfo);
+ il->abs_y_min = absinfo.minimum;
+ il->abs_y_max = absinfo.maximum;
}
}
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 03/10] virtio-gpu: move virtio_gpu_gl_block
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 01/10] ui: Support non-zero minimum values for absolute input axes Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 02/10] ui: input-linux: Add absolute event support Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 04/10] egl-helpers: drop support for gles and debug logging Gerd Hoffmann
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Michael S. Tsirkin
Move to virtio-gpu-3d.c where all the other virgl code lives too.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20170505104101.30589-2-kraxel@redhat.com
---
include/hw/virtio/virtio-gpu.h | 1 +
hw/display/virtio-gpu-3d.c | 16 ++++++++++++++++
hw/display/virtio-gpu.c | 18 ++----------------
3 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index f3ffdceca4..83f474ffc3 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -169,6 +169,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd);
void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
void virtio_gpu_virgl_reset(VirtIOGPU *g);
+void virtio_gpu_gl_block(void *opaque, bool block);
int virtio_gpu_virgl_init(VirtIOGPU *g);
#endif
diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
index f49b7fe8cd..8c106a662d 100644
--- a/hw/display/virtio-gpu-3d.c
+++ b/hw/display/virtio-gpu-3d.c
@@ -600,6 +600,22 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g)
}
}
+void virtio_gpu_gl_block(void *opaque, bool block)
+{
+ VirtIOGPU *g = opaque;
+
+ if (block) {
+ g->renderer_blocked++;
+ } else {
+ g->renderer_blocked--;
+ }
+ assert(g->renderer_blocked >= 0);
+
+ if (g->renderer_blocked == 0) {
+ virtio_gpu_process_cmdq(g);
+ }
+}
+
int virtio_gpu_virgl_init(VirtIOGPU *g)
{
int ret;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index e1056f34df..cfb5dfa336 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -929,28 +929,14 @@ static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
return 0;
}
-static void virtio_gpu_gl_block(void *opaque, bool block)
-{
- VirtIOGPU *g = opaque;
-
- if (block) {
- g->renderer_blocked++;
- } else {
- g->renderer_blocked--;
- }
- assert(g->renderer_blocked >= 0);
-
- if (g->renderer_blocked == 0) {
- virtio_gpu_process_cmdq(g);
- }
-}
-
const GraphicHwOps virtio_gpu_ops = {
.invalidate = virtio_gpu_invalidate_display,
.gfx_update = virtio_gpu_update_display,
.text_update = virtio_gpu_text_update,
.ui_info = virtio_gpu_ui_info,
+#ifdef CONFIG_VIRGL
.gl_block = virtio_gpu_gl_block,
+#endif
};
static const VMStateDescription vmstate_virtio_gpu_scanout = {
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 04/10] egl-helpers: drop support for gles and debug logging
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (2 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 03/10] virtio-gpu: move virtio_gpu_gl_block Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 05/10] egl-helpers: fix display init for x11 Gerd Hoffmann
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Leftover from the early opengl days.
Unused now, so delete the dead code.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170505104101.30589-3-kraxel@redhat.com
---
include/ui/egl-helpers.h | 2 +-
ui/egl-helpers.c | 52 +++++-------------------------------------------
ui/gtk-egl.c | 2 +-
3 files changed, 7 insertions(+), 49 deletions(-)
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 88a13e827b..fec7da14a5 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -21,7 +21,7 @@ int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc);
EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
-int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug);
+int qemu_egl_init_dpy(EGLNativeDisplayType dpy);
EGLContext qemu_egl_init_ctx(void);
#endif /* EGL_HELPERS_H */
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index b7b6b2e3cc..a3d7c3d7f5 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -26,18 +26,6 @@ EGLConfig qemu_egl_config;
/* ---------------------------------------------------------------------- */
-static bool egl_gles;
-static int egl_debug;
-
-#define egl_dbg(_x ...) \
- do { \
- if (egl_debug) { \
- fprintf(stderr, "egl: " _x); \
- } \
- } while (0);
-
-/* ---------------------------------------------------------------------- */
-
#ifdef CONFIG_OPENGL_DMABUF
int qemu_egl_rn_fd;
@@ -105,7 +93,7 @@ int egl_rendernode_init(const char *rendernode)
goto err;
}
- qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev, false, false);
+ qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev);
if (!epoxy_has_egl_extension(qemu_egl_display,
"EGL_KHR_surfaceless_context")) {
@@ -171,8 +159,6 @@ EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
EGLSurface esurface;
EGLBoolean b;
- egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
- (unsigned long) win);
esurface = eglCreateWindowSurface(qemu_egl_display,
qemu_egl_config,
(EGLNativeWindowType)win, NULL);
@@ -242,7 +228,7 @@ static EGLDisplay qemu_egl_get_display(void *native)
return dpy;
}
-int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
+int qemu_egl_init_dpy(EGLNativeDisplayType dpy)
{
static const EGLint conf_att_gl[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@@ -253,56 +239,34 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
EGL_ALPHA_SIZE, 0,
EGL_NONE,
};
- static const EGLint conf_att_gles[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 5,
- EGL_BLUE_SIZE, 5,
- EGL_ALPHA_SIZE, 0,
- EGL_NONE,
- };
EGLint major, minor;
EGLBoolean b;
EGLint n;
- if (debug) {
- egl_debug = 1;
- setenv("EGL_LOG_LEVEL", "debug", true);
- setenv("LIBGL_DEBUG", "verbose", true);
- }
-
- egl_dbg("qemu_egl_get_display (dpy %p) ...\n", dpy);
qemu_egl_display = qemu_egl_get_display(dpy);
if (qemu_egl_display == EGL_NO_DISPLAY) {
error_report("egl: eglGetDisplay failed");
return -1;
}
- egl_dbg("eglInitialize ...\n");
b = eglInitialize(qemu_egl_display, &major, &minor);
if (b == EGL_FALSE) {
error_report("egl: eglInitialize failed");
return -1;
}
- egl_dbg("eglBindAPI ...\n");
- b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
+ b = eglBindAPI(EGL_OPENGL_API);
if (b == EGL_FALSE) {
error_report("egl: eglBindAPI failed");
return -1;
}
- egl_dbg("eglChooseConfig ...\n");
- b = eglChooseConfig(qemu_egl_display,
- gles ? conf_att_gles : conf_att_gl,
+ b = eglChooseConfig(qemu_egl_display, conf_att_gl,
&qemu_egl_config, 1, &n);
if (b == EGL_FALSE || n != 1) {
error_report("egl: eglChooseConfig failed");
return -1;
}
-
- egl_gles = gles;
return 0;
}
@@ -311,17 +275,11 @@ EGLContext qemu_egl_init_ctx(void)
static const EGLint ctx_att_gl[] = {
EGL_NONE
};
- static const EGLint ctx_att_gles[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
EGLContext ectx;
EGLBoolean b;
- egl_dbg("eglCreateContext ...\n");
ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
- egl_gles ? ctx_att_gles : ctx_att_gl);
+ ctx_att_gl);
if (ectx == EGL_NO_CONTEXT) {
error_report("egl: eglCreateContext failed");
return NULL;
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index d53288f027..89492c0e02 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -246,7 +246,7 @@ void gtk_egl_init(void)
GdkDisplay *gdk_display = gdk_display_get_default();
Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
- if (qemu_egl_init_dpy(x11_display, false, false) < 0) {
+ if (qemu_egl_init_dpy(x11_display) < 0) {
return;
}
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 05/10] egl-helpers: fix display init for x11
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (3 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 04/10] egl-helpers: drop support for gles and debug logging Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 06/10] egl-helpers: add missing error check Gerd Hoffmann
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
When running on gtk we need X11 platform not mesa platform.
Create separate functions for mesa and x11 so we can keep
the egl #ifdef mess local to egl-helpers.c
Fixes: 0ea1523fb6703aa0dcd65e66b59e96fec028e60a
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170505104101.30589-4-kraxel@redhat.com
---
include/ui/egl-helpers.h | 3 ++-
ui/egl-helpers.c | 34 ++++++++++++++++++++++++++--------
ui/gtk-egl.c | 2 +-
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index fec7da14a5..c785d60e91 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -21,7 +21,8 @@ int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc);
EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
-int qemu_egl_init_dpy(EGLNativeDisplayType dpy);
+int qemu_egl_init_dpy_x11(EGLNativeDisplayType dpy);
+int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy);
EGLContext qemu_egl_init_ctx(void);
#endif /* EGL_HELPERS_H */
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index a3d7c3d7f5..ec2e325e21 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -93,7 +93,7 @@ int egl_rendernode_init(const char *rendernode)
goto err;
}
- qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev);
+ qemu_egl_init_dpy_mesa((EGLNativeDisplayType)qemu_egl_rn_gbm_dev);
if (!epoxy_has_egl_extension(qemu_egl_display,
"EGL_KHR_surfaceless_context")) {
@@ -206,20 +206,19 @@ EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
* platform extensions (EGL_KHR_platform_gbm and friends) yet it doesn't seem
* like mesa will be able to advertise these (even though it can do EGL 1.5).
*/
-static EGLDisplay qemu_egl_get_display(void *native)
+static EGLDisplay qemu_egl_get_display(EGLNativeDisplayType native,
+ EGLenum platform)
{
EGLDisplay dpy = EGL_NO_DISPLAY;
-#ifdef EGL_MESA_platform_gbm
/* In practise any EGL 1.5 implementation would support the EXT extension */
if (epoxy_has_egl_extension(NULL, "EGL_EXT_platform_base")) {
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplayEXT =
(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
- if (getPlatformDisplayEXT) {
- dpy = getPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, native, NULL);
+ if (getPlatformDisplayEXT && platform != 0) {
+ dpy = getPlatformDisplayEXT(platform, native, NULL);
}
}
-#endif
if (dpy == EGL_NO_DISPLAY) {
/* fallback */
@@ -228,7 +227,8 @@ static EGLDisplay qemu_egl_get_display(void *native)
return dpy;
}
-int qemu_egl_init_dpy(EGLNativeDisplayType dpy)
+static int qemu_egl_init_dpy(EGLNativeDisplayType dpy,
+ EGLenum platform)
{
static const EGLint conf_att_gl[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@@ -243,7 +243,7 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy)
EGLBoolean b;
EGLint n;
- qemu_egl_display = qemu_egl_get_display(dpy);
+ qemu_egl_display = qemu_egl_get_display(dpy, platform);
if (qemu_egl_display == EGL_NO_DISPLAY) {
error_report("egl: eglGetDisplay failed");
return -1;
@@ -270,6 +270,24 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy)
return 0;
}
+int qemu_egl_init_dpy_x11(EGLNativeDisplayType dpy)
+{
+#ifdef EGL_KHR_platform_x11
+ return qemu_egl_init_dpy(dpy, EGL_PLATFORM_X11_KHR);
+#else
+ return qemu_egl_init_dpy(dpy, 0);
+#endif
+}
+
+int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy)
+{
+#ifdef EGL_MESA_platform_gbm
+ return qemu_egl_init_dpy(dpy, EGL_PLATFORM_GBM_MESA);
+#else
+ return qemu_egl_init_dpy(dpy, 0);
+#endif
+}
+
EGLContext qemu_egl_init_ctx(void)
{
static const EGLint ctx_att_gl[] = {
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 89492c0e02..cf48cca259 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -246,7 +246,7 @@ void gtk_egl_init(void)
GdkDisplay *gdk_display = gdk_display_get_default();
Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
- if (qemu_egl_init_dpy(x11_display) < 0) {
+ if (qemu_egl_init_dpy_x11(x11_display) < 0) {
return;
}
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 06/10] egl-helpers: add missing error check
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (4 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 05/10] egl-helpers: fix display init for x11 Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 07/10] egl: explicitly ask for core context Gerd Hoffmann
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Code didn't check for qemu_egl_init_dpy_mesa() failures, add it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20170505104101.30589-5-kraxel@redhat.com
---
ui/egl-helpers.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index ec2e325e21..b50225158b 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -80,6 +80,7 @@ static int qemu_egl_rendernode_open(const char *rendernode)
int egl_rendernode_init(const char *rendernode)
{
qemu_egl_rn_fd = -1;
+ int rc;
qemu_egl_rn_fd = qemu_egl_rendernode_open(rendernode);
if (qemu_egl_rn_fd == -1) {
@@ -93,7 +94,11 @@ int egl_rendernode_init(const char *rendernode)
goto err;
}
- qemu_egl_init_dpy_mesa((EGLNativeDisplayType)qemu_egl_rn_gbm_dev);
+ rc = qemu_egl_init_dpy_mesa((EGLNativeDisplayType)qemu_egl_rn_gbm_dev);
+ if (rc != 0) {
+ /* qemu_egl_init_dpy_mesa reports error */
+ goto err;
+ }
if (!epoxy_has_egl_extension(qemu_egl_display,
"EGL_KHR_surfaceless_context")) {
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 07/10] egl: explicitly ask for core context
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (5 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 06/10] egl-helpers: add missing error check Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 08/10] opengl: add egl-headless display Gerd Hoffmann
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170505104101.30589-6-kraxel@redhat.com
---
ui/egl-context.c | 7 ++++---
ui/egl-helpers.c | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/ui/egl-context.c b/ui/egl-context.c
index 3a02b68d1a..2161969abe 100644
--- a/ui/egl-context.c
+++ b/ui/egl-context.c
@@ -7,9 +7,10 @@ QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,
{
EGLContext ctx;
EGLint ctx_att[] = {
- EGL_CONTEXT_CLIENT_VERSION, params->major_ver,
- EGL_CONTEXT_MINOR_VERSION_KHR, params->minor_ver,
- EGL_NONE
+ EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ EGL_CONTEXT_CLIENT_VERSION, params->major_ver,
+ EGL_CONTEXT_MINOR_VERSION_KHR, params->minor_ver,
+ EGL_NONE
};
ctx = eglCreateContext(qemu_egl_display, qemu_egl_config,
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index b50225158b..4a4d3370ee 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -296,6 +296,7 @@ int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy)
EGLContext qemu_egl_init_ctx(void)
{
static const EGLint ctx_att_gl[] = {
+ EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_NONE
};
EGLContext ectx;
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 08/10] opengl: add egl-headless display
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (6 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 07/10] egl: explicitly ask for core context Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 09/10] vnc: simple clean up Gerd Hoffmann
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Paolo Bonzini
Add egl-headless user interface. It doesn't provide a real user
interface, it only provides opengl support using drm render nodes.
It will copy back the bits rendered by the guest using virgl back
to a DisplaySurface and kick the usual display update code paths,
so spice and vnc and screendump can pick it up.
Use it this way:
qemu -display egl-headless -vnc $display
qemu -display egl-headless -spice gl=off,$args
Note that you should prefer native spice opengl support (-spice
gl=on) if possible because that delivers better performance.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170505104101.30589-7-kraxel@redhat.com
---
include/ui/console.h | 3 +
ui/egl-headless.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++
vl.c | 16 ++++++
ui/Makefile.objs | 1 +
4 files changed, 178 insertions(+)
create mode 100644 ui/egl-headless.c
diff --git a/include/ui/console.h b/include/ui/console.h
index d759338816..7262bef6d3 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -527,4 +527,7 @@ static inline void early_gtk_display_init(int opengl)
}
#endif
+/* egl-headless.c */
+void egl_headless_init(void);
+
#endif
diff --git a/ui/egl-headless.c b/ui/egl-headless.c
new file mode 100644
index 0000000000..d8d800f8a6
--- /dev/null
+++ b/ui/egl-headless.c
@@ -0,0 +1,158 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/sysemu.h"
+#include "ui/console.h"
+#include "ui/egl-helpers.h"
+#include "ui/egl-context.h"
+
+typedef struct egl_dpy {
+ DisplayChangeListener dcl;
+ DisplaySurface *ds;
+ int width, height;
+ GLuint texture;
+ GLuint framebuffer;
+ GLuint blit_texture;
+ GLuint blit_framebuffer;
+ bool y_0_top;
+} egl_dpy;
+
+static void egl_refresh(DisplayChangeListener *dcl)
+{
+ graphic_hw_update(dcl->con);
+}
+
+static void egl_gfx_update(DisplayChangeListener *dcl,
+ int x, int y, int w, int h)
+{
+}
+
+static void egl_gfx_switch(DisplayChangeListener *dcl,
+ struct DisplaySurface *new_surface)
+{
+ egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
+
+ edpy->ds = new_surface;
+}
+
+static void egl_scanout_disable(DisplayChangeListener *dcl)
+{
+ egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
+
+ edpy->texture = 0;
+ /* XXX: delete framebuffers here ??? */
+}
+
+static void egl_scanout_texture(DisplayChangeListener *dcl,
+ uint32_t backing_id,
+ bool backing_y_0_top,
+ uint32_t backing_width,
+ uint32_t backing_height,
+ uint32_t x, uint32_t y,
+ uint32_t w, uint32_t h)
+{
+ egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
+
+ edpy->texture = backing_id;
+ edpy->y_0_top = backing_y_0_top;
+
+ /* source framebuffer */
+ if (!edpy->framebuffer) {
+ glGenFramebuffers(1, &edpy->framebuffer);
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->framebuffer);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, edpy->texture, 0);
+
+ /* dest framebuffer */
+ if (!edpy->blit_framebuffer) {
+ glGenFramebuffers(1, &edpy->blit_framebuffer);
+ glGenTextures(1, &edpy->blit_texture);
+ edpy->width = 0;
+ edpy->height = 0;
+ }
+ if (edpy->width != backing_width || edpy->height != backing_height) {
+ edpy->width = backing_width;
+ edpy->height = backing_height;
+ glBindTexture(GL_TEXTURE_2D, edpy->blit_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+ edpy->width, edpy->height,
+ 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->blit_framebuffer);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, edpy->blit_texture, 0);
+ }
+}
+
+static void egl_scanout_flush(DisplayChangeListener *dcl,
+ uint32_t x, uint32_t y,
+ uint32_t w, uint32_t h)
+{
+ egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
+ GLuint y1, y2;
+
+ if (!edpy->texture || !edpy->ds) {
+ return;
+ }
+ assert(surface_width(edpy->ds) == edpy->width);
+ assert(surface_height(edpy->ds) == edpy->height);
+ assert(surface_format(edpy->ds) == PIXMAN_x8r8g8b8);
+
+ /* blit framebuffer, flip if needed */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->framebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, edpy->blit_framebuffer);
+ glViewport(0, 0, edpy->width, edpy->height);
+ y1 = edpy->y_0_top ? edpy->height : 0;
+ y2 = edpy->y_0_top ? 0 : edpy->height;
+ glBlitFramebuffer(0, y1, edpy->width, y2,
+ 0, 0, edpy->width, edpy->height,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ /* read pixels to surface */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->blit_framebuffer);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glReadPixels(0, 0, edpy->width, edpy->height,
+ GL_BGRA, GL_UNSIGNED_BYTE, surface_data(edpy->ds));
+
+ /* notify about updates */
+ dpy_gfx_update(edpy->dcl.con, x, y, w, h);
+}
+
+static const DisplayChangeListenerOps egl_ops = {
+ .dpy_name = "egl-headless",
+ .dpy_refresh = egl_refresh,
+ .dpy_gfx_update = egl_gfx_update,
+ .dpy_gfx_switch = egl_gfx_switch,
+
+ .dpy_gl_ctx_create = qemu_egl_create_context,
+ .dpy_gl_ctx_destroy = qemu_egl_destroy_context,
+ .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
+ .dpy_gl_ctx_get_current = qemu_egl_get_current_context,
+
+ .dpy_gl_scanout_disable = egl_scanout_disable,
+ .dpy_gl_scanout_texture = egl_scanout_texture,
+ .dpy_gl_update = egl_scanout_flush,
+};
+
+void egl_headless_init(void)
+{
+ QemuConsole *con;
+ egl_dpy *edpy;
+ int idx;
+
+ if (egl_rendernode_init(NULL) < 0) {
+ error_report("egl: render node init failed");
+ exit(1);
+ }
+
+ for (idx = 0;; idx++) {
+ con = qemu_console_lookup_by_index(idx);
+ if (!con || !qemu_console_is_graphic(con)) {
+ break;
+ }
+
+ edpy = g_new0(egl_dpy, 1);
+ edpy->dcl.con = con;
+ edpy->dcl.ops = &egl_ops;
+ register_displaychangelistener(&edpy->dcl);
+ }
+}
diff --git a/vl.c b/vl.c
index 58023fca02..aca99e1c77 100644
--- a/vl.c
+++ b/vl.c
@@ -2050,6 +2050,7 @@ typedef enum DisplayType {
DT_SDL,
DT_COCOA,
DT_GTK,
+ DT_EGL,
DT_NONE,
} DisplayType;
@@ -2127,6 +2128,15 @@ static DisplayType select_display(const char *p)
error_report("VNC requires a display argument vnc=<display>");
exit(1);
}
+ } else if (strstart(p, "egl-headless", &opts)) {
+#ifdef CONFIG_OPENGL
+ request_opengl = 1;
+ display_opengl = 1;
+ display = DT_EGL;
+#else
+ fprintf(stderr, "egl support is disabled\n");
+ exit(1);
+#endif
} else if (strstart(p, "curses", &opts)) {
#ifdef CONFIG_CURSES
display = DT_CURSES;
@@ -4659,6 +4669,12 @@ int main(int argc, char **argv, char **envp)
qemu_spice_display_init();
}
+#ifdef CONFIG_OPENGL
+ if (display_type == DT_EGL) {
+ egl_headless_init();
+ }
+#endif
+
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
exit(1);
}
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 27566b32f1..aac6ae8bef 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -33,6 +33,7 @@ common-obj-y += shader.o
common-obj-y += console-gl.o
common-obj-y += egl-helpers.o
common-obj-y += egl-context.o
+common-obj-y += egl-headless.o
ifeq ($(CONFIG_GTK_GL),y)
common-obj-$(CONFIG_GTK) += gtk-gl-area.o
else
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 09/10] vnc: simple clean up
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (7 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 08/10] opengl: add egl-headless display Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-12 11:51 ` [Qemu-devel] [PULL 10/10] vnc: replace hweight_long() with ctpopl() Gerd Hoffmann
2017-05-15 13:29 ` [Qemu-devel] [PULL 00/10] ui patch queue Stefan Hajnoczi
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Wei Qi, Gerd Hoffmann
From: Wei Qi <weiqi4@huawei.com>
It is unnecessary to assign 'packed_bytes' to 'estimated_bytes', because 'estimated_bytes' unused after assignment.
Signed-off-by: Wei Qi <weiqi4@huawei.com>
Reviewed-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc-enc-zrle.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
index 5489870e70..fd63d4f688 100644
--- a/ui/vnc-enc-zrle.c
+++ b/ui/vnc-enc-zrle.c
@@ -163,7 +163,6 @@ static void zrle_choose_palette_rle(VncState *vs, int w, int h,
if (packed_bytes < estimated_bytes) {
*use_rle = false;
*use_palette = true;
- estimated_bytes = packed_bytes;
}
}
}
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PULL 10/10] vnc: replace hweight_long() with ctpopl()
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (8 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 09/10] vnc: simple clean up Gerd Hoffmann
@ 2017-05-12 11:51 ` Gerd Hoffmann
2017-05-15 13:29 ` [Qemu-devel] [PULL 00/10] ui patch queue Stefan Hajnoczi
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2017-05-12 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Cédric Le Goater, Gerd Hoffmann
From: Cédric Le Goater <clg@kaod.org>
ctpopl() has a better implementation than hweight_long() and ui/vnc.c
being the last user of hweight_long(), we can simply remove it.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1489415605-13105-1-git-send-email-clg@kaod.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/qemu/bitops.h | 10 ----------
ui/vnc.c | 6 +++---
2 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 1881284cb5..3f0926cf40 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -201,16 +201,6 @@ static inline unsigned long find_first_zero_bit(const unsigned long *addr,
return find_next_zero_bit(addr, size, 0);
}
-static inline unsigned long hweight_long(unsigned long w)
-{
- unsigned long count;
-
- for (count = 0; w; w >>= 1) {
- count += w & 1;
- }
- return count;
-}
-
/**
* rol8 - rotate an 8-bit value left
* @word: value to rotate
diff --git a/ui/vnc.c b/ui/vnc.c
index 601f9ec539..47b49c7318 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2061,15 +2061,15 @@ static void set_pixel_format(VncState *vs, int bits_per_pixel,
}
vs->client_pf.rmax = red_max ? red_max : 0xFF;
- vs->client_pf.rbits = hweight_long(red_max);
+ vs->client_pf.rbits = ctpopl(red_max);
vs->client_pf.rshift = red_shift;
vs->client_pf.rmask = red_max << red_shift;
vs->client_pf.gmax = green_max ? green_max : 0xFF;
- vs->client_pf.gbits = hweight_long(green_max);
+ vs->client_pf.gbits = ctpopl(green_max);
vs->client_pf.gshift = green_shift;
vs->client_pf.gmask = green_max << green_shift;
vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
- vs->client_pf.bbits = hweight_long(blue_max);
+ vs->client_pf.bbits = ctpopl(blue_max);
vs->client_pf.bshift = blue_shift;
vs->client_pf.bmask = blue_max << blue_shift;
vs->client_pf.bits_per_pixel = bits_per_pixel;
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PULL 00/10] ui patch queue
2017-05-12 11:51 [Qemu-devel] [PULL 00/10] ui patch queue Gerd Hoffmann
` (9 preceding siblings ...)
2017-05-12 11:51 ` [Qemu-devel] [PULL 10/10] vnc: replace hweight_long() with ctpopl() Gerd Hoffmann
@ 2017-05-15 13:29 ` Stefan Hajnoczi
10 siblings, 0 replies; 12+ messages in thread
From: Stefan Hajnoczi @ 2017-05-15 13:29 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2830 bytes --]
On Fri, May 12, 2017 at 01:51:25PM +0200, Gerd Hoffmann wrote:
> Hi,
>
> Here is the ui patch queue with some vnc cleanups, absolute event
> support for input linux, egl bugfixes and the new eg-headless ui.
>
> please pull,
> Gerd
>
> The following changes since commit 76d20ea0f1b26ebd5da2f5fb2fdf3250cde887bb:
>
> Merge remote-tracking branch 'armbru/tags/pull-qapi-2017-05-04-v3' into staging (2017-05-09 15:49:14 -0400)
>
> are available in the git repository at:
>
> git://git.kraxel.org/qemu tags/pull-ui-20170512-1
>
> for you to fetch changes up to 7c9209e7bfb8c09ab5a4cadaa84928d146874a05:
>
> vnc: replace hweight_long() with ctpopl() (2017-05-12 12:36:02 +0200)
>
> ----------------------------------------------------------------
> ui: add egl-headless
> ui: some vnc cleanups
> ui: absolute events for input-linux
>
> ----------------------------------------------------------------
> Cédric Le Goater (1):
> vnc: replace hweight_long() with ctpopl()
>
> Gerd Hoffmann (6):
> virtio-gpu: move virtio_gpu_gl_block
> egl-helpers: drop support for gles and debug logging
> egl-helpers: fix display init for x11
> egl-helpers: add missing error check
> egl: explicitly ask for core context
> opengl: add egl-headless display
>
> Philippe Voinov (2):
> ui: Support non-zero minimum values for absolute input axes
> ui: input-linux: Add absolute event support
>
> Wei Qi (1):
> vnc: simple clean up
>
> include/hw/virtio/virtio-gpu.h | 1 +
> include/qemu/bitops.h | 10 ---
> include/ui/console.h | 3 +
> include/ui/egl-helpers.h | 3 +-
> include/ui/input.h | 11 +--
> hw/display/virtio-gpu-3d.c | 16 +++++
> hw/display/virtio-gpu.c | 18 +----
> hw/input/virtio-input-hid.c | 6 +-
> ui/egl-context.c | 7 +-
> ui/egl-headless.c | 158 +++++++++++++++++++++++++++++++++++++++++
> ui/egl-helpers.c | 88 +++++++++--------------
> ui/gtk-egl.c | 2 +-
> ui/gtk.c | 4 +-
> ui/input-linux.c | 25 ++++++-
> ui/input.c | 31 +++++---
> ui/sdl.c | 4 +-
> ui/sdl2.c | 4 +-
> ui/spice-input.c | 4 +-
> ui/vnc-enc-zrle.c | 1 -
> ui/vnc.c | 10 +--
> vl.c | 16 +++++
> ui/Makefile.objs | 1 +
> ui/cocoa.m | 4 +-
> 23 files changed, 311 insertions(+), 116 deletions(-)
> create mode 100644 ui/egl-headless.c
>
Thanks, applied to my staging tree:
https://github.com/stefanha/qemu/commits/staging
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread