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.");
142 if (draw_data->CmdListsCount == 0) {
146 using VS = impeller::ImguiRasterVertexShader;
147 using FS = impeller::ImguiRasterFragmentShader;
150 IM_ASSERT(bd !=
nullptr &&
"Did you call ImGui_ImplImpeller_Init()?");
152 size_t total_vtx_bytes = draw_data->TotalVtxCount *
sizeof(VS::PerVertexData);
153 size_t total_idx_bytes = draw_data->TotalIdxCount *
sizeof(ImDrawIdx);
154 if (!total_vtx_bytes || !total_idx_bytes) {
160 buffer_desc.
size = total_vtx_bytes + total_idx_bytes;
163 auto buffer = bd->context->GetResourceAllocator()->CreateBuffer(buffer_desc);
164 buffer->SetLabel(
"ImGui vertex+index buffer");
167 draw_data->DisplayPos.x, draw_data->DisplayPos.y,
168 draw_data->DisplaySize.x, draw_data->DisplaySize.y);
171 .
rect = display_rect.
Scale(draw_data->FramebufferScale.x,
172 draw_data->FramebufferScale.y)};
175 VS::UniformBuffer uniforms;
180 size_t vertex_buffer_offset = 0;
181 size_t index_buffer_offset = total_vtx_bytes;
183 for (
int draw_list_i = 0; draw_list_i < draw_data->CmdListsCount;
185 const ImDrawList* cmd_list = draw_data->CmdLists[draw_list_i];
195 std::vector<VS::PerVertexData> vtx_data;
196 vtx_data.reserve(cmd_list->VtxBuffer.size());
197 for (
const auto& v : cmd_list->VtxBuffer) {
198 ImVec4 color = ImGui::ColorConvertU32ToFloat4(v.col);
199 vtx_data.push_back({{v.pos.x, v.pos.y},
201 {color.x, color.y, color.z, color.w}});
204 auto draw_list_vtx_bytes =
205 static_cast<size_t>(vtx_data.size() *
sizeof(VS::PerVertexData));
206 auto draw_list_idx_bytes =
207 static_cast<size_t>(cmd_list->IdxBuffer.size_in_bytes());
208 if (!buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*
>(vtx_data.data()),
210 vertex_buffer_offset)) {
211 IM_ASSERT(
false &&
"Could not copy vertices to buffer.");
213 if (!buffer->CopyHostBuffer(
214 reinterpret_cast<uint8_t*
>(cmd_list->IdxBuffer.Data),
216 IM_ASSERT(
false &&
"Could not copy indices to buffer.");
219 for (
int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
220 const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
222 if (pcmd->UserCallback) {
223 pcmd->UserCallback(cmd_list, pcmd);
227 (pcmd->ClipRect.x - draw_data->DisplayPos.x) *
228 draw_data->FramebufferScale.x,
229 (pcmd->ClipRect.y - draw_data->DisplayPos.y) *
230 draw_data->FramebufferScale.y,
231 (pcmd->ClipRect.z - draw_data->DisplayPos.x) *
232 draw_data->FramebufferScale.x,
233 (pcmd->ClipRect.w - draw_data->DisplayPos.y) *
234 draw_data->FramebufferScale.y);
237 auto visible_clip = clip_rect.Intersection(viewport.rect);
238 if (!visible_clip.has_value()) {
241 clip_rect = visible_clip.value();
246 auto visible_clip = clip_rect.Intersection(
248 if (!visible_clip.has_value()) {
251 clip_rect = visible_clip.value();
255 std::format(
"ImGui draw list {} (command {})", draw_list_i, cmd_i));
259 VS::BindUniformBuffer(render_pass, vtx_uniforms);
260 FS::BindTex(render_pass, bd->font_texture, bd->sampler);
263 vertex_buffer_offset + pcmd->VtxOffset *
sizeof(ImDrawVert);
270 pcmd->IdxOffset *
sizeof(ImDrawIdx),
271 pcmd->ElemCount *
sizeof(ImDrawIdx)));
281 vertex_buffer_offset += draw_list_vtx_bytes;
282 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