| 121 | } |
| 122 | |
| 123 | void new_plot(float *data, std::size_t data_size, const ImVec2 &scale, const ImVec4 &color, const ImRect &bb) { |
| 124 | ImGuiWindow* window = im::GetCurrentWindow(); |
| 125 | if (window->SkipItems) |
| 126 | return; |
| 127 | |
| 128 | const float scale_min = scale.x, scale_max = scale.y; |
| 129 | |
| 130 | const int values_count_min = 2; |
| 131 | if (data_size < values_count_min) |
| 132 | return; |
| 133 | |
| 134 | int res_w = ImMin((int)(bb.Max.x - bb.Min.x), (int)data_size) - 1; |
| 135 | int item_count = data_size - 1; |
| 136 | |
| 137 | const float t_step = 1.0f / (float)res_w; |
| 138 | const float inv_scale = (scale_min == scale_max) ? 0.0f : (1.0f / (scale_max - scale_min)); |
| 139 | |
| 140 | float v0 = data[0]; |
| 141 | float t0 = 0.0f; |
| 142 | ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale) ); // Point in the normalized space of our target rectangle |
| 143 | |
| 144 | const ImU32 col_base = IM_COL32(color.x, color.y, color.z, color.w); |
| 145 | |
| 146 | for (int n = 0; n < res_w; n++) { |
| 147 | const float t1 = t0 + t_step; |
| 148 | const int v1_idx = (int)(t0 * item_count + 0.5f); |
| 149 | const float v1 = data[v1_idx + 1]; |
| 150 | const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) * inv_scale) ); |
| 151 | |
| 152 | // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. |
| 153 | ImVec2 pos0 = ImLerp(bb.Min, bb.Max, tp0); |
| 154 | ImVec2 pos1 = ImLerp(bb.Min, bb.Max, tp1); |
| 155 | window->DrawList->AddLine(pos0, pos1, col_base); |
| 156 | |
| 157 | t0 = t1; |
| 158 | tp0 = tp1; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | Result draw_profile_tab(Config &ctx) { |
| 163 | if (!im::BeginTabItem("Profile")) |