Correctly render flipped/rotated screens
This commit is contained in:
parent
2a896eae5f
commit
bd8fc3f7d4
28
src/main.c
28
src/main.c
@ -347,6 +347,21 @@ static inline void color_to_float_array(GtkStyleContext *ctx,
|
||||
out[3] = color.alpha;
|
||||
}
|
||||
|
||||
static unsigned form_get_rotation(GtkWidget *form) {
|
||||
GtkBuilder *builder = GTK_BUILDER(g_object_get_data(G_OBJECT(form), "builder"));
|
||||
unsigned rot;
|
||||
for (rot = 0; rot < NUM_ROTATIONS; rot++) {
|
||||
GtkWidget *rotate = GTK_WIDGET(gtk_builder_get_object(builder,
|
||||
ROTATE_IDS[rot]));
|
||||
gboolean selected;
|
||||
g_object_get(rotate, "active", &selected, NULL);
|
||||
if (selected) {
|
||||
return rot;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void queue_canvas_draw(struct wd_state *state) {
|
||||
GtkStyleContext *style_ctx = gtk_widget_get_style_context(state->canvas);
|
||||
color_to_float_array(style_ctx,
|
||||
@ -379,6 +394,13 @@ static void queue_canvas_draw(struct wd_state *state) {
|
||||
wl_list_insert(&state->render.heads, &head->render->link);
|
||||
}
|
||||
struct wd_render_head_data *render = head->render;
|
||||
render->queued.rotation = form_get_rotation(GTK_WIDGET(form_iter->data));
|
||||
if (render->queued.rotation & 1) {
|
||||
int tmp = w;
|
||||
w = h;
|
||||
h = tmp;
|
||||
}
|
||||
render->queued.x_invert = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "flipped")));
|
||||
render->x1 = floor(x * state->zoom - state->render.scroll_x - state->render.x_origin);
|
||||
render->y1 = floor(y * state->zoom - state->render.scroll_y - state->render.y_origin);
|
||||
render->x2 = floor(render->x1 + w * state->zoom / scale);
|
||||
@ -839,6 +861,10 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data)
|
||||
render->y_invert = frame->y_invert;
|
||||
render->swap_rgb = frame->swap_rgb;
|
||||
}
|
||||
if (render->preview) {
|
||||
render->active.rotation = render->queued.rotation;
|
||||
render->active.x_invert = render->queued.x_invert;
|
||||
}
|
||||
} else if (render->preview
|
||||
|| render->pixels == NULL || size_changed(render)) {
|
||||
render->tex_width = render->x2 - render->x1;
|
||||
@ -852,6 +878,8 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data)
|
||||
render->pixels = cairo_image_surface_get_data(head->surface);
|
||||
render->tex_stride = cairo_image_surface_get_stride(head->surface);
|
||||
render->updated_at = tick;
|
||||
render->active.rotation = 0;
|
||||
render->active.x_invert = false;
|
||||
render->y_invert = false;
|
||||
render->swap_rgb = false;
|
||||
}
|
||||
|
43
src/render.c
43
src/render.c
@ -253,20 +253,39 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info,
|
||||
int i = 0;
|
||||
wl_list_for_each_reverse(head, &info->heads, link) {
|
||||
float *tri_ptr = res->tris + i * BT_UV_QUAD_SIZE;
|
||||
float x1 = head->x1;
|
||||
float y1 = head->y1;
|
||||
float x2 = head->x2;
|
||||
float y2 = head->y2;
|
||||
float x1 = head->active.x_invert ? head->x2 : head->x1;
|
||||
float y1 = head->y_invert ? head->y2 : head->y1;
|
||||
float x2 = head->active.x_invert ? head->x1 : head->x2;
|
||||
float y2 = head->y_invert ? head->y1 : head->y2;
|
||||
|
||||
float t1 = head->y_invert ? 1.f : 0.f;
|
||||
float t2 = head->y_invert ? 0.f : 1.f;
|
||||
float sa = 0.f;
|
||||
float sb = 1.f;
|
||||
float sc = sb;
|
||||
float sd = sa;
|
||||
float ta = 0.f;
|
||||
float tb = ta;
|
||||
float tc = 1.f;
|
||||
float td = tc;
|
||||
for (int i = 0; i < head->active.rotation; i++) {
|
||||
float tmp = sd;
|
||||
sd = sc;
|
||||
sc = sb;
|
||||
sb = sa;
|
||||
sa = tmp;
|
||||
|
||||
PUSH_POINT_UV(tri_ptr, x1, y1, 0.f, t1)
|
||||
PUSH_POINT_UV(tri_ptr, x2, y1, 1.f, t1)
|
||||
PUSH_POINT_UV(tri_ptr, x1, y2, 0.f, t2)
|
||||
PUSH_POINT_UV(tri_ptr, x1, y2, 0.f, t2)
|
||||
PUSH_POINT_UV(tri_ptr, x2, y1, 1.f, t1)
|
||||
PUSH_POINT_UV(tri_ptr, x2, y2, 1.f, t2)
|
||||
tmp = td;
|
||||
td = tc;
|
||||
tc = tb;
|
||||
tb = ta;
|
||||
ta = tmp;
|
||||
}
|
||||
|
||||
PUSH_POINT_UV(tri_ptr, x1, y1, sa, ta)
|
||||
PUSH_POINT_UV(tri_ptr, x2, y1, sb, tb)
|
||||
PUSH_POINT_UV(tri_ptr, x1, y2, sd, td)
|
||||
PUSH_POINT_UV(tri_ptr, x1, y2, sd, td)
|
||||
PUSH_POINT_UV(tri_ptr, x2, y1, sb, tb)
|
||||
PUSH_POINT_UV(tri_ptr, x2, y2, sc, tc)
|
||||
|
||||
tris += 6;
|
||||
i++;
|
||||
|
@ -148,25 +148,33 @@ struct wd_head {
|
||||
|
||||
struct wd_gl_data;
|
||||
|
||||
struct wd_render_head_flags {
|
||||
uint8_t rotation;
|
||||
bool x_invert;
|
||||
};
|
||||
|
||||
struct wd_render_head_data {
|
||||
struct wl_list link;
|
||||
uint64_t updated_at;
|
||||
uint64_t transition_begin;
|
||||
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
|
||||
struct wd_render_head_flags queued;
|
||||
struct wd_render_head_flags active;
|
||||
|
||||
uint8_t *pixels;
|
||||
unsigned tex_stride;
|
||||
unsigned tex_width;
|
||||
unsigned tex_height;
|
||||
|
||||
bool preview;
|
||||
bool y_invert;
|
||||
bool swap_rgb;
|
||||
uint64_t updated_at;
|
||||
|
||||
bool hovered;
|
||||
uint64_t transition_begin;
|
||||
};
|
||||
|
||||
struct wd_render_data {
|
||||
|
Loading…
Reference in New Issue
Block a user