backend: gl: preparation for new backend API transition

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-04-02 03:42:14 +01:00
parent 06469a1bb8
commit 3088cbc770
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
1 changed files with 83 additions and 48 deletions

View File

@ -257,26 +257,25 @@ _gl_average_texture_color(backend_t *base, GLuint source_texture, GLuint destina
* Returned texture must not be deleted, since it's owned by the gl_image. It will be
* deleted when the gl_image is released.
*/
static GLuint gl_average_texture_color(backend_t *base, struct backend_image *img) {
static GLuint gl_average_texture_color(backend_t *base, struct gl_texture *img) {
auto gd = (struct gl_data *)base;
auto inner = (struct gl_texture *)img->inner;
// Prepare textures which will be used for destination and source of rendering
// during downscaling.
const int texture_count = ARR_SIZE(inner->auxiliary_texture);
if (!inner->auxiliary_texture[0]) {
assert(!inner->auxiliary_texture[1]);
glGenTextures(texture_count, inner->auxiliary_texture);
const int texture_count = ARR_SIZE(img->auxiliary_texture);
if (!img->auxiliary_texture[0]) {
assert(!img->auxiliary_texture[1]);
glGenTextures(texture_count, img->auxiliary_texture);
glActiveTexture(GL_TEXTURE0);
for (int i = 0; i < texture_count; i++) {
glBindTexture(GL_TEXTURE_2D, inner->auxiliary_texture[i]);
glBindTexture(GL_TEXTURE_2D, img->auxiliary_texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,
(GLint[]){0, 0, 0, 0});
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, inner->width,
inner->height, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, img->width, img->height,
0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
}
}
@ -289,7 +288,7 @@ static GLuint gl_average_texture_color(backend_t *base, struct backend_image *im
// Enable shaders
glUseProgram(gd->brightness_shader.prog);
glUniform2f(glGetUniformLocationChecked(gd->brightness_shader.prog, "texsize"),
(GLfloat)inner->width, (GLfloat)inner->height);
(GLfloat)img->width, (GLfloat)img->height);
// Prepare vertex attributes
GLuint vao;
@ -314,8 +313,8 @@ static GLuint gl_average_texture_color(backend_t *base, struct backend_image *im
// Do actual recursive render to 1x1 texture
GLuint result_texture = _gl_average_texture_color(
base, inner->texture, inner->auxiliary_texture[0],
inner->auxiliary_texture[1], fbo, inner->width, inner->height);
base, img->texture, img->auxiliary_texture[0], img->auxiliary_texture[1], fbo,
img->width, img->height);
// Cleanup vertex attributes
glDisableVertexAttribArray(vert_coord_loc);
@ -346,33 +345,29 @@ static GLuint gl_average_texture_color(backend_t *base, struct backend_image *im
* Render a region with texture data.
*
* @param ptex the texture
* @param target the framebuffer to render into
* @param dst_x,dst_y the top left corner of region where this texture
* should go. In OpenGL coordinate system (important!).
* @param reg_tgt the clip region, in Xorg coordinate system
* @param reg_visible ignored
* @param target_texture the texture to render into
* @param blit_args arguments for the blit
* @param coord GL vertices
* @param indices GL indices
* @param nrects number of rectangles to render
*/
static void _gl_compose(backend_t *base, struct backend_image *img, GLuint target,
struct backend_image *mask, coord_t mask_offset, GLint *coord,
GLuint *indices, int nrects) {
static void gl_blit_inner(backend_t *base, GLuint target_texture,
struct backend_blit_args *blit_args, GLint *coord,
GLuint *indices, int nrects) {
// FIXME(yshui) breaks when `mask` and `img` doesn't have the same y_inverted
// value. but we don't ever hit this problem because all of our
// images and masks are y_inverted.
auto gd = (struct gl_data *)base;
auto inner = (struct gl_texture *)img->inner;
auto mask_texture =
mask ? ((struct gl_texture *)mask->inner)->texture : gd->default_mask_texture;
if (!img || !inner->texture) {
log_error("Missing texture.");
return;
}
auto img = (struct gl_texture *)blit_args->source_image;
auto mask_image = blit_args->mask ? (struct gl_texture *)blit_args->mask->image : NULL;
auto mask_texture = mask_image ? mask_image->texture : gd->default_mask_texture;
GLuint brightness = 0;
if (img->max_brightness < 1.0) {
if (blit_args->max_brightness < 1.0) {
brightness = gl_average_texture_color(base, img);
}
auto win_shader = inner->shader;
auto win_shader = (gl_win_shader_t *)blit_args->shader;
if (!win_shader) {
win_shader = gd->default_shader;
}
@ -381,33 +376,34 @@ static void _gl_compose(backend_t *base, struct backend_image *img, GLuint targe
assert(win_shader->prog);
glUseProgram(win_shader->prog);
if (win_shader->uniform_opacity >= 0) {
glUniform1f(win_shader->uniform_opacity, (float)img->opacity);
glUniform1f(win_shader->uniform_opacity, (float)blit_args->opacity);
}
if (win_shader->uniform_invert_color >= 0) {
glUniform1i(win_shader->uniform_invert_color, img->color_inverted);
glUniform1i(win_shader->uniform_invert_color, blit_args->color_inverted);
}
if (win_shader->uniform_tex >= 0) {
glUniform1i(win_shader->uniform_tex, 0);
}
if (win_shader->uniform_effective_size >= 0) {
glUniform2f(win_shader->uniform_effective_size, (float)img->ewidth,
(float)img->eheight);
glUniform2f(win_shader->uniform_effective_size, (float)blit_args->ewidth,
(float)blit_args->eheight);
}
if (win_shader->uniform_dim >= 0) {
glUniform1f(win_shader->uniform_dim, (float)img->dim);
glUniform1f(win_shader->uniform_dim, (float)blit_args->dim);
}
if (win_shader->uniform_brightness >= 0) {
glUniform1i(win_shader->uniform_brightness, 1);
}
if (win_shader->uniform_max_brightness >= 0) {
glUniform1f(win_shader->uniform_max_brightness, (float)img->max_brightness);
glUniform1f(win_shader->uniform_max_brightness,
(float)blit_args->max_brightness);
}
if (win_shader->uniform_corner_radius >= 0) {
glUniform1f(win_shader->uniform_corner_radius, (float)img->corner_radius);
glUniform1f(win_shader->uniform_corner_radius, (float)blit_args->corner_radius);
}
if (win_shader->uniform_border_width >= 0) {
auto border_width = img->border_width;
if (border_width > img->corner_radius) {
auto border_width = blit_args->border_width;
if (border_width > blit_args->corner_radius) {
border_width = 0;
}
glUniform1f(win_shader->uniform_border_width, (float)border_width);
@ -420,12 +416,13 @@ static void _gl_compose(backend_t *base, struct backend_image *img, GLuint targe
}
glUniform1i(win_shader->uniform_mask_tex, 2);
glUniform2f(win_shader->uniform_mask_offset, (float)mask_offset.x,
(float)mask_offset.y);
if (mask != NULL) {
glUniform1i(win_shader->uniform_mask_inverted, mask->color_inverted);
if (blit_args->mask != NULL) {
glUniform2f(win_shader->uniform_mask_offset,
(float)blit_args->mask->origin.x,
(float)blit_args->mask->origin.y);
glUniform1i(win_shader->uniform_mask_inverted, blit_args->mask->inverted);
glUniform1f(win_shader->uniform_mask_corner_radius,
(GLfloat)mask->corner_radius);
(GLfloat)blit_args->mask->corner_radius);
} else {
glUniform1i(win_shader->uniform_mask_inverted, 0);
glUniform1f(win_shader->uniform_mask_corner_radius, 0);
@ -441,7 +438,7 @@ static void _gl_compose(backend_t *base, struct backend_image *img, GLuint targe
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, brightness);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, inner->texture);
glBindTexture(GL_TEXTURE_2D, img->texture);
GLuint vao;
glGenVertexArrays(1, &vao);
@ -460,7 +457,9 @@ static void _gl_compose(backend_t *base, struct backend_image *img, GLuint targe
glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE, sizeof(GLint) * 4, NULL);
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_INT, GL_FALSE,
sizeof(GLint) * 4, (void *)(sizeof(GLint) * 2));
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gd->back_fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
target_texture, 0);
glDrawElements(GL_TRIANGLES, nrects * 6, GL_UNSIGNED_INT, NULL);
glDisableVertexAttribArray(vert_coord_loc);
@ -577,10 +576,33 @@ void gl_compose(backend_t *base, image_handle image, coord_t image_dst,
auto coord = ccalloc(nrects * 16, GLint);
auto indices = ccalloc(nrects * 6, GLuint);
coord_t mask_offset = {.x = mask_dst.x - image_dst.x, .y = mask_dst.y - image_dst.y};
struct coord mask_offset = {.x = mask_dst.x - image_dst.x,
.y = mask_dst.y - image_dst.y};
x_rect_to_coords(nrects, rects, image_dst, inner->height, inner->height,
gd->height, inner->y_inverted, coord, indices);
_gl_compose(base, img, gd->back_fbo, mask, mask_offset, coord, indices, nrects);
struct backend_mask mask_args = {
.image = mask ? (image_handle)mask->inner : NULL,
.origin = mask_offset,
.corner_radius = mask ? mask->corner_radius : 0,
.inverted = mask ? mask->color_inverted : false,
};
pixman_region32_init(&mask_args.region);
struct backend_blit_args blit_args = {
.source_image = (image_handle)img->inner,
.mask = mask ? &mask_args : NULL,
.shader = (void *)inner->shader,
.opacity = img->opacity,
.color_inverted = img->color_inverted,
.ewidth = img->ewidth,
.eheight = img->eheight,
.dim = img->dim,
.corner_radius = img->corner_radius,
.border_width = img->border_width,
.max_brightness = img->max_brightness,
};
gl_blit_inner(base, gd->back_texture, &blit_args, coord, indices, nrects);
free(indices);
free(coord);
@ -1338,7 +1360,20 @@ image_handle gl_shadow_from_mask(backend_t *base, image_handle mask_,
radius , radius + inner->height, 0 , inner->height,};
// clang-format on
GLuint indices[] = {0, 1, 2, 2, 3, 0};
_gl_compose(base, mask, fbo, NULL, (coord_t){0}, coords, indices, 1);
struct backend_blit_args blit_args = {
.source_image = (image_handle)mask->inner,
.mask = NULL,
.shader = (void *)inner->shader,
.opacity = mask->opacity,
.color_inverted = mask->color_inverted,
.ewidth = mask->ewidth,
.eheight = mask->eheight,
.dim = mask->dim,
.corner_radius = mask->corner_radius,
.border_width = mask->border_width,
.max_brightness = mask->max_brightness,
};
gl_blit_inner(base, source_texture, &blit_args, coords, indices, 1);
}
gl_check_err();