23 Point global_pass_position) {
27 if (clip_coverage.has_value()) {
28 clip_coverage = clip_coverage->
Shift(-global_pass_position);
31 scissor = scissor.Intersection(
IRect::MakeSize(pass.GetRenderTargetSize()))
34 pass.SetScissor(scissor);
37static void ApplyFramebufferBlend(Entity& entity) {
38 auto src_contents = entity.GetContents();
39 auto contents = std::make_shared<FramebufferBlendContents>();
40 contents->SetChildContents(src_contents);
41 contents->SetBlendMode(entity.GetBlendMode());
42 entity.SetContents(std::move(contents));
59 const Color& clear_color) {
60 const std::shared_ptr<Context>& context =
renderer.GetContext();
74 if (context->GetCapabilities()->SupportsOffscreenMSAA()) {
86 .clear_color = clear_color},
99 .clear_color = clear_color,
105 return std::make_unique<EntityPassTarget>(
106 target,
renderer.GetDeviceCapabilities().SupportsReadFromResolve(),
107 renderer.GetDeviceCapabilities().SupportsImplicitResolvingMSAA());
112 bool requires_readback)
115 render_target_(render_target),
116 requires_readback_(requires_readback),
118 Rect::MakeSize(render_target.GetRenderTargetSize()))) {
124 bool requires_readback,
128 render_target_(render_target),
129 requires_readback_(requires_readback),
131 Rect::MakeSize(render_target.GetRenderTargetSize()))) {
137 bool requires_readback,
141 render_target_(render_target),
142 requires_readback_(requires_readback),
144 Rect::MakeSize(render_target.GetRenderTargetSize()))) {
148void ExperimentalCanvas::SetupRenderPass() {
154 if (!stencil_attachment.has_value() || !depth_attachment.has_value()) {
159 *renderer_.
GetContext()->GetResourceAllocator(),
160 color0.texture->GetSize(),
161 renderer_.
GetContext()->GetCapabilities()->SupportsOffscreenMSAA(),
174 if (requires_readback_) {
176 renderer_, color0.texture->GetSize(), 1,
179 entity_pass_targets_.push_back(std::make_unique<EntityPassTarget>(
185 auto inline_pass = std::make_unique<InlinePassContext>(
186 renderer_, *entity_pass_targets_.back(), 0);
187 inline_pass_contexts_.emplace_back(std::move(inline_pass));
188 auto result = inline_pass_contexts_.back()->GetRenderPass(0u);
189 render_passes_.push_back(
result.pass);
200 <<
" after allocating " << total_content_depth;
208 std::optional<Rect>
bounds,
209 const std::shared_ptr<ImageFilter>& backdrop_filter,
211 uint32_t total_content_depth,
212 bool can_distribute_opacity) {
213 if (can_distribute_opacity && !backdrop_filter &&
215 Save(total_content_depth);
221 if (!
bounds.has_value()) {
234 subpass_coverage.
GetSize().height),
236 entity_pass_targets_.push_back(std::move(
target));
237 save_layer_state_.push_back(
SaveLayerState{paint_copy, subpass_coverage});
245 <<
" after allocating " << total_content_depth;
250 auto inline_pass = std::make_unique<InlinePassContext>(
251 renderer_, *entity_pass_targets_.back(), 0);
252 inline_pass_contexts_.emplace_back(std::move(inline_pass));
254 auto result = inline_pass_contexts_.back()->GetRenderPass(0u);
255 render_passes_.push_back(
result.pass);
292 auto inline_pass = std::move(inline_pass_contexts_.back());
295 save_layer_state_.pop_back();
297 std::shared_ptr<Contents> contents =
302 inline_pass->EndPass();
303 render_passes_.pop_back();
304 inline_pass_contexts_.pop_back();
315 ApplyFramebufferBlend(element_entity);
317 VALIDATION_LOG <<
"Emulated advanced blends are currently unsupported.";
322 element_entity.
Render(renderer_, *render_passes_.back());
342 auto clip_restore = std::make_shared<ClipRestoreContents>();
347 if (current_clip_coverage.has_value()) {
350 current_clip_coverage =
351 current_clip_coverage->Shift(-GetGlobalPassPosition());
355 if (clip_coverage.coverage.has_value()) {
357 clip_coverage.coverage->Shift(GetGlobalPassPosition());
362 GetClipHeightFloor(),
363 GetGlobalPassPosition());
368 *render_passes_.back(), GetGlobalPassPosition());
375 entity.
Render(renderer_, *render_passes_.back());
382 const std::shared_ptr<TextFrame>& text_frame,
389 auto text_contents = std::make_shared<TextContents>();
390 text_contents->SetTextFrame(text_frame);
391 text_contents->SetForceTextColor(
paint.mask_blur_descriptor.has_value());
393 text_contents->SetColor(
paint.color);
394 text_contents->SetOffset(position);
395 text_contents->SetTextProperties(
paint.color,
415 AddRenderEntityToCurrentPass(std::move(entity),
false);
418void ExperimentalCanvas::AddRenderEntityToCurrentPass(
Entity entity,
437 ApplyFramebufferBlend(entity);
439 VALIDATION_LOG <<
"Emulated advanced blends are currently unsupported.";
444 entity.
Render(renderer_, *render_passes_.back());
447void ExperimentalCanvas::AddClipEntityToCurrentPass(Entity entity) {
466 if (current_clip_coverage.has_value()) {
469 current_clip_coverage =
470 current_clip_coverage->Shift(-GetGlobalPassPosition());
473 auto clip_coverage = entity.GetClipCoverage(current_clip_coverage);
474 if (clip_coverage.coverage.has_value()) {
475 clip_coverage.coverage =
476 clip_coverage.coverage->Shift(GetGlobalPassPosition());
479 EntityPassClipStack::ClipStateResult clip_state_result =
481 clip_coverage, entity, GetClipHeightFloor(), GetGlobalPassPosition());
483 if (clip_state_result.clip_did_change) {
486 *render_passes_.back(), GetGlobalPassPosition());
489 if (!clip_state_result.should_render) {
493 entity.Render(renderer_, *render_passes_.back());
496bool ExperimentalCanvas::BlitToOnscreen() {
497 auto command_buffer = renderer_.
GetContext()->CreateCommandBuffer();
498 command_buffer->SetLabel(
"EntityPass Root Command Buffer");
499 auto offscreen_target = entity_pass_targets_.back()->GetRenderTarget();
503 ->SupportsTextureToTextureBlits()) {
504 auto blit_pass = command_buffer->CreateBlitPass();
505 blit_pass->AddCopy(offscreen_target.GetRenderTargetTexture(),
507 if (!blit_pass->EncodeCommands(
508 renderer_.
GetContext()->GetResourceAllocator())) {
514 ->Submit({command_buffer})
519 auto render_pass = command_buffer->CreateRenderPass(render_target_);
520 render_pass->SetLabel(
"EntityPass Root Render Pass");
523 auto size_rect =
Rect::MakeSize(offscreen_target.GetRenderTargetSize());
525 contents->SetTexture(offscreen_target.GetRenderTargetTexture());
526 contents->SetSourceRect(size_rect);
527 contents->SetLabel(
"Root pass blit");
530 entity.SetContents(contents);
533 if (!entity.Render(renderer_, *render_pass)) {
539 if (!render_pass->EncodeCommands()) {
545 ->Submit({command_buffer})
554 FML_DCHECK(inline_pass_contexts_.size() == 1u);
555 inline_pass_contexts_.back()->EndPass();
560 if (requires_readback_) {
564 render_passes_.clear();
565 inline_pass_contexts_.clear();
void Initialize(std::optional< Rect > cull_rect)
const Matrix & GetCurrentTransform() const
size_t GetClipHeight() const
std::optional< Rect > initial_cull_rect_
std::deque< CanvasStackEntry > transform_stack_
virtual bool SupportsImplicitResolvingMSAA() const =0
Whether the context backend supports multisampled rendering to the on-screen surface without requirin...
virtual bool SupportsFramebufferFetch() const =0
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
virtual bool SupportsReadFromResolve() const =0
Whether the context backend supports binding the current RenderPass attachments. This is supported if...
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() const
const Capabilities & GetDeviceCapabilities() const
std::shared_ptr< Context > GetContext() const
A class that tracks all clips that have been recorded in the current entity pass stencil.
std::optional< Rect > CurrentClipCoverage() const
void PushSubpass(std::optional< Rect > subpass_coverage, size_t clip_height)
ClipStateResult ApplyClipState(Contents::ClipCoverage global_clip_coverage, Entity &entity, size_t clip_height_floor, Point global_pass_position)
Applies the current clip state to an Entity. If the given Entity is a clip operation,...
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
bool SetInheritedOpacity(Scalar alpha)
@ kSubpassPrependSnapshotTransform
@ kSubpassAppendSnapshotTransform
void SetClipDepth(uint32_t clip_depth)
BlendMode GetBlendMode() const
void SetContents(std::shared_ptr< Contents > contents)
void SetBlendMode(BlendMode blend_mode)
bool Render(const ContentContext &renderer, RenderPass &parent_pass) const
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
static constexpr BlendMode kLastPipelineBlendMode
Contents::ClipCoverage GetClipCoverage(const std::optional< Rect > ¤t_clip_coverage) const
void DrawTextFrame(const std::shared_ptr< TextFrame > &text_frame, Point position, const Paint &paint) override
ExperimentalCanvas(ContentContext &renderer, RenderTarget &render_target, bool requires_readback)
void Save(uint32_t total_content_depth) override
void SaveLayer(const Paint &paint, std::optional< Rect > bounds, const std::shared_ptr< ImageFilter > &backdrop_filter, ContentBoundsPromise bounds_promise, uint32_t total_content_depth, bool can_distribute_opacity) override
std::shared_ptr< Contents > CreateContentsForSubpassTarget(std::shared_ptr< Texture > target, const Matrix &effect_transform) override
std::shared_ptr< Texture > GetRenderTargetTexture() const
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
void SetupDepthStencilAttachments(const Context &context, Allocator &allocator, ISize size, bool msaa, const std::string &label="Offscreen", RenderTarget::AttachmentConfig stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &depth_stencil_texture=nullptr)
ISize GetRenderTargetSize() const
const std::optional< DepthAttachment > & GetDepthAttachment() const
const std::optional< StencilAttachment > & GetStencilAttachment() const
static std::shared_ptr< TextureContents > MakeRect(Rect destination)
A common case factory that marks the texture contents as having a destination rectangle....
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
Optional< SkRect > bounds
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static void SetClipScissor(std::optional< Rect > clip_coverage, RenderPass &pass, Point global_pass_position)
static std::unique_ptr< EntityPassTarget > CreateRenderTarget(ContentContext &renderer, ISize size, int mip_count, const Color &clear_color)
static const constexpr RenderTarget::AttachmentConfig kDefaultStencilConfig
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Entity::RenderingMode rendering_mode
std::optional< Rect > cull_rect
static constexpr Color BlackTransparent()
std::optional< Rect > coverage
static constexpr Matrix MakeTranslation(const Vector3 &t)
static bool CanApplyOpacityPeephole(const Paint &paint)
Whether or not a save layer with the provided paint can perform the opacity peephole optimization.
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
RoundOut(const TRect< U > &r)
static constexpr TRect MakeSize(const TSize< U > &size)
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
constexpr TPoint< Type > GetOrigin() const
Returns the upper left corner of the rectangle as specified by the left/top or x/y values when it was...
static constexpr TSize MakeWH(Type width, Type height)