gles2: update texture only if needed
When a surface is on a non-primary plane (overlay), we do not need to keep the GL texture up-to-date, since we are not using it. Avoid calling glTex(Sub)Image2D in that case, and accumulate the texture damage separately. This is especially useful for backends, that can put wl_shm buffers into overlays. The empty damage check has to be moved from surface_accumulate_damage() into gles2_renderer_flush_damage(), because it really needs to check the accumulated damage, not only the current damage. Otherwise, if a surface migrates from a plane to the primary plane, and does not have new damage, the texture would not be updated even for accumulated damage. Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
a51e6fa322
commit
bcdd579a58
+3
-2
@@ -239,6 +239,7 @@ weston_surface_create(struct weston_compositor *compositor)
|
|||||||
|
|
||||||
surface->num_textures = 0;
|
surface->num_textures = 0;
|
||||||
surface->num_images = 0;
|
surface->num_images = 0;
|
||||||
|
pixman_region32_init(&surface->texture_damage);
|
||||||
|
|
||||||
surface->buffer = NULL;
|
surface->buffer = NULL;
|
||||||
surface->output = NULL;
|
surface->output = NULL;
|
||||||
@@ -782,6 +783,7 @@ destroy_surface(struct wl_resource *resource)
|
|||||||
if (surface->buffer)
|
if (surface->buffer)
|
||||||
wl_list_remove(&surface->buffer_destroy_listener.link);
|
wl_list_remove(&surface->buffer_destroy_listener.link);
|
||||||
|
|
||||||
|
pixman_region32_fini(&surface->texture_damage);
|
||||||
compositor->renderer->destroy_surface(surface);
|
compositor->renderer->destroy_surface(surface);
|
||||||
|
|
||||||
pixman_region32_fini(&surface->transform.boundingbox);
|
pixman_region32_fini(&surface->transform.boundingbox);
|
||||||
@@ -905,8 +907,7 @@ static void
|
|||||||
surface_accumulate_damage(struct weston_surface *surface,
|
surface_accumulate_damage(struct weston_surface *surface,
|
||||||
pixman_region32_t *opaque)
|
pixman_region32_t *opaque)
|
||||||
{
|
{
|
||||||
if (pixman_region32_not_empty(&surface->damage) &&
|
if (surface->buffer && wl_buffer_is_shm(surface->buffer))
|
||||||
surface->buffer && wl_buffer_is_shm(surface->buffer))
|
|
||||||
surface->compositor->renderer->flush_damage(surface);
|
surface->compositor->renderer->flush_damage(surface);
|
||||||
|
|
||||||
if (surface->transform.enabled) {
|
if (surface->transform.enabled) {
|
||||||
|
|||||||
@@ -410,6 +410,7 @@ struct weston_surface {
|
|||||||
struct weston_compositor *compositor;
|
struct weston_compositor *compositor;
|
||||||
GLuint textures[3];
|
GLuint textures[3];
|
||||||
int num_textures;
|
int num_textures;
|
||||||
|
pixman_region32_t texture_damage;
|
||||||
pixman_region32_t clip;
|
pixman_region32_t clip;
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_t opaque;
|
pixman_region32_t opaque;
|
||||||
|
|||||||
+18
-2
@@ -775,6 +775,18 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
|
|||||||
int i, n;
|
int i, n;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pixman_region32_union(&surface->texture_damage,
|
||||||
|
&surface->texture_damage, &surface->damage);
|
||||||
|
|
||||||
|
/* Avoid upload, if the texture won't be used this time.
|
||||||
|
* We still accumulate the damage in texture_damage.
|
||||||
|
*/
|
||||||
|
if (surface->plane != &surface->compositor->primary_plane)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pixman_region32_not_empty(&surface->texture_damage))
|
||||||
|
return;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, surface->textures[0]);
|
glBindTexture(GL_TEXTURE_2D, surface->textures[0]);
|
||||||
|
|
||||||
if (!surface->compositor->has_unpack_subimage) {
|
if (!surface->compositor->has_unpack_subimage) {
|
||||||
@@ -783,14 +795,14 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
|
|||||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
|
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
|
||||||
wl_shm_buffer_get_data(surface->buffer));
|
wl_shm_buffer_get_data(surface->buffer));
|
||||||
|
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GL_UNPACK_ROW_LENGTH
|
#ifdef GL_UNPACK_ROW_LENGTH
|
||||||
/* Mesa does not define GL_EXT_unpack_subimage */
|
/* Mesa does not define GL_EXT_unpack_subimage */
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch);
|
||||||
data = wl_shm_buffer_get_data(surface->buffer);
|
data = wl_shm_buffer_get_data(surface->buffer);
|
||||||
rectangles = pixman_region32_rectangles(&surface->damage, &n);
|
rectangles = pixman_region32_rectangles(&surface->texture_damage, &n);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1);
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1);
|
||||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1);
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1);
|
||||||
@@ -801,6 +813,10 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
|
|||||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
|
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
done:
|
||||||
|
pixman_region32_fini(&surface->texture_damage);
|
||||||
|
pixman_region32_init(&surface->texture_damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user