Flutter Impeller
pass_bindings_cache_mtl.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 namespace impeller {
8 
9 void PassBindingsCacheMTL::SetEncoder(id<MTLRenderCommandEncoder> encoder) {
10  encoder_ = encoder;
11 }
12 
14  id<MTLRenderPipelineState> pipeline) {
15  if (pipeline == pipeline_) {
16  return;
17  }
18  pipeline_ = pipeline;
19  [encoder_ setRenderPipelineState:pipeline_];
20 }
21 
23  id<MTLDepthStencilState> depth_stencil) {
24  if (depth_stencil_ == depth_stencil) {
25  return;
26  }
27  depth_stencil_ = depth_stencil;
28  [encoder_ setDepthStencilState:depth_stencil_];
29 }
30 
32  uint64_t index,
33  uint64_t offset,
34  id<MTLBuffer> buffer) {
35  auto& buffers_map = buffers_[stage];
36  auto found = buffers_map.find(index);
37  if (found != buffers_map.end() && found->second.buffer == buffer) {
38  // The right buffer is bound. Check if its offset needs to be updated.
39  if (found->second.offset == offset) {
40  // Buffer and its offset is identical. Nothing to do.
41  return true;
42  }
43 
44  // Only the offset needs to be updated.
45  found->second.offset = offset;
46 
47  switch (stage) {
49  [encoder_ setVertexBufferOffset:offset atIndex:index];
50  return true;
52  [encoder_ setFragmentBufferOffset:offset atIndex:index];
53  return true;
54  default:
55  VALIDATION_LOG << "Cannot update buffer offset of an unknown stage.";
56  return false;
57  }
58  return true;
59  }
60  buffers_map[index] = {buffer, static_cast<size_t>(offset)};
61  switch (stage) {
63  [encoder_ setVertexBuffer:buffer offset:offset atIndex:index];
64  return true;
66  [encoder_ setFragmentBuffer:buffer offset:offset atIndex:index];
67  return true;
68  default:
69  VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
70  return false;
71  }
72  return false;
73 }
74 
76  uint64_t index,
77  id<MTLTexture> texture) {
78  auto& texture_map = textures_[stage];
79  auto found = texture_map.find(index);
80  if (found != texture_map.end() && found->second == texture) {
81  // Already bound.
82  return true;
83  }
84  texture_map[index] = texture;
85  switch (stage) {
87  [encoder_ setVertexTexture:texture atIndex:index];
88  return true;
90  [encoder_ setFragmentTexture:texture atIndex:index];
91  return true;
92  default:
93  VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
94  return false;
95  }
96  return false;
97 }
98 
100  uint64_t index,
101  id<MTLSamplerState> sampler) {
102  auto& sampler_map = samplers_[stage];
103  auto found = sampler_map.find(index);
104  if (found != sampler_map.end() && found->second == sampler) {
105  // Already bound.
106  return true;
107  }
108  sampler_map[index] = sampler;
109  switch (stage) {
111  [encoder_ setVertexSamplerState:sampler atIndex:index];
112  return true;
114  [encoder_ setFragmentSamplerState:sampler atIndex:index];
115  return true;
116  default:
117  VALIDATION_LOG << "Cannot bind buffer to unknown shader stage.";
118  return false;
119  }
120  return false;
121 }
122 
124  if (viewport_.has_value() && viewport_.value() == viewport) {
125  return;
126  }
127  [encoder_ setViewport:MTLViewport{
128  .originX = viewport.rect.GetX(),
129  .originY = viewport.rect.GetY(),
130  .width = viewport.rect.GetWidth(),
131  .height = viewport.rect.GetHeight(),
132  .znear = viewport.depth_range.z_near,
133  .zfar = viewport.depth_range.z_far,
134  }];
135  viewport_ = viewport;
136 }
137 
139  if (scissor_.has_value() && scissor_.value() == scissor) {
140  return;
141  }
142  [encoder_
143  setScissorRect:MTLScissorRect{
144  .x = static_cast<NSUInteger>(scissor.GetX()),
145  .y = static_cast<NSUInteger>(scissor.GetY()),
146  .width = static_cast<NSUInteger>(scissor.GetWidth()),
147  .height = static_cast<NSUInteger>(scissor.GetHeight()),
148  }];
149  scissor_ = scissor;
150 }
151 
152 void PassBindingsCacheMTL::SetStencilRef(uint32_t stencil_ref) {
153  if (stencil_ref_.has_value() && stencil_ref_.value() == stencil_ref) {
154  return;
155  }
156  [encoder_ setStencilReferenceValue:stencil_ref];
157  stencil_ref_ = stencil_ref;
158 }
159 
160 } // namespace impeller
void SetScissor(const IRect &scissor)
Set the encoder scissor rect if the value is different from the current encoder state.
void SetStencilRef(uint32_t stencil_ref)
Set the encoder's stencil reference if the value is different from the current encoder state.
void SetRenderPipelineState(id< MTLRenderPipelineState > pipeline)
Set the render pipeline state for the current encoder.
bool SetSampler(ShaderStage stage, uint64_t index, id< MTLSamplerState > sampler)
Set the sampler for the given stage and binding.
bool SetBuffer(ShaderStage stage, uint64_t index, uint64_t offset, id< MTLBuffer > buffer)
Set the buffer for the given shader stage, binding, and offset.
void SetViewport(const Viewport &viewport)
Set the viewport if the value is different from the current encoder state.
void SetDepthStencilState(id< MTLDepthStencilState > depth_stencil)
Set the depth and stencil state for the current encoder.
void SetEncoder(id< MTLRenderCommandEncoder > encoder)
Set the command encoder for this pass bindings cache.
bool SetTexture(ShaderStage stage, uint64_t index, id< MTLTexture > texture)
Set the texture for the given stage and binding.
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:341
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:351
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:337
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:345
DepthRange depth_range
Definition: formats.h:405
#define VALIDATION_LOG
Definition: validation.h:91