@@ -250,11 +250,7 @@ bool ClipContents::Render(const ContentContext& renderer,
|
||||
if (!geometry_) {
|
||||
return true;
|
||||
}
|
||||
if constexpr (ContentContext::kEnableStencilThenCover) {
|
||||
return RenderDepthClip(renderer, entity, pass, clip_op_, *geometry_);
|
||||
} else {
|
||||
return RenderStencilClip(renderer, entity, pass, clip_op_, *geometry_);
|
||||
}
|
||||
return RenderDepthClip(renderer, entity, pass, clip_op_, *geometry_);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -22,11 +22,6 @@ namespace testing {
|
||||
using EntityTest = EntityPlayground;
|
||||
|
||||
TEST_P(EntityTest, ClipContentsOptimizesFullScreenIntersectClips) {
|
||||
if (!ContentContext::kEnableStencilThenCover) {
|
||||
GTEST_SKIP();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up mock environment.
|
||||
|
||||
auto content_context = GetContentContext();
|
||||
|
||||
@@ -203,11 +203,7 @@ class ColorSourceContents : public Contents {
|
||||
options.stencil_mode =
|
||||
ContentContextOptions::StencilMode::kLegacyClipIncrement;
|
||||
}
|
||||
if constexpr (ContentContext::kEnableStencilThenCover) {
|
||||
pass.SetStencilReference(0);
|
||||
} else {
|
||||
pass.SetStencilReference(entity.GetClipDepth());
|
||||
}
|
||||
pass.SetStencilReference(0);
|
||||
|
||||
VertexShaderT::BindFrameInfo(
|
||||
pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
@@ -232,13 +228,9 @@ class ColorSourceContents : public Contents {
|
||||
if (geometry_result.mode == GeometryResult::Mode::kPreventOverdraw) {
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
if constexpr (ContentContext::kEnableStencilThenCover) {
|
||||
Entity restore_entity = entity.Clone();
|
||||
restore_entity.SetClipDepth(0);
|
||||
return restore.Render(renderer, restore_entity, pass);
|
||||
} else {
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
Entity restore_entity = entity.Clone();
|
||||
restore_entity.SetClipDepth(0);
|
||||
return restore.Render(renderer, restore_entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -397,16 +397,6 @@ class ContentContext {
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
/// This setting does two things:
|
||||
/// 1. Enables clipping with the depth buffer, freeing up the stencil buffer.
|
||||
/// See also: https://github.com/flutter/flutter/issues/138460
|
||||
/// 2. Switches the generic tessellation fallback to use stencil-then-cover.
|
||||
/// See also: https://github.com/flutter/flutter/issues/123671
|
||||
///
|
||||
// TODO(bdero): Remove this setting once StC is fully de-risked
|
||||
// https://github.com/flutter/flutter/issues/123671
|
||||
static constexpr bool kEnableStencilThenCover = true;
|
||||
|
||||
#if IMPELLER_ENABLE_3D
|
||||
std::shared_ptr<scene::SceneContext> GetSceneContext() const;
|
||||
#endif // IMPELLER_ENABLE_3D
|
||||
|
||||
@@ -27,10 +27,8 @@ ContentContextOptions OptionsFromPass(const RenderPass& pass) {
|
||||
FML_DCHECK(pass.HasDepthAttachment() == pass.HasStencilAttachment());
|
||||
|
||||
opts.has_depth_stencil_attachments = has_depth_stencil_attachments;
|
||||
if constexpr (ContentContext::kEnableStencilThenCover) {
|
||||
opts.depth_compare = CompareFunction::kGreater;
|
||||
opts.stencil_mode = ContentContextOptions::StencilMode::kIgnore;
|
||||
}
|
||||
opts.depth_compare = CompareFunction::kGreater;
|
||||
opts.stencil_mode = ContentContextOptions::StencilMode::kIgnore;
|
||||
return opts;
|
||||
}
|
||||
|
||||
|
||||
@@ -232,9 +232,6 @@ Entity ApplyClippedBlurStyle(Entity::ClipOperation clip_operation,
|
||||
blur_entity.SetNewClipDepth(entity.GetNewClipDepth());
|
||||
blur_entity.SetTransform(entity.GetTransform() * blur_transform);
|
||||
result = blur_entity.Render(renderer, pass) && result;
|
||||
if constexpr (!ContentContext::kEnableStencilThenCover) {
|
||||
result = restore->Render(renderer, entity, pass) && result;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
auto coverage =
|
||||
|
||||
@@ -756,9 +756,6 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
static void SetClipScissor(std::optional<Rect> clip_coverage,
|
||||
RenderPass& pass,
|
||||
Point global_pass_position) {
|
||||
if constexpr (!ContentContext::kEnableStencilThenCover) {
|
||||
return;
|
||||
}
|
||||
// Set the scissor to the clip coverage area. We do this prior to rendering
|
||||
// the clip itself and all its contents.
|
||||
IRect scissor;
|
||||
|
||||
@@ -101,22 +101,11 @@ EntityPassClipStack::ClipStateResult EntityPassClipStack::ApplyClipState(
|
||||
subpass_state.clip_coverage.resize(restoration_index + 1);
|
||||
result.clip_did_change = true;
|
||||
|
||||
if constexpr (ContentContext::kEnableStencilThenCover) {
|
||||
// Skip all clip restores when stencil-then-cover is enabled.
|
||||
if (subpass_state.clip_coverage.back().coverage.has_value()) {
|
||||
RecordEntity(entity, global_clip_coverage.type, Rect());
|
||||
}
|
||||
return result;
|
||||
// Skip all clip restores when stencil-then-cover is enabled.
|
||||
if (subpass_state.clip_coverage.back().coverage.has_value()) {
|
||||
RecordEntity(entity, global_clip_coverage.type, Rect());
|
||||
}
|
||||
|
||||
if (!subpass_state.clip_coverage.back().coverage.has_value()) {
|
||||
// Running this restore op won't make anything renderable, so skip it.
|
||||
return result;
|
||||
}
|
||||
|
||||
auto restore_contents =
|
||||
static_cast<ClipRestoreContents*>(entity.GetContents().get());
|
||||
restore_contents->SetRestoreCoverage(restore_coverage);
|
||||
return result;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -2795,11 +2795,7 @@ TEST_P(EntityTest, FillPathGeometryGetPositionBufferReturnsExpectedMode) {
|
||||
.Close()
|
||||
.TakePath();
|
||||
GeometryResult result = get_result(path);
|
||||
if constexpr (ContentContext::kEnableStencilThenCover) {
|
||||
EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
|
||||
} else {
|
||||
EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
|
||||
}
|
||||
EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,37 +37,6 @@ GeometryResult FillPathGeometry::GetPositionBuffer(
|
||||
}
|
||||
|
||||
VertexBuffer vertex_buffer;
|
||||
if constexpr (!ContentContext::kEnableStencilThenCover) {
|
||||
if (!path_.IsConvex()) {
|
||||
auto tesselation_result = renderer.GetTessellator()->Tessellate(
|
||||
path_, entity.GetTransform().GetMaxBasisLength(),
|
||||
[&vertex_buffer, &host_buffer](
|
||||
const float* vertices, size_t vertices_count,
|
||||
const uint16_t* indices, size_t indices_count) {
|
||||
vertex_buffer.vertex_buffer = host_buffer.Emplace(
|
||||
vertices, vertices_count * sizeof(float) * 2, alignof(float));
|
||||
if (indices != nullptr) {
|
||||
vertex_buffer.index_buffer = host_buffer.Emplace(
|
||||
indices, indices_count * sizeof(uint16_t), alignof(uint16_t));
|
||||
vertex_buffer.vertex_count = indices_count;
|
||||
vertex_buffer.index_type = IndexType::k16bit;
|
||||
} else {
|
||||
vertex_buffer.index_buffer = {};
|
||||
vertex_buffer.vertex_count = vertices_count;
|
||||
vertex_buffer.index_type = IndexType::kNone;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (tesselation_result != Tessellator::Result::kSuccess) {
|
||||
return {};
|
||||
}
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangle,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
auto points = renderer.GetTessellator()->TessellateConvex(
|
||||
path_, entity.GetTransform().GetMaxBasisLength());
|
||||
@@ -111,41 +80,6 @@ GeometryResult FillPathGeometry::GetPositionUVBuffer(
|
||||
auto uv_transform =
|
||||
texture_coverage.GetNormalizingTransform() * effect_transform;
|
||||
|
||||
if constexpr (!ContentContext::kEnableStencilThenCover) {
|
||||
if (!path_.IsConvex()) {
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
|
||||
auto tesselation_result = renderer.GetTessellator()->Tessellate(
|
||||
path_, entity.GetTransform().GetMaxBasisLength(),
|
||||
[&vertex_builder, &uv_transform](
|
||||
const float* vertices, size_t vertices_count,
|
||||
const uint16_t* indices, size_t indices_count) {
|
||||
for (auto i = 0u; i < vertices_count * 2; i += 2) {
|
||||
VS::PerVertexData data;
|
||||
Point vtx = {vertices[i], vertices[i + 1]};
|
||||
data.position = vtx;
|
||||
data.texture_coords = uv_transform * vtx;
|
||||
vertex_builder.AppendVertex(data);
|
||||
}
|
||||
FML_DCHECK(vertex_builder.GetVertexCount() == vertices_count);
|
||||
if (indices != nullptr) {
|
||||
for (auto i = 0u; i < indices_count; i++) {
|
||||
vertex_builder.AppendIndex(indices[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (tesselation_result != Tessellator::Result::kSuccess) {
|
||||
return {};
|
||||
}
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangle,
|
||||
.vertex_buffer =
|
||||
vertex_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()),
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
auto points = renderer.GetTessellator()->TessellateConvex(
|
||||
path_, entity.GetTransform().GetMaxBasisLength());
|
||||
|
||||
@@ -169,7 +103,7 @@ GeometryResult FillPathGeometry::GetPositionUVBuffer(
|
||||
|
||||
GeometryResult::Mode FillPathGeometry::GetResultMode() const {
|
||||
const auto& bounding_box = path_.GetBoundingBox();
|
||||
if (!ContentContext::kEnableStencilThenCover || path_.IsConvex() ||
|
||||
if (path_.IsConvex() ||
|
||||
(bounding_box.has_value() && bounding_box->IsEmpty())) {
|
||||
return GeometryResult::Mode::kNormal;
|
||||
}
|
||||
|
||||
@@ -151,19 +151,16 @@ InlinePassContext::RenderPassResult InlinePassContext::GetRenderPass(
|
||||
color0.store_action =
|
||||
is_msaa ? StoreAction::kMultisampleResolve : StoreAction::kStore;
|
||||
|
||||
if (ContentContext::kEnableStencilThenCover) {
|
||||
auto depth = pass_target_.GetRenderTarget().GetDepthAttachment();
|
||||
if (!depth.has_value()) {
|
||||
VALIDATION_LOG << "Depth attachment unexpectedly missing from the "
|
||||
"EntityPass render target.";
|
||||
return {};
|
||||
}
|
||||
depth->load_action = LoadAction::kClear;
|
||||
depth->store_action = StoreAction::kDontCare;
|
||||
pass_target_.target_.SetDepthAttachment(depth.value());
|
||||
}
|
||||
|
||||
auto depth = pass_target_.GetRenderTarget().GetDepthAttachment();
|
||||
if (!depth.has_value()) {
|
||||
VALIDATION_LOG << "Depth attachment unexpectedly missing from the "
|
||||
"EntityPass render target.";
|
||||
return {};
|
||||
}
|
||||
depth->load_action = LoadAction::kClear;
|
||||
depth->store_action = StoreAction::kDontCare;
|
||||
pass_target_.target_.SetDepthAttachment(depth.value());
|
||||
|
||||
auto stencil = pass_target_.GetRenderTarget().GetStencilAttachment();
|
||||
if (!depth.has_value() || !stencil.has_value()) {
|
||||
VALIDATION_LOG << "Stencil/Depth attachment unexpectedly missing from the "
|
||||
|
||||
Reference in New Issue
Block a user