[retro-gtk/wip/aplazas/gl-display: 1/3] gl-display: 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/3] gl-display: Blit the texture for simple filters
- Date: Fri, 17 Nov 2017 12:37:24 +0000 (UTC)
commit 75cb42e4ea3b00893fbe215774ed86f177fd0eb4
Author: Adrien Plazas <kekun plazas laposte net>
Date: Fri Nov 17 10:29:38 2017 +0100
gl-display: 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.
Also defaults to smooth rendering in case of broken GLSL 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..e287948 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 (filter_uris[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]