render: Working on damage tracking on the GPU
parent
b73b812bf8
commit
a4503e5e14
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <GLES2/gl2.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <pixman.h>
|
||||
|
||||
struct dmabuf_frame;
|
||||
|
||||
|
@ -28,10 +29,12 @@ struct renderer {
|
|||
GLuint last_texture;
|
||||
GLuint dmabuf_shader_program;
|
||||
GLuint texture_shader_program;
|
||||
GLuint damage_shader_program;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
GLint read_format;
|
||||
GLint read_type;
|
||||
struct pixman_region16 current_damage;
|
||||
};
|
||||
|
||||
int renderer_init(struct renderer* self, uint32_t width, uint32_t height);
|
||||
|
@ -44,3 +47,5 @@ int render_framebuffer(struct renderer* self, const void* addr, uint32_t format,
|
|||
/* Copy a horizontal stripe from the GL frame into a pixel buffer */
|
||||
void render_copy_pixels(struct renderer* self, void* dst, uint32_t y,
|
||||
uint32_t height);
|
||||
|
||||
void render_check_damage(struct renderer* self, GLenum target, GLuint tex);
|
||||
|
|
45
src/render.c
45
src/render.c
|
@ -281,10 +281,14 @@ void renderer_destroy(struct renderer* self)
|
|||
eglDestroySurface(self->display, self->surface);
|
||||
eglDestroyContext(self->display, self->context);
|
||||
eglTerminate(self->display);
|
||||
|
||||
pixman_region_fini(&self->current_damage);
|
||||
}
|
||||
|
||||
int renderer_init(struct renderer* self, uint32_t width, uint32_t height)
|
||||
{
|
||||
pixman_region_init(&self->current_damage);
|
||||
|
||||
if (!eglBindAPI(EGL_OPENGL_ES_API))
|
||||
return -1;
|
||||
|
||||
|
@ -430,6 +434,7 @@ int render_dmabuf_frame(struct renderer* self, struct dmabuf_frame* frame)
|
|||
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
|
||||
|
||||
glUseProgram(self->dmabuf_shader_program);
|
||||
glViewport(0, 0, self->width, self->height);
|
||||
gl_render();
|
||||
|
||||
if (self->last_texture)
|
||||
|
@ -460,7 +465,10 @@ int render_framebuffer(struct renderer* self, const void* addr, uint32_t format,
|
|||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0);
|
||||
|
||||
render_check_damage(self, GL_TEXTURE_2D, tex);
|
||||
|
||||
glUseProgram(self->texture_shader_program);
|
||||
glViewport(0, 0, self->width, self->height);
|
||||
gl_render();
|
||||
|
||||
if (self->last_texture)
|
||||
|
@ -480,3 +488,40 @@ void render_copy_pixels(struct renderer* self, void* dst, uint32_t y,
|
|||
glReadPixels(0, y, self->width, height, self->read_format,
|
||||
self->read_type, dst);
|
||||
}
|
||||
|
||||
void render_check_damage(struct renderer* self, GLenum target, GLuint tex)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(target, tex);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(target, self->last_texture);
|
||||
|
||||
// TODO: Create this damage shader program
|
||||
glUseProgram(self->damage_shader_program);
|
||||
|
||||
int width = self->width / 32;
|
||||
int height = self->height / 32;
|
||||
|
||||
uint32_t* buffer = malloc(width * height * 4);
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
gl_render();
|
||||
|
||||
glReadPixels(0, 0, width, height, self->read_format, self->read_type,
|
||||
buffer);
|
||||
|
||||
struct pixman_region16* damage = &self->current_damage;
|
||||
pixman_region_clear(damage);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
for (int x = 0; x < width; ++x)
|
||||
if (buffer[y * width + x])
|
||||
pixman_region_union_rect(damage, damage,
|
||||
x * 32, y * 32,
|
||||
32, 32);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue