|
|
@ -124,6 +124,10 @@ struct gl_renderer { |
|
|
|
PFNEGLCREATEIMAGEKHRPROC create_image; |
|
|
|
PFNEGLCREATEIMAGEKHRPROC create_image; |
|
|
|
PFNEGLDESTROYIMAGEKHRPROC destroy_image; |
|
|
|
PFNEGLDESTROYIMAGEKHRPROC destroy_image; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef EGL_EXT_swap_buffers_with_damage |
|
|
|
|
|
|
|
PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
int has_unpack_subimage; |
|
|
|
int has_unpack_subimage; |
|
|
|
|
|
|
|
|
|
|
|
PFNEGLBINDWAYLANDDISPLAYWL bind_display; |
|
|
|
PFNEGLBINDWAYLANDDISPLAYWL bind_display; |
|
|
@ -677,6 +681,17 @@ draw_output_border_texture(struct gl_output_state *go, |
|
|
|
glDisableVertexAttribArray(0); |
|
|
|
glDisableVertexAttribArray(0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
|
|
|
output_has_borders(struct weston_output *output) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct gl_output_state *go = get_output_state(output); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return go->borders[GL_RENDERER_BORDER_TOP].data || |
|
|
|
|
|
|
|
go->borders[GL_RENDERER_BORDER_RIGHT].data || |
|
|
|
|
|
|
|
go->borders[GL_RENDERER_BORDER_BOTTOM].data || |
|
|
|
|
|
|
|
go->borders[GL_RENDERER_BORDER_LEFT].data; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
|
draw_output_borders(struct weston_output *output, |
|
|
|
draw_output_borders(struct weston_output *output, |
|
|
|
enum gl_border_status border_status) |
|
|
|
enum gl_border_status border_status) |
|
|
@ -731,6 +746,43 @@ draw_output_borders(struct weston_output *output, |
|
|
|
full_width, bottom->height); |
|
|
|
full_width, bottom->height); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
|
|
output_get_border_damage(struct weston_output *output, |
|
|
|
|
|
|
|
enum gl_border_status border_status, |
|
|
|
|
|
|
|
pixman_region32_t *damage) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct gl_output_state *go = get_output_state(output); |
|
|
|
|
|
|
|
struct gl_border_image *top, *bottom, *left, *right; |
|
|
|
|
|
|
|
int full_width, full_height; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (border_status == BORDER_STATUS_CLEAN) |
|
|
|
|
|
|
|
return; /* Clean. Nothing to do. */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
top = &go->borders[GL_RENDERER_BORDER_TOP]; |
|
|
|
|
|
|
|
bottom = &go->borders[GL_RENDERER_BORDER_BOTTOM]; |
|
|
|
|
|
|
|
left = &go->borders[GL_RENDERER_BORDER_LEFT]; |
|
|
|
|
|
|
|
right = &go->borders[GL_RENDERER_BORDER_RIGHT]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
full_width = output->current_mode->width + left->width + right->width; |
|
|
|
|
|
|
|
full_height = output->current_mode->height + top->height + bottom->height; |
|
|
|
|
|
|
|
if (border_status & BORDER_TOP_DIRTY) |
|
|
|
|
|
|
|
pixman_region32_union_rect(damage, damage, |
|
|
|
|
|
|
|
0, 0, |
|
|
|
|
|
|
|
full_width, top->height); |
|
|
|
|
|
|
|
if (border_status & BORDER_LEFT_DIRTY) |
|
|
|
|
|
|
|
pixman_region32_union_rect(damage, damage, |
|
|
|
|
|
|
|
0, top->height, |
|
|
|
|
|
|
|
left->width, output->current_mode->height); |
|
|
|
|
|
|
|
if (border_status & BORDER_RIGHT_DIRTY) |
|
|
|
|
|
|
|
pixman_region32_union_rect(damage, damage, |
|
|
|
|
|
|
|
full_width - right->width, top->height, |
|
|
|
|
|
|
|
right->width, output->current_mode->height); |
|
|
|
|
|
|
|
if (border_status & BORDER_BOTTOM_DIRTY) |
|
|
|
|
|
|
|
pixman_region32_union_rect(damage, damage, |
|
|
|
|
|
|
|
0, full_height - bottom->height, |
|
|
|
|
|
|
|
full_width, bottom->height); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
static void |
|
|
|
output_get_damage(struct weston_output *output, |
|
|
|
output_get_damage(struct weston_output *output, |
|
|
|
pixman_region32_t *buffer_damage, uint32_t *border_damage) |
|
|
|
pixman_region32_t *buffer_damage, uint32_t *border_damage) |
|
|
@ -802,6 +854,11 @@ gl_renderer_repaint_output(struct weston_output *output, |
|
|
|
struct gl_renderer *gr = get_renderer(compositor); |
|
|
|
struct gl_renderer *gr = get_renderer(compositor); |
|
|
|
EGLBoolean ret; |
|
|
|
EGLBoolean ret; |
|
|
|
static int errored; |
|
|
|
static int errored; |
|
|
|
|
|
|
|
#ifdef EGL_EXT_swap_buffers_with_damage |
|
|
|
|
|
|
|
int i, nrects, buffer_height; |
|
|
|
|
|
|
|
EGLint *egl_damage, *d; |
|
|
|
|
|
|
|
pixman_box32_t *rects; |
|
|
|
|
|
|
|
#endif |
|
|
|
pixman_region32_t buffer_damage, total_damage; |
|
|
|
pixman_region32_t buffer_damage, total_damage; |
|
|
|
enum gl_border_status border_damage = BORDER_STATUS_CLEAN; |
|
|
|
enum gl_border_status border_damage = BORDER_STATUS_CLEAN; |
|
|
|
|
|
|
|
|
|
|
@ -847,7 +904,48 @@ gl_renderer_repaint_output(struct weston_output *output, |
|
|
|
pixman_region32_copy(&output->previous_damage, output_damage); |
|
|
|
pixman_region32_copy(&output->previous_damage, output_damage); |
|
|
|
wl_signal_emit(&output->frame_signal, output); |
|
|
|
wl_signal_emit(&output->frame_signal, output); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef EGL_EXT_swap_buffers_with_damage |
|
|
|
|
|
|
|
if (gr->swap_buffers_with_damage) { |
|
|
|
|
|
|
|
pixman_region32_init(&buffer_damage); |
|
|
|
|
|
|
|
weston_transformed_region(output->width, output->height, |
|
|
|
|
|
|
|
output->transform, |
|
|
|
|
|
|
|
output->current_scale, |
|
|
|
|
|
|
|
output_damage, &buffer_damage); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (output_has_borders(output)) { |
|
|
|
|
|
|
|
pixman_region32_translate(&buffer_damage, |
|
|
|
|
|
|
|
go->borders[GL_RENDERER_BORDER_LEFT].width, |
|
|
|
|
|
|
|
go->borders[GL_RENDERER_BORDER_TOP].height); |
|
|
|
|
|
|
|
output_get_border_damage(output, go->border_status, |
|
|
|
|
|
|
|
&buffer_damage); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rects = pixman_region32_rectangles(&buffer_damage, &nrects); |
|
|
|
|
|
|
|
egl_damage = malloc(nrects * 4 * sizeof(EGLint)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buffer_height = go->borders[GL_RENDERER_BORDER_TOP].height + |
|
|
|
|
|
|
|
output->current_mode->height + |
|
|
|
|
|
|
|
go->borders[GL_RENDERER_BORDER_BOTTOM].height; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d = egl_damage; |
|
|
|
|
|
|
|
for (i = 0; i < nrects; ++i) { |
|
|
|
|
|
|
|
*d++ = rects[i].x1; |
|
|
|
|
|
|
|
*d++ = buffer_height - rects[i].y2; |
|
|
|
|
|
|
|
*d++ = rects[i].x2 - rects[i].x1; |
|
|
|
|
|
|
|
*d++ = rects[i].y2 - rects[i].y1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ret = gr->swap_buffers_with_damage(gr->egl_display, |
|
|
|
|
|
|
|
go->egl_surface, |
|
|
|
|
|
|
|
egl_damage, nrects); |
|
|
|
|
|
|
|
free(egl_damage); |
|
|
|
|
|
|
|
pixman_region32_fini(&buffer_damage); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ret = eglSwapBuffers(gr->egl_display, go->egl_surface); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#else /* ! defined EGL_EXT_swap_buffers_with_damage */ |
|
|
|
ret = eglSwapBuffers(gr->egl_display, go->egl_surface); |
|
|
|
ret = eglSwapBuffers(gr->egl_display, go->egl_surface); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
if (ret == EGL_FALSE && !errored) { |
|
|
|
if (ret == EGL_FALSE && !errored) { |
|
|
|
errored = 1; |
|
|
|
errored = 1; |
|
|
|
weston_log("Failed in eglSwapBuffers.\n"); |
|
|
|
weston_log("Failed in eglSwapBuffers.\n"); |
|
|
@ -1958,6 +2056,15 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface) |
|
|
|
weston_log("warning: EGL_EXT_buffer_age not supported. " |
|
|
|
weston_log("warning: EGL_EXT_buffer_age not supported. " |
|
|
|
"Performance could be affected.\n"); |
|
|
|
"Performance could be affected.\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef EGL_EXT_swap_buffers_with_damage |
|
|
|
|
|
|
|
if (strstr(extensions, "EGL_EXT_swap_buffers_with_damage")) |
|
|
|
|
|
|
|
gr->swap_buffers_with_damage = |
|
|
|
|
|
|
|
(void *) eglGetProcAddress("eglSwapBuffersWithDamageEXT"); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
weston_log("warning: EGL_EXT_swap_buffers_with_damage not " |
|
|
|
|
|
|
|
"supported. Performance could be affected.\n"); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
|
|
|
|
|
|
|
|
if (compile_shaders(ec)) |
|
|
|
if (compile_shaders(ec)) |
|
|
|