Do image clipping using OpenGL rather than on the CPU

This commit is contained in:
Kovid Goyal 2017-10-07 10:08:26 +05:30
parent 3a344d86fe
commit d5088a3e5b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 13 additions and 8 deletions

View File

@ -582,7 +582,7 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
Image *img; ImageRef *ref; Image *img; ImageRef *ref;
ImageRect r; ImageRect r;
float screen_width = dx * num_cols, screen_height = dy * num_rows; float screen_width = dx * num_cols, screen_height = dy * num_rows;
float screen_bottom = screen_top - screen_height, screen_right = screen_left + screen_width; float screen_bottom = screen_top - screen_height;
float screen_width_px = num_cols * global_state.cell_width; float screen_width_px = num_cols * global_state.cell_width;
float screen_height_px = num_rows * global_state.cell_height; float screen_height_px = num_rows * global_state.cell_height;
float y0 = screen_top - dy * scrolled_by; float y0 = screen_top - dy * scrolled_by;
@ -599,12 +599,6 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
if (ref->num_cols) r.right = screen_left + (ref->start_column + ref->num_cols) * dx; if (ref->num_cols) r.right = screen_left + (ref->start_column + ref->num_cols) * dx;
else r.right = r.left + screen_width * (float)ref->src_width / screen_width_px; else r.right = r.left + screen_width * (float)ref->src_width / screen_width_px;
// Clip image to screen boundaries
if (r.top > screen_top) r.top = screen_top;
if (r.bottom < screen_bottom) r.bottom = screen_bottom;
if (r.left < screen_left) r.left = screen_left;
if (r.right > screen_right) r.right = screen_right;
if (ref->z_index < 0) self->num_of_negative_refs++; else self->num_of_positive_refs++; if (ref->z_index < 0) self->num_of_negative_refs++; else self->num_of_positive_refs++;
ensure_space_for(self, render_data, ImageRenderData, self->count + 1, capacity, 100); ensure_space_for(self, render_data, ImageRenderData, self->count + 1, capacity, 100);
ImageRenderData *rd = self->render_data + self->count; ImageRenderData *rd = self->render_data + self->count;

View File

@ -313,6 +313,7 @@ draw_graphics(ImageRenderData *data, GLuint start, GLuint count) {
glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT); check_gl(); glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT); check_gl();
GLuint base = 4 * start; GLuint base = 4 * start;
glEnable(GL_SCISSOR_TEST);
for (GLuint i=0; i < count;) { for (GLuint i=0; i < count;) {
ImageRenderData *rd = data + start + i; ImageRenderData *rd = data + start + i;
glBindTexture(GL_TEXTURE_2D, rd->texture_id); check_gl(); glBindTexture(GL_TEXTURE_2D, rd->texture_id); check_gl();
@ -321,6 +322,7 @@ draw_graphics(ImageRenderData *data, GLuint start, GLuint count) {
// before implementing it. // before implementing it.
for (GLuint k=0; k < rd->group_count; k++, base += 4, i++) glDrawArrays(GL_TRIANGLE_FAN, base, 4); for (GLuint k=0; k < rd->group_count; k++, base += 4, i++) glDrawArrays(GL_TRIANGLE_FAN, base, 4);
} }
glDisable(GL_SCISSOR_TEST);
} }
@ -354,6 +356,15 @@ draw_cells_interleaved(Screen *screen) {
static void static void
draw_cells_impl(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen, CursorRenderInfo *cursor) { draw_cells_impl(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen, CursorRenderInfo *cursor) {
GLfloat h = (GLfloat)screen->lines * dy;
#define SCALE(w, x) ((GLfloat)(global_state.viewport_##w) * (GLfloat)(x))
glScissor(
(GLint)(SCALE(width, (xstart + 1.0f) / 2.0f)),
(GLint)(SCALE(height, ((ystart - h) + 1.0f) / 2.0f)),
(GLsizei)(ceilf(SCALE(width, (float)screen->columns * dx / 2.0f))),
(GLsizei)(ceilf(SCALE(height, h / 2.0f)))
);
#undef SCALE
cell_prepare_to_render(vao_idx, screen, xstart, ystart, dx, dy, cursor); cell_prepare_to_render(vao_idx, screen, xstart, ystart, dx, dy, cursor);
if (screen->grman->num_of_negative_refs) draw_cells_interleaved(screen); if (screen->grman->num_of_negative_refs) draw_cells_interleaved(screen);
else draw_all_cells(screen); else draw_all_cells(screen);

View File

@ -222,7 +222,7 @@ class TestGraphics(BaseTest):
self.ae(len(l), 2) self.ae(len(l), 2)
rect_eq(l[0]['src_rect'], 2 / 10, 1 / 20, (2 + 3) / 10, (1 + 5)/20) rect_eq(l[0]['src_rect'], 2 / 10, 1 / 20, (2 + 3) / 10, (1 + 5)/20)
left, top = -1 + dx + 3 * dx / cw, 1 - 1 * dy / ch left, top = -1 + dx + 3 * dx / cw, 1 - 1 * dy / ch
rect_eq(l[0]['dest_rect'], left, top, min(1, -1 + (1 + s.columns) * dx), max(-1, top - dy * 5 / ch)) rect_eq(l[0]['dest_rect'], left, top, -1 + (1 + s.columns) * dx, top - dy * 5 / ch)
rect_eq(l[1]['src_rect'], 0, 0, 1, 1) rect_eq(l[1]['src_rect'], 0, 0, 1, 1)
rect_eq(l[1]['dest_rect'], -1, 1, -1 + dx, 1 - dy) rect_eq(l[1]['dest_rect'], -1, 1, -1 + dx, 1 - dy)
self.ae(l[0]['group_count'], 1), self.ae(l[1]['group_count'], 1) self.ae(l[0]['group_count'], 1), self.ae(l[1]['group_count'], 1)