store viewport width & height in fx_renderer

This commit is contained in:
Will McKinnon 2023-04-24 00:11:55 -04:00
parent 50e2422e74
commit b61041980f
5 changed files with 40 additions and 59 deletions

View file

@ -14,8 +14,7 @@ struct fx_framebuffer {
void fx_framebuffer_bind(struct fx_framebuffer *buffer, GLsizei width, GLsizei height); void fx_framebuffer_bind(struct fx_framebuffer *buffer, GLsizei width, GLsizei height);
void fx_framebuffer_create(struct wlr_output *output, struct fx_framebuffer *buffer, void fx_framebuffer_create(struct fx_framebuffer *buffer, int width, int height, bool bind);
bool bind);
void fx_framebuffer_release(struct fx_framebuffer *buffer); void fx_framebuffer_release(struct fx_framebuffer *buffer);

View file

@ -4,6 +4,7 @@
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#include <stdbool.h> #include <stdbool.h>
#include <wlr/render/egl.h>
#include "sway/desktop/fx_renderer/fx_framebuffer.h" #include "sway/desktop/fx_renderer/fx_framebuffer.h"
#include "sway/desktop/fx_renderer/fx_texture.h" #include "sway/desktop/fx_renderer/fx_texture.h"
@ -69,11 +70,9 @@ struct blur_shader {
}; };
struct fx_renderer { struct fx_renderer {
struct wlr_egl *egl;
float projection[9]; float projection[9];
struct sway_output *sway_output; int viewport_width, viewport_height;
GLuint stencil_buffer_id; GLuint stencil_buffer_id;
@ -147,7 +146,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl);
void fx_renderer_fini(struct fx_renderer *renderer); void fx_renderer_fini(struct fx_renderer *renderer);
void fx_renderer_begin(struct fx_renderer *renderer, struct sway_output *output); void fx_renderer_begin(struct fx_renderer *renderer, int width, int height);
void fx_renderer_end(struct fx_renderer *renderer); void fx_renderer_end(struct fx_renderer *renderer);
@ -176,8 +175,8 @@ void fx_render_border_corner(struct fx_renderer *renderer, const struct wlr_box
void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *box, void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *box,
const float color[static 4], const float projection[static 9], int radius, float blur_sigma); const float color[static 4], const float projection[static 9], int radius, float blur_sigma);
void fx_render_blur(struct fx_renderer *renderer, struct sway_output *output, void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9],
const float matrix[static 9], struct fx_framebuffer **buffer, struct fx_framebuffer **buffer, struct blur_shader *shader, const struct wlr_box *box,
struct blur_shader *shader, const struct wlr_box *box, int blur_radius); int blur_radius);
#endif #endif

View file

