From 72fc647a968a3990fc9c83febc26736fb15e2c30 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Thu, 13 Jan 2022 23:57:48 +0000 Subject: [PATCH] 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 --- libweston/renderer-gl/gl-renderer.c | 328 +++++++++++++++------------- 1 file changed, 176 insertions(+), 152 deletions(-) diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 3ab96109..77ff41ee 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/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 =