Commit 7216e9333e423fe6bf3a14396d31394e6e66f9be Parent: 9c9e396f412c7a640613c68e8fb706c43bf11979 Author: mcol <mcol@posteo.net> Date: 2020-11-05 23:00:36 +0000 Committer: mcol <mcol@posteo.net> Committed: 2020-11-05 23:00:36 +0000 add basic rendering, based on tinywm
src/output.h Modified
@@ -12,6 +12,17 @@ }; +struct render_data { + struct wlr_output *output; + struct wlr_renderer *renderer; + struct view *view; + struct timespec *when; +}; + + +void render_surface( + struct wlr_surface *surface, int sx, int sy, void *data +); void on_frame(struct wl_listener *listener, void *data); void on_new_output(struct wl_listener *listener, void *data); void set_up_outputs(struct server *server);
src/output.c Modified
@@ -1,22 +1,87 @@ +#include <time.h> +#include <wlr/types/wlr_matrix.h> #include <wlr/types/wlr_output_layout.h> #include "output.h" #include "types.h" +void render_surface( + struct wlr_surface *surface, int sx, int sy, void *data +) { + struct render_data *rdata = data; + struct view *view = rdata->view; + struct wlr_output *output = rdata->output; + + struct wlr_texture *texture = wlr_surface_get_texture(surface); + if (texture == NULL) { + return; + } + + // get output-relative coordinates + double ox = 0, oy = 0; + wlr_output_layout_output_coords( + view->server->output_layout, output, &ox, &oy + ); + ox += view->x + sx, oy += view->y + sy; + + // scale for HiDPI + struct wlr_box box = { + .x = ox * output->scale, + .y = oy * output->scale, + .width = surface->current.width * output->scale, + .height = surface->current.height * output->scale, + }; + + // this is where any rendering magic might happen + float matrix[9]; + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, 0, + output->transform_matrix); + + wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1); + wlr_surface_send_frame_done(surface, rdata->when); +} + + void on_frame(struct wl_listener *listener, void *data) { - struct output *output = wl_container_of(listener, output, frame_listener); - struct wlr_output *wlr_output = output->wlr_output; + struct output *output = wl_container_of(listener, output, frame_listener); + struct wlr_renderer *renderer = output->server->renderer; + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + if (!wlr_output_attach_render(output->wlr_output, NULL)) { + return; + } - wlr_output_attach_render(wlr_output, NULL); + int width, height; + wlr_output_effective_resolution(output->wlr_output, &width, &height); + wlr_renderer_begin(renderer, width, height); - struct wlr_renderer *renderer = - wlr_backend_get_renderer(wlr_output->backend); + float color[4] = {0.3, 0.05, 0.7, 1.0}; // background + wlr_renderer_clear(renderer, color); + + struct view *view; + wl_list_for_each_reverse(view, &output->server->views, link) { + if (!view->is_mapped) { + continue; + } + struct render_data rdata = { + .output = output->wlr_output, + .view = view, + .renderer = renderer, + .when = &now, + }; + wlr_xdg_surface_for_each_surface( + view->surface, render_surface, &rdata + ); + } - wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); - wlr_renderer_clear(renderer, (float[]){0, 0, 0, 1}); - wlr_renderer_end(renderer); - wlr_output_commit(wlr_output); + wlr_output_render_software_cursors(output->wlr_output, NULL); // no-op with HW cursors + wlr_renderer_end(renderer); + wlr_output_commit(output->wlr_output); }