@ -6,7 +6,7 @@ void fx_framebuffer_bind(struct fx_framebuffer *buffer, GLsizei width, GLsizei h
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
} }
void fx_framebuffer_create(struct wlr_output *output, struct fx_framebuffer *buffer, bool bind) { void fx_framebuffer_create(struct fx_framebuffer *buffer, int width, int height, bool bind) {
bool firstAlloc = false; bool firstAlloc = false;
// Create a new framebuffer // Create a new framebuffer
@ -25,9 +25,6 @@ void fx_framebuffer_create(struct wlr_output *output, struct fx_framebuffer *buf
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} }
int width, height;
wlr_output_transformed_resolution(output, &width, &height);
if (firstAlloc || buffer->texture.width != width || buffer->texture.height != height) { if (firstAlloc || buffer->texture.width != width || buffer->texture.height != height) {
glBindTexture(GL_TEXTURE_2D, buffer->texture.id); glBindTexture(GL_TEXTURE_2D, buffer->texture.id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

View file

@ -15,7 +15,6 @@
#include "log.h" #include "log.h"
#include "sway/desktop/fx_renderer/fx_renderer.h" #include "sway/desktop/fx_renderer/fx_renderer.h"
#include "sway/desktop/fx_renderer/matrix.h" #include "sway/desktop/fx_renderer/matrix.h"
#include "sway/output.h"
#include "sway/server.h" #include "sway/server.h"
// shaders // shaders
@ -35,14 +34,11 @@ static const GLfloat verts[] = {
0, 1, // bottom left 0, 1, // bottom left
}; };
static void create_stencil_buffer(struct wlr_output* output, GLuint *buffer_id) { static void create_stencil_buffer(GLuint *buffer_id, int width, int height) {
if (*buffer_id != (uint32_t) -1) { if (*buffer_id != (uint32_t) -1) {
return; return;
} }
int width, height;
wlr_output_transformed_resolution(output, &width, &height);
glGenRenderbuffers(1, buffer_id); glGenRenderbuffers(1, buffer_id);
glBindRenderbuffer(GL_RENDERBUFFER, *buffer_id); glBindRenderbuffer(GL_RENDERBUFFER, *buffer_id);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height); glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
@ -205,8 +201,6 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not make EGL current"); sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not make EGL current");
return NULL; return NULL;
} }
// TODO: needed?
renderer->egl = egl;
renderer->main_buffer.fb = -1; renderer->main_buffer.fb = -1;
@ -337,7 +331,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
} }
if (!eglMakeCurrent(wlr_egl_get_display(renderer->egl), if (!eglMakeCurrent(wlr_egl_get_display(egl),
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL"); sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL");
goto error; goto error;
@ -359,7 +353,7 @@ error:
glDeleteProgram(renderer->shaders.tex_rgbx.program); glDeleteProgram(renderer->shaders.tex_rgbx.program);
glDeleteProgram(renderer->shaders.tex_ext.program); glDeleteProgram(renderer->shaders.tex_ext.program);
if (!eglMakeCurrent(wlr_egl_get_display(renderer->egl), if (!eglMakeCurrent(wlr_egl_get_display(egl),
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL"); sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL");
} }
@ -379,13 +373,10 @@ void fx_renderer_fini(struct fx_renderer *renderer) {
release_stencil_buffer(&renderer->stencil_buffer_id); release_stencil_buffer(&renderer->stencil_buffer_id);
} }
void fx_renderer_begin(struct fx_renderer *renderer, struct sway_output *sway_output) { void fx_renderer_begin(struct fx_renderer *renderer, int width, int height) {
struct wlr_output *output = sway_output->wlr_output; renderer->viewport_width = width;
renderer->viewport_height = height;
int width, height;
wlr_output_transformed_resolution(output, &width, &height);
renderer->sway_output = sway_output;
// Store the wlr framebuffer // Store the wlr framebuffer
GLint wlr_fb = -1; GLint wlr_fb = -1;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &wlr_fb); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &wlr_fb);
@ -395,14 +386,11 @@ void fx_renderer_begin(struct fx_renderer *renderer, struct sway_output *sway_ou
} }
renderer->wlr_buffer.fb = wlr_fb; renderer->wlr_buffer.fb = wlr_fb;
// Create the main framebuffer // Create the framebuffers
fx_framebuffer_create(output, &renderer->main_buffer, true); fx_framebuffer_create(&renderer->main_buffer, width, height, true);
// Create the stencil buffer and attach it to our main_buffer fx_framebuffer_create(&renderer->effects_buffer, width, height, false);
create_stencil_buffer(output, &renderer->stencil_buffer_id); fx_framebuffer_create(&renderer->effects_buffer_swapped, width, height, false);
create_stencil_buffer(&renderer->stencil_buffer_id, width, height);
// Create a new blur/effects framebuffers
fx_framebuffer_create(output, &renderer->effects_buffer, false);
fx_framebuffer_create(output, &renderer->effects_buffer_swapped, false);
// refresh projection matrix // refresh projection matrix
matrix_projection(renderer->projection, width, height, matrix_projection(renderer->projection, width, height,
@ -761,9 +749,9 @@ void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *bo
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} }
void fx_render_blur(struct fx_renderer *renderer, struct sway_output *output, void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9],
const float matrix[static 9], struct fx_framebuffer **buffer, struct fx_framebuffer **buffer, struct blur_shader *shader,
struct blur_shader *shader, const struct wlr_box *box, int blur_radius) { const struct wlr_box *box, int blur_radius) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
@ -784,12 +772,10 @@ void fx_render_blur(struct fx_renderer *renderer, struct sway_output *output,
glUniform1i(shader->tex, 0); glUniform1i(shader->tex, 0);
glUniform1f(shader->radius, blur_radius); glUniform1f(shader->radius, blur_radius);
int width, height;
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
if (shader == &renderer->shaders.blur1) { if (shader == &renderer->shaders.blur1) {
glUniform2f(shader->halfpixel, 0.5f / (width / 2.0f), 0.5f / (height / 2.0f)); glUniform2f(shader->halfpixel, 0.5f / (renderer->viewport_width / 2.0f), 0.5f / (renderer->viewport_height / 2.0f));
} else { } else {
glUniform2f(shader->halfpixel, 0.5f / (width * 2.0f), 0.5f / (height * 2.0f)); glUniform2f(shader->halfpixel, 0.5f / (renderer->viewport_width * 2.0f), 0.5f / (renderer->viewport_height * 2.0f));
} }
glVertexAttribPointer(shader->pos_attrib, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(shader->pos_attrib, 2, GL_FLOAT, GL_FALSE, 0, verts);

View file

@ -187,7 +187,7 @@ void render_blur_segments(struct fx_renderer *renderer, struct sway_output *outp
const pixman_box32_t box = rects[i]; const pixman_box32_t box = rects[i];
struct wlr_box new_box = { box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1 }; struct wlr_box new_box = { box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1 };
fx_renderer_scissor(&new_box); fx_renderer_scissor(&new_box);
fx_render_blur(renderer, output, matrix, buffer, shader, &new_box, blur_radius); fx_render_blur(renderer, matrix, buffer, shader, &new_box, blur_radius);
} }
} }
@ -441,14 +441,13 @@ static void render_drag_icons(struct sway_output *output,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
void render_whole_output(struct fx_renderer *renderer, pixman_region32_t *original_damage, void render_whole_output(struct fx_renderer *renderer, struct wlr_output *wlr_output,
struct fx_texture *texture) { pixman_region32_t *original_damage, struct fx_texture *texture) {
struct wlr_output *output = renderer->sway_output->wlr_output; struct wlr_box monitor_box = get_monitor_box(wlr_output);
struct wlr_box monitor_box = get_monitor_box(output);
enum wl_output_transform transform = wlr_output_transform_invert(output->transform); enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
float matrix[9]; float matrix[9];
wlr_matrix_project_box(matrix, &monitor_box, transform, 0.0, output->transform_matrix); wlr_matrix_project_box(matrix, &monitor_box, transform, 0.0, wlr_output->transform_matrix);
pixman_region32_t damage; pixman_region32_t damage;
pixman_region32_init(&damage); pixman_region32_init(&damage);
@ -463,7 +462,7 @@ void render_whole_output(struct fx_renderer *renderer, pixman_region32_t *origin
int nrects; int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) { for (int i = 0; i < nrects; ++i) {
scissor_output(output, &rects[i]); scissor_output(wlr_output, &rects[i]);
fx_render_texture_with_matrix(renderer, texture, &monitor_box, matrix, get_undecorated_decoration_data()); fx_render_texture_with_matrix(renderer, texture, &monitor_box, matrix, get_undecorated_decoration_data());
} }
@ -484,7 +483,7 @@ void render_monitor_blur(struct sway_output *output, pixman_region32_t *damage)
wlr_output->transform_matrix, &monitor_box); wlr_output->transform_matrix, &monitor_box);
// Render the newly blurred content into the blur_buffer // Render the newly blurred content into the blur_buffer
fx_framebuffer_create(wlr_output, &renderer->blur_buffer, true); fx_framebuffer_create(&renderer->blur_buffer, monitor_box.width, monitor_box.height, true);
// Clear the damaged region of the blur_buffer // Clear the damaged region of the blur_buffer
float clear_color[] = { 0, 0, 0, 0 }; float clear_color[] = { 0, 0, 0, 0 };
int nrects; int nrects;
@ -493,7 +492,7 @@ void render_monitor_blur(struct sway_output *output, pixman_region32_t *damage)
scissor_output(wlr_output, &rects[i]); scissor_output(wlr_output, &rects[i]);
fx_renderer_clear(clear_color); fx_renderer_clear(clear_color);
} }
render_whole_output(renderer, &fake_damage, &buffer->texture); render_whole_output(renderer, wlr_output, &fake_damage, &buffer->texture);
fx_framebuffer_bind(&renderer->main_buffer, monitor_box.width, monitor_box.height); fx_framebuffer_bind(&renderer->main_buffer, monitor_box.width, monitor_box.height);
pixman_region32_fini(&fake_damage); pixman_region32_fini(&fake_damage);
@ -1750,9 +1749,6 @@ void output_render(struct sway_output *output, struct timespec *when,
struct wlr_output *wlr_output = output->wlr_output; struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer; struct fx_renderer *renderer = output->renderer;
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
struct sway_workspace *workspace = output->current.active_workspace; struct sway_workspace *workspace = output->current.active_workspace;
if (workspace == NULL) { if (workspace == NULL) {
return; return;
@ -1763,6 +1759,12 @@ void output_render(struct sway_output *output, struct timespec *when,
fullscreen_con = workspace->current.fullscreen; fullscreen_con = workspace->current.fullscreen;
} }
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
fx_renderer_begin(renderer, width, height);
if (debug.damage == DAMAGE_RERENDER) { if (debug.damage == DAMAGE_RERENDER) {
pixman_region32_union_rect(damage, damage, 0, 0, width, height); pixman_region32_union_rect(damage, damage, 0, 0, width, height);
} }
@ -1806,8 +1808,6 @@ void output_render(struct sway_output *output, struct timespec *when,
fx_renderer_clear((float[]){1, 1, 0, 1}); fx_renderer_clear((float[]){1, 1, 0, 1});
} }
fx_renderer_begin(renderer, output);
if (!damage_not_empty) { if (!damage_not_empty) {
// Output isn't damaged but needs buffer swap // Output isn't damaged but needs buffer swap
goto renderer_end; goto renderer_end;
@ -1959,7 +1959,7 @@ renderer_end:
fx_renderer_clear(clear_color); fx_renderer_clear(clear_color);
} }
} }
render_whole_output(renderer, &extended_damage, &renderer->main_buffer.texture); render_whole_output(renderer, wlr_output, &extended_damage, &renderer->main_buffer.texture);
fx_renderer_scissor(NULL); fx_renderer_scissor(NULL);
fx_renderer_end(renderer); fx_renderer_end(renderer);