renderer: Add damage shaders

shader-damage-experiments
Andri Yngvason 2020-03-25 22:30:05 +00:00
parent 557f0f365b
commit 6536cbd56f
4 changed files with 101 additions and 32 deletions

View File

@ -43,7 +43,8 @@ struct renderer {
GLint read_format; GLint read_format;
GLint read_type; GLint read_type;
struct renderer_fbo fbo; struct renderer_fbo frame_fbo;
struct renderer_fbo damage_fbo;
GLuint tex[2]; GLuint tex[2];
int tex_index; int tex_index;
@ -55,7 +56,14 @@ struct renderer {
GLint u_tex0; GLint u_tex0;
GLint u_tex1; GLint u_tex1;
GLint u_proj; GLint u_proj;
} shader; } frame_shader;
struct {
GLuint program;
GLint u_tex0;
GLint u_tex1;
GLint u_proj;
} damage_shader;
}; };
int renderer_init(struct renderer* self, const struct output* output, int renderer_init(struct renderer* self, const struct output* output,

View File

@ -0,0 +1,13 @@
#extension GL_OES_EGL_image_external: require
precision mediump float;
uniform samplerExternalOES u_tex0;
varying vec2 v_texture;
void main()
{
float r = float(texture2D(u_tex0, v_texture).rgb != texture2D(u_tex1, v_texture).rgb);
gl_FragColor = vec4(r);
}

View File

@ -0,0 +1,12 @@
precision mediump float;
uniform sampler2D u_tex0;
uniform sampler2D u_tex1;
varying vec2 v_texture;
void main()
{
float r = float(texture2D(u_tex0, v_texture).rgb != texture2D(u_tex1, v_texture).rgb);
gl_FragColor = vec4(r);
}

View File

@ -375,21 +375,8 @@ void gl_clear(void)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
void render(struct renderer* self) void gl_draw(void)
{ {
glActiveTexture(GL_TEXTURE0);
glBindTexture(self->tex_target, renderer_current_tex(self));
glActiveTexture(GL_TEXTURE1);
glBindTexture(self->tex_target, renderer_last_tex(self));
glUseProgram(self->shader.program);
glUniform1i(self->shader.u_tex0, 0);
glUniform1i(self->shader.u_tex1, 1);
const float* proj = transforms[self->output->transform];
glUniformMatrix2fv(self->shader.u_proj, 1, GL_FALSE, proj);
static const GLfloat s_vertices[4][2] = { static const GLfloat s_vertices[4][2] = {
{ -1.0, 1.0 }, { -1.0, 1.0 },
{ 1.0, 1.0 }, { 1.0, 1.0 },
@ -420,6 +407,24 @@ void render(struct renderer* self)
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
} }
void render(struct renderer* self)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(self->tex_target, renderer_current_tex(self));
glActiveTexture(GL_TEXTURE1);
glBindTexture(self->tex_target, renderer_last_tex(self));
glUseProgram(self->frame_shader.program);
glUniform1i(self->frame_shader.u_tex0, 0);
glUniform1i(self->frame_shader.u_tex1, 1);
const float* proj = transforms[self->output->transform];
glUniformMatrix2fv(self->frame_shader.u_proj, 1, GL_FALSE, proj);
gl_draw();
}
void destroy_fbo(struct renderer_fbo* fbo) void destroy_fbo(struct renderer_fbo* fbo)
{ {
glDeleteFramebuffers(1, &fbo->fbo); glDeleteFramebuffers(1, &fbo->fbo);
@ -456,10 +461,10 @@ int create_fbo(struct renderer_fbo* dst, GLint format, uint32_t width,
void renderer_destroy(struct renderer* self) void renderer_destroy(struct renderer* self)
{ {
glDeleteProgram(self->shader.program); glDeleteProgram(self->frame_shader.program);
eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE, eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT); EGL_NO_CONTEXT);
destroy_fbo(&self->fbo); destroy_fbo(&self->frame_fbo);
glDeleteTextures(ARRAY_LEN(self->tex), self->tex); glDeleteTextures(ARRAY_LEN(self->tex), self->tex);
eglDestroyContext(self->display, self->context); eglDestroyContext(self->display, self->context);
eglTerminate(self->display); eglTerminate(self->display);
@ -524,33 +529,56 @@ int renderer_init(struct renderer* self, const struct output* output,
uint32_t tf_width = output_get_transformed_width(output); uint32_t tf_width = output_get_transformed_width(output);
uint32_t tf_height = output_get_transformed_height(output); uint32_t tf_height = output_get_transformed_height(output);
if (create_fbo(&self->fbo, GL_RGBA8_OES, tf_width, tf_height) < 0) if (create_fbo(&self->frame_fbo, GL_RGBA8_OES, tf_width, tf_height) < 0)
goto fbo_failure; goto frame_fbo_failure;
glBindFramebuffer(GL_FRAMEBUFFER, self->fbo.fbo); if (create_fbo(&self->damage_fbo, GL_R8_EXT, tf_width, tf_height) < 0)
goto damage_fbo_failure;
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo.fbo);
switch (input_type) { switch (input_type) {
case RENDERER_INPUT_DMABUF: case RENDERER_INPUT_DMABUF:
self->tex_target = GL_TEXTURE_EXTERNAL_OES; self->tex_target = GL_TEXTURE_EXTERNAL_OES;
if (gl_compile_shader_program(&self->shader.program, if (gl_compile_shader_program(&self->frame_shader.program,
"dmabuf-vertex.glsl", "dmabuf-vertex.glsl",
"dmabuf-fragment.glsl") < 0) "dmabuf-fragment.glsl") < 0)
goto shader_failure; goto frame_shader_failure;
if (gl_compile_shader_program(&self->damage_shader.program,
"dmabuf-vertex.glsl",
"dmabuf-damage-fragment.glsl") < 0)
goto damage_shader_failure;
break; break;
case RENDERER_INPUT_FB: case RENDERER_INPUT_FB:
self->tex_target = GL_TEXTURE_2D; self->tex_target = GL_TEXTURE_2D;
if (gl_compile_shader_program(&self->shader.program, if (gl_compile_shader_program(&self->frame_shader.program,
"texture-vertex.glsl", "texture-vertex.glsl",
"texture-fragment.glsl") < 0) "texture-fragment.glsl") < 0)
goto shader_failure; goto frame_shader_failure;
if (gl_compile_shader_program(&self->damage_shader.program,
"texture-vertex.glsl",
"texture-damage-fragment.glsl") < 0)
goto damage_shader_failure;
break; break;
} }
self->shader.u_tex0 = glGetUniformLocation(self->shader.program, "u_tex0"); self->frame_shader.u_tex0 =
self->shader.u_tex1 = glGetUniformLocation(self->shader.program, "u_tex1"); glGetUniformLocation(self->frame_shader.program, "u_tex0");
self->shader.u_proj = glGetUniformLocation(self->shader.program, "u_proj"); self->frame_shader.u_tex1 =
glGetUniformLocation(self->frame_shader.program, "u_tex1");
self->frame_shader.u_proj =
glGetUniformLocation(self->frame_shader.program, "u_proj");
self->damage_shader.u_tex0 =
glGetUniformLocation(self->damage_shader.program, "u_tex0");
self->damage_shader.u_tex1 =
glGetUniformLocation(self->damage_shader.program, "u_tex1");
self->damage_shader.u_proj =
glGetUniformLocation(self->damage_shader.program, "u_proj");
self->output = output; self->output = output;
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &self->read_format); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &self->read_format);
@ -564,8 +592,13 @@ int renderer_init(struct renderer* self, const struct output* output,
return 0; return 0;
shader_failure: damage_shader_failure:
fbo_failure: glDeleteShader(self->frame_shader.program);
frame_shader_failure:
destroy_fbo(&self->damage_fbo);
damage_fbo_failure:
destroy_fbo(&self->frame_fbo);
frame_fbo_failure:
glDeleteTextures(ARRAY_LEN(self->tex), self->tex); glDeleteTextures(ARRAY_LEN(self->tex), self->tex);
late_extension_failure: late_extension_failure:
make_current_failure: make_current_failure:
@ -663,6 +696,9 @@ void render_copy_pixels(struct renderer* self, void* dst, uint32_t y,
uint32_t width = output_get_transformed_width(self->output); uint32_t width = output_get_transformed_width(self->output);
glReadPixels(0, y, width, height, self->read_format, self->read_type, GLint read_format, read_type;
dst); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
glReadPixels(0, y, width, height, read_format, read_type, dst);
} }