* [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers
2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
2017-06-07 19:16 ` Marc-André Lureau
2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add a collection of egl_fb_*() helper functions to manage and use opengl
framebuffers, which is a common pattern in UI code with opengl support.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/egl-helpers.h | 14 ++++++++++
ui/egl-helpers.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index c785d60e91..01aa45fb32 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -8,6 +8,20 @@
extern EGLDisplay *qemu_egl_display;
extern EGLConfig qemu_egl_config;
+typedef struct egl_fb {
+ int width;
+ int height;
+ GLuint texture;
+ GLuint framebuffer;
+ bool delete_texture;
+} egl_fb;
+
+void egl_fb_destroy(egl_fb *fb);
+void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint texture);
+void egl_fb_create_new_tex(egl_fb *fb, int width, int height);
+void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip);
+void egl_fb_read(void *dst, egl_fb *src);
+
#ifdef CONFIG_OPENGL_DMABUF
extern int qemu_egl_rn_fd;
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 4a4d3370ee..b14250ae62 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -24,6 +24,75 @@
EGLDisplay *qemu_egl_display;
EGLConfig qemu_egl_config;
+/* ------------------------------------------------------------------ */
+
+void egl_fb_destroy(egl_fb *fb)
+{
+ if (!fb->framebuffer) {
+ return;
+ }
+
+ if (fb->delete_texture) {
+ glDeleteTextures(1, &fb->texture);
+ fb->delete_texture = false;
+ }
+ glDeleteFramebuffers(1, &fb->framebuffer);
+
+ fb->width = 0;
+ fb->height = 0;
+ fb->texture = 0;
+ fb->framebuffer = 0;
+}
+
+void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint texture)
+{
+ fb->width = width;
+ fb->height = height;
+ fb->texture = texture;
+ if (!fb->framebuffer) {
+ glGenFramebuffers(1, &fb->framebuffer);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb->framebuffer);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, fb->texture, 0);
+}
+
+void egl_fb_create_new_tex(egl_fb *fb, int width, int height)
+{
+ GLuint texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
+ 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
+
+ egl_fb_create_for_tex(fb, width, height, texture);
+ fb->delete_texture = true;
+}
+
+void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
+{
+ GLuint y1, y2;
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->framebuffer);
+ glViewport(0, 0, dst->width, dst->height);
+ y1 = flip ? src->height : 0;
+ y2 = flip ? 0 : src->height;
+ glBlitFramebuffer(0, y1, src->width, y2,
+ 0, 0, dst->width, dst->height,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+}
+
+void egl_fb_read(void *dst, egl_fb *src)
+{
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glReadPixels(0, 0, src->width, src->height,
+ GL_BGRA, GL_UNSIGNED_BYTE, dst);
+}
+
/* ---------------------------------------------------------------------- */
#ifdef CONFIG_OPENGL_DMABUF
--
2.9.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers
2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
@ 2017-06-07 19:16 ` Marc-André Lureau
0 siblings, 0 replies; 11+ messages in thread
From: Marc-André Lureau @ 2017-06-07 19:16 UTC (permalink / raw)
To: Gerd Hoffmann, qemu-devel
Hi
On Tue, Jun 6, 2017 at 3:06 PM Gerd Hoffmann <kraxel@redhat.com> wrote:
> Add a collection of egl_fb_*() helper functions to manage and use opengl
> framebuffers, which is a common pattern in UI code with opengl support.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> include/ui/egl-helpers.h | 14 ++++++++++
> ui/egl-helpers.c | 69
> ++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 83 insertions(+)
>
> diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
> index c785d60e91..01aa45fb32 100644
> --- a/include/ui/egl-helpers.h
> +++ b/include/ui/egl-helpers.h
> @@ -8,6 +8,20 @@
> extern EGLDisplay *qemu_egl_display;
> extern EGLConfig qemu_egl_config;
>
> +typedef struct egl_fb {
> + int width;
> + int height;
> + GLuint texture;
> + GLuint framebuffer;
> + bool delete_texture;
> +} egl_fb;
> +
> +void egl_fb_destroy(egl_fb *fb);
> +void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint
> texture);
> +void egl_fb_create_new_tex(egl_fb *fb, int width, int height);
> +void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip);
> +void egl_fb_read(void *dst, egl_fb *src);
> +
> #ifdef CONFIG_OPENGL_DMABUF
>
> extern int qemu_egl_rn_fd;
> diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
> index 4a4d3370ee..b14250ae62 100644
> --- a/ui/egl-helpers.c
> +++ b/ui/egl-helpers.c
> @@ -24,6 +24,75 @@
> EGLDisplay *qemu_egl_display;
> EGLConfig qemu_egl_config;
>
> +/* ------------------------------------------------------------------ */
> +
> +void egl_fb_destroy(egl_fb *fb)
> +{
> + if (!fb->framebuffer) {
> + return;
> + }
> +
> + if (fb->delete_texture) {
> + glDeleteTextures(1, &fb->texture);
> + fb->delete_texture = false;
> + }
> + glDeleteFramebuffers(1, &fb->framebuffer);
> +
> + fb->width = 0;
> + fb->height = 0;
> + fb->texture = 0;
> + fb->framebuffer = 0;
> +}
> +
> +void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint
> texture)
> +{
> + fb->width = width;
> + fb->height = height;
> + fb->texture = texture;
> + if (!fb->framebuffer) {
> + glGenFramebuffers(1, &fb->framebuffer);
> + }
> +
> + glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb->framebuffer);
> + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> GL_COLOR_ATTACHMENT0_EXT,
> + GL_TEXTURE_2D, fb->texture, 0);
> +}
> +
> +void egl_fb_create_new_tex(egl_fb *fb, int width, int height)
> +{
> + GLuint texture;
> +
> + glGenTextures(1, &texture);
> + glBindTexture(GL_TEXTURE_2D, texture);
> + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
> + 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
> +
> + egl_fb_create_for_tex(fb, width, height, texture);
> + fb->delete_texture = true;
> +}
> +
> +void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
> +{
> + GLuint y1, y2;
> +
> + glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
> + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->framebuffer);
> + glViewport(0, 0, dst->width, dst->height);
> + y1 = flip ? src->height : 0;
> + y2 = flip ? 0 : src->height;
> + glBlitFramebuffer(0, y1, src->width, y2,
> + 0, 0, dst->width, dst->height,
> + GL_COLOR_BUFFER_BIT, GL_NEAREST);
>
Not much to say, except that GL_LINEAR could give better visual results for
desktop display when scaling down (if this case could happen).
> +}
> +
> +void egl_fb_read(void *dst, egl_fb *src)
> +{
> + glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
> + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
> + glReadPixels(0, 0, src->width, src->height,
> + GL_BGRA, GL_UNSIGNED_BYTE, dst);
> +}
> +
> /* ----------------------------------------------------------------------
> */
>
> #ifdef CONFIG_OPENGL_DMABUF
> --
> 2.9.3
>
>
the rest looks good to me,
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
2017-06-07 21:02 ` Marc-André Lureau
2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 4/4] gtk: " Gerd Hoffmann
3 siblings, 1 reply; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/egl-headless.c | 67 ++++++++++++++-----------------------------------------
1 file changed, 17 insertions(+), 50 deletions(-)
diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index d8d800f8a6..809bfde99c 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -8,14 +8,13 @@
typedef struct egl_dpy {
DisplayChangeListener dcl;
DisplaySurface *ds;
- int width, height;
- GLuint texture;
- GLuint framebuffer;
- GLuint blit_texture;
- GLuint blit_framebuffer;
+ egl_fb guest_fb;
+ egl_fb blit_fb;
bool y_0_top;
} egl_dpy;
+/* ------------------------------------------------------------------ */
+
static void egl_refresh(DisplayChangeListener *dcl)
{
graphic_hw_update(dcl->con);
@@ -38,8 +37,8 @@ static void egl_scanout_disable(DisplayChangeListener *dcl)
{
egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
- edpy->texture = 0;
- /* XXX: delete framebuffers here ??? */
+ egl_fb_destroy(&edpy->guest_fb);
+ egl_fb_destroy(&edpy->blit_fb);
}
static void egl_scanout_texture(DisplayChangeListener *dcl,
@@ -52,34 +51,17 @@ static void egl_scanout_texture(DisplayChangeListener *dcl,
{
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);
+ egl_fb_create_for_tex(&edpy->guest_fb,
+ backing_width, backing_height, backing_id);
/* 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);
+ if (edpy->blit_fb.width != backing_width ||
+ edpy->blit_fb.height != backing_height) {
+ egl_fb_destroy(&edpy->blit_fb);
+ egl_fb_create_new_tex(&edpy->blit_fb, backing_width, backing_height);
}
}
@@ -88,32 +70,17 @@ static void egl_scanout_flush(DisplayChangeListener *dcl,
uint32_t w, uint32_t h)
{
egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
- GLuint y1, y2;
- if (!edpy->texture || !edpy->ds) {
+ if (!edpy->guest_fb.texture || !edpy->ds) {
return;
}
- assert(surface_width(edpy->ds) == edpy->width);
- assert(surface_height(edpy->ds) == edpy->height);
+ assert(surface_width(edpy->ds) == edpy->guest_fb.width);
+ assert(surface_height(edpy->ds) == edpy->guest_fb.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);
+ egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
+ egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
- /* 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);
}
--
2.9.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
@ 2017-06-07 21:02 ` Marc-André Lureau
2017-06-12 8:20 ` Gerd Hoffmann
0 siblings, 1 reply; 11+ messages in thread
From: Marc-André Lureau @ 2017-06-07 21:02 UTC (permalink / raw)
To: Gerd Hoffmann, qemu-devel
Hi
The patch looks good to me, but I tried to use egl-headless for the first
time, and I get a weird crash on virgl init:
(gdb) bt
#0 0x00007fffd8cd935f in rawmemchr () at /lib64/libc.so.6
#1 0x00007fffd8cc1832 in _IO_str_init_static_internal () at
/lib64/libc.so.6
#2 0x00007fffd8cb37e7 in vsscanf () at /lib64/libc.so.6
#3 0x00007ffff6e818a6 in vsscanf () at /lib64/libasan.so.3
#4 0x00007ffff6e819d3 in sscanf () at /lib64/libasan.so.3
#5 0x00007ffff6bfe239 in vrender_get_glsl_version
(glsl_version=0x60e00001f2b8) at vrend_renderer.c:6026
#6 0x00007ffff6bfe239 in vrend_create_context (id=id@entry=0,
nlen=nlen@entry=0, debug_name=debug_name@entry=0x0) at vrend_renderer.c:4033
#7 0x00007ffff6c04f2f in vrend_renderer_context_create_internal (handle=0,
nlen=0, debug_name=0x0) at vrend_decode.c:1066
#8 0x00007ffff6bf72a3 in vrend_renderer_init (cbs=<optimized out>,
flags=0) at vrend_renderer.c:3874
#9 0x0000555556b52cc1 in virtio_gpu_virgl_init (g=0x633000008d10) at
/home/elmarco/src/qemu/hw/display/virtio-gpu-3d.c:623
This doesn't happen when I use virgl/spice (gl=on obviously)
I guess you don't know what's going on, and I will look further later, I
just thought it was worth to report in case you had an idea.
On Tue, Jun 6, 2017 at 3:05 PM Gerd Hoffmann <kraxel@redhat.com> wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
> ui/egl-headless.c | 67
> ++++++++++++++-----------------------------------------
> 1 file changed, 17 insertions(+), 50 deletions(-)
>
> diff --git a/ui/egl-headless.c b/ui/egl-headless.c
> index d8d800f8a6..809bfde99c 100644
> --- a/ui/egl-headless.c
> +++ b/ui/egl-headless.c
> @@ -8,14 +8,13 @@
> typedef struct egl_dpy {
> DisplayChangeListener dcl;
> DisplaySurface *ds;
> - int width, height;
> - GLuint texture;
> - GLuint framebuffer;
> - GLuint blit_texture;
> - GLuint blit_framebuffer;
> + egl_fb guest_fb;
> + egl_fb blit_fb;
> bool y_0_top;
> } egl_dpy;
>
> +/* ------------------------------------------------------------------ */
> +
> static void egl_refresh(DisplayChangeListener *dcl)
> {
> graphic_hw_update(dcl->con);
> @@ -38,8 +37,8 @@ static void egl_scanout_disable(DisplayChangeListener
> *dcl)
> {
> egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
>
> - edpy->texture = 0;
> - /* XXX: delete framebuffers here ??? */
> + egl_fb_destroy(&edpy->guest_fb);
> + egl_fb_destroy(&edpy->blit_fb);
> }
>
> static void egl_scanout_texture(DisplayChangeListener *dcl,
> @@ -52,34 +51,17 @@ static void egl_scanout_texture(DisplayChangeListener
> *dcl,
> {
> 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);
> + egl_fb_create_for_tex(&edpy->guest_fb,
> + backing_width, backing_height, backing_id);
>
> /* 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);
> + if (edpy->blit_fb.width != backing_width ||
> + edpy->blit_fb.height != backing_height) {
> + egl_fb_destroy(&edpy->blit_fb);
> + egl_fb_create_new_tex(&edpy->blit_fb, backing_width,
> backing_height);
> }
> }
>
> @@ -88,32 +70,17 @@ static void egl_scanout_flush(DisplayChangeListener
> *dcl,
> uint32_t w, uint32_t h)
> {
> egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
> - GLuint y1, y2;
>
> - if (!edpy->texture || !edpy->ds) {
> + if (!edpy->guest_fb.texture || !edpy->ds) {
> return;
> }
> - assert(surface_width(edpy->ds) == edpy->width);
> - assert(surface_height(edpy->ds) == edpy->height);
> + assert(surface_width(edpy->ds) == edpy->guest_fb.width);
> + assert(surface_height(edpy->ds) == edpy->guest_fb.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);
> + egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
> + egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
>
> - /* 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);
> }
>
> --
> 2.9.3
>
>
> --
Marc-André Lureau
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
2017-06-07 21:02 ` Marc-André Lureau
@ 2017-06-12 8:20 ` Gerd Hoffmann
0 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-12 8:20 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel
On Wed, 2017-06-07 at 21:02 +0000, Marc-André Lureau wrote:
> Hi
>
> The patch looks good to me, but I tried to use egl-headless for the
> first time, and I get a weird crash on virgl init:
> (gdb) bt
> #0 0x00007fffd8cd935f in rawmemchr () at /lib64/libc.so.6
> #1 0x00007fffd8cc1832 in _IO_str_init_static_internal () at
> /lib64/libc.so.6
> #2 0x00007fffd8cb37e7 in vsscanf () at /lib64/libc.so.6
> #3 0x00007ffff6e818a6 in vsscanf () at /lib64/libasan.so.3
> #4 0x00007ffff6e819d3 in sscanf () at /lib64/libasan.so.3
> #5 0x00007ffff6bfe239 in vrender_get_glsl_version
> (glsl_version=0x60e00001f2b8) at vrend_renderer.c:6026
> #6 0x00007ffff6bfe239 in vrend_create_context (id=id@entry=0, nlen=n
> len@entry=0, debug_name=debug_name@entry=0x0) at
> vrend_renderer.c:4033
> #7 0x00007ffff6c04f2f in vrend_renderer_context_create_internal
> (handle=0, nlen=0, debug_name=0x0) at vrend_decode.c:1066
> #8 0x00007ffff6bf72a3 in vrend_renderer_init (cbs=<optimized out>,
> flags=0) at vrend_renderer.c:3874
> #9 0x0000555556b52cc1 in virtio_gpu_virgl_init (g=0x633000008d10) at
> /home/elmarco/src/qemu/hw/display/virtio-gpu-3d.c:623
>
> This doesn't happen when I use virgl/spice (gl=on obviously)
>
> I guess you don't know what's going on,
No, havn't seen this before.
cheers,
Gerd
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 3/4] sdl2: use framebuffer helper functions.
2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
2017-06-08 7:11 ` Marc-André Lureau
2017-06-06 11:04 ` [Qemu-devel] [PATCH 4/4] gtk: " Gerd Hoffmann
3 siblings, 1 reply; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/sdl2.h | 8 ++++++--
ui/sdl2-gl.c | 38 ++++++++------------------------------
2 files changed, 14 insertions(+), 32 deletions(-)
diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index aaf226c2c0..454367ac84 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -7,6 +7,10 @@
#include <SDL.h>
#include <SDL_syswm.h>
+#ifdef CONFIG_OPENGL
+# include "ui/egl-helpers.h"
+#endif
+
struct sdl2_console {
DisplayChangeListener dcl;
DisplaySurface *surface;
@@ -23,8 +27,8 @@ struct sdl2_console {
SDL_GLContext winctx;
#ifdef CONFIG_OPENGL
ConsoleGLState *gls;
- GLuint tex_id;
- GLuint fbo_id;
+ egl_fb guest_fb;
+ egl_fb win_fb;
bool y0_top;
bool scanout_mode;
#endif
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index 1cd77e2c16..6640d0a9c8 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -42,14 +42,7 @@ static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
scon->scanout_mode = scanout;
if (!scon->scanout_mode) {
- if (scon->fbo_id) {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, 0, 0);
- glDeleteFramebuffers(1, &scon->fbo_id);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- scon->fbo_id = 0;
- }
+ egl_fb_destroy(&scon->guest_fb);
if (scon->surface) {
surface_gl_destroy_texture(scon->gls, scon->surface);
surface_gl_create_texture(scon->gls, scon->surface);
@@ -191,7 +184,6 @@ void sdl2_gl_scanout_disable(DisplayChangeListener *dcl)
assert(scon->opengl);
scon->w = 0;
scon->h = 0;
- scon->tex_id = 0;
sdl2_set_scanout_mode(scon, false);
}
@@ -210,48 +202,34 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
scon->y = y;
scon->w = w;
scon->h = h;
- scon->tex_id = backing_id;
scon->y0_top = backing_y_0_top;
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
sdl2_set_scanout_mode(scon, true);
- if (!scon->fbo_id) {
- glGenFramebuffers(1, &scon->fbo_id);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, scon->tex_id, 0);
+ egl_fb_create_for_tex(&scon->guest_fb, backing_width, backing_height,
+ backing_id);
}
void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- int ww, wh, y1, y2;
assert(scon->opengl);
if (!scon->scanout_mode) {
return;
}
- if (!scon->fbo_id) {
+ if (!scon->guest_fb.framebuffer) {
return;
}
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
- SDL_GetWindowSize(scon->real_window, &ww, &wh);
- glViewport(0, 0, ww, wh);
- y1 = scon->y0_top ? 0 : scon->h;
- y2 = scon->y0_top ? scon->h : 0;
- glBlitFramebuffer(0, y1, scon->w, y2,
- 0, 0, ww, wh,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
+ SDL_GetWindowSize(scon->real_window,
+ &scon->win_fb.width,
+ &scon->win_fb.height);
+ egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top);
SDL_GL_SwapWindow(scon->real_window);
}
--
2.9.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 3/4] sdl2: use framebuffer helper functions.
2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
@ 2017-06-08 7:11 ` Marc-André Lureau
2017-06-12 8:23 ` Gerd Hoffmann
0 siblings, 1 reply; 11+ messages in thread
From: Marc-André Lureau @ 2017-06-08 7:11 UTC (permalink / raw)
To: Gerd Hoffmann, qemu-devel
Hi
On Tue, Jun 6, 2017 at 3:05 PM Gerd Hoffmann <kraxel@redhat.com> wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> include/ui/sdl2.h | 8 ++++++--
> ui/sdl2-gl.c | 38 ++++++++------------------------------
> 2 files changed, 14 insertions(+), 32 deletions(-)
>
> diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
> index aaf226c2c0..454367ac84 100644
> --- a/include/ui/sdl2.h
> +++ b/include/ui/sdl2.h
> @@ -7,6 +7,10 @@
> #include <SDL.h>
> #include <SDL_syswm.h>
>
> +#ifdef CONFIG_OPENGL
> +# include "ui/egl-helpers.h"
> +#endif
> +
> struct sdl2_console {
> DisplayChangeListener dcl;
> DisplaySurface *surface;
> @@ -23,8 +27,8 @@ struct sdl2_console {
> SDL_GLContext winctx;
> #ifdef CONFIG_OPENGL
> ConsoleGLState *gls;
> - GLuint tex_id;
> - GLuint fbo_id;
> + egl_fb guest_fb;
> + egl_fb win_fb;
> bool y0_top;
> bool scanout_mode;
> #endif
> diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
> index 1cd77e2c16..6640d0a9c8 100644
> --- a/ui/sdl2-gl.c
> +++ b/ui/sdl2-gl.c
> @@ -42,14 +42,7 @@ static void sdl2_set_scanout_mode(struct sdl2_console
> *scon, bool scanout)
>
> scon->scanout_mode = scanout;
> if (!scon->scanout_mode) {
> - if (scon->fbo_id) {
> - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> - GL_COLOR_ATTACHMENT0_EXT,
> - GL_TEXTURE_2D, 0, 0);
> - glDeleteFramebuffers(1, &scon->fbo_id);
> - glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
> - scon->fbo_id = 0;
> - }
> + egl_fb_destroy(&scon->guest_fb);
> if (scon->surface) {
> surface_gl_destroy_texture(scon->gls, scon->surface);
> surface_gl_create_texture(scon->gls, scon->surface);
> @@ -191,7 +184,6 @@ void sdl2_gl_scanout_disable(DisplayChangeListener
> *dcl)
> assert(scon->opengl);
> scon->w = 0;
> scon->h = 0;
> - scon->tex_id = 0;
> sdl2_set_scanout_mode(scon, false);
> }
>
> @@ -210,48 +202,34 @@ void sdl2_gl_scanout_texture(DisplayChangeListener
> *dcl,
> scon->y = y;
> scon->w = w;
> scon->h = h;
> - scon->tex_id = backing_id;
> scon->y0_top = backing_y_0_top;
>
> SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
>
> sdl2_set_scanout_mode(scon, true);
> - if (!scon->fbo_id) {
> - glGenFramebuffers(1, &scon->fbo_id);
> - }
> -
> - glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
> - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> GL_COLOR_ATTACHMENT0_EXT,
> - GL_TEXTURE_2D, scon->tex_id, 0);
> + egl_fb_create_for_tex(&scon->guest_fb, backing_width, backing_height,
> + backing_id);
> }
>
> void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
> uint32_t x, uint32_t y, uint32_t w, uint32_t h)
> {
> struct sdl2_console *scon = container_of(dcl, struct sdl2_console,
> dcl);
> - int ww, wh, y1, y2;
>
> assert(scon->opengl);
> if (!scon->scanout_mode) {
> return;
> }
> - if (!scon->fbo_id) {
> + if (!scon->guest_fb.framebuffer) {
> return;
> }
>
> SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
>
> - glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
> - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
> -
> - SDL_GetWindowSize(scon->real_window, &ww, &wh);
> - glViewport(0, 0, ww, wh);
> - y1 = scon->y0_top ? 0 : scon->h;
> - y2 = scon->y0_top ? scon->h : 0;
> - glBlitFramebuffer(0, y1, scon->w, y2,
> - 0, 0, ww, wh,
> - GL_COLOR_BUFFER_BIT, GL_NEAREST);
> - glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
> + SDL_GetWindowSize(scon->real_window,
> + &scon->win_fb.width,
> + &scon->win_fb.height);
>
It's a bit weird to have win_fb used without being really initialized.
Furthermore, there doesn't seem to be guarantee that glGenFramebuffers(1,
&fb->framebuffer) will make only non-0 values.
Perhaps you would also need a bool delete_fb, and a function to setup a
egl_fb from existing fb id.
+ egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top);
>
> SDL_GL_SwapWindow(scon->real_window);
> }
> --
> 2.9.3
>
>
>
Looks good otherwise.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 4/4] gtk: use framebuffer helper functions.
2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
` (2 preceding siblings ...)
2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
3 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/gtk.h | 4 ++--
ui/gtk-egl.c | 38 ++++++++------------------------------
ui/gtk-gl-area.c | 26 +++++++-------------------
3 files changed, 17 insertions(+), 51 deletions(-)
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index ca9a2268de..2f7b720358 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -52,8 +52,8 @@ typedef struct VirtualGfxConsole {
EGLSurface esurface;
int glupdates;
int x, y, w, h;
- GLuint tex_id;
- GLuint fbo_id;
+ egl_fb guest_fb;
+ egl_fb win_fb;
bool y0_top;
bool scanout_mode;
#endif
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index cf48cca259..c40f028b4b 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -30,14 +30,7 @@ static void gtk_egl_set_scanout_mode(VirtualConsole *vc, bool scanout)
vc->gfx.scanout_mode = scanout;
if (!vc->gfx.scanout_mode) {
- if (vc->gfx.fbo_id) {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, 0, 0);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- glDeleteFramebuffers(1, &vc->gfx.fbo_id);
- vc->gfx.fbo_id = 0;
- }
+ egl_fb_destroy(&vc->gfx.guest_fb);
if (vc->gfx.surface) {
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
@@ -176,7 +169,6 @@ void gd_egl_scanout_disable(DisplayChangeListener *dcl)
vc->gfx.w = 0;
vc->gfx.h = 0;
- vc->gfx.tex_id = 0;
gtk_egl_set_scanout_mode(vc, false);
}
@@ -192,20 +184,14 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl,
vc->gfx.y = y;
vc->gfx.w = w;
vc->gfx.h = h;
- vc->gfx.tex_id = backing_id;
vc->gfx.y0_top = backing_y_0_top;
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
gtk_egl_set_scanout_mode(vc, true);
- if (!vc->gfx.fbo_id) {
- glGenFramebuffers(1, &vc->gfx.fbo_id);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, vc->gfx.tex_id, 0);
+ egl_fb_create_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
+ backing_id);
}
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
@@ -213,30 +199,22 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
GdkWindow *window;
- int ww, wh, y1, y2;
if (!vc->gfx.scanout_mode) {
return;
}
- if (!vc->gfx.fbo_id) {
+ if (!vc->gfx.guest_fb.framebuffer) {
return;
}
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
window = gtk_widget_get_window(vc->gfx.drawing_area);
- gdk_drawable_get_size(window, &ww, &wh);
- glViewport(0, 0, ww, wh);
- y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
- y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
- glBlitFramebuffer(0, y1, vc->gfx.w, y2,
- 0, 0, ww, wh,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
+ gdk_drawable_get_size(window,
+ &vc->gfx.win_fb.width,
+ &vc->gfx.win_fb.height);
+ egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
}
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index b05c665cbb..18b298fc21 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -26,14 +26,7 @@ static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
vc->gfx.scanout_mode = scanout;
if (!vc->gfx.scanout_mode) {
- if (vc->gfx.fbo_id) {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, 0, 0);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- glDeleteFramebuffers(1, &vc->gfx.fbo_id);
- vc->gfx.fbo_id = 0;
- }
+ egl_fb_destroy(&vc->gfx.guest_fb);
if (vc->gfx.surface) {
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
@@ -56,11 +49,11 @@ void gd_gl_area_draw(VirtualConsole *vc)
wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
if (vc->gfx.scanout_mode) {
- if (!vc->gfx.fbo_id) {
+ if (!vc->gfx.guest_fb.framebuffer) {
return;
}
- glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
/* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
glViewport(0, 0, ww, wh);
@@ -181,24 +174,19 @@ void gd_gl_area_scanout_texture(DisplayChangeListener *dcl,
vc->gfx.y = y;
vc->gfx.w = w;
vc->gfx.h = h;
- vc->gfx.tex_id = backing_id;
vc->gfx.y0_top = backing_y_0_top;
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
- if (vc->gfx.tex_id == 0 || vc->gfx.w == 0 || vc->gfx.h == 0) {
+ if (vc->gfx.guest_fb.framebuffer == 0 ||
+ vc->gfx.w == 0 || vc->gfx.h == 0) {
gtk_gl_area_set_scanout_mode(vc, false);
return;
}
gtk_gl_area_set_scanout_mode(vc, true);
- if (!vc->gfx.fbo_id) {
- glGenFramebuffers(1, &vc->gfx.fbo_id);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, vc->gfx.tex_id, 0);
+ egl_fb_create_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
+ backing_id);
}
void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
--
2.9.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
2017-06-14 8:41 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
@ 2017-06-14 8:41 ` Gerd Hoffmann
0 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-14 8:41 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/egl-headless.c | 67 ++++++++++++++-----------------------------------------
1 file changed, 17 insertions(+), 50 deletions(-)
diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index d8d800f8a6..809bfde99c 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -8,14 +8,13 @@
typedef struct egl_dpy {
DisplayChangeListener dcl;
DisplaySurface *ds;
- int width, height;
- GLuint texture;
- GLuint framebuffer;
- GLuint blit_texture;
- GLuint blit_framebuffer;
+ egl_fb guest_fb;
+ egl_fb blit_fb;
bool y_0_top;
} egl_dpy;
+/* ------------------------------------------------------------------ */
+
static void egl_refresh(DisplayChangeListener *dcl)
{
graphic_hw_update(dcl->con);
@@ -38,8 +37,8 @@ static void egl_scanout_disable(DisplayChangeListener *dcl)
{
egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
- edpy->texture = 0;
- /* XXX: delete framebuffers here ??? */
+ egl_fb_destroy(&edpy->guest_fb);
+ egl_fb_destroy(&edpy->blit_fb);
}
static void egl_scanout_texture(DisplayChangeListener *dcl,
@@ -52,34 +51,17 @@ static void egl_scanout_texture(DisplayChangeListener *dcl,
{
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);
+ egl_fb_create_for_tex(&edpy->guest_fb,
+ backing_width, backing_height, backing_id);
/* 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);
+ if (edpy->blit_fb.width != backing_width ||
+ edpy->blit_fb.height != backing_height) {
+ egl_fb_destroy(&edpy->blit_fb);
+ egl_fb_create_new_tex(&edpy->blit_fb, backing_width, backing_height);
}
}
@@ -88,32 +70,17 @@ static void egl_scanout_flush(DisplayChangeListener *dcl,
uint32_t w, uint32_t h)
{
egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
- GLuint y1, y2;
- if (!edpy->texture || !edpy->ds) {
+ if (!edpy->guest_fb.texture || !edpy->ds) {
return;
}
- assert(surface_width(edpy->ds) == edpy->width);
- assert(surface_height(edpy->ds) == edpy->height);
+ assert(surface_width(edpy->ds) == edpy->guest_fb.width);
+ assert(surface_height(edpy->ds) == edpy->guest_fb.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);
+ egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
+ egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
- /* 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);
}
--
2.9.3
^ permalink raw reply related [flat|nested] 11+ messages in thread