*/
int pending_output_layout_change;
+ struct wl_listener renderer_lost;
+
struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1;
struct wl_listener gamma_control_set_gamma;
void magnify(struct output *output, struct wlr_buffer *output_buffer,
struct wlr_box *damage);
bool is_magnify_on(void);
+void magnify_reset(void);
#endif /* LABWC_MAGNIFIER_H */
static bool magnify_on;
static double mag_scale = 0.0;
+/* Reuse a single scratch buffer */
+static struct wlr_buffer *tmp_buffer = NULL;
+static struct wlr_texture *tmp_texture = NULL;
+
#define CLAMP(in, lower, upper) MAX(MIN((in), (upper)), (lower))
void
struct wlr_fbox src_box;
bool fullscreen = false;
- /* Reuse a single scratch buffer */
- static struct wlr_buffer *tmp_buffer = NULL;
- static struct wlr_texture *tmp_texture = NULL;
-
/* TODO: This looks way too complicated to just get the used format */
struct wlr_drm_format wlr_drm_format = {0};
struct wlr_shm_attributes shm_attribs = {0};
/* Extract source region into temporary buffer */
struct wlr_render_pass *tmp_render_pass = wlr_renderer_begin_buffer_pass(
server->renderer, tmp_buffer, NULL);
+ if (!tmp_render_pass) {
+ wlr_log(WLR_ERROR, "Failed to begin magnifier render pass");
+ return;
+ }
wlr_buffer_lock(output_buffer);
struct wlr_texture *output_texture = wlr_texture_from_buffer(
/* Render to the output buffer itself */
tmp_render_pass = wlr_renderer_begin_buffer_pass(
server->renderer, output_buffer, NULL);
+ if (!tmp_render_pass) {
+ wlr_log(WLR_ERROR, "Failed to begin second magnifier render pass");
+ goto cleanup;
+ }
/* Borders */
if (fullscreen) {
}
}
+/* Reset any buffers held by the magnifier */
+void
+magnify_reset(void)
+{
+ if (tmp_texture && tmp_buffer) {
+ wlr_texture_destroy(tmp_texture);
+ wlr_buffer_drop(tmp_buffer);
+ tmp_buffer = NULL;
+ tmp_texture = NULL;
+ }
+}
+
/* Report whether magnification is enabled */
bool
is_magnify_on(void)
#include "idle.h"
#include "labwc.h"
#include "layers.h"
+#include "magnifier.h"
#include "menu/menu.h"
#include "output-state.h"
#include "output-virtual.h"
}
}
+static void
+handle_renderer_lost(struct wl_listener *listener, void *data)
+{
+ struct server *server = wl_container_of(listener, server, renderer_lost);
+
+ wlr_log(WLR_INFO, "Re-creating renderer after GPU reset");
+
+ struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend);
+ if (!renderer) {
+ wlr_log(WLR_ERROR, "Unable to create renderer");
+ return;
+ }
+
+ struct wlr_allocator *allocator =
+ wlr_allocator_autocreate(server->backend, renderer);
+ if (!allocator) {
+ wlr_log(WLR_ERROR, "Unable to create allocator");
+ wlr_renderer_destroy(renderer);
+ return;
+ }
+
+ struct wlr_renderer *old_renderer = server->renderer;
+ struct wlr_allocator *old_allocator = server->allocator;
+ server->renderer = renderer;
+ server->allocator = allocator;
+
+ wl_list_remove(&server->renderer_lost.link);
+ wl_signal_add(&server->renderer->events.lost, &server->renderer_lost);
+
+ wlr_compositor_set_renderer(compositor, renderer);
+
+ struct output *output;
+ wl_list_for_each(output, &server->outputs, link) {
+ wlr_output_init_render(output->wlr_output,
+ server->allocator, server->renderer);
+ }
+
+ reload_config_and_theme(server);
+
+ magnify_reset();
+
+ wlr_allocator_destroy(old_allocator);
+ wlr_renderer_destroy(old_renderer);
+}
+
void
server_init(struct server *server)
{
exit(EXIT_FAILURE);
}
+ server->renderer_lost.notify = handle_renderer_lost;
+ wl_signal_add(&server->renderer->events.lost, &server->renderer_lost);
+
wlr_renderer_init_wl_display(server->renderer, server->wl_display);
/*