[retro-gtk/wip/aplazas/gl-display: 1/2] gl-isplay: Blit the texture for simple filters
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk/wip/aplazas/gl-display: 1/2] gl-isplay: Blit the texture for simple filters
- Date: Fri, 17 Nov 2017 09:36:33 +0000 (UTC)
commit d45e498c2f4b7ebaee70ebe2c4b9a62540fa13bc
Author: Adrien Plazas <kekun plazas laposte net>
Date: Fri Nov 17 10:29:38 2017 +0100
gl-isplay: Blit the texture for simple filters
Blits the texture on the output framebuffer rather than drawing it with
a shader program for the smooth and sharp filter.
This results in shorter drawing times and allow to drop the
corresponding GLSL filters.
retro-gtk/retro-gl-display.c | 122 +++++++++++++++++++++++++++++++-----------
1 files changed, 91 insertions(+), 31 deletions(-)
---
diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c
index 95d9f04..aaf5cb8 100644
--- a/retro-gtk/retro-gl-display.c
+++ b/retro-gtk/retro-gl-display.c
@@ -16,6 +16,7 @@ struct _RetroGLDisplay
gulong on_video_output_id;
RetroGLSLFilter *glsl_filter[RETRO_VIDEO_FILTER_COUNT];
+ GLuint framebuffer;
GLuint texture;
};
@@ -50,8 +51,8 @@ static GLuint elements[] = {
};
static const gchar *filter_uris[] = {
- "resource:///org/gnome/Retro/glsl-filters/bicubic.filter",
- "resource:///org/gnome/Retro/glsl-filters/sharp.filter",
+ NULL,
+ NULL,
"resource:///org/gnome/Retro/glsl-filters/crt-simple.filter",
};
@@ -98,6 +99,72 @@ retro_gl_display_get_video_box (RetroGLDisplay *self,
}
static void
+retro_gl_display_blit_texture (RetroGLDisplay *self,
+ GLenum filter)
+{
+ gdouble w = 0.0;
+ gdouble h = 0.0;
+ gdouble x = 0.0;
+ gdouble y = 0.0;
+
+ retro_gl_display_get_video_box (self, &w, &h, &x, &y);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, self->framebuffer);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, self->texture, 0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+
+ glBindFramebuffer (GL_READ_FRAMEBUFFER, self->framebuffer);
+ glBlitFramebuffer (0, 0,
+ gdk_pixbuf_get_width (self->pixbuf),
+ gdk_pixbuf_get_height (self->pixbuf),
+ (GLint) x, (GLint) (y + h), (GLint) (x + w), (GLint) y,
+ GL_COLOR_BUFFER_BIT,
+ filter);
+ glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
+}
+
+static void
+retro_gl_display_draw_texture (RetroGLDisplay *self,
+ RetroGLSLFilter *filter)
+{
+ GLfloat source_width, source_height;
+ GLfloat target_width, target_height;
+ GLfloat output_width, output_height;
+
+ retro_glsl_filter_use_program (filter);
+
+ retro_glsl_filter_apply_texture_params (filter);
+
+ retro_glsl_filter_set_uniform_1f (filter, "relative_aspect_ratio",
+ (gfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self)) /
+ (gfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self)) /
+ self->aspect_ratio);
+
+ source_width = (GLfloat) gdk_pixbuf_get_width (self->pixbuf);
+ source_height = (GLfloat) gdk_pixbuf_get_height (self->pixbuf);
+ target_width = (GLfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self));
+ target_height = (GLfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self));
+ output_width = (GLfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self));
+ output_height = (GLfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self));
+
+ retro_glsl_filter_set_uniform_4f (filter, "sourceSize[0]",
+ source_width, source_height,
+ 1.0f / source_width, 1.0f / source_height);
+
+ retro_glsl_filter_set_uniform_4f (filter, "targetSize",
+ target_width, target_height,
+ 1.0f / target_width, 1.0f / target_height);
+
+ retro_glsl_filter_set_uniform_4f (filter, "outputSize",
+ output_width, output_height,
+ 1.0f / output_width, 1.0f / output_height);
+
+ glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+
+}
+
+static void
retro_gl_display_realize (RetroGLDisplay *self)
{
GLuint vertex_buffer_object;
@@ -120,6 +187,9 @@ retro_gl_display_realize (RetroGLDisplay *self)
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (elements), elements, GL_STATIC_DRAW);
for (filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++) {
+ if (self->glsl_filter[filter] == NULL)
+ continue;
+
self->glsl_filter[filter] = retro_glsl_filter_new (filter_uris[filter], NULL);
retro_glsl_filter_prepare_program (self->glsl_filter[filter], &inner_error);
if (G_UNLIKELY (inner_error != NULL)) {
@@ -149,6 +219,10 @@ retro_gl_display_realize (RetroGLDisplay *self)
offsetof (RetroVertex, texture_coordinates));
}
+ glDeleteFramebuffers (1, &self->framebuffer);
+ self->framebuffer = 0;
+ glGenFramebuffers(1, &self->framebuffer);
+
glDeleteTextures (1, &self->texture);
self->texture = 0;
glGenTextures (1, &self->texture);
@@ -168,6 +242,8 @@ retro_gl_display_unrealize (RetroGLDisplay *self)
gtk_gl_area_make_current (GTK_GL_AREA (self));
+ glDeleteFramebuffers (1, &self->framebuffer);
+ self->framebuffer = 0;
glDeleteTextures (1, &self->texture);
self->texture = 0;
for (filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
@@ -177,9 +253,6 @@ retro_gl_display_unrealize (RetroGLDisplay *self)
static gboolean
retro_gl_display_render (RetroGLDisplay *self)
{
- GLfloat source_width, source_height;
- GLfloat target_width, target_height;
- GLfloat output_width, output_height;
RetroVideoFilter filter;
g_return_val_if_fail (self != NULL, FALSE);
@@ -190,14 +263,9 @@ retro_gl_display_render (RetroGLDisplay *self)
RETRO_VIDEO_FILTER_SMOOTH :
self->filter;
- if (self->glsl_filter[filter] == NULL)
- return FALSE;
-
if (self->pixbuf == NULL)
return FALSE;
- retro_glsl_filter_use_program (self->glsl_filter[filter]);
-
glTexImage2D (GL_TEXTURE_2D,
0,
GL_RGB,
@@ -207,33 +275,25 @@ retro_gl_display_render (RetroGLDisplay *self)
GL_RGBA, GL_UNSIGNED_BYTE,
gdk_pixbuf_get_pixels (self->pixbuf));
- retro_glsl_filter_apply_texture_params (self->glsl_filter[filter]);
+ if (filter == RETRO_VIDEO_FILTER_SMOOTH) {
+ retro_gl_display_blit_texture (self, GL_LINEAR);
- retro_glsl_filter_set_uniform_1f (self->glsl_filter[filter], "relative_aspect_ratio",
- (gfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self)) /
- (gfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self)) /
- self->aspect_ratio);
+ return FALSE;
+ }
- source_width = (GLfloat) gdk_pixbuf_get_width (self->pixbuf);
- source_height = (GLfloat) gdk_pixbuf_get_height (self->pixbuf);
- target_width = (GLfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self));
- target_height = (GLfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self));
- output_width = (GLfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self));
- output_height = (GLfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self));
+ if (filter == RETRO_VIDEO_FILTER_SHARP) {
+ retro_gl_display_blit_texture (self, GL_NEAREST);
- retro_glsl_filter_set_uniform_4f (self->glsl_filter[filter], "sourceSize[0]",
- source_width, source_height,
- 1.0f / source_width, 1.0f / source_height);
+ return FALSE;
+ }
- retro_glsl_filter_set_uniform_4f (self->glsl_filter[filter], "targetSize",
- target_width, target_height,
- 1.0f / target_width, 1.0f / target_height);
+ if (self->glsl_filter[filter] == NULL) {
+ retro_gl_display_blit_texture (self, GL_LINEAR);
- retro_glsl_filter_set_uniform_4f (self->glsl_filter[filter], "outputSize",
- output_width, output_height,
- 1.0f / output_width, 1.0f / output_height);
+ return FALSE;
+ }
- glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ retro_gl_display_draw_texture (self, self->glsl_filter[filter]);
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]