[Impeller] Assign subpass depth on restore rather than creation. (flutter/engine#50626)

The subpass depth is used for drawing the texture to the parent pass. So it needs a depth > all of the clips contained within the subpass.

Also correct the way we're assigning the depth value in shaders.
This commit is contained in:
Brandon DeRosier 2024-02-16 20:39:13 -08:00 committed by GitHub
parent d3c5ebf9cd
commit ca0765d43a
20 changed files with 261 additions and 227 deletions

View File

@ -3525,10 +3525,10 @@ TEST_P(AiksTest, CorrectClipDepthAssignedToEntities) {
canvas.DrawRRect(Rect::MakeLTRB(0, 0, 100, 100), {10, 10}, {}); // Depth 2
canvas.Save();
{
canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 5
canvas.SaveLayer({}); // Depth 3
canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
canvas.SaveLayer({}); // Depth 4
{
canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 3
}
canvas.Restore(); // Restore the savelayer.
}
@ -3538,9 +3538,13 @@ TEST_P(AiksTest, CorrectClipDepthAssignedToEntities) {
auto picture = canvas.EndRecordingAsPicture();
std::array<uint32_t, 5> expected = {
2, // DrawRRect
4, // ClipRRect
3, // SaveLayer
4, // DrawRRect
4, // ClipRRect -- Has a depth value equal to the max depth of all the
// content it affect. In this case, the SaveLayer and all
// its contents are affected.
4, // SaveLayer -- The SaveLayer is drawn to the parent pass after its
// contents are rendered, so it should have a depth value
// greater than all its contents.
3, // DrawRRect
5, // Restore (will be removed once we switch to the clip depth approach)
};
std::vector<uint32_t> actual;
@ -3557,7 +3561,7 @@ TEST_P(AiksTest, CorrectClipDepthAssignedToEntities) {
ASSERT_EQ(actual.size(), expected.size());
for (size_t i = 0; i < expected.size(); i++) {
EXPECT_EQ(actual[i], expected[i]) << "Index: " << i;
EXPECT_EQ(expected[i], actual[i]) << "Index: " << i;
}
}

View File

@ -176,7 +176,6 @@ void Canvas::Save(bool create_subpass,
if (create_subpass) {
entry.rendering_mode = Entity::RenderingMode::kSubpass;
auto subpass = std::make_unique<EntityPass>();
subpass->SetNewClipDepth(++current_depth_);
subpass->SetEnableOffscreenCheckerboard(
debug_options.offscreen_texture_checkerboard);
if (backdrop_filter) {
@ -214,6 +213,7 @@ bool Canvas::Restore() {
if (transform_stack_.back().rendering_mode ==
Entity::RenderingMode::kSubpass) {
current_pass_->SetNewClipDepth(++current_depth_);
current_pass_ = GetCurrentPass().GetSuperpass();
FML_DCHECK(current_pass_);
}

View File

@ -200,6 +200,7 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
VS::FrameInfo info;
info.depth = entity.GetShaderClipDepth();
info.mvp = pass.GetOrthographicTransform();
VS::BindFrameInfo(pass, renderer.GetTransientsBuffer().EmplaceUniform(info));

View File

@ -21,7 +21,12 @@ ContentContextOptions OptionsFromPass(const RenderPass& pass) {
ContentContextOptions opts;
opts.sample_count = pass.GetSampleCount();
opts.color_attachment_pixel_format = pass.GetRenderTargetPixelFormat();
opts.has_depth_stencil_attachments = pass.HasStencilAttachment();
bool has_depth_stencil_attachments =
pass.HasDepthAttachment() && pass.HasStencilAttachment();
FML_DCHECK(pass.HasDepthAttachment() == pass.HasStencilAttachment());
opts.has_depth_stencil_attachments = has_depth_stencil_attachments;
return opts;
}

View File

@ -470,6 +470,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
FS::FragInfo frag_info;
VS::FrameInfo frame_info;
frame_info.depth = entity.GetShaderClipDepth();
auto dst_sampler_descriptor = dst_snapshot->sampler_descriptor;
if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {

View File

@ -89,6 +89,7 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options));
TextureFillVertexShader::FrameInfo frame_info;
frame_info.depth = 0.0;
frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1));
frame_info.texture_sampler_y_coord_scale = 1.0;
frame_info.alpha = 1.0;

View File

@ -21,7 +21,8 @@ in vec2 src_texture_coords;
out vec2 v_src_texture_coords;
void main() {
gl_Position = frame_info.mvp * vec4(vertices, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0);
gl_Position.z = frame_info.depth;
v_src_texture_coords =
IPRemapCoords(src_texture_coords, frame_info.src_y_coord_scale);
}

View File

@ -20,7 +20,8 @@ out vec2 v_texture_coords;
out f16vec4 v_color;
void main() {
gl_Position = frame_info.mvp * vec4(vertices, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0);
gl_Position.z = frame_info.depth;
v_color = f16vec4(color);
v_texture_coords =
IPRemapCoords(texture_coords, frame_info.texture_sampler_y_coord_scale);

View File

@ -13,5 +13,6 @@ frame_info;
in vec2 position;
void main() {
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
}

View File

@ -80,7 +80,8 @@ void main() {
0.0, 1.0);
}
gl_Position = frame_info.mvp * vec4(position.xy, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position.xy, 0.0, 1.0);
gl_Position.z = frame_info.depth;
v_uv = uv_origin + unit_position * uv_size;
v_text_color = frame_info.text_color;
}

View File

@ -17,6 +17,7 @@ in vec2 position;
out vec2 v_position;
void main() {
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
v_position = IPVec2TransformPosition(frame_info.matrix, position);
}

View File

@ -17,6 +17,7 @@ in vec4 color;
out f16vec4 v_color;
void main() {
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
v_color = f16vec4(color);
}

View File

@ -15,7 +15,8 @@ in vec2 position;
out vec2 v_position;
void main() {
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
// The fragment stage uses local coordinates to compute the blur.
v_position = position;
}

View File

@ -17,6 +17,7 @@ in vec2 position;
out vec2 _fragCoord;
void main() {
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
_fragCoord = position;
}

View File

@ -17,5 +17,6 @@ IMPELLER_MAYBE_FLAT out f16vec4 v_color;
void main() {
v_color = frame_info.color;
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
}

View File

@ -20,7 +20,8 @@ out vec2 v_texture_coords;
IMPELLER_MAYBE_FLAT out float16_t v_alpha;
void main() {
gl_Position = frame_info.mvp * vec4(position, frame_info.depth, 1.0);
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
gl_Position.z = frame_info.depth;
v_alpha = frame_info.alpha;
v_texture_coords =
IPRemapCoords(texture_coords, frame_info.texture_sampler_y_coord_scale);

View File

@ -159,6 +159,7 @@ TEST_P(ComputeSubgroupTest, PathPlayground) {
.index_type = IndexType::kNone});
VS::FrameInfo frame_info;
frame_info.depth = 0.0;
auto world_matrix = Matrix::MakeScale(GetContentScale());
frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
frame_info.color = Color::Red().Premultiply();
@ -357,6 +358,7 @@ TEST_P(ComputeSubgroupTest, LargePath) {
.index_type = IndexType::kNone});
VS::FrameInfo frame_info;
frame_info.depth = 0.0;
auto world_matrix = Matrix::MakeScale(GetContentScale());
frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
frame_info.color = Color::Red().Premultiply();
@ -436,6 +438,7 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) {
.index_type = IndexType::kNone});
VS::FrameInfo frame_info;
frame_info.depth = 0.0;
auto world_matrix = Matrix::MakeScale(GetContentScale());
frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
frame_info.color = Color::Red().Premultiply();

View File

@ -12,6 +12,7 @@ RenderPass::RenderPass(std::shared_ptr<const Context> context,
: context_(std::move(context)),
sample_count_(target.GetSampleCount()),
pixel_format_(target.GetRenderTargetPixelFormat()),
has_depth_attachment_(target.GetDepthAttachment().has_value()),
has_stencil_attachment_(target.GetStencilAttachment().has_value()),
render_target_size_(target.GetRenderTargetSize()),
render_target_(target),
@ -27,6 +28,10 @@ PixelFormat RenderPass::GetRenderTargetPixelFormat() const {
return pixel_format_;
}
bool RenderPass::HasDepthAttachment() const {
return has_depth_attachment_;
}
bool RenderPass::HasStencilAttachment() const {
return has_stencil_attachment_;
}

View File

@ -156,6 +156,10 @@ class RenderPass : public ResourceBinder {
/// @brief The pixel format of the attached render target.
PixelFormat GetRenderTargetPixelFormat() const;
//----------------------------------------------------------------------------
/// @brief Whether the render target has a depth attachment.
bool HasDepthAttachment() const;
//----------------------------------------------------------------------------
/// @brief Whether the render target has an stencil attachment.
bool HasStencilAttachment() const;
@ -169,6 +173,7 @@ class RenderPass : public ResourceBinder {
// a const reference.
const SampleCount sample_count_;
const PixelFormat pixel_format_;
const bool has_depth_attachment_;
const bool has_stencil_attachment_;
const ISize render_target_size_;
const RenderTarget render_target_;

File diff suppressed because it is too large Load Diff