Correctly render flipped/rotated screens

This commit is contained in:
Jason Francis 2019-08-23 17:35:59 -04:00
parent 2a896eae5f
commit bd8fc3f7d4
3 changed files with 70 additions and 15 deletions

View File

@ -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;
}

View File

@ -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++;

View File

@ -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 {