58 const std::shared_ptr<impeller::Context>& context) {
59 ImGuiIO& io = ImGui::GetIO();
60 IM_ASSERT(io.BackendRendererUserData ==
nullptr &&
61 "Already initialized a renderer backend!");
66 io.BackendRendererUserData =
reinterpret_cast<void*
>(bd);
67 io.BackendRendererName =
"imgui_impl_impeller";
69 ImGuiBackendFlags_RendererHasVtxOffset;
73 bd->context = context;
77 unsigned char* pixels;
79 io.Fonts->GetTexDataAsRGBA32(&pixels, &
width, &
height);
88 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
89 IM_ASSERT(bd->font_texture !=
nullptr &&
90 "Could not allocate ImGui font texture.");
91 bd->font_texture->SetLabel(
"ImGui Font Texture");
93 auto command_buffer = context->CreateCommandBuffer();
94 auto blit_pass = command_buffer->CreateBlitPass();
95 auto mapping = std::make_shared<fml::NonOwnedMapping>(
96 reinterpret_cast<const uint8_t*
>(pixels),
99 context->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
103 blit_pass->EncodeCommands();
105 [[maybe_unused]]
bool uploaded =
106 context->GetCommandQueue()->Submit({command_buffer}).ok();
107 IM_ASSERT(uploaded &&
108 "Could not upload ImGui font texture to device memory.");
114 impeller::ImguiRasterFragmentShader>::
115 MakeDefaultPipelineDescriptor(*context);
116 IM_ASSERT(desc.has_value() &&
"Could not create Impeller pipeline");
117 if (desc.has_value()) {
119 desc->ClearStencilAttachments();
120 desc->ClearDepthAttachment();
124 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
125 IM_ASSERT(bd->pipeline !=
nullptr &&
"Could not create ImGui pipeline.");
126 IM_ASSERT(bd->pipeline !=
nullptr &&
"Could not create ImGui sampler.");
147 if (draw_data->CmdListsCount == 0) {
151 using VS = impeller::ImguiRasterVertexShader;
152 using FS = impeller::ImguiRasterFragmentShader;
155 IM_ASSERT(bd !=
nullptr &&
"Did you call ImGui_ImplImpeller_Init()?");
157 size_t total_vtx_bytes = draw_data->TotalVtxCount *
sizeof(VS::PerVertexData);
158 size_t total_idx_bytes = draw_data->TotalIdxCount *
sizeof(ImDrawIdx);
159 if (!total_vtx_bytes || !total_idx_bytes) {
165 buffer_desc.
size = total_vtx_bytes + total_idx_bytes;
168 auto buffer = bd->context->GetResourceAllocator()->CreateBuffer(buffer_desc);
169 buffer->SetLabel(
"ImGui vertex+index buffer");
172 draw_data->DisplayPos.x, draw_data->DisplayPos.y,
173 draw_data->DisplaySize.x, draw_data->DisplaySize.y);
176 .
rect = display_rect.
Scale(draw_data->FramebufferScale.x,
177 draw_data->FramebufferScale.y)};
180 VS::UniformBuffer uniforms;
185 size_t vertex_buffer_offset = 0;
186 size_t index_buffer_offset = total_vtx_bytes;
188 for (
int draw_list_i = 0; draw_list_i < draw_data->CmdListsCount;
190 const ImDrawList* cmd_list = draw_data->CmdLists[draw_list_i];
200 std::vector<VS::PerVertexData> vtx_data;
201 vtx_data.reserve(cmd_list->VtxBuffer.size());
202 for (
const auto& v : cmd_list->VtxBuffer) {
203 ImVec4 color = ImGui::ColorConvertU32ToFloat4(v.col);
204 vtx_data.push_back({{v.pos.x, v.pos.y},
206 {color.x, color.y, color.z, color.w}});
209 auto draw_list_vtx_bytes =
210 static_cast<size_t>(vtx_data.size() *
sizeof(VS::PerVertexData));
211 auto draw_list_idx_bytes =
212 static_cast<size_t>(cmd_list->IdxBuffer.size_in_bytes());
213 if (!buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*
>(vtx_data.data()),
215 vertex_buffer_offset)) {
216 IM_ASSERT(
false &&
"Could not copy vertices to buffer.");
218 if (!buffer->CopyHostBuffer(
219 reinterpret_cast<uint8_t*
>(cmd_list->IdxBuffer.Data),
221 IM_ASSERT(
false &&
"Could not copy indices to buffer.");
224 for (
int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
225 const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
227 if (pcmd->UserCallback) {
228 pcmd->UserCallback(cmd_list, pcmd);
232 (pcmd->ClipRect.x - draw_data->DisplayPos.x) *
233 draw_data->FramebufferScale.x,
234 (pcmd->ClipRect.y - draw_data->DisplayPos.y) *
235 draw_data->FramebufferScale.y,
236 (pcmd->ClipRect.z - draw_data->DisplayPos.x) *
237 draw_data->FramebufferScale.x,
238 (pcmd->ClipRect.w - draw_data->DisplayPos.y) *
239 draw_data->FramebufferScale.y);
242 auto visible_clip = clip_rect.Intersection(viewport.rect);
243 if (!visible_clip.has_value()) {
246 clip_rect = visible_clip.value();
251 auto visible_clip = clip_rect.Intersection(
253 if (!visible_clip.has_value()) {
256 clip_rect = visible_clip.value();
260 std::format(
"ImGui draw list {} (command {})", draw_list_i, cmd_i));
264 VS::BindUniformBuffer(render_pass, vtx_uniforms);
265 FS::BindTex(render_pass, bd->font_texture, bd->sampler);
268 vertex_buffer_offset + pcmd->VtxOffset *
sizeof(ImDrawVert);
275 pcmd->IdxOffset *
sizeof(ImDrawIdx),
276 pcmd->ElemCount *
sizeof(ImDrawIdx)));
286 vertex_buffer_offset += draw_list_vtx_bytes;
287 index_buffer_offset += draw_list_idx_bytes;
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
constexpr size_t GetByteSizeOfBaseMipLevel() const