diff --git a/include/render/gles2.h b/include/render/gles2.h index 6b852dcb7..1950bd94d 100644 --- a/include/render/gles2.h +++ b/include/render/gles2.h @@ -134,7 +134,6 @@ struct wlr_gles2_texture { struct wlr_gles2_render_pass { struct wlr_render_pass base; struct wlr_gles2_buffer *buffer; - float projection_matrix[9]; struct wlr_egl_context prev_ctx; struct wlr_gles2_render_timer *timer; struct wlr_drm_syncobj_timeline *signal_timeline; diff --git a/include/render/vulkan.h b/include/render/vulkan.h index 78109356f..a03b21d02 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -384,7 +384,6 @@ struct wlr_vk_render_pass { struct wlr_vk_command_buffer *command_buffer; struct rect_union updated_region; VkPipeline bound_pipeline; - float projection[9]; bool failed; bool srgb_pathway; // if false, rendering via intermediate blending buffer struct wlr_color_transform *color_transform; diff --git a/include/util/matrix.h b/include/util/matrix.h index c45c99a06..e9aeb63b9 100644 --- a/include/util/matrix.h +++ b/include/util/matrix.h @@ -4,40 +4,31 @@ #include struct wlr_box; - -/** Writes the identity matrix into mat */ -void wlr_matrix_identity(float mat[static 9]); +struct wlr_fbox; /** mat ← a × b */ -void wlr_matrix_multiply(float mat[static 9], const float a[static 9], +void matrix_multiply(float mat[static 9], const float a[static 9], const float b[static 9]); -/** Writes a 2D translation matrix to mat of magnitude (x, y) */ -void wlr_matrix_translate(float mat[static 9], float x, float y); - -/** Writes a 2D scale matrix to mat of magnitude (x, y) */ -void wlr_matrix_scale(float mat[static 9], float x, float y); - /** Writes a transformation matrix which applies the specified * wl_output_transform to mat */ -void wlr_matrix_transform(float mat[static 9], - enum wl_output_transform transform); +void matrix_transform(float mat[static 9], enum wl_output_transform transform); /** Shortcut for the various matrix operations involved in projecting the - * specified wlr_box onto a given orthographic projection with a given - * rotation. The result is written to mat, which can be applied to each - * coordinate of the box to get a new coordinate from [-1,1]. */ -void wlr_matrix_project_box(float mat[static 9], const struct wlr_box *box, - enum wl_output_transform transform, const float projection[static 9]); + * specified wlr_box onto a given orthographic projection. The result is + * written to mat, which can be applied to each coordinate of the box to get a + * new coordinate from [-1,1]. + */ +void matrix_project_box(float mat[static 9], const struct wlr_box *box); + +void matrix_project_fbox(float mat[static 9], const struct wlr_fbox *box); /** - * Writes a 2D orthographic projection matrix to mat of (width, height) with a - * specified wl_output_transform. + * Writes a 2D orthographic projection matrix to mat of (width, height). * * Equivalent to glOrtho(0, width, 0, height, 1, -1) with the transform applied. */ -void matrix_projection(float mat[static 9], int width, int height, - enum wl_output_transform transform); +void matrix_projection(float mat[static 9], int width, int height); /** * Compute the inverse of a matrix. diff --git a/render/gles2/pass.c b/render/gles2/pass.c index b10ac047d..d634ebfff 100644 --- a/render/gles2/pass.c +++ b/render/gles2/pass.c @@ -124,31 +124,25 @@ static void render(const struct wlr_box *box, const pixman_region32_t *clip, GLi pixman_region32_fini(®ion); } -static void set_proj_matrix(GLint loc, float proj[9], const struct wlr_box *box) { +static void set_proj_matrix(GLint loc, struct wlr_gles2_buffer *buffer, const struct wlr_box *box) { float gl_matrix[9]; - wlr_matrix_identity(gl_matrix); - wlr_matrix_translate(gl_matrix, box->x, box->y); - wlr_matrix_scale(gl_matrix, box->width, box->height); - wlr_matrix_multiply(gl_matrix, proj, gl_matrix); + matrix_project_box(gl_matrix, box); + matrix_projection(gl_matrix, buffer->buffer->width, buffer->buffer->height); glUniformMatrix3fv(loc, 1, GL_FALSE, gl_matrix); } static void set_tex_matrix(GLint loc, enum wl_output_transform trans, const struct wlr_fbox *box) { float tex_matrix[9]; - wlr_matrix_identity(tex_matrix); - wlr_matrix_translate(tex_matrix, box->x, box->y); - wlr_matrix_scale(tex_matrix, box->width, box->height); - wlr_matrix_translate(tex_matrix, .5, .5); + matrix_project_fbox(tex_matrix, box); // since textures have a different origin point we have to transform // differently if we are rotating if (trans & WL_OUTPUT_TRANSFORM_90) { - wlr_matrix_transform(tex_matrix, wlr_output_transform_invert(trans)); + matrix_transform(tex_matrix, wlr_output_transform_invert(trans)); } else { - wlr_matrix_transform(tex_matrix, trans); + matrix_transform(tex_matrix, trans); } - wlr_matrix_translate(tex_matrix, -.5, -.5); glUniformMatrix3fv(loc, 1, GL_FALSE, tex_matrix); } @@ -244,7 +238,7 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, glUniform1i(shader->tex, 0); glUniform1f(shader->alpha, alpha); - set_proj_matrix(shader->proj, pass->projection_matrix, &dst_box); + set_proj_matrix(shader->proj, pass->buffer, &dst_box); set_tex_matrix(shader->tex_proj, options->transform, &src_fbox); render(&dst_box, options->clip, shader->pos_attrib); @@ -267,7 +261,7 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass, glUseProgram(renderer->shaders.quad.program); - set_proj_matrix(renderer->shaders.quad.proj, pass->projection_matrix, &box); + set_proj_matrix(renderer->shaders.quad.proj, pass->buffer, &box); glUniform4f(renderer->shaders.quad.color, color->r, color->g, color->b, color->a); render(&box, options->clip, renderer->shaders.quad.pos_attrib); @@ -329,9 +323,6 @@ struct wlr_gles2_render_pass *begin_gles2_buffer_pass(struct wlr_gles2_buffer *b pass->signal_point = signal_point; } - matrix_projection(pass->projection_matrix, wlr_buffer->width, wlr_buffer->height, - WL_OUTPUT_TRANSFORM_FLIPPED_180); - push_gles2_debug(renderer); glBindFramebuffer(GL_FRAMEBUFFER, fbo); diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 529743305..17fa56575 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -616,10 +616,11 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass, switch (options->blend_mode) { case WLR_RENDER_BLEND_MODE_PREMULTIPLIED:; - float proj[9], matrix[9]; - wlr_matrix_identity(proj); - wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, proj); - wlr_matrix_multiply(matrix, pass->projection, matrix); + float matrix[9]; + matrix_project_box(matrix, &box); + matrix_projection(matrix, + pass->render_buffer->wlr_buffer->width, + pass->render_buffer->wlr_buffer->height); struct wlr_vk_render_format_setup *setup = pass->srgb_pathway ? pass->render_buffer->srgb.render_setup : @@ -707,10 +708,12 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, wlr_render_texture_options_get_dst_box(options, &dst_box); float alpha = wlr_render_texture_options_get_alpha(options); - float proj[9], matrix[9]; - wlr_matrix_identity(proj); - wlr_matrix_project_box(matrix, &dst_box, options->transform, proj); - wlr_matrix_multiply(matrix, pass->projection, matrix); + float matrix[9]; + matrix_project_box(matrix, &dst_box); + matrix_transform(matrix, options->transform); + matrix_projection(matrix, + pass->render_buffer->wlr_buffer->width, + pass->render_buffer->wlr_buffer->height); struct wlr_vk_vert_pcr_data vert_pcr_data = { .uv_off = { @@ -1156,10 +1159,6 @@ struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *rend .maxDepth = 1, }); - // matrix_projection() assumes a GL coordinate system so we need - // to pass WL_OUTPUT_TRANSFORM_FLIPPED_180 to adjust it for vulkan. - matrix_projection(pass->projection, width, height, WL_OUTPUT_TRANSFORM_FLIPPED_180); - wlr_buffer_lock(buffer->wlr_buffer); pass->render_buffer = buffer; pass->command_buffer = cb; diff --git a/util/matrix.c b/util/matrix.c index 640787c95..e8b783f0b 100644 --- a/util/matrix.c +++ b/util/matrix.c @@ -4,16 +4,7 @@ #include #include "util/matrix.h" -void wlr_matrix_identity(float mat[static 9]) { - static const float identity[9] = { - 1.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f, - }; - memcpy(mat, identity, sizeof(identity)); -} - -void wlr_matrix_multiply(float mat[static 9], const float a[static 9], +void matrix_multiply(float mat[static 9], const float a[static 9], const float b[static 9]) { float product[9]; @@ -32,24 +23,6 @@ void wlr_matrix_multiply(float mat[static 9], const float a[static 9], memcpy(mat, product, sizeof(product)); } -void wlr_matrix_translate(float mat[static 9], float x, float y) { - float translate[9] = { - 1.0f, 0.0f, x, - 0.0f, 1.0f, y, - 0.0f, 0.0f, 1.0f, - }; - wlr_matrix_multiply(mat, mat, translate); -} - -void wlr_matrix_scale(float mat[static 9], float x, float y) { - float scale[9] = { - x, 0.0f, 0.0f, - 0.0f, y, 0.0f, - 0.0f, 0.0f, 1.0f, - }; - wlr_matrix_multiply(mat, mat, scale); -} - static const float transforms[][9] = { [WL_OUTPUT_TRANSFORM_NORMAL] = { 1.0f, 0.0f, 0.0f, @@ -58,21 +31,21 @@ static const float transforms[][9] = { }, [WL_OUTPUT_TRANSFORM_90] = { 0.0f, 1.0f, 0.0f, - -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, }, [WL_OUTPUT_TRANSFORM_180] = { - -1.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, + -1.0f, 0.0f, 1.0f, + 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, }, [WL_OUTPUT_TRANSFORM_270] = { - 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }, [WL_OUTPUT_TRANSFORM_FLIPPED] = { - -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, }, @@ -83,62 +56,57 @@ static const float transforms[][9] = { }, [WL_OUTPUT_TRANSFORM_FLIPPED_180] = { 1.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, }, [WL_OUTPUT_TRANSFORM_FLIPPED_270] = { - 0.0f, -1.0f, 0.0f, - -1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 1.0f, + -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, }, }; -void wlr_matrix_transform(float mat[static 9], +void matrix_transform(float mat[static 9], enum wl_output_transform transform) { - wlr_matrix_multiply(mat, mat, transforms[transform]); + matrix_multiply(mat, mat, transforms[transform]); } -void matrix_projection(float mat[static 9], int width, int height, - enum wl_output_transform transform) { - memset(mat, 0, sizeof(*mat) * 9); +void matrix_projection(float mat[static 9], int width, int height) { + struct wlr_fbox fbox = { + .x = -1.0f, + .y = -1.0f, + .width = 2.0f / width, + .height = 2.0f / height, + }; - const float *t = transforms[transform]; - float x = 2.0f / width; - float y = 2.0f / height; + float trans[9]; + matrix_project_fbox(trans, &fbox); + matrix_multiply(mat, trans, mat); +} - // Rotation + reflection - mat[0] = x * t[0]; - mat[1] = x * t[1]; - mat[3] = y * -t[3]; - mat[4] = y * -t[4]; +void matrix_project_fbox(float mat[static 9], const struct wlr_fbox *box) { + mat[0] = box->width; + mat[1] = 0.0f; + mat[2] = box->x; - // Translation - mat[2] = -copysign(1.0f, mat[0] + mat[1]); - mat[5] = -copysign(1.0f, mat[3] + mat[4]); + mat[3] = 0.0f; + mat[4] = box->height; + mat[5] = box->y; - // Identity + mat[6] = 0.0f; + mat[7] = 0.0f; mat[8] = 1.0f; } -void wlr_matrix_project_box(float mat[static 9], const struct wlr_box *box, - enum wl_output_transform transform, const float projection[static 9]) { - int x = box->x; - int y = box->y; - int width = box->width; - int height = box->height; +void matrix_project_box(float mat[static 9], const struct wlr_box *box) { + struct wlr_fbox fbox = { + .x = box->x, + .y = box->y, + .width = box->width, + .height = box->height, + }; - wlr_matrix_identity(mat); - wlr_matrix_translate(mat, x, y); - - wlr_matrix_scale(mat, width, height); - - if (transform != WL_OUTPUT_TRANSFORM_NORMAL) { - wlr_matrix_translate(mat, 0.5, 0.5); - wlr_matrix_transform(mat, transform); - wlr_matrix_translate(mat, -0.5, -0.5); - } - - wlr_matrix_multiply(mat, projection, mat); + matrix_project_fbox(mat, &fbox); } void matrix_invert(float out[static 9], float m[static 9]) {