8 #include "fml/logging.h"
22 return std::nextafterf(
48 const std::optional<Rect>& current_clip_coverage)
const {
49 if (!current_clip_coverage.has_value()) {
50 return {.
type = ClipCoverage::Type::kAppend, .coverage = std::nullopt};
56 return {.type = ClipCoverage::Type::kAppend,
57 .coverage = current_clip_coverage};
60 return {.type = ClipCoverage::Type::kAppend, .coverage = std::nullopt};
62 auto coverage = geometry_->GetCoverage(entity.
GetTransform());
63 if (!coverage.has_value() || !current_clip_coverage.has_value()) {
64 return {.type = ClipCoverage::Type::kAppend, .coverage = std::nullopt};
67 .type = ClipCoverage::Type::kAppend,
68 .coverage = current_clip_coverage->Intersection(coverage.value()),
75 const std::optional<Rect> clip_coverage)
const {
103 options.depth_write_enabled =
false;
104 options.primitive_type = geometry_result.type;
106 switch (geometry_result.mode) {
109 options.stencil_mode =
114 options.stencil_mode =
120 options.stencil_mode =
126 info.mvp = geometry_result.transform;
129 if (!pass.
Draw().ok()) {
135 options.depth_write_enabled =
true;
141 options.stencil_mode =
148 std::optional<Rect> maybe_cover_area =
150 if (!maybe_cover_area.has_value()) {
153 cover_area = maybe_cover_area.value();
156 auto points = cover_area.GetPoints();
158 VertexBufferBuilder<VS::PerVertexData>{}
159 .AddVertices({{points[0]}, {points[1]}, {points[2]}, {points[3]}})
168 return pass.
Draw().ok();
171 bool ClipContents::RenderStencilClip(
const ContentContext& renderer,
172 const Entity& entity,
175 const Geometry& geometry)
const {
183 pass.SetStencilReference(entity.GetClipDepth());
187 pass.SetCommandLabel(
"Difference Clip (Increment)");
189 options.stencil_mode =
194 VertexBufferBuilder<VS::PerVertexData>{}
195 .AddVertices({{points[0]}, {points[1]}, {points[2]}, {points[3]}})
196 .CreateVertexBuffer(renderer.GetTransientsBuffer());
198 pass.SetVertexBuffer(std::move(vertices));
200 info.mvp = pass.GetOrthographicTransform();
201 VS::BindFrameInfo(pass,
202 renderer.GetTransientsBuffer().EmplaceUniform(info));
205 pass.SetPipeline(renderer.GetClipPipeline(options));
210 pass.SetCommandLabel(
"Difference Clip (Punch)");
211 pass.SetStencilReference(entity.GetClipDepth() + 1);
213 options.stencil_mode =
217 pass.SetCommandLabel(
"Intersect Clip");
219 options.stencil_mode =
223 auto geometry_result = geometry.GetPositionBuffer(renderer, entity, pass);
224 options.primitive_type = geometry_result.type;
225 pass.SetPipeline(renderer.GetClipPipeline(options));
227 pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer));
229 info.mvp = geometry_result.transform;
230 VS::BindFrameInfo(pass, renderer.GetTransientsBuffer().EmplaceUniform(info));
232 return pass.Draw().ok();
242 return RenderDepthClip(renderer, entity, pass, clip_op_, *geometry_);
244 return RenderStencilClip(renderer, entity, pass, clip_op_, *geometry_);
257 std::optional<Rect> restore_coverage) {
258 restore_coverage_ = restore_coverage;
262 const Entity& entity)
const {
268 const std::optional<Rect>& current_clip_coverage)
const {
274 const std::optional<Rect> clip_coverage)
const {
304 {
Point(ltrb[0], ltrb[1])},
305 {
Point(ltrb[2], ltrb[1])},
306 {
Point(ltrb[0], ltrb[3])},
307 {
Point(ltrb[2], ltrb[3])},
317 return pass.
Draw().ok();