Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/xrt/compositor/metal/comp_metal_compositor.m
Original file line number Diff line number Diff line change
Expand Up @@ -4018,6 +4018,21 @@ - (BOOL)wantsUpdateLayer
}
}

// #1788: window-space layers BLEND over the projection content,
// same rule as D3D11/D3D12, vk_native and GL (#1786/#1787):
// SOURCE_ALPHA_BIT clear means premultiplied bytes (colour src
// ONE), set means straight (colour src SOURCE_ALPHA); colour dst
// and the alpha "over" (ONE / ONE_MINUS_SOURCE_ALPHA) are shared,
// so atlas alpha survives for transparent sessions (#225/#1784).
// The blended projection pipelines carry exactly those factors.
// Deliberately NOT comp_layer_blend_mode() (#1599): see the
// comment in comp_d3d11_renderer.cpp's window-space draw. And
// never projection_pipeline — its REPLACE is for the base blit.
bool ws_premultiplied =
(layer->data.flags & XRT_LAYER_COMPOSITION_BLEND_TEXTURE_SOURCE_ALPHA_BIT) == 0;
id<MTLRenderPipelineState> ws_pipeline =
ws_premultiplied ? c->proj_premult_pipeline : c->proj_straight_pipeline;

// Source UV sub-rect (default to full texture if not specified)
struct xrt_normalized_rect nr = ws->sub.norm_rect;
if (nr.w <= 0.0f || nr.h <= 0.0f) {
Expand Down Expand Up @@ -4060,7 +4075,7 @@ - (BOOL)wantsUpdateLayer
}
[encoder setViewport:vp];

[encoder setRenderPipelineState:c->projection_pipeline];
[encoder setRenderPipelineState:ws_pipeline];
[encoder setDepthStencilState:c->depth_stencil_state];
[encoder setFragmentTexture:src_tex atIndex:0];
[encoder setFragmentSamplerState:c->sampler_linear atIndex:0];
Expand Down
4 changes: 3 additions & 1 deletion tests/tests_comp_layer_view_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,9 @@ TEST_CASE("comp_layer_blend_mode: no backend reimplements the blend rule (#1621)
// channel D3D11's is (its own premul/straight decision, deliberately
// not comp_layer_blend_mode() -- see comp_d3d11_renderer.cpp).
{"gl/comp_gl_compositor.cpp", 1},
{"metal/comp_metal_compositor.m", 0},
// #1788: Metal's one allowance is the same Local2D / window-space
// channel as D3D11/D3D12/GL (#1581, #1786).
{"metal/comp_metal_compositor.m", 1},
// The Local2D / window-space channel, above.
{"d3d11/comp_d3d11_renderer.cpp", 1},
/*
Expand Down
Loading