127 {
128 if (draw_data->CmdListsCount == 0) {
129 return;
130 }
132 render_pass.
GetContext()->GetResourceAllocator());
133
134 using VS = impeller::ImguiRasterVertexShader;
135 using FS = impeller::ImguiRasterFragmentShader;
136
138 IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplImpeller_Init()?");
139
140 size_t total_vtx_bytes = draw_data->TotalVtxCount * sizeof(VS::PerVertexData);
141 size_t total_idx_bytes = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
142 if (!total_vtx_bytes || !total_idx_bytes) {
143 return;
144 }
145
146
148 buffer_desc.
size = total_vtx_bytes + total_idx_bytes;
150
151 auto buffer = bd->context->GetResourceAllocator()->CreateBuffer(buffer_desc);
153
155 draw_data->DisplayPos.x, draw_data->DisplayPos.y,
156 draw_data->DisplaySize.x, draw_data->DisplaySize.y);
157
159 .
rect = display_rect.
Scale(draw_data->FramebufferScale.x,
160 draw_data->FramebufferScale.y)};
161
162
163 VS::UniformBuffer uniforms;
166 auto vtx_uniforms = host_buffer->EmplaceUniform(uniforms);
167
168 size_t vertex_buffer_offset = 0;
169 size_t index_buffer_offset = total_vtx_bytes;
170
171 for (int draw_list_i = 0; draw_list_i < draw_data->CmdListsCount;
172 draw_list_i++) {
173 const ImDrawList* cmd_list = draw_data->CmdLists[draw_list_i];
174
175
176
177
178
179
180
181
182
183 std::vector<VS::PerVertexData> vtx_data;
184 vtx_data.reserve(cmd_list->VtxBuffer.size());
185 for (const auto& v : cmd_list->VtxBuffer) {
186 ImVec4
color = ImGui::ColorConvertU32ToFloat4(v.col);
187 vtx_data.push_back({{v.pos.x, v.pos.y},
188 {v.uv.x, v.uv.y},
190 }
191
192 auto draw_list_vtx_bytes =
193 static_cast<size_t>(vtx_data.size() * sizeof(VS::PerVertexData));
194 auto draw_list_idx_bytes =
195 static_cast<size_t>(cmd_list->IdxBuffer.size_in_bytes());
196 if (!
buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*
>(vtx_data.data()),
198 vertex_buffer_offset)) {
199 IM_ASSERT(false && "Could not copy vertices to buffer.");
200 }
201 if (!
buffer->CopyHostBuffer(
202 reinterpret_cast<uint8_t*>(cmd_list->IdxBuffer.Data),
204 IM_ASSERT(false && "Could not copy indices to buffer.");
205 }
206
207 for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
208 const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
209
210 if (pcmd->UserCallback) {
211 pcmd->UserCallback(cmd_list, pcmd);
212 } else {
213
215 (pcmd->ClipRect.x - draw_data->DisplayPos.x) *
216 draw_data->FramebufferScale.x,
217 (pcmd->ClipRect.y - draw_data->DisplayPos.y) *
218 draw_data->FramebufferScale.y,
219 (pcmd->ClipRect.z - draw_data->DisplayPos.x) *
220 draw_data->FramebufferScale.x,
221 (pcmd->ClipRect.w - draw_data->DisplayPos.y) *
222 draw_data->FramebufferScale.y);
223 {
224
225 auto visible_clip = clip_rect.Intersection(viewport.rect);
226 if (!visible_clip.has_value()) {
227 continue;
228 }
229 clip_rect = visible_clip.value();
230 }
231 {
232
233
234 auto visible_clip = clip_rect.Intersection(
236 if (!visible_clip.has_value()) {
237 continue;
238 }
239 clip_rect = visible_clip.value();
240 }
241
243 "ImGui draw list %d (command %d)", draw_list_i, cmd_i));
247 VS::BindUniformBuffer(render_pass, vtx_uniforms);
248 FS::BindTex(render_pass, bd->font_texture, bd->sampler);
249
250 size_t vb_start =
251 vertex_buffer_offset + pcmd->VtxOffset * sizeof(ImDrawVert);
252
260 index_buffer_offset + pcmd->IdxOffset * sizeof(ImDrawIdx),
261 pcmd->ElemCount * sizeof(ImDrawIdx))};
266
268 }
269 }
270
271 vertex_buffer_offset += draw_list_vtx_bytes;
272 index_buffer_offset += draw_list_idx_bytes;
273 }
274 host_buffer->Reset();
275}
static std::shared_ptr< HostBuffer > Create(const std::shared_ptr< Allocator > &allocator)
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor > > &pipeline)
The pipeline to use for this command.
virtual void SetScissor(IRect scissor)
ISize GetRenderTargetSize() const
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
const std::shared_ptr< const Context > & GetContext() const
virtual void SetBaseVertex(uint64_t value)
virtual void SetViewport(Viewport viewport)
static const uint8_t buffer[]
static ImGui_ImplImpeller_Data * ImGui_ImplImpeller_GetBackendData()
std::string SPrintF(const char *format,...)
std::shared_ptr< const DeviceBuffer > buffer
static constexpr Matrix MakeOrthographic(TSize< T > size)
constexpr Matrix Translate(const Vector3 &t) const
RoundOut(const TRect< U > &r)
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr TRect Scale(Type scale) const
static constexpr TRect MakeSize(const TSize< U > &size)
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
BufferView index_buffer
The index buffer binding used by the vertex shader stage.