renderer: Swap FPOs rather than textures
parent
f0fa12425b
commit
b0a6b6bd2a
|
@ -32,6 +32,7 @@ enum renderer_input_type {
|
||||||
struct renderer_fbo {
|
struct renderer_fbo {
|
||||||
GLuint rbo;
|
GLuint rbo;
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
|
GLuint tex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct renderer {
|
struct renderer {
|
||||||
|
@ -43,11 +44,10 @@ struct renderer {
|
||||||
GLint read_format;
|
GLint read_format;
|
||||||
GLint read_type;
|
GLint read_type;
|
||||||
|
|
||||||
struct renderer_fbo frame_fbo;
|
struct renderer_fbo frame_fbo[2];
|
||||||
struct renderer_fbo damage_fbo;
|
int frame_index;
|
||||||
|
|
||||||
GLuint tex[2];
|
struct renderer_fbo damage_fbo;
|
||||||
int tex_index;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLuint program;
|
GLuint program;
|
||||||
|
|
82
src/render.c
82
src/render.c
|
@ -386,22 +386,16 @@ void gl_draw(void)
|
||||||
glDisableVertexAttribArray(1);
|
glDisableVertexAttribArray(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_swap_textures(struct renderer* self)
|
void renderer_swap(struct renderer* self)
|
||||||
{
|
{
|
||||||
self->tex_index ^= 1;
|
self->frame_index ^= 1;
|
||||||
GLuint tex = self->tex[self->tex_index];
|
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
GL_TEXTURE_2D, tex, 0);
|
|
||||||
|
|
||||||
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_frame(struct renderer* self)
|
void render_frame(struct renderer* self)
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo.fbo);
|
renderer_swap(self);
|
||||||
|
|
||||||
renderer_swap_textures(self);
|
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo[self->frame_index].fbo);
|
||||||
|
|
||||||
glUseProgram(self->frame_shader.program);
|
glUseProgram(self->frame_shader.program);
|
||||||
|
|
||||||
|
@ -420,9 +414,9 @@ void render_damage(struct renderer* self)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, self->damage_fbo.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, self->damage_fbo.fbo);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, self->tex[self->tex_index]);
|
glBindTexture(GL_TEXTURE_2D, self->frame_fbo[self->frame_index].tex);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, self->tex[!self->tex_index]);
|
glBindTexture(GL_TEXTURE_2D, self->frame_fbo[!self->frame_index].tex);
|
||||||
|
|
||||||
glUseProgram(self->damage_shader.program);
|
glUseProgram(self->damage_shader.program);
|
||||||
|
|
||||||
|
@ -438,6 +432,8 @@ void destroy_fbo(struct renderer_fbo* fbo)
|
||||||
{
|
{
|
||||||
glDeleteFramebuffers(1, &fbo->fbo);
|
glDeleteFramebuffers(1, &fbo->fbo);
|
||||||
glDeleteRenderbuffers(1, &fbo->rbo);
|
glDeleteRenderbuffers(1, &fbo->rbo);
|
||||||
|
if (fbo->tex)
|
||||||
|
glDeleteTextures(1, &fbo->tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_fbo(struct renderer_fbo* dst, GLint format, uint32_t width,
|
int create_fbo(struct renderer_fbo* dst, GLint format, uint32_t width,
|
||||||
|
@ -464,26 +460,26 @@ int create_fbo(struct renderer_fbo* dst, GLint format, uint32_t width,
|
||||||
|
|
||||||
dst->fbo = fbo;
|
dst->fbo = fbo;
|
||||||
dst->rbo = rbo;
|
dst->rbo = rbo;
|
||||||
|
dst->tex = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_textured_fbo(struct renderer_fbo* dst, uint32_t width,
|
int create_textured_fbo(struct renderer_fbo* dst, GLint format, uint32_t width,
|
||||||
uint32_t height, GLuint tex)
|
uint32_t height)
|
||||||
{
|
{
|
||||||
GLuint rbo = 0;
|
GLuint tex = 0;
|
||||||
glGenRenderbuffers(1, &rbo);
|
glGenTextures(1, &tex);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width,
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
|
||||||
height);
|
GL_UNSIGNED_BYTE, NULL);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
GLuint fbo = 0;
|
GLuint fbo = 0;
|
||||||
glGenFramebuffers(1, &fbo);
|
glGenFramebuffers(1, &fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
|
|
||||||
GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT,
|
|
||||||
GL_RENDERBUFFER, rbo);
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
GL_TEXTURE_2D, tex, 0);
|
GL_TEXTURE_2D, tex, 0);
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
@ -495,31 +491,19 @@ int create_textured_fbo(struct renderer_fbo* dst, uint32_t width,
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->fbo = fbo;
|
dst->fbo = fbo;
|
||||||
dst->rbo = rbo;
|
dst->rbo = 0;
|
||||||
|
dst->tex = tex;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint create_texture_attachment(GLint format, uint32_t width, uint32_t height)
|
|
||||||
{
|
|
||||||
GLuint tex = 0;
|
|
||||||
glGenTextures(1, &tex);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
|
|
||||||
GL_UNSIGNED_BYTE, NULL);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer_destroy(struct renderer* self)
|
void renderer_destroy(struct renderer* self)
|
||||||
{
|
{
|
||||||
glDeleteProgram(self->frame_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->frame_fbo);
|
destroy_fbo(&self->frame_fbo[1]);
|
||||||
glDeleteTextures(ARRAY_LEN(self->tex), self->tex);
|
destroy_fbo(&self->frame_fbo[0]);
|
||||||
eglDestroyContext(self->display, self->context);
|
eglDestroyContext(self->display, self->context);
|
||||||
eglTerminate(self->display);
|
eglTerminate(self->display);
|
||||||
}
|
}
|
||||||
|
@ -581,17 +565,16 @@ 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);
|
||||||
|
|
||||||
self->tex[0] = create_texture_attachment(GL_RGBA, tf_width, tf_height);
|
if (create_textured_fbo(&self->frame_fbo[0], GL_RGBA, tf_width, tf_height) < 0)
|
||||||
self->tex[1] = create_texture_attachment(GL_RGBA, tf_width, tf_height);
|
goto frame_fbo_failure_0;
|
||||||
|
|
||||||
if (create_textured_fbo(&self->frame_fbo, tf_width, tf_height,
|
if (create_textured_fbo(&self->frame_fbo[1], GL_RGBA, tf_width, tf_height) < 0)
|
||||||
self->tex[0]) < 0)
|
goto frame_fbo_failure_1;
|
||||||
goto frame_fbo_failure;
|
|
||||||
|
|
||||||
if (create_fbo(&self->damage_fbo, GL_R8_EXT, tf_width, tf_height) < 0)
|
if (create_fbo(&self->damage_fbo, GL_R8_EXT, tf_width, tf_height) < 0)
|
||||||
goto damage_fbo_failure;
|
goto damage_fbo_failure;
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo[0].fbo);
|
||||||
|
|
||||||
switch (input_type) {
|
switch (input_type) {
|
||||||
case RENDERER_INPUT_DMABUF:
|
case RENDERER_INPUT_DMABUF:
|
||||||
|
@ -640,9 +623,10 @@ damage_shader_failure:
|
||||||
frame_shader_failure:
|
frame_shader_failure:
|
||||||
destroy_fbo(&self->damage_fbo);
|
destroy_fbo(&self->damage_fbo);
|
||||||
damage_fbo_failure:
|
damage_fbo_failure:
|
||||||
destroy_fbo(&self->frame_fbo);
|
destroy_fbo(&self->frame_fbo[1]);
|
||||||
frame_fbo_failure:
|
frame_fbo_failure_1:
|
||||||
glDeleteTextures(ARRAY_LEN(self->tex), self->tex);
|
destroy_fbo(&self->frame_fbo[0]);
|
||||||
|
frame_fbo_failure_0:
|
||||||
late_extension_failure:
|
late_extension_failure:
|
||||||
make_current_failure:
|
make_current_failure:
|
||||||
eglDestroyContext(self->display, self->context);
|
eglDestroyContext(self->display, self->context);
|
||||||
|
@ -758,7 +742,7 @@ void renderer_read_pixels(struct renderer* self, void* dst, uint32_t y,
|
||||||
void renderer_read_frame(struct renderer* self, void* dst, uint32_t y,
|
void renderer_read_frame(struct renderer* self, void* dst, uint32_t y,
|
||||||
uint32_t height)
|
uint32_t height)
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo[self->frame_index].fbo);
|
||||||
renderer_read_pixels(self, dst, y, height);
|
renderer_read_pixels(self, dst, y, height);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue