[Impeller] Get rid of redundant viewport and scissor bindings. (flutter/engine#35330)

This commit is contained in:
Chinmay Garde 2022-08-11 11:28:37 -07:00 committed by GitHub
parent c111abc418
commit 2fde4a2cd0
2 changed files with 45 additions and 21 deletions

View File

@ -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<NSUInteger>(scissor.origin.x),
.y = static_cast<NSUInteger>(scissor.origin.y),
.width = static_cast<NSUInteger>(scissor.size.width),
.height =
static_cast<NSUInteger>(scissor.size.height),
}];
scissor_ = scissor;
}
private:
struct BufferOffsetPair {
id<MTLBuffer> buffer = nullptr;
@ -314,6 +344,8 @@ struct PassBindingsCache {
std::map<ShaderStage, BufferMap> buffers_;
std::map<ShaderStage, TextureMap> textures_;
std::map<ShaderStage, SamplerMap> samplers_;
std::optional<Viewport> viewport_;
std::optional<IRect> scissor_;
};
static bool Bind(PassBindingsCache& pass,
@ -423,6 +455,11 @@ bool RenderPassMTL::EncodeCommands(const std::shared_ptr<Allocator>& allocator,
PipelineMTL::Cast(*command.pipeline).GetMTLRenderPipelineState());
pass_bindings.SetDepthStencilState(
PipelineMTL::Cast(*command.pipeline).GetMTLDepthStencilState());
pass_bindings.SetViewport(command.viewport.value_or<Viewport>(
{.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>& allocator,
[encoder setCullMode:ToMTLCullMode(pipeline_desc.GetCullMode())];
[encoder setStencilReferenceValue:command.stencil_reference];
auto v = command.viewport.value_or<Viewport>(
{.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<NSUInteger>(s.origin.x),
.y = static_cast<NSUInteger>(s.origin.y),
.width = static_cast<NSUInteger>(s.size.width),
.height = static_cast<NSUInteger>(s.size.height),
};
[encoder setScissorRect:scissor];
if (!bind_stage_resources(command.vertex_bindings, ShaderStage::kVertex)) {
return false;
}

View File

@ -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 {