compositor: prepare for multi-planar surfaces.
Make weston_surface::texture and ::surface an array, while keeping [0] for RGB surfaces. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
4ab9468865
commit
023f855f8d
@ -257,12 +257,12 @@ drm_output_prepare_scanout_surface(struct drm_output *output)
|
||||
es->geometry.width != output->base.current->width ||
|
||||
es->geometry.height != output->base.current->height ||
|
||||
es->transform.enabled ||
|
||||
es->image == EGL_NO_IMAGE_KHR)
|
||||
es->images[0] == EGL_NO_IMAGE_KHR)
|
||||
return -1;
|
||||
|
||||
bo = gbm_bo_create_from_egl_image(c->gbm,
|
||||
c->base.egl_display,
|
||||
es->image,
|
||||
es->images[0],
|
||||
es->geometry.width,
|
||||
es->geometry.height,
|
||||
GBM_BO_USE_SCANOUT);
|
||||
@ -567,7 +567,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
||||
if (surface_is_primary(ec, es))
|
||||
return -1;
|
||||
|
||||
if (es->image == EGL_NO_IMAGE_KHR)
|
||||
if (es->num_images != 1 || es->images[0] == EGL_NO_IMAGE_KHR)
|
||||
return -1;
|
||||
|
||||
if (!drm_surface_transform_supported(es))
|
||||
@ -591,7 +591,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
||||
return -1;
|
||||
|
||||
bo = gbm_bo_create_from_egl_image(c->gbm, c->base.egl_display,
|
||||
es->image, es->geometry.width,
|
||||
es->images[0], es->geometry.width,
|
||||
es->geometry.height,
|
||||
GBM_BO_USE_SCANOUT);
|
||||
format = gbm_bo_get_format(bo);
|
||||
|
@ -238,7 +238,6 @@ weston_surface_create(struct weston_compositor *compositor)
|
||||
surface->surface.resource.client = NULL;
|
||||
|
||||
surface->compositor = compositor;
|
||||
surface->image = EGL_NO_IMAGE_KHR;
|
||||
surface->alpha = 1.0;
|
||||
surface->blend = 1;
|
||||
surface->opaque_rect[0] = 0.0;
|
||||
@ -247,6 +246,9 @@ weston_surface_create(struct weston_compositor *compositor)
|
||||
surface->opaque_rect[3] = 0.0;
|
||||
surface->pitch = 1;
|
||||
|
||||
surface->num_textures = 0;
|
||||
surface->num_images = 0;
|
||||
|
||||
surface->buffer = NULL;
|
||||
surface->output = NULL;
|
||||
|
||||
@ -661,6 +663,8 @@ weston_surface_unmap(struct weston_surface *surface)
|
||||
static void
|
||||
destroy_surface(struct wl_resource *resource)
|
||||
{
|
||||
int i;
|
||||
|
||||
struct weston_surface *surface =
|
||||
container_of(resource,
|
||||
struct weston_surface, surface.resource);
|
||||
@ -669,15 +673,14 @@ destroy_surface(struct wl_resource *resource)
|
||||
if (weston_surface_is_mapped(surface))
|
||||
weston_surface_unmap(surface);
|
||||
|
||||
if (surface->texture)
|
||||
glDeleteTextures(1, &surface->texture);
|
||||
glDeleteTextures(surface->num_textures, surface->textures);
|
||||
|
||||
if (surface->buffer)
|
||||
wl_list_remove(&surface->buffer_destroy_listener.link);
|
||||
|
||||
if (surface->image != EGL_NO_IMAGE_KHR)
|
||||
for (i = 0; i < surface->num_images; i++)
|
||||
compositor->destroy_image(compositor->egl_display,
|
||||
surface->image);
|
||||
surface->images[i]);
|
||||
|
||||
pixman_region32_fini(&surface->transform.boundingbox);
|
||||
pixman_region32_fini(&surface->damage);
|
||||
@ -700,11 +703,32 @@ weston_surface_destroy(struct weston_surface *surface)
|
||||
destroy_surface(&surface->surface.resource);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_textures(struct weston_surface *es, int num_textures)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (num_textures <= es->num_textures)
|
||||
return;
|
||||
|
||||
for (i = es->num_textures; i < num_textures; i++) {
|
||||
glGenTextures(1, &es->textures[i]);
|
||||
glBindTexture(GL_TEXTURE_2D, es->textures[i]);
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
es->num_textures = num_textures;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
||||
{
|
||||
struct weston_surface *es = (struct weston_surface *) surface;
|
||||
struct weston_compositor *ec = es->compositor;
|
||||
int i;
|
||||
|
||||
if (es->buffer) {
|
||||
weston_buffer_post_release(es->buffer);
|
||||
@ -716,14 +740,13 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
||||
if (!buffer) {
|
||||
if (weston_surface_is_mapped(es))
|
||||
weston_surface_unmap(es);
|
||||
if (es->image != EGL_NO_IMAGE_KHR) {
|
||||
ec->destroy_image(ec->egl_display, es->image);
|
||||
es->image = NULL;
|
||||
}
|
||||
if (es->texture) {
|
||||
glDeleteTextures(1, &es->texture);
|
||||
es->texture = 0;
|
||||
for (i = 0; i < es->num_images; i++) {
|
||||
ec->destroy_image(ec->egl_display, es->images[i]);
|
||||
es->images[i] = NULL;
|
||||
}
|
||||
es->num_images = 0;
|
||||
glDeleteTextures(es->num_textures, es->textures);
|
||||
es->num_textures = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -738,20 +761,12 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
||||
pixman_region32_init(&es->opaque);
|
||||
}
|
||||
|
||||
if (!es->texture) {
|
||||
glGenTextures(1, &es->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
es->shader = &ec->texture_shader;
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||
}
|
||||
|
||||
if (wl_buffer_is_shm(buffer)) {
|
||||
es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
|
||||
es->shader = &ec->texture_shader;
|
||||
|
||||
ensure_textures(es, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, es->textures[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
|
||||
es->pitch, es->buffer->height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
|
||||
@ -760,15 +775,19 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
||||
else
|
||||
es->blend = 1;
|
||||
} else {
|
||||
if (es->image != EGL_NO_IMAGE_KHR)
|
||||
ec->destroy_image(ec->egl_display, es->image);
|
||||
es->image = ec->create_image(ec->egl_display, NULL,
|
||||
EGL_WAYLAND_BUFFER_WL,
|
||||
buffer, NULL);
|
||||
if (es->images[0] != EGL_NO_IMAGE_KHR)
|
||||
ec->destroy_image(ec->egl_display, es->images[0]);
|
||||
es->images[0] = ec->create_image(ec->egl_display, NULL,
|
||||
EGL_WAYLAND_BUFFER_WL,
|
||||
buffer, NULL);
|
||||
es->num_images = 1;
|
||||
|
||||
ec->image_target_texture_2d(GL_TEXTURE_2D, es->image);
|
||||
ensure_textures(es, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, es->textures[0]);
|
||||
ec->image_target_texture_2d(GL_TEXTURE_2D, es->images[0]);
|
||||
|
||||
es->pitch = buffer->width;
|
||||
es->shader = &ec->texture_shader;
|
||||
}
|
||||
}
|
||||
|
||||
@ -877,7 +896,7 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output,
|
||||
|
||||
n = texture_region(es, &repaint);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, es->textures[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
|
||||
@ -980,7 +999,7 @@ update_shm_texture(struct weston_surface *surface)
|
||||
int i, n;
|
||||
#endif
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, surface->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, surface->textures[0]);
|
||||
|
||||
if (!surface->compositor->has_unpack_subimage) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
|
||||
|
@ -385,7 +385,8 @@ enum {
|
||||
struct weston_surface {
|
||||
struct wl_surface surface;
|
||||
struct weston_compositor *compositor;
|
||||
GLuint texture;
|
||||
GLuint textures[3];
|
||||
int num_textures;
|
||||
pixman_region32_t clip;
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_t opaque;
|
||||
@ -446,7 +447,8 @@ struct weston_surface {
|
||||
|
||||
struct wl_list frame_callback_list;
|
||||
|
||||
EGLImageKHR image;
|
||||
EGLImageKHR images[3];
|
||||
int num_images;
|
||||
|
||||
struct wl_buffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
|
Loading…
Reference in New Issue
Block a user