From 2fde4a2cd098ec9fb096d8ded91f779e0635e606 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Thu, 11 Aug 2022 11:28:37 -0700 Subject: [PATCH] [Impeller] Get rid of redundant viewport and scissor bindings. (flutter/engine#35330) --- .../renderer/backend/metal/render_pass_mtl.mm | 58 ++++++++++++------- .../src/flutter/impeller/renderer/formats.h | 8 +++ 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm index 5f38a621577..90f074e682b 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -299,6 +299,36 @@ struct PassBindingsCache { return false; } + void SetViewport(const Viewport& viewport) { + if (viewport_.has_value() && viewport_.value() == viewport) { + return; + } + [encoder_ setViewport:MTLViewport{ + .originX = viewport.rect.origin.x, + .originY = viewport.rect.origin.y, + .width = viewport.rect.size.width, + .height = viewport.rect.size.height, + .znear = viewport.depth_range.z_near, + .zfar = viewport.depth_range.z_far, + }]; + viewport_ = viewport; + } + + void SetScissor(const IRect& scissor) { + if (scissor_.has_value() && scissor_.value() == scissor) { + return; + } + [encoder_ + setScissorRect:MTLScissorRect{ + .x = static_cast(scissor.origin.x), + .y = static_cast(scissor.origin.y), + .width = static_cast(scissor.size.width), + .height = + static_cast(scissor.size.height), + }]; + scissor_ = scissor; + } + private: struct BufferOffsetPair { id buffer = nullptr; @@ -314,6 +344,8 @@ struct PassBindingsCache { std::map buffers_; std::map textures_; std::map samplers_; + std::optional viewport_; + std::optional scissor_; }; static bool Bind(PassBindingsCache& pass, @@ -423,6 +455,11 @@ bool RenderPassMTL::EncodeCommands(const std::shared_ptr& allocator, PipelineMTL::Cast(*command.pipeline).GetMTLRenderPipelineState()); pass_bindings.SetDepthStencilState( PipelineMTL::Cast(*command.pipeline).GetMTLDepthStencilState()); + pass_bindings.SetViewport(command.viewport.value_or( + {.rect = Rect::MakeSize(GetRenderTargetSize())})); + pass_bindings.SetScissor( + command.scissor.value_or(IRect::MakeSize(GetRenderTargetSize()))); + [encoder setFrontFacingWinding:pipeline_desc.GetWindingOrder() == WindingOrder::kClockwise ? MTLWindingClockwise @@ -430,27 +467,6 @@ bool RenderPassMTL::EncodeCommands(const std::shared_ptr& allocator, [encoder setCullMode:ToMTLCullMode(pipeline_desc.GetCullMode())]; [encoder setStencilReferenceValue:command.stencil_reference]; - auto v = command.viewport.value_or( - {.rect = Rect::MakeSize(GetRenderTargetSize())}); - MTLViewport viewport = { - .originX = v.rect.origin.x, - .originY = v.rect.origin.y, - .width = v.rect.size.width, - .height = v.rect.size.height, - .znear = v.depth_range.z_near, - .zfar = v.depth_range.z_far, - }; - [encoder setViewport:viewport]; - - auto s = command.scissor.value_or(IRect::MakeSize(GetRenderTargetSize())); - MTLScissorRect scissor = { - .x = static_cast(s.origin.x), - .y = static_cast(s.origin.y), - .width = static_cast(s.size.width), - .height = static_cast(s.size.height), - }; - [encoder setScissorRect:scissor]; - if (!bind_stage_resources(command.vertex_bindings, ShaderStage::kVertex)) { return false; } diff --git a/engine/src/flutter/impeller/renderer/formats.h b/engine/src/flutter/impeller/renderer/formats.h index ebf318f42ca..65509c6a3ae 100644 --- a/engine/src/flutter/impeller/renderer/formats.h +++ b/engine/src/flutter/impeller/renderer/formats.h @@ -184,11 +184,19 @@ enum class PrimitiveType { struct DepthRange { Scalar z_near = 0.0; Scalar z_far = 1.0; + + constexpr bool operator==(const DepthRange& other) const { + return z_near == other.z_near && z_far == other.z_far; + } }; struct Viewport { Rect rect; DepthRange depth_range; + + constexpr bool operator==(const Viewport& other) const { + return rect == other.rect && depth_range == other.depth_range; + } }; enum class MinMagFilter {