Skip to content

Commit

Permalink
egl-helpers: add helpers to handle opengl framebuffers
Browse files Browse the repository at this point in the history
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>
Message-id: 20170614084149.31314-2-kraxel@redhat.com
  • Loading branch information
kraxel committed Jun 21, 2017
1 parent 8dfaf23 commit 6fafc26
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
15 changes: 15 additions & 0 deletions include/ui/egl-helpers.h
Expand Up @@ -8,6 +8,21 @@
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_setup_default(egl_fb *fb, int width, int height);
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;
Expand Down
76 changes: 76 additions & 0 deletions ui/egl-helpers.c
Expand Up @@ -24,6 +24,82 @@
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_setup_default(egl_fb *fb, int width, int height)
{
fb->width = width;
fb->height = height;
fb->framebuffer = 0; /* default framebuffer */
}

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_LINEAR);
}

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
Expand Down

0 comments on commit 6fafc26

Please sign in to comment.