diff options
| author | vaxerski <43317083+vaxerski@users.noreply.github.com> | 2022-05-28 17:32:19 +0200 |
|---|---|---|
| committer | vaxerski <43317083+vaxerski@users.noreply.github.com> | 2022-05-28 17:32:19 +0200 |
| commit | 8c10857f14e6c91f3b3099b9508e1f4d68c2d276 (patch) | |
| tree | ad71ebd03a25f0b1832bcb93b2c39567c54b5d4d /src/debug/HyprDebugOverlay.cpp | |
| parent | 9b6960eb554f320492fd1414ecb9e52a3ad3b7d4 (diff) | |
Added a debug overlay
Diffstat (limited to 'src/debug/HyprDebugOverlay.cpp')
| -rw-r--r-- | src/debug/HyprDebugOverlay.cpp | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp new file mode 100644 index 00000000..214965a8 --- /dev/null +++ b/src/debug/HyprDebugOverlay.cpp @@ -0,0 +1,154 @@ +#include "HyprDebugOverlay.hpp" +#include "../Compositor.hpp" + +void CHyprMonitorDebugOverlay::renderData(SMonitor* pMonitor, float µs) { + m_dLastRenderTimes.push_back(µs / 1000.f); + + if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate) + m_dLastRenderTimes.pop_front(); + + if (!m_pMonitor) + m_pMonitor = pMonitor; +} + +void CHyprMonitorDebugOverlay::frameData(SMonitor* pMonitor) { + m_dLastFrametimes.push_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f); + + if (m_dLastFrametimes.size() > (long unsigned int)pMonitor->refreshRate) + m_dLastFrametimes.pop_front(); + + m_tpLastFrame = std::chrono::high_resolution_clock::now(); + + if (!m_pMonitor) + m_pMonitor = pMonitor; +} + +int CHyprMonitorDebugOverlay::draw(int offset) { + + if (!m_pMonitor) + return 0; + + int yOffset = offset; + cairo_text_extents_t cairoExtents; + float maxX = 0; + std::string text = ""; + + // get avg fps + float avgFrametime = 0; + for (auto& ft : m_dLastFrametimes) { + avgFrametime += ft; + } + avgFrametime /= m_dLastFrametimes.size() == 0 ? 1 : m_dLastFrametimes.size(); + + float avgRenderTime = 0; + for (auto& rt : m_dLastRenderTimes) { + avgRenderTime += rt; + } + avgRenderTime /= m_dLastRenderTimes.size() == 0 ? 1 : m_dLastRenderTimes.size(); + + const float FPS = 1.f / (avgFrametime / 1000.f); // frametimes are in ms + const float idealFPS = m_dLastFrametimes.size(); + + cairo_select_font_face(g_pDebugOverlay->m_pCairo, "Noto Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + + cairo_set_font_size(g_pDebugOverlay->m_pCairo, 10); + cairo_set_source_rgba(g_pDebugOverlay->m_pCairo, 1.f, 1.f, 1.f, 1.f); + + yOffset += 10; + cairo_move_to(g_pDebugOverlay->m_pCairo, 0, yOffset); + text = m_pMonitor->szName; + cairo_show_text(g_pDebugOverlay->m_pCairo, text.c_str()); + cairo_text_extents(g_pDebugOverlay->m_pCairo, text.c_str(), &cairoExtents); + if (cairoExtents.width > maxX) maxX = cairoExtents.width; + + cairo_set_font_size(g_pDebugOverlay->m_pCairo, 16); + + if (FPS > idealFPS * 0.95f) + cairo_set_source_rgba(g_pDebugOverlay->m_pCairo, 0.2f, 1.f, 0.2f, 1.f); + else if (FPS > idealFPS * 0.8f) + cairo_set_source_rgba(g_pDebugOverlay->m_pCairo, 1.f, 1.f, 0.2f, 1.f); + else + cairo_set_source_rgba(g_pDebugOverlay->m_pCairo, 1.f, 0.2f, 0.2f, 1.f); + + yOffset += 17; + cairo_move_to(g_pDebugOverlay->m_pCairo, 0, yOffset); + text = std::string(std::to_string((int)FPS) + " FPS"); + cairo_show_text(g_pDebugOverlay->m_pCairo, text.c_str()); + cairo_text_extents(g_pDebugOverlay->m_pCairo, text.c_str(), &cairoExtents); + if (cairoExtents.width > maxX) maxX = cairoExtents.width; + + cairo_set_font_size(g_pDebugOverlay->m_pCairo, 10); + cairo_set_source_rgba(g_pDebugOverlay->m_pCairo, 1.f, 1.f, 1.f, 1.f); + + yOffset += 11; + cairo_move_to(g_pDebugOverlay->m_pCairo, 0, yOffset); + text = std::string("Avg Frametime: " + std::to_string((int)avgFrametime) + "." + std::to_string((int)(avgFrametime * 10.f) % 10) + "ms"); + cairo_show_text(g_pDebugOverlay->m_pCairo, text.c_str()); + cairo_text_extents(g_pDebugOverlay->m_pCairo, text.c_str(), &cairoExtents); + if (cairoExtents.width > maxX) maxX = cairoExtents.width; + + yOffset += 11; + cairo_move_to(g_pDebugOverlay->m_pCairo, 0, yOffset); + text = std::string("Avg Rendertime: " + std::to_string((int)avgRenderTime) + "." + std::to_string((int)(avgRenderTime * 10.f) % 10) + "ms"); + cairo_show_text(g_pDebugOverlay->m_pCairo, text.c_str()); + cairo_text_extents(g_pDebugOverlay->m_pCairo, text.c_str(), &cairoExtents); + if (cairoExtents.width > maxX) maxX = cairoExtents.width; + + yOffset += 11; + + g_pHyprRenderer->damageBox(&m_wbLastDrawnBox); + m_wbLastDrawnBox = {(int)g_pCompositor->m_lMonitors.front().vecPosition.x, (int)g_pCompositor->m_lMonitors.front().vecPosition.y + offset - 1, (int)maxX + 2, yOffset - offset + 2}; + g_pHyprRenderer->damageBox(&m_wbLastDrawnBox); + + return yOffset - offset; +} + +void CHyprDebugOverlay::renderData(SMonitor* pMonitor, float µs) { + m_mMonitorOverlays[pMonitor].renderData(pMonitor, µs); +} + +void CHyprDebugOverlay::frameData(SMonitor* pMonitor) { + m_mMonitorOverlays[pMonitor].frameData(pMonitor); +} + +void CHyprDebugOverlay::draw() { + + const auto PMONITOR = &g_pCompositor->m_lMonitors.front(); + + if (!m_pCairoSurface || !m_pCairo) { + m_pCairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y); + m_pCairo = cairo_create(m_pCairoSurface); + } + + // clear the pixmap + cairo_save(m_pCairo); + cairo_set_operator(m_pCairo, CAIRO_OPERATOR_CLEAR); + cairo_paint(m_pCairo); + cairo_restore(m_pCairo); + + // draw the things + int offsetY = 0; + for (auto& m : g_pCompositor->m_lMonitors) { + offsetY += m_mMonitorOverlays[&m].draw(offsetY); + offsetY += 5; // for padding between mons + } + + cairo_surface_flush(m_pCairoSurface); + + // copy the data to an OpenGL texture we have + const auto DATA = cairo_image_surface_get_data(m_pCairoSurface); + m_tTexture.allocate(); + glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + +#ifndef GLES2 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); +#endif + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecSize.x, PMONITOR->vecSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA); + + wlr_box pMonBox = {0,0,PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y}; + g_pHyprOpenGL->renderTexture(m_tTexture, &pMonBox, 255.f); +} |
