gl_common, new glx: implement partial updates

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-07-26 02:02:34 +01:00
parent 06dba4b196
commit 5a861d5d6a
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
3 changed files with 30 additions and 12 deletions

View File

@ -1159,13 +1159,27 @@ static void gl_image_apply_alpha(backend_t *base, struct gl_image *img,
glDeleteFramebuffers(1, &fbo); glDeleteFramebuffers(1, &fbo);
} }
void gl_present(backend_t *base) { void gl_present(backend_t *base, const region_t *region) {
auto gd = (struct gl_data *)base; auto gd = (struct gl_data *)base;
GLuint indices[] = {0, 1, 2, 2, 3, 0}; int nrects;
GLint coord[] = { const rect_t *rect = pixman_region32_rectangles((region_t *)region, &nrects);
0, 0, gd->width, 0, gd->width, gd->height, 0, gd->height, auto coord = ccalloc(nrects * 8, GLint);
}; auto indices = ccalloc(nrects * 6, GLuint);
for (int i = 0; i < nrects; i++) {
// clang-format off
memcpy(&coord[i * 8],
(GLint[]){rect[i].x1, gd->height - rect[i].y2,
rect[i].x2, gd->height - rect[i].y2,
rect[i].x2, gd->height - rect[i].y1,
rect[i].x1, gd->height - rect[i].y1},
sizeof(GLint) * 8);
// clang-format on
GLuint u = (GLuint)(i * 4);
memcpy(&indices[i * 6], (GLuint[]){u + 0, u + 1, u + 2, u + 2, u + 3, u + 0},
sizeof(GLuint) * 6);
}
glUseProgram(gd->present_prog); glUseProgram(gd->present_prog);
glBindTexture(GL_TEXTURE_2D, gd->back_texture); glBindTexture(GL_TEXTURE_2D, gd->back_texture);
@ -1179,18 +1193,22 @@ void gl_present(backend_t *base) {
glEnableVertexAttribArray(vert_coord_loc); glEnableVertexAttribArray(vert_coord_loc);
glBindBuffer(GL_ARRAY_BUFFER, bo[0]); glBindBuffer(GL_ARRAY_BUFFER, bo[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo[1]);
glBufferData(GL_ARRAY_BUFFER, (long)sizeof(coord), coord, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, (long)sizeof(GLint) * nrects * 8, coord, GL_STREAM_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (long)sizeof(indices), indices, GL_STREAM_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, (long)sizeof(GLuint) * nrects * 6, indices,
GL_STREAM_DRAW);
glVertexAttribPointer(vert_coord_loc, 2, GL_UNSIGNED_INT, GL_FALSE, glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE,
sizeof(GLuint) * 2, NULL); sizeof(GLint) * 2, NULL);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL); glDrawElements(GL_TRIANGLES, nrects * 6, GL_UNSIGNED_INT, NULL);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glDeleteBuffers(2, bo); glDeleteBuffers(2, bo);
glDeleteVertexArrays(1, &vao); glDeleteVertexArrays(1, &vao);
free(coord);
free(indices);
} }
/// stub for backend_operations::image_op /// stub for backend_operations::image_op

View File

@ -113,7 +113,7 @@ void gl_get_blur_size(void *blur_context, int *width, int *height);
bool gl_is_image_transparent(backend_t *base, void *image_data); bool gl_is_image_transparent(backend_t *base, void *image_data);
void gl_fill(backend_t *base, struct color, const region_t *clip); void gl_fill(backend_t *base, struct color, const region_t *clip);
void gl_present(backend_t *base); void gl_present(backend_t *base, const region_t *);
static inline void gl_delete_texture(GLuint texture) { static inline void gl_delete_texture(GLuint texture) {
glDeleteTextures(1, &texture); glDeleteTextures(1, &texture);

View File

@ -438,7 +438,7 @@ err:
static void glx_present(backend_t *base, const region_t *region attr_unused) { static void glx_present(backend_t *base, const region_t *region attr_unused) {
struct _glx_data *gd = (void *)base; struct _glx_data *gd = (void *)base;
gl_present(base); gl_present(base, region);
glXSwapBuffers(gd->display, gd->target_win); glXSwapBuffers(gd->display, gd->target_win);
// XXX there should be no need to block compton will wait for render to finish // XXX there should be no need to block compton will wait for render to finish
if (!gd->gl.is_nvidia) { if (!gd->gl.is_nvidia) {