diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index c2b52ad4b..045f0074c 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -378,6 +378,15 @@ enum weston_repaint_status { REPAINT_DEFERRED, }; +/** Output's required framebuffer alpha encoding + * + * \ingroup output + */ +enum weston_output_fb_alpha_encoding { + WESTON_OUTPUT_FB_ALPHA_ENCODING_PREMULT = 0, + WESTON_OUTPUT_FB_ALPHA_ENCODING_STRAIGHT, +}; + /** Content producer for heads * * \rst @@ -582,6 +591,8 @@ struct weston_output { enum weston_color_format color_format; + enum weston_output_fb_alpha_encoding fb_alpha_encoding; + /** * Set by the shell to indicate there's some content for this * output to display. diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index 1d2bd3901..ac10cf13b 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -562,6 +562,18 @@ drm_output_render(struct drm_output_state *state) scanout_state = drm_output_state_get_plane(state, scanout_plane); weston_assert_ptr_null(c, scanout_state->fb); + if (output->base.fb_alpha_encoding == WESTON_OUTPUT_FB_ALPHA_ENCODING_PREMULT) { + weston_assert_true(c, drm_plane_supports_blend_mode(scanout_plane, + WDRM_PLANE_BLEND_DEFAULT)); + scanout_state->blend_mode = WDRM_PLANE_BLEND_DEFAULT; + } else if (output->base.fb_alpha_encoding == WESTON_OUTPUT_FB_ALPHA_ENCODING_STRAIGHT) { + weston_assert_true(c, drm_plane_supports_blend_mode(scanout_plane, + WDRM_PLANE_BLEND_COVERAGE)); + scanout_state->blend_mode = WDRM_PLANE_BLEND_COVERAGE; + } else { + weston_assert_not_reached(c, "unknown fb alpha encoding"); + } + pixman_region32_init(&damage); weston_output_flush_damage_for_primary_plane(&output->base, &damage); @@ -2677,6 +2689,19 @@ drm_output_init_planes(struct drm_output *output) } primary_plane_zpos_min = scanout_plane->zpos_min; + /** + * If only coverage blend mode supported by primary plane, renderers + * should produce straight alpha fb's. + */ + if (!drm_plane_supports_blend_mode(scanout_plane, WDRM_PLANE_BLEND_DEFAULT)) { + if (!drm_plane_supports_blend_mode(scanout_plane, WDRM_PLANE_BLEND_COVERAGE)) { + weston_log("Error: primary plane must support either premult " + "or coverage alpha blend mode.\n"); + return -1; + } + output->base.fb_alpha_encoding = WESTON_OUTPUT_FB_ALPHA_ENCODING_STRAIGHT; + } + /* Failing to find a cursor plane is not fatal, as we'll fall back * to software cursor. */ cursor_plane = @@ -2884,6 +2909,27 @@ should_wait_drm_events(struct drm_device *device) return false; } +static void +maybe_disable_underlays_for_coverage_alpha(struct drm_output *output, + const struct weston_renderer *renderer) +{ + struct weston_compositor *wc = output->base.compositor; + + /** + * When straight alpha mode is set, we must feed the primary plane with + * straight alpha fb's. If renderer can't do that, we can still support + * straight alpha outputs by disabling underlays (as the primary plane + * won't get blended with something below it). + */ + if (output->base.fb_alpha_encoding == WESTON_OUTPUT_FB_ALPHA_ENCODING_STRAIGHT && + !renderer->can_render_fb_encoding_straight_alpha(wc)) { + weston_log("Disabling underlay planes for output '%s': straight alpha " + "is set but renderer can't produce straight alpha fb's.\n", + output->base.name); + output->has_underlay = false; + } +} + static int drm_output_enable(struct weston_output *base) { @@ -2922,6 +2968,8 @@ drm_output_enable(struct weston_output *base) if (ret < 0) goto err_crtc; + maybe_disable_underlays_for_coverage_alpha(output, b->compositor->renderer); + if (drm_output_init_legacy_gamma_size(output) < 0) goto err_planes; diff --git a/libweston/backend-drm/state-propose.c b/libweston/backend-drm/state-propose.c index 9e4c1f19b..972977e98 100644 --- a/libweston/backend-drm/state-propose.c +++ b/libweston/backend-drm/state-propose.c @@ -103,6 +103,36 @@ drm_output_check_plane_has_view_assigned(struct drm_plane *plane, return false; } +static bool +select_plane_blend_mode(struct drm_plane_state *state, + struct drm_fb *fb, char **err_msg) +{ + struct drm_plane *plane = state->plane; + + if (drm_plane_supports_blend_mode(plane, WDRM_PLANE_BLEND_DEFAULT)) { + state->blend_mode = WDRM_PLANE_BLEND_DEFAULT; + return true; + } + + /** + * TODO: for now we don't support coverage alpha from the color + * representation protocol. With that we'd be able to place non-opaque + * straight alpha content in planes that only support coverage blend + * mode. + */ + if (drm_plane_supports_blend_mode(plane, WDRM_PLANE_BLEND_COVERAGE)) { + if (state->alpha != DRM_PLANE_ALPHA_OPAQUE || fb->format->bits.a != 0) { + str_printf(err_msg, "can't offload non-opaque content for outputs in alpha coverage mode"); + return false; + } + state->blend_mode = WDRM_PLANE_BLEND_COVERAGE; + return true; + } + + str_printf(err_msg, "neither pre-mult or coverage blend modes are supported"); + return false; +} + static struct drm_plane_state * drm_output_try_paint_node_on_plane(struct drm_plane_handle *handle, struct drm_output_state *output_state, @@ -116,6 +146,7 @@ drm_output_try_paint_node_on_plane(struct drm_plane_handle *handle, struct drm_backend *b = device->backend; struct drm_plane *plane = handle->plane; struct drm_plane_state *state = NULL; + char *err_msg; assert(!device->disable_client_buffer_scanout); assert(output == handle->output); @@ -133,6 +164,13 @@ drm_output_try_paint_node_on_plane(struct drm_plane_handle *handle, drm_plane_state_coords_for_paint_node(state, pnode, zpos); + if (!select_plane_blend_mode(state, fb, &err_msg)) { + drm_debug(b, "\t\t\t[paint node] not placing paint node %s on plane %lu: %s\n", + pnode->internal_name, (unsigned long) plane->plane_id, err_msg); + free(err_msg); + goto out; + } + /* We hold one reference for the lifetime of this function; from * calling drm_fb_get_from_paint_node() in * drm_output_prepare_plane_view(), so, we take another reference @@ -238,6 +276,7 @@ drm_output_prepare_cursor_paint_node(struct drm_output_state *output_state, struct drm_plane *plane; struct drm_plane_state *plane_state; const char *p_name; + char *err_msg; assert(!device->cursors_are_broken); assert(handle); @@ -283,6 +322,13 @@ drm_output_prepare_cursor_paint_node(struct drm_output_state *output_state, */ plane_state->fb = drm_fb_ref(output->gbm_cursor_fb[0]); + if (!select_plane_blend_mode(plane_state, plane_state->fb, &err_msg)) { + drm_debug(b, "\t\t\t\t[%s] not assigning paint node %s to %s plane (%s)\n", + p_name, pnode->internal_name, p_name, err_msg); + free(err_msg); + goto err; + } + /* The cursor API is somewhat special: in cursor_bo_update(), we upload * a buffer which is always cursor_width x cursor_height, even if the * surface we want to promote is actually smaller than this. Manually diff --git a/libweston/compositor.c b/libweston/compositor.c index 5c9462e77..4d8a73d81 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -8376,6 +8376,7 @@ weston_output_init(struct weston_output *output, output->allow_protection = true; output->power_state = WESTON_OUTPUT_POWER_NORMAL; output->repaint_only_on_capture = false; + output->fb_alpha_encoding = WESTON_OUTPUT_FB_ALPHA_ENCODING_PREMULT; wl_list_init(&output->head_list); diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index 65f754c25..bb8590630 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -201,6 +201,14 @@ struct weston_renderer { uint32_t format, const uint64_t *modifiers, unsigned int count); + /** Checks if renderer is able to produce fb's with straight alpha + * encoding (i.e. not pre-multiplied by alpha). + * + * \param wc The Weston compositor instance. + * \return True if renderer is capable, false otherwise. + */ + bool (*can_render_fb_encoding_straight_alpha)(struct weston_compositor *wc); + enum weston_renderer_type type; const struct gl_renderer_interface *gl; const struct vulkan_renderer_interface *vulkan; diff --git a/libweston/noop-renderer.c b/libweston/noop-renderer.c index a27bb827b..afa3e953a 100644 --- a/libweston/noop-renderer.c +++ b/libweston/noop-renderer.c @@ -57,6 +57,12 @@ noop_renderer_flush_damage(struct weston_paint_node *pnode) { } +static bool +noop_renderer_can_render_fb_encoding_straight_alpha(struct weston_compositor *wc) +{ + return false; +} + static void noop_renderer_attach(struct weston_paint_node *pnode) { @@ -135,6 +141,7 @@ noop_renderer_init(struct weston_compositor *ec) renderer->base.flush_damage = noop_renderer_flush_damage; renderer->base.attach = noop_renderer_attach; renderer->base.destroy = noop_renderer_destroy; + renderer->base.can_render_fb_encoding_straight_alpha = noop_renderer_can_render_fb_encoding_straight_alpha; renderer->base.type = WESTON_RENDERER_NOOP; ec->renderer = &renderer->base; diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index ca948e784..447247c0d 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -947,6 +947,12 @@ pixman_renderer_destroy_renderbuffer(weston_renderbuffer_t renderbuffer) free(rb); } +static bool +pixman_renderer_can_render_fb_encoding_straight_alpha(struct weston_compositor *wc) +{ + return false; +} + static bool pixman_renderer_discard_renderbuffers(struct pixman_output_state *po, bool destroy) @@ -1080,6 +1086,8 @@ pixman_renderer_init(struct weston_compositor *ec) renderer->base.create_renderbuffer_dmabuf = NULL; renderer->base.destroy_renderbuffer = pixman_renderer_destroy_renderbuffer; + renderer->base.can_render_fb_encoding_straight_alpha = + pixman_renderer_can_render_fb_encoding_straight_alpha; renderer->base.type = WESTON_RENDERER_PIXMAN; renderer->base.pixman = &pixman_renderer_interface; ec->renderer = &renderer->base; diff --git a/libweston/renderer-gl/fragment.glsl b/libweston/renderer-gl/fragment.glsl index c7b4f5f88..a737ca3c4 100644 --- a/libweston/renderer-gl/fragment.glsl +++ b/libweston/renderer-gl/fragment.glsl @@ -60,6 +60,10 @@ #define SHADER_COLOR_MAPPING_3DLUT 1 #define SHADER_COLOR_MAPPING_MATRIX 2 +/* enum gl_shader_fb_alpha_encoding */ +#define SHADER_FB_ALPHA_ENCODING_PREMULT 0 +#define SHADER_FB_ALPHA_ENCODING_STRAIGHT 1 + #if DEF_VARIANT == SHADER_VARIANT_EXTERNAL #extension GL_OES_EGL_image_external : require #endif @@ -91,6 +95,7 @@ compile_const int c_color_post_curve = DEF_COLOR_POST_CURVE; compile_const int c_fb_fetch_curve = DEF_FB_FETCH_CURVE; compile_const int c_fb_store_curve = DEF_FB_STORE_CURVE; compile_const int c_color_effect = DEF_COLOR_EFFECT; +compile_const int c_fb_alpha_encoding = DEF_FB_ALPHA_ENCODING; compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT; compile_const bool c_tint = DEF_TINT; @@ -570,15 +575,29 @@ main() vec4 src; vec4 dst; + /* Always alpha pre-multiplied. */ src = fragment_input_color_premult(); - /* Framebuffer must have straight alpha. */ + /** + * Framebuffer content is pre-multiplied if c_alpha_premult_blending, + * straight alpha otherwise. + */ dst = gl_LastFragData[0]; dst.rgb = color_curve(c_fb_fetch_curve, fb_fetch_curve_lut, fb_fetch_curve_par, dst.rgb); - /* glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); */ - dst = src + (1.0 - src.a) * dst; + if (c_fb_alpha_encoding == SHADER_FB_ALPHA_ENCODING_PREMULT) { + /* glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); */ + dst = src + (1.0 - src.a) * dst; + } else { + /* SHADER_FB_ALPHA_ENCODING_STRAIGHT; same formula here, but + * dst is not alpha pre-mult. */ + dst.rgb = src.rgb + (1.0 - src.a) * dst.rgb * dst.a; + dst.a = src.a + (1.0 - src.a) * dst.a; + /* Leave the fb as straight alpha */ + if (dst.a > 0.0) + dst.rgb /= dst.a; + } dst.rgb = color_curve(c_fb_store_curve, fb_store_curve_lut, fb_store_curve_par, dst.rgb); diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index a15574f05..7511874e1 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -252,6 +252,12 @@ enum gl_shader_color_mapping { SHADER_COLOR_MAPPING_MATRIX, }; +/* Keep the following in sync with fragment.glsl. */ +enum gl_shader_fb_alpha_encoding { + SHADER_FB_ALPHA_ENCODING_PREMULT = 0, + SHADER_FB_ALPHA_ENCODING_STRAIGHT, +}; + enum gl_shader_attrib_loc { SHADER_ATTRIB_LOC_POSITION = 0, SHADER_ATTRIB_LOC_TEXCOORD, @@ -313,6 +319,7 @@ struct gl_shader_requirements unsigned color_post_curve:3; /* enum gl_shader_color_curve */ bool shader_blending:1; + unsigned fb_alpha_encoding:1; /* enum gl_shader_fb_alpha_encoding */ unsigned fb_fetch_curve:3; /* enum gl_shader_color_curve */ unsigned fb_store_curve:3; /* enum gl_shader_color_curve */ @@ -320,7 +327,7 @@ struct gl_shader_requirements * The total size of all bitfields plus pad_bits_ must fill up exactly * how many bytes the compiler allocates for them together. */ - unsigned pad_bits_:7; + unsigned pad_bits_:6; }; static_assert(sizeof(struct gl_shader_requirements) == 4 /* total bitfield size in bytes */, @@ -406,6 +413,8 @@ struct gl_shader_config { union gl_shader_config_color_curve fb_fetch_curve; union gl_shader_config_color_curve fb_store_curve; + enum gl_shader_fb_alpha_encoding fb_alpha_encoding; + enum weston_color_matrix_coef yuv_coefficients; enum weston_color_quant_range yuv_range; }; @@ -787,7 +796,8 @@ void gl_shader_blender_destroy(struct gl_shader_blender *shader_blender); struct gl_shader_blender * -gl_shader_blender_create(struct gl_renderer *gr, struct weston_output *output); +gl_shader_blender_create(struct gl_renderer *gr, struct weston_output *output, + enum gl_shader_fb_alpha_encoding fb_alpha_encoding); void gl_shader_config_set_blender(struct gl_renderer *gr, diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 4bd78d239..356ab2c2c 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -4791,6 +4791,26 @@ gl_renderer_create_window_surface(struct gl_renderer *gr, return egl_surface; } +static bool +gl_renderer_can_render_fb_encoding_straight_alpha(struct weston_compositor *wc) +{ + const struct weston_testsuite_quirks *quirks = &wc->test_data.test_quirks; + struct gl_renderer *gr = get_renderer(wc); + + if (!gl_features_has(gr, FEATURE_SHADER_BLENDING)) + return false; + + /* In-shader blending is required. */ + if (quirks->blending_impl == WESTON_BLENDING_IMPL_FF) + return false; + + /* This forbids in-shader blending. */ + if (quirks->gl_force_full_redraw_of_shadow_fb) + return false; + + return true; +} + static int gl_renderer_output_create(struct weston_output *output, EGLSurface surface, @@ -4801,8 +4821,11 @@ gl_renderer_output_create(struct weston_output *output, struct weston_compositor *wc = output->compositor; struct gl_renderer *gr = get_renderer(wc); const struct weston_testsuite_quirks *quirks = &wc->test_data.test_quirks; + enum gl_shader_fb_alpha_encoding fb_alpha_encoding; bool needs_fb_curves; bool needs_shadow; + bool needs_shader_blending; + bool needs_straight_alpha; int i; assert(!get_output_state(output)); @@ -4830,25 +4853,33 @@ gl_renderer_output_create(struct weston_output *output, go->render_sync = EGL_NO_SYNC_KHR; needs_shadow = quirks->gl_force_full_redraw_of_shadow_fb; + needs_straight_alpha = output->fb_alpha_encoding == WESTON_OUTPUT_FB_ALPHA_ENCODING_STRAIGHT && + gl_renderer_can_render_fb_encoding_straight_alpha(wc); + needs_shader_blending = quirks->blending_impl == WESTON_BLENDING_IMPL_SHADER || + needs_straight_alpha; needs_fb_curves = output->color_outcome->from_blend_to_output && !output->from_blend_to_output_by_backend; if (needs_fb_curves) weston_assert_true(wc, gl_features_has(gr, FEATURE_COLOR_TRANSFORMS)); - if (!needs_shadow && needs_fb_curves) { + if (needs_shader_blending) + weston_assert_false(wc, needs_shadow); + + if (!needs_shadow && (needs_fb_curves || needs_shader_blending)) { switch (quirks->blending_impl) { - case WESTON_BLENDING_IMPL_AUTO: - go->shader_blender = gl_shader_blender_create(gr, output); - break; case WESTON_BLENDING_IMPL_FF: + weston_assert_false(wc, needs_shader_blending); go->shader_blender = NULL; break; + case WESTON_BLENDING_IMPL_AUTO: case WESTON_BLENDING_IMPL_SHADER: - go->shader_blender = gl_shader_blender_create(gr, output); - if (!go->shader_blender) { - weston_log("Error: quirks were used to force in-shader blending, " - "but it's not supported by the GLES implementation.\n" + fb_alpha_encoding = needs_straight_alpha ? SHADER_FB_ALPHA_ENCODING_STRAIGHT : + SHADER_FB_ALPHA_ENCODING_PREMULT; + go->shader_blender = gl_shader_blender_create(gr, output, fb_alpha_encoding); + if (needs_shader_blending && !go->shader_blender) { + weston_log("Error: in-shader blending required but not supported by " + "the GLES implementation.\n" "Quitting...\n"); weston_compositor_exit_with_code(wc, RESULT_SKIP); } @@ -5235,6 +5266,7 @@ gl_renderer_display_create(struct weston_compositor *ec, gr->base.surface_copy_content = gl_renderer_surface_copy_content; gr->base.fill_buffer_info = gl_renderer_fill_buffer_info; gr->base.buffer_init = gl_renderer_buffer_init; + gr->base.can_render_fb_encoding_straight_alpha = gl_renderer_can_render_fb_encoding_straight_alpha; gr->base.output_set_border = gl_renderer_output_set_border; gr->base.type = WESTON_RENDERER_GL; diff --git a/libweston/renderer-gl/gl-shader-config-color-transformation.c b/libweston/renderer-gl/gl-shader-config-color-transformation.c index b225df00a..29d32c84c 100644 --- a/libweston/renderer-gl/gl-shader-config-color-transformation.c +++ b/libweston/renderer-gl/gl-shader-config-color-transformation.c @@ -67,6 +67,7 @@ struct gl_renderer_color_effect { /** for in-shader blending */ struct gl_shader_blender { + enum gl_shader_fb_alpha_encoding fb_alpha_encoding; struct gl_renderer_color_curve fb_fetch_curve; struct gl_renderer_color_curve fb_store_curve; }; @@ -588,40 +589,51 @@ gl_shader_blender_destroy(struct gl_shader_blender *shader_blender) } struct gl_shader_blender * -gl_shader_blender_create(struct gl_renderer *gr, struct weston_output *output) +gl_shader_blender_create(struct gl_renderer *gr, struct weston_output *output, + enum gl_shader_fb_alpha_encoding fb_alpha_encoding) { struct gl_shader_blender *shader_blender; struct weston_color_curve *fb_fetch; const struct weston_color_curve *fb_store; const struct weston_color_transform *xform; + const struct weston_color_curve identity_curve = { + .type = WESTON_COLOR_CURVE_TYPE_IDENTITY, + }; bool ok; if (!gl_features_has(gr, FEATURE_SHADER_BLENDING)) return NULL; - xform = output->color_outcome->from_blend_to_output; - if (!xform) - return NULL; - - fb_store = weston_color_transform_as_single_curve(xform); - if (!fb_store) - return NULL; - - fb_fetch = weston_color_curve_create_inverse(fb_store); - if (!fb_fetch) - return NULL; - shader_blender = xzalloc(sizeof *shader_blender); - ok = gl_color_curve_init(gr, &shader_blender->fb_store_curve, fb_store, NULL) && - gl_color_curve_init(gr, &shader_blender->fb_fetch_curve, fb_fetch, NULL); - free(fb_fetch); + shader_blender->fb_alpha_encoding = fb_alpha_encoding; - if (!ok) { - free(shader_blender); - return NULL; + xform = output->color_outcome->from_blend_to_output; + if (xform) { + fb_store = weston_color_transform_as_single_curve(xform); + if (!fb_store) + goto fail; + + fb_fetch = weston_color_curve_create_inverse(fb_store); + if (!fb_fetch) + goto fail; + + ok = gl_color_curve_init(gr, &shader_blender->fb_store_curve, fb_store, NULL) && + gl_color_curve_init(gr, &shader_blender->fb_fetch_curve, fb_fetch, NULL); + + free(fb_fetch); + } else { + ok = gl_color_curve_init(gr, &shader_blender->fb_store_curve, &identity_curve, NULL) && + gl_color_curve_init(gr, &shader_blender->fb_fetch_curve, &identity_curve, NULL); } + if (!ok) + goto fail; + return shader_blender; + +fail: + free(shader_blender); + return NULL; } void @@ -637,9 +649,12 @@ gl_shader_config_set_blender(struct gl_renderer *gr, sconf->req.fb_store_curve = shader_blender->fb_store_curve.type; sconf->fb_store_curve = shader_blender->fb_store_curve.u; + + sconf->fb_alpha_encoding = shader_blender->fb_alpha_encoding; } else { sconf->req.shader_blending = false; sconf->req.fb_fetch_curve = SHADER_COLOR_CURVE_IDENTITY; sconf->req.fb_store_curve = SHADER_COLOR_CURVE_IDENTITY; + sconf->fb_alpha_encoding = SHADER_FB_ALPHA_ENCODING_PREMULT; } } diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c index 02ba41c7d..1f29c4265 100644 --- a/libweston/renderer-gl/gl-shaders.c +++ b/libweston/renderer-gl/gl-shaders.c @@ -191,6 +191,18 @@ gl_shader_color_mapping_to_string(enum gl_shader_color_mapping kind) return gl_shader_enum_map_get(gl_shader_color_mapping_mapping, kind); } +static const struct gl_shader_enum_map gl_shader_fb_alpha_encoding_mapping[] = { + ENUMVAL(SHADER_FB_ALPHA_ENCODING_PREMULT, "pre-mult"), + ENUMVAL(SHADER_FB_ALPHA_ENCODING_STRAIGHT, "straight"), +}; + +static const struct gl_shader_enum_map * +gl_shader_fb_alpha_encoding_to_string(enum gl_shader_fb_alpha_encoding kind) +{ + return gl_shader_enum_map_get(gl_shader_fb_alpha_encoding_mapping, kind); +} + + static void dump_program_with_line_numbers(int count, const char **sources) { @@ -256,7 +268,7 @@ create_shader_description_string(const struct gl_shader_requirements *req) int size; char *str; - size = asprintf(&str, "%s tc, %s tex, %s effect, CP{ %s, %s, %s }, %cpremult_in %ctint %cshader_blending (%s, %s)", + size = asprintf(&str, "%s tc, %s tex, %s effect, CP{ %s, %s, %s }, %cpremult_in %ctint %cshader_blending fb_alpha_encoding %s (%s, %s)", gl_shader_texcoord_input_to_string(req->texcoord_input)->desc, gl_shader_texture_variant_to_string(req->variant)->desc, gl_shader_color_effect_to_string(req->color_effect)->desc, @@ -266,6 +278,7 @@ create_shader_description_string(const struct gl_shader_requirements *req) req->input_is_premult ? '+' : '-', req->tint ? '+' : '-', req->shader_blending ? '+' : '-', + gl_shader_fb_alpha_encoding_to_string(req->fb_alpha_encoding)->desc, gl_shader_color_curve_to_string(req->fb_fetch_curve)->desc, gl_shader_color_curve_to_string(req->fb_store_curve)->desc); if (size < 0) @@ -305,6 +318,7 @@ create_fragment_shader_config_string(const struct gl_shader_requirements *req) "#define DEF_COLOR_MAPPING %s\n" "#define DEF_COLOR_POST_CURVE %s\n" "#define DEF_SHADER_BLENDING %s\n" + "#define DEF_FB_ALPHA_ENCODING %s\n" "#define DEF_FB_FETCH_CURVE %s\n" "#define DEF_FB_STORE_CURVE %s\n" "#define DEF_COLOR_EFFECT %s\n" @@ -317,6 +331,7 @@ create_fragment_shader_config_string(const struct gl_shader_requirements *req) gl_shader_color_mapping_to_string(req->color_mapping)->symbol, gl_shader_color_curve_to_string(req->color_post_curve)->symbol, req->shader_blending ? "1" : "0", + gl_shader_fb_alpha_encoding_to_string(req->fb_alpha_encoding)->symbol, gl_shader_color_curve_to_string(req->fb_fetch_curve)->symbol, gl_shader_color_curve_to_string(req->fb_store_curve)->symbol, gl_shader_color_effect_to_string(req->color_effect)->symbol, diff --git a/libweston/renderer-vulkan/vulkan-renderer.c b/libweston/renderer-vulkan/vulkan-renderer.c index 369385c43..6c739b981 100644 --- a/libweston/renderer-vulkan/vulkan-renderer.c +++ b/libweston/renderer-vulkan/vulkan-renderer.c @@ -3196,6 +3196,12 @@ vulkan_renderer_buffer_init(struct weston_compositor *ec, wl_signal_add(&buffer->destroy_signal, &vb->destroy_listener); } +static bool +vulkan_renderer_can_render_fb_encoding_straight_alpha(struct weston_compositor *wc) +{ + return false; +} + static void vulkan_renderer_output_destroy_border(struct weston_output *output, enum weston_renderer_border_side side) @@ -4393,6 +4399,7 @@ vulkan_renderer_display_create(struct weston_compositor *ec, vr->base.attach = vulkan_renderer_attach; vr->base.destroy = vulkan_renderer_destroy; vr->base.buffer_init = vulkan_renderer_buffer_init; + vr->base.can_render_fb_encoding_straight_alpha = vulkan_renderer_can_render_fb_encoding_straight_alpha; vr->base.output_set_border = vulkan_renderer_output_set_border, vr->base.type = WESTON_RENDERER_VULKAN;