gl-renderer: Split buffer state away from surface state

gl_surface_state has a bunch of members which are tied to the input
buffer, rather than the surface per se.

Split them out into a separate gl_buffer_state member as a first step
towards sanitising its use and lifetime.

Signed-off-by: Daniel Stone <daniels@collabora.com>
dev
Daniel Stone 3 years ago
parent 0c65b23848
commit 72fc647a96
  1. 328
      libweston/renderer-gl/gl-renderer.c

@ -168,11 +168,9 @@ struct yuv_format_descriptor {
struct yuv_plane_descriptor plane[4];
};
struct gl_surface_state {
struct gl_buffer_state {
GLfloat color[4];
GLuint textures[3];
int num_textures;
bool needs_full_upload;
pixman_region32_t texture_damage;
@ -186,8 +184,6 @@ struct gl_surface_state {
int num_images;
enum gl_shader_texture_variant shader_variant;
struct weston_buffer_reference buffer_ref;
struct weston_buffer_release_reference buffer_release_ref;
enum buffer_type buffer_type;
int pitch; /* in pixels */
int height; /* in pixels */
@ -198,13 +194,25 @@ struct gl_surface_state {
int offset[3]; /* offset per plane */
int hsub[3]; /* horizontal subsampling per plane */
int vsub[3]; /* vertical subsampling per plane */
};
struct gl_surface_state {
struct weston_surface *surface;
struct gl_buffer_state buffer;
/* These buffer references should really be attached to paint nodes
* rather than either buffer or surface state */
struct weston_buffer_reference buffer_ref;
struct weston_buffer_release_reference buffer_release_ref;
/* Whether this surface was used in the current output repaint.
Used only in the context of a gl_renderer_repaint_output call. */
bool used_in_output_repaint;
GLuint textures[3];
int num_textures;
struct wl_listener surface_destroy_listener;
struct wl_listener renderer_destroy_listener;
};
@ -568,6 +576,7 @@ texture_region(struct weston_view *ev,
pixman_region32_t *surf_region)
{
struct gl_surface_state *gs = get_surface_state(ev->surface);
struct gl_buffer_state *gb = &gs->buffer;
struct weston_compositor *ec = ev->surface->compositor;
struct gl_renderer *gr = get_renderer(ec);
GLfloat *v, inv_width, inv_height;
@ -593,8 +602,8 @@ texture_region(struct weston_view *ev,
v = wl_array_add(&gr->vertices, nrects * nsurf * 8 * 4 * sizeof *v);
vtxcnt = wl_array_add(&gr->vtxcnt, nrects * nsurf * sizeof *vtxcnt);
inv_width = 1.0 / gs->pitch;
inv_height = 1.0 / gs->height;
inv_width = 1.0 / gb->pitch;
inv_height = 1.0 / gb->height;
for (i = 0; i < nrects; i++) {
pixman_box32_t *rect = &rects[i];
@ -634,10 +643,10 @@ texture_region(struct weston_view *ev,
sx, sy,
&bx, &by);
*(v++) = bx * inv_width;
if (gs->y_inverted) {
if (gb->y_inverted) {
*(v++) = by * inv_height;
} else {
*(v++) = (gs->height - by) * inv_height;
*(v++) = (gb->height - by) * inv_height;
}
}
@ -967,6 +976,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
struct weston_view *ev)
{
struct gl_surface_state *gs = get_surface_state(ev->surface);
struct gl_buffer_state *gb = &gs->buffer;
bool recording_censor =
(output->disable_planes > 0) &&
(ev->surface->desired_protection > WESTON_HDCP_DISABLE);
@ -974,7 +984,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
bool unprotected_censor =
(ev->surface->desired_protection > output->current_protection);
if (gs->direct_display) {
if (gb->direct_display) {
censor_override(sconf, output);
return;
}
@ -993,14 +1003,15 @@ static void
gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
struct gl_surface_state *gs)
{
struct gl_buffer_state *gb = &gs->buffer;
int i;
sconf->req.variant = gs->shader_variant;
sconf->req.variant = gb->shader_variant;
sconf->req.input_is_premult =
gl_shader_texture_variant_can_be_premult(gs->shader_variant);
gl_shader_texture_variant_can_be_premult(gb->shader_variant);
for (i = 0; i < 4; i++)
sconf->unicolor[i] = gs->color[i];
sconf->unicolor[i] = gb->color[i];
assert(gs->num_textures <= GL_SHADER_INPUT_TEX_MAX);
for (i = 0; i < gs->num_textures; i++)
@ -1042,6 +1053,7 @@ draw_paint_node(struct weston_paint_node *pnode,
{
struct gl_renderer *gr = get_renderer(pnode->surface->compositor);
struct gl_surface_state *gs = get_surface_state(pnode->surface);
struct gl_buffer_state *gb = &gs->buffer;
/* repaint bounding region in global coordinates: */
pixman_region32_t repaint;
/* opaque region in surface coordinates: */
@ -1054,7 +1066,7 @@ draw_paint_node(struct weston_paint_node *pnode,
/* In case of a runtime switch of renderers, we may not have received
* an attach for this surface since the switch. In that case we don't
* have a valid buffer or a proper shader set up so skip rendering. */
if (gs->shader_variant == SHADER_VARIANT_NONE && !gs->direct_display)
if (gb->shader_variant == SHADER_VARIANT_NONE && !gb->direct_display)
return;
pixman_region32_init(&repaint);
@ -1845,6 +1857,7 @@ gl_renderer_flush_damage(struct weston_surface *surface,
const struct weston_testsuite_quirks *quirks =
&surface->compositor->test_data.test_quirks;
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = &gs->buffer;
struct weston_view *view;
bool texture_used;
pixman_box32_t *rectangles;
@ -1853,8 +1866,8 @@ gl_renderer_flush_damage(struct weston_surface *surface,
assert(buffer);
pixman_region32_union(&gs->texture_damage,
&gs->texture_damage, &surface->damage);
pixman_region32_union(&gb->texture_damage,
&gb->texture_damage, &surface->damage);
/* This can happen if a SHM wl_buffer gets destroyed before we flush
* damage, because wayland-server just nukes the wl_shm_buffer from
@ -1877,36 +1890,36 @@ gl_renderer_flush_damage(struct weston_surface *surface,
if (!texture_used)
return;
if (!pixman_region32_not_empty(&gs->texture_damage) &&
!gs->needs_full_upload)
if (!pixman_region32_not_empty(&gb->texture_damage) &&
!gb->needs_full_upload)
goto done;
data = wl_shm_buffer_get_data(buffer->shm_buffer);
glActiveTexture(GL_TEXTURE0);
if (gs->needs_full_upload || quirks->gl_force_full_upload) {
if (gb->needs_full_upload || quirks->gl_force_full_upload) {
glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0);
wl_shm_buffer_begin_access(buffer->shm_buffer);
for (j = 0; j < gs->num_textures; j++) {
glBindTexture(GL_TEXTURE_2D, gs->textures[j]);
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
gs->pitch / gs->hsub[j]);
gb->pitch / gb->hsub[j]);
glTexImage2D(GL_TEXTURE_2D, 0,
gs->gl_format[j],
gs->pitch / gs->hsub[j],
buffer->height / gs->vsub[j],
gb->gl_format[j],
gb->pitch / gb->hsub[j],
buffer->height / gb->vsub[j],
0,
gl_format_from_internal(gs->gl_format[j]),
gs->gl_pixel_type,
data + gs->offset[j]);
gl_format_from_internal(gb->gl_format[j]),
gb->gl_pixel_type,
data + gb->offset[j]);
}
wl_shm_buffer_end_access(buffer->shm_buffer);
goto done;
}
rectangles = pixman_region32_rectangles(&gs->texture_damage, &n);
rectangles = pixman_region32_rectangles(&gb->texture_damage, &n);
wl_shm_buffer_begin_access(buffer->shm_buffer);
for (i = 0; i < n; i++) {
pixman_box32_t r;
@ -1916,27 +1929,27 @@ gl_renderer_flush_damage(struct weston_surface *surface,
for (j = 0; j < gs->num_textures; j++) {
glBindTexture(GL_TEXTURE_2D, gs->textures[j]);
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
gs->pitch / gs->hsub[j]);
gb->pitch / gb->hsub[j]);
glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT,
r.x1 / gs->hsub[j]);
r.x1 / gb->hsub[j]);
glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT,
r.y1 / gs->hsub[j]);
r.y1 / gb->hsub[j]);
glTexSubImage2D(GL_TEXTURE_2D, 0,
r.x1 / gs->hsub[j],
r.y1 / gs->vsub[j],
(r.x2 - r.x1) / gs->hsub[j],
(r.y2 - r.y1) / gs->vsub[j],
gl_format_from_internal(gs->gl_format[j]),
gs->gl_pixel_type,
data + gs->offset[j]);
r.x1 / gb->hsub[j],
r.y1 / gb->vsub[j],
(r.x2 - r.x1) / gb->hsub[j],
(r.y2 - r.y1) / gb->vsub[j],
gl_format_from_internal(gb->gl_format[j]),
gb->gl_pixel_type,
data + gb->offset[j]);
}
}
wl_shm_buffer_end_access(buffer->shm_buffer);
done:
pixman_region32_fini(&gs->texture_damage);
pixman_region32_init(&gs->texture_damage);
gs->needs_full_upload = false;
pixman_region32_fini(&gb->texture_damage);
pixman_region32_init(&gb->texture_damage);
gb->needs_full_upload = false;
weston_buffer_reference(&gs->buffer_ref, buffer,
BUFFER_WILL_NOT_BE_ACCESSED);
@ -1949,7 +1962,8 @@ ensure_textures(struct gl_surface_state *gs, GLenum target, int num_textures)
int i;
if (num_textures <= gs->num_textures) {
glDeleteTextures(gs->num_textures - num_textures, &gs->textures[num_textures]);
glDeleteTextures(gs->num_textures - num_textures,
&gs->textures[num_textures]);
gs->num_textures = num_textures;
return;
}
@ -1973,6 +1987,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
struct gl_buffer_state *gb = &gs->buffer;
GLenum gl_format[3] = {0, 0, 0};
GLenum gl_pixel_type;
int pitch;
@ -1980,27 +1995,27 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
bool using_glesv2 = gr->gl_version < gr_gl_version(3, 0);
num_planes = 1;
gs->offset[0] = 0;
gs->hsub[0] = 1;
gs->vsub[0] = 1;
gb->offset[0] = 0;
gb->hsub[0] = 1;
gb->vsub[0] = 1;
switch (wl_shm_buffer_get_format(shm_buffer)) {
case WL_SHM_FORMAT_XRGB8888:
gs->shader_variant = SHADER_VARIANT_RGBX;
gb->shader_variant = SHADER_VARIANT_RGBX;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = GL_BGRA_EXT;
gl_pixel_type = GL_UNSIGNED_BYTE;
es->is_opaque = true;
break;
case WL_SHM_FORMAT_ARGB8888:
gs->shader_variant = SHADER_VARIANT_RGBA;
gb->shader_variant = SHADER_VARIANT_RGBA;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = GL_BGRA_EXT;
gl_pixel_type = GL_UNSIGNED_BYTE;
es->is_opaque = false;
break;
case WL_SHM_FORMAT_RGB565:
gs->shader_variant = SHADER_VARIANT_RGBX;
gb->shader_variant = SHADER_VARIANT_RGBX;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 2;
gl_format[0] = GL_RGB;
gl_pixel_type = GL_UNSIGNED_SHORT_5_6_5;
@ -2011,7 +2026,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
if (!gr->has_texture_type_2_10_10_10_rev) {
goto unsupported;
}
gs->shader_variant = SHADER_VARIANT_RGBA;
gb->shader_variant = SHADER_VARIANT_RGBA;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = using_glesv2 ? GL_RGBA : GL_RGB10_A2;
gl_pixel_type = GL_UNSIGNED_INT_2_10_10_10_REV_EXT;
@ -2021,7 +2036,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
if (!gr->has_texture_type_2_10_10_10_rev) {
goto unsupported;
}
gs->shader_variant = SHADER_VARIANT_RGBX;
gb->shader_variant = SHADER_VARIANT_RGBX;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = using_glesv2 ? GL_RGBA : GL_RGB10_A2;
gl_pixel_type = GL_UNSIGNED_INT_2_10_10_10_REV_EXT;
@ -2030,7 +2045,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
case WL_SHM_FORMAT_ABGR16161616F:
if (!gr->gl_supports_color_transforms)
goto unsupported;
gs->shader_variant = SHADER_VARIANT_RGBA;
gb->shader_variant = SHADER_VARIANT_RGBA;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 8;
gl_format[0] = GL_RGBA16F;
gl_pixel_type = GL_HALF_FLOAT;
@ -2039,7 +2054,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
case WL_SHM_FORMAT_XBGR16161616F:
if (!gr->gl_supports_color_transforms)
goto unsupported;
gs->shader_variant = SHADER_VARIANT_RGBX;
gb->shader_variant = SHADER_VARIANT_RGBX;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 8;
gl_format[0] = GL_RGBA16F;
gl_pixel_type = GL_HALF_FLOAT;
@ -2048,7 +2063,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
case WL_SHM_FORMAT_ABGR16161616:
if (!gr->has_texture_norm16)
goto unsupported;
gs->shader_variant = SHADER_VARIANT_RGBA;
gb->shader_variant = SHADER_VARIANT_RGBA;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 8;
gl_format[0] = GL_RGBA16_EXT;
gl_pixel_type = GL_UNSIGNED_SHORT;
@ -2057,7 +2072,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
case WL_SHM_FORMAT_XBGR16161616:
if (!gr->has_texture_norm16)
goto unsupported;
gs->shader_variant = SHADER_VARIANT_RGBX;
gb->shader_variant = SHADER_VARIANT_RGBX;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 8;
gl_format[0] = GL_RGBA16_EXT;
gl_pixel_type = GL_UNSIGNED_SHORT;
@ -2065,18 +2080,18 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
break;
#endif
case WL_SHM_FORMAT_YUV420:
gs->shader_variant = SHADER_VARIANT_Y_U_V;
gb->shader_variant = SHADER_VARIANT_Y_U_V;
pitch = wl_shm_buffer_get_stride(shm_buffer);
gl_pixel_type = GL_UNSIGNED_BYTE;
num_planes = 3;
gs->offset[1] = gs->offset[0] + (pitch / gs->hsub[0]) *
(buffer->height / gs->vsub[0]);
gs->hsub[1] = 2;
gs->vsub[1] = 2;
gs->offset[2] = gs->offset[1] + (pitch / gs->hsub[1]) *
(buffer->height / gs->vsub[1]);
gs->hsub[2] = 2;
gs->vsub[2] = 2;
gb->offset[1] = gb->offset[0] + (pitch / gb->hsub[0]) *
(buffer->height / gb->vsub[0]);
gb->hsub[1] = 2;
gb->vsub[1] = 2;
gb->offset[2] = gb->offset[1] + (pitch / gb->hsub[1]) *
(buffer->height / gb->vsub[1]);
gb->hsub[2] = 2;
gb->vsub[2] = 2;
if (gr->has_gl_texture_rg) {
gl_format[0] = GL_R8_EXT;
gl_format[1] = GL_R8_EXT;
@ -2092,29 +2107,29 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
pitch = wl_shm_buffer_get_stride(shm_buffer);
gl_pixel_type = GL_UNSIGNED_BYTE;
num_planes = 2;
gs->offset[1] = gs->offset[0] + (pitch / gs->hsub[0]) *
(buffer->height / gs->vsub[0]);
gs->hsub[1] = 2;
gs->vsub[1] = 2;
gb->offset[1] = gb->offset[0] + (pitch / gb->hsub[0]) *
(buffer->height / gb->vsub[0]);
gb->hsub[1] = 2;
gb->vsub[1] = 2;
if (gr->has_gl_texture_rg) {
gs->shader_variant = SHADER_VARIANT_Y_UV;
gb->shader_variant = SHADER_VARIANT_Y_UV;
gl_format[0] = GL_R8_EXT;
gl_format[1] = GL_RG8_EXT;
} else {
gs->shader_variant = SHADER_VARIANT_Y_XUXV;
gb->shader_variant = SHADER_VARIANT_Y_XUXV;
gl_format[0] = GL_LUMINANCE;
gl_format[1] = GL_LUMINANCE_ALPHA;
}
es->is_opaque = true;
break;
case WL_SHM_FORMAT_YUYV:
gs->shader_variant = SHADER_VARIANT_Y_XUXV;
gb->shader_variant = SHADER_VARIANT_Y_XUXV;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 2;
gl_pixel_type = GL_UNSIGNED_BYTE;
num_planes = 2;
gs->offset[1] = 0;
gs->hsub[1] = 2;
gs->vsub[1] = 1;
gb->offset[1] = 0;
gb->hsub[1] = 2;
gb->vsub[1] = 1;
if (gr->has_gl_texture_rg)
gl_format[0] = GL_RG8_EXT;
else
@ -2127,7 +2142,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian
* a:b: g: r in SHADER_VARIANT_XYUV
*/
gs->shader_variant = SHADER_VARIANT_XYUV;
gb->shader_variant = SHADER_VARIANT_XYUV;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = GL_RGBA;
gl_pixel_type = GL_UNSIGNED_BYTE;
@ -2143,23 +2158,23 @@ unsupported:
/* Only allocate a texture if it doesn't match existing one.
* If a switch from DRM allocated buffer to a SHM buffer is
* happening, we need to allocate a new texture buffer. */
if (pitch != gs->pitch ||
buffer->height != gs->height ||
gl_format[0] != gs->gl_format[0] ||
gl_format[1] != gs->gl_format[1] ||
gl_format[2] != gs->gl_format[2] ||
gl_pixel_type != gs->gl_pixel_type ||
gs->buffer_type != BUFFER_TYPE_SHM) {
gs->pitch = pitch;
gs->height = buffer->height;
gs->gl_format[0] = gl_format[0];
gs->gl_format[1] = gl_format[1];
gs->gl_format[2] = gl_format[2];
gs->gl_pixel_type = gl_pixel_type;
gs->buffer_type = BUFFER_TYPE_SHM;
gs->needs_full_upload = true;
gs->y_inverted = true;
gs->direct_display = false;
if (pitch != gb->pitch ||
buffer->height != gb->height ||
gl_format[0] != gb->gl_format[0] ||
gl_format[1] != gb->gl_format[1] ||
gl_format[2] != gb->gl_format[2] ||
gl_pixel_type != gb->gl_pixel_type ||
gb->buffer_type != BUFFER_TYPE_SHM) {
gb->pitch = pitch;
gb->height = buffer->height;
gb->gl_format[0] = gl_format[0];
gb->gl_format[1] = gl_format[1];
gb->gl_format[2] = gl_format[2];
gb->gl_pixel_type = gl_pixel_type;
gb->buffer_type = BUFFER_TYPE_SHM;
gb->needs_full_upload = true;
gb->y_inverted = true;
gb->direct_display = false;
gs->surface = es;
@ -2235,13 +2250,14 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
struct gl_buffer_state *gb = &gs->buffer;
EGLint attribs[5];
GLenum target;
int i, num_planes;
for (i = 0; i < gs->num_images; i++) {
egl_image_unref(gs->images[i]);
gs->images[i] = NULL;
for (i = 0; i < gb->num_images; i++) {
egl_image_unref(gb->images[i]);
gb->images[i] = NULL;
}
es->is_opaque = false;
switch (format) {
@ -2251,31 +2267,31 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
case EGL_TEXTURE_RGBA:
default:
num_planes = 1;
gs->shader_variant = SHADER_VARIANT_RGBA;
gb->shader_variant = SHADER_VARIANT_RGBA;
break;
case EGL_TEXTURE_EXTERNAL_WL:
num_planes = 1;
gs->shader_variant = SHADER_VARIANT_EXTERNAL;
gb->shader_variant = SHADER_VARIANT_EXTERNAL;
break;
case EGL_TEXTURE_Y_UV_WL:
num_planes = 2;
gs->shader_variant = SHADER_VARIANT_Y_UV;
gb->shader_variant = SHADER_VARIANT_Y_UV;
es->is_opaque = true;
break;
case EGL_TEXTURE_Y_U_V_WL:
num_planes = 3;
gs->shader_variant = SHADER_VARIANT_Y_U_V;
gb->shader_variant = SHADER_VARIANT_Y_U_V;
es->is_opaque = true;
break;
case EGL_TEXTURE_Y_XUXV_WL:
num_planes = 2;
gs->shader_variant = SHADER_VARIANT_Y_XUXV;
gb->shader_variant = SHADER_VARIANT_Y_XUXV;
es->is_opaque = true;
break;
}
gs->num_images = num_planes;
target = gl_shader_texture_variant_get_target(gs->shader_variant);
gb->num_images = num_planes;
target = gl_shader_texture_variant_get_target(gb->shader_variant);
ensure_textures(gs, target, num_planes);
for (i = 0; i < num_planes; i++) {
attribs[0] = EGL_WAYLAND_PLANE_WL;
@ -2284,24 +2300,24 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
attribs[3] = EGL_TRUE;
attribs[4] = EGL_NONE;
gs->images[i] = egl_image_create(gr,
gb->images[i] = egl_image_create(gr,
EGL_WAYLAND_BUFFER_WL,
buffer->legacy_buffer,
attribs);
if (!gs->images[i]) {
if (!gb->images[i]) {
weston_log("failed to create img for plane %d\n", i);
continue;
}
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(target, gs->textures[i]);
gr->image_target_texture_2d(target, gs->images[i]->image);
gr->image_target_texture_2d(target, gb->images[i]->image);
}
gs->pitch = buffer->width;
gs->height = buffer->height;
gs->buffer_type = BUFFER_TYPE_EGL;
gs->y_inverted = (buffer->buffer_origin == ORIGIN_TOP_LEFT);
gb->pitch = buffer->width;
gb->height = buffer->height;
gb->buffer_type = BUFFER_TYPE_EGL;
gb->y_inverted = (buffer->buffer_origin == ORIGIN_TOP_LEFT);
}
static void
@ -2869,19 +2885,20 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
{
struct gl_renderer *gr = get_renderer(surface->compositor);
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = &gs->buffer;
struct dmabuf_image *image;
GLenum target;
int i;
for (i = 0; i < gs->num_images; i++)
egl_image_unref(gs->images[i]);
gs->num_images = 0;
for (i = 0; i < gb->num_images; i++)
egl_image_unref(gb->images[i]);
gb->num_images = 0;
gs->pitch = buffer->width;
gs->height = buffer->height;
gs->buffer_type = BUFFER_TYPE_EGL;
gs->y_inverted = (buffer->buffer_origin == ORIGIN_TOP_LEFT);
gs->direct_display = dmabuf->direct_display;
gb->pitch = buffer->width;
gb->height = buffer->height;
gb->buffer_type = BUFFER_TYPE_EGL;
gb->y_inverted = (buffer->buffer_origin == ORIGIN_TOP_LEFT);
gb->direct_display = dmabuf->direct_display;
surface->is_opaque = pixel_format_is_opaque(buffer->pixel_format);
if (dmabuf->direct_display)
@ -2892,19 +2909,19 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
/* The dmabuf_image should have been created during the import */
assert(image != NULL);
gs->num_images = image->num_images;
for (i = 0; i < gs->num_images; ++i)
gs->images[i] = egl_image_ref(image->images[i]);
gb->num_images = image->num_images;
for (i = 0; i < gb->num_images; ++i)
gb->images[i] = egl_image_ref(image->images[i]);
target = gl_shader_texture_variant_get_target(image->shader_variant);
ensure_textures(gs, target, gs->num_images);
for (i = 0; i < gs->num_images; ++i) {
ensure_textures(gs, target, gb->num_images);
for (i = 0; i < gb->num_images; ++i) {
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(target, gs->textures[i]);
gr->image_target_texture_2d(target, gs->images[i]->image);
gr->image_target_texture_2d(target, gb->images[i]->image);
}
gs->shader_variant = image->shader_variant;
gb->shader_variant = image->shader_variant;
}
static const struct weston_drm_format_array *
@ -2977,16 +2994,17 @@ gl_renderer_surface_set_color(struct weston_surface *surface,
float red, float green, float blue, float alpha)
{
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = &gs->buffer;
gs->color[0] = red;
gs->color[1] = green;
gs->color[2] = blue;
gs->color[3] = alpha;
gs->buffer_type = BUFFER_TYPE_SOLID;
gs->pitch = 1;
gs->height = 1;
gb->color[0] = red;
gb->color[1] = green;
gb->color[2] = blue;
gb->color[3] = alpha;
gb->buffer_type = BUFFER_TYPE_SOLID;
gb->pitch = 1;
gb->height = 1;
gs->shader_variant = SHADER_VARIANT_SOLID;
gb->shader_variant = SHADER_VARIANT_SOLID;
}
static void
@ -2995,6 +3013,7 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
struct gl_buffer_state *gb = &gs->buffer;
EGLint format;
int i;
@ -3005,16 +3024,16 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
es->buffer_release_ref.buffer_release);
if (!buffer) {
for (i = 0; i < gs->num_images; i++) {
egl_image_unref(gs->images[i]);
gs->images[i] = NULL;
for (i = 0; i < gb->num_images; i++) {
egl_image_unref(gb->images[i]);
gb->images[i] = NULL;
}
gs->num_images = 0;
gb->num_images = 0;
glDeleteTextures(gs->num_textures, gs->textures);
gs->num_textures = 0;
gs->buffer_type = BUFFER_TYPE_NULL;
gs->y_inverted = true;
gs->direct_display = false;
gb->buffer_type = BUFFER_TYPE_NULL;
gb->y_inverted = true;
gb->direct_display = false;
es->is_opaque = false;
return;
}
@ -3057,8 +3076,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
weston_buffer_reference(&gs->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
weston_buffer_release_reference(&gs->buffer_release_ref, NULL);
gs->buffer_type = BUFFER_TYPE_NULL;
gs->y_inverted = true;
gb->buffer_type = BUFFER_TYPE_NULL;
gb->y_inverted = true;
es->is_opaque = false;
weston_buffer_send_server_error(buffer,
"disconnecting due to unhandled buffer type");
@ -3069,13 +3088,14 @@ gl_renderer_surface_get_content_size(struct weston_surface *surface,
int *width, int *height)
{
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = &gs->buffer;
if (gs->buffer_type == BUFFER_TYPE_NULL) {
if (gb->buffer_type == BUFFER_TYPE_NULL) {
*width = 0;
*height = 0;
} else {
*width = gs->pitch;
*height = gs->height;
*width = gb->pitch;
*height = gb->height;
}
}
@ -3129,6 +3149,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
const GLenum gl_format = GL_RGBA; /* PIXMAN_a8b8g8r8 little-endian */
struct gl_renderer *gr = get_renderer(surface->compositor);
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = &gs->buffer;
int cw, ch;
GLuint fbo;
GLuint tex;
@ -3137,11 +3158,11 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
gl_renderer_surface_get_content_size(surface, &cw, &ch);
switch (gs->buffer_type) {
switch (gb->buffer_type) {
case BUFFER_TYPE_NULL:
return -1;
case BUFFER_TYPE_SOLID:
*(uint32_t *)target = pack_color(format, gs->color);
*(uint32_t *)target = pack_color(format, gb->color);
return 0;
case BUFFER_TYPE_SHM:
gl_renderer_flush_damage(surface, gs->buffer_ref.buffer);
@ -3172,7 +3193,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
glViewport(0, 0, cw, ch);
glDisable(GL_BLEND);
if (gs->y_inverted)
if (gb->y_inverted)
ARRAY_COPY(sconf.projection.d, projmat_normal);
else
ARRAY_COPY(sconf.projection.d, projmat_yinvert);
@ -3210,6 +3231,7 @@ out:
static void
surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
{
struct gl_buffer_state *gb = &gs->buffer;
int i;
wl_list_remove(&gs->surface_destroy_listener.link);
@ -3219,13 +3241,13 @@ surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
glDeleteTextures(gs->num_textures, gs->textures);
for (i = 0; i < gs->num_images; i++)
egl_image_unref(gs->images[i]);
for (i = 0; i < gb->num_images; i++)
egl_image_unref(gb->images[i]);
weston_buffer_reference(&gs->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
weston_buffer_release_reference(&gs->buffer_release_ref, NULL);
pixman_region32_fini(&gs->texture_damage);
pixman_region32_fini(&gb->texture_damage);
free(gs);
}
@ -3261,23 +3283,25 @@ static int
gl_renderer_create_surface(struct weston_surface *surface)
{
struct gl_surface_state *gs;
struct gl_buffer_state *gb;
struct gl_renderer *gr = get_renderer(surface->compositor);
gs = zalloc(sizeof *gs);
if (gs == NULL)
return -1;
gb = &gs->buffer;
/* A buffer is never attached to solid color surfaces, yet
* they still go through texcoord computations. Do not divide
* by zero there.
*/
gs->pitch = 1;
gs->y_inverted = true;
gs->direct_display = false;
gb->pitch = 1;
gb->y_inverted = true;
gb->direct_display = false;
gs->surface = surface;
pixman_region32_init(&gs->texture_damage);
pixman_region32_init(&gb->texture_damage);
surface->renderer_state = gs;
gs->surface_destroy_listener.notify =

Loading…
Cancel
Save