mirror of
https://github.com/wolfpld/tracy.git
synced 2026-09-16 07:14:25 +00:00
Compare commits
3 Commits
slomp/webg
...
slomp/pin-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffb7ce8a33 | ||
|
|
a6d16f5515 | ||
|
|
e58f4819ba |
@@ -16,6 +16,7 @@ TimelineController::TimelineController( View& view, Worker& worker, bool threadi
|
||||
, m_scroll( 0 )
|
||||
, m_centerItemkey( nullptr )
|
||||
, m_centerItemOffsetY( 0 )
|
||||
, m_pinnedTop( 0 )
|
||||
, m_firstFrame( true )
|
||||
, m_view( view )
|
||||
, m_worker( worker )
|
||||
@@ -53,16 +54,28 @@ void TimelineController::UpdateCenterItem()
|
||||
const auto timelineMousePosY = mousePos.y - ImGui::GetWindowPos().y;
|
||||
int centerY = timelineMousePosY + ImGui::GetScrollY();
|
||||
|
||||
int yBegin = 0;
|
||||
int yEnd = 0;
|
||||
// Pinned items are fixed to the viewport and excluded from the scrolling
|
||||
// flow, so centering only considers the normal items in the middle band.
|
||||
const void* firstNormalKey = nullptr;
|
||||
const void* lastNormalKey = nullptr;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
if( item->IsPinned() ) continue;
|
||||
if( !firstNormalKey ) firstNormalKey = item->GetKey();
|
||||
lastNormalKey = item->GetKey();
|
||||
}
|
||||
|
||||
int yBegin = 0;
|
||||
int yEnd = m_pinnedTop;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
if( item->IsPinned() ) continue;
|
||||
m_centerItemkey = item->GetKey();
|
||||
yBegin = yEnd;
|
||||
yEnd += item->GetHeight();
|
||||
|
||||
const auto inLowerBounds = m_centerItemkey == m_items.front()->GetKey() || yBegin <= centerY;
|
||||
const auto inUpperBounds = m_centerItemkey == m_items.back()->GetKey() || centerY < yEnd;
|
||||
const auto inLowerBounds = m_centerItemkey == firstNormalKey || yBegin <= centerY;
|
||||
const auto inUpperBounds = m_centerItemkey == lastNormalKey || centerY < yEnd;
|
||||
|
||||
if( inLowerBounds && inUpperBounds )
|
||||
{
|
||||
@@ -83,9 +96,10 @@ std::optional<int> TimelineController::CalculateScrollPosition() const
|
||||
const auto timelineMousePosY = mousePos.y - ImGui::GetWindowPos().y;
|
||||
|
||||
int yBegin = 0;
|
||||
int yEnd = 0;
|
||||
int yEnd = m_pinnedTop;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
if( item->IsPinned() ) continue;
|
||||
yBegin = yEnd;
|
||||
yEnd += item->GetHeight();
|
||||
|
||||
@@ -101,6 +115,19 @@ std::optional<int> TimelineController::CalculateScrollPosition() const
|
||||
|
||||
void TimelineController::End( double pxns, const ImVec2& wpos, bool hover, bool vcenter, float yMin, float yMax )
|
||||
{
|
||||
// Pinned tracks are lifted out of the scrolling flow and drawn fixed to the
|
||||
// top (queues/threads) or bottom (plots) of the viewport. Heights are the
|
||||
// previous frame's values (zero on the first frame); items still animate.
|
||||
int pinnedTop = 0;
|
||||
int pinnedBottom = 0;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
if( !item->IsPinned() ) continue;
|
||||
if( item->PinToBottom() ) pinnedBottom += item->GetHeight();
|
||||
else pinnedTop += item->GetHeight();
|
||||
}
|
||||
m_pinnedTop = pinnedTop;
|
||||
|
||||
auto shouldUpdateCenterItem = [&] () {
|
||||
const auto imguiChangedScroll = m_scroll != ImGui::GetScrollY();
|
||||
const auto& mouseDelta = ImGui::GetIO().MouseDelta;
|
||||
@@ -138,28 +165,84 @@ void TimelineController::End( double pxns, const ImVec2& wpos, bool hover, bool
|
||||
ctx.wpos = wpos;
|
||||
ctx.hover = hover;
|
||||
|
||||
int yOffset = 0;
|
||||
const int curScrollY = (int)ImGui::GetScrollY();
|
||||
const int windowHeight = (int)ImGui::GetWindowHeight();
|
||||
const int bottomStart = curScrollY + windowHeight - pinnedBottom;
|
||||
|
||||
// Content-space Y offset an item is drawn at. Pinned items compensate for the
|
||||
// scroll position so they stay fixed in the viewport; normal items flow in the
|
||||
// middle band, below the pinned-top band.
|
||||
auto itemYOffset = [&] ( TimelineItem* item, int topRun, int normalRun, int bottomRun ) -> int {
|
||||
if( !item->IsPinned() ) return pinnedTop + normalRun;
|
||||
return item->PinToBottom() ? bottomStart + bottomRun : curScrollY + topRun;
|
||||
};
|
||||
|
||||
int topOffset = 0, normalOffset = 0, bottomOffset = 0;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
const int off = itemYOffset( item, topOffset, normalOffset, bottomOffset );
|
||||
if( item->WantPreprocess() && item->IsVisible() )
|
||||
{
|
||||
const auto yPos = wpos.y + yOffset;
|
||||
const bool visible = m_firstFrame || ( yPos < yMax && yPos + item->GetHeight() >= yMin );
|
||||
const auto yPos = wpos.y + off;
|
||||
const bool visible = item->IsPinned() || m_firstFrame || ( yPos < yMax && yPos + item->GetHeight() >= yMin );
|
||||
item->Preprocess( ctx, m_td, visible, yPos );
|
||||
}
|
||||
yOffset += m_firstFrame ? 0 : item->GetHeight();
|
||||
const int h = m_firstFrame ? 0 : item->GetHeight();
|
||||
if( !item->IsPinned() ) normalOffset += h;
|
||||
else if( item->PinToBottom() ) bottomOffset += h;
|
||||
else topOffset += h;
|
||||
}
|
||||
m_td.Sync();
|
||||
|
||||
yOffset = 0;
|
||||
auto draw = ImGui::GetWindowDrawList();
|
||||
const auto bgColor = ImGui::GetColorU32( ImGuiCol_WindowBg );
|
||||
|
||||
// Normal (middle) items. Cull headers to the band between the pinned regions,
|
||||
// and suppress interaction whenever the mouse is over a pinned band, so tracks
|
||||
// scrolling underneath a pinned band stay inert.
|
||||
TimelineContext ctxNormal = ctx;
|
||||
if( pinnedTop > 0 ) ctxNormal.yMin = std::max<float>( ctx.yMin, wpos.y + curScrollY + pinnedTop );
|
||||
if( pinnedBottom > 0 ) ctxNormal.yMax = std::min<float>( ctx.yMax, wpos.y + bottomStart );
|
||||
const auto mouseY = ImGui::GetMousePos().y;
|
||||
const bool mouseInTopBand = pinnedTop > 0 && mouseY >= wpos.y + curScrollY && mouseY < wpos.y + curScrollY + pinnedTop;
|
||||
const bool mouseInBottomBand = pinnedBottom > 0 && mouseY >= wpos.y + bottomStart && mouseY < wpos.y + curScrollY + windowHeight;
|
||||
ctxNormal.hover = ctx.hover && !mouseInTopBand && !mouseInBottomBand;
|
||||
int normalRunning = 0;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
auto currentFrameItemHeight = item->GetHeight();
|
||||
item->Draw( m_firstFrame, ctx, yOffset );
|
||||
if( m_firstFrame ) currentFrameItemHeight = item->GetHeight();
|
||||
yOffset += currentFrameItemHeight;
|
||||
if( item->IsPinned() ) continue;
|
||||
auto h = item->GetHeight();
|
||||
item->Draw( m_firstFrame, ctxNormal, pinnedTop + normalRunning );
|
||||
if( m_firstFrame ) h = item->GetHeight();
|
||||
normalRunning += h;
|
||||
}
|
||||
|
||||
// Pinned-top band (queues/threads), fixed at the viewport top.
|
||||
if( pinnedTop > 0 ) draw->AddRectFilled( ImVec2( wpos.x, wpos.y + curScrollY ), ImVec2( wpos.x + ctx.w, wpos.y + curScrollY + pinnedTop ), bgColor );
|
||||
int topRunning = 0;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
if( !item->IsPinned() || item->PinToBottom() ) continue;
|
||||
auto h = item->GetHeight();
|
||||
item->Draw( m_firstFrame, ctx, curScrollY + topRunning );
|
||||
if( m_firstFrame ) h = item->GetHeight();
|
||||
topRunning += h;
|
||||
}
|
||||
|
||||
// Pinned-bottom band (plots), fixed at the viewport bottom.
|
||||
if( pinnedBottom > 0 ) draw->AddRectFilled( ImVec2( wpos.x, wpos.y + bottomStart ), ImVec2( wpos.x + ctx.w, wpos.y + curScrollY + windowHeight ), bgColor );
|
||||
int bottomRunning = 0;
|
||||
for( auto& item : m_items )
|
||||
{
|
||||
if( !item->IsPinned() || !item->PinToBottom() ) continue;
|
||||
auto h = item->GetHeight();
|
||||
item->Draw( m_firstFrame, ctx, bottomStart + bottomRunning );
|
||||
if( m_firstFrame ) h = item->GetHeight();
|
||||
bottomRunning += h;
|
||||
}
|
||||
|
||||
int yOffset = pinnedTop + normalRunning + pinnedBottom;
|
||||
|
||||
if( const auto scrollY = CalculateScrollPosition() )
|
||||
{
|
||||
int clampedScrollY = std::min<int>( *scrollY, std::max<int>( yOffset - ImGui::GetWindowHeight(), 0 ) );
|
||||
|
||||
@@ -58,6 +58,8 @@ private:
|
||||
const void* m_centerItemkey;
|
||||
int m_centerItemOffsetY;
|
||||
|
||||
int m_pinnedTop;
|
||||
|
||||
bool m_firstFrame;
|
||||
|
||||
View& m_view;
|
||||
|
||||
@@ -108,6 +108,15 @@ struct LockDraw
|
||||
std::vector<LockDrawItem> data;
|
||||
};
|
||||
|
||||
struct LockHighlight
|
||||
{
|
||||
int64_t id;
|
||||
int64_t begin;
|
||||
int64_t end;
|
||||
uint8_t thread;
|
||||
bool blocked;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace tracy
|
||||
TimelineItem::TimelineItem( View& view, Worker& worker, const void* key, bool wantPreprocess )
|
||||
: m_visible( true )
|
||||
, m_showFull( true )
|
||||
, m_pinned( false )
|
||||
, m_height( 0 )
|
||||
, m_wantPreprocess( wantPreprocess )
|
||||
, m_key( key )
|
||||
@@ -121,6 +122,11 @@ void TimelineItem::Draw( bool firstFrame, const TimelineContext& ctx, int yOffse
|
||||
SetVisible( false );
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if( ImGui::MenuItem( m_pinned ? ICON_FA_THUMBTACK_SLASH " Unpin" : ICON_FA_THUMBTACK " Pin" ) )
|
||||
{
|
||||
m_pinned = !m_pinned;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
DrawExtraPopupItems();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,12 @@ public:
|
||||
virtual void SetVisible( bool visible ) { m_visible = visible; }
|
||||
virtual bool IsVisible() const { return m_visible; }
|
||||
|
||||
void SetPinned( bool pinned ) { m_pinned = pinned; }
|
||||
bool IsPinned() const { return m_pinned; }
|
||||
// Pinned items are lifted out of the scrolling flow: false keeps them fixed
|
||||
// at the top of the viewport (queues/threads), true at the bottom (plots).
|
||||
virtual bool PinToBottom() const { return false; }
|
||||
|
||||
void SetShowFull( bool showFull ) { m_showFull = showFull; }
|
||||
|
||||
// returns 0 instead of the correct value for the first frame
|
||||
@@ -58,6 +64,7 @@ protected:
|
||||
|
||||
bool m_visible;
|
||||
bool m_showFull;
|
||||
bool m_pinned;
|
||||
|
||||
private:
|
||||
void AdjustThreadHeight( bool firstFrame, int yBegin, int yEnd );
|
||||
|
||||
@@ -19,6 +19,8 @@ protected:
|
||||
uint32_t HeaderLineColor() const override { return 0x8844DDDD; }
|
||||
const char* HeaderLabel() const override;
|
||||
|
||||
bool PinToBottom() const override { return true; }
|
||||
|
||||
int64_t RangeBegin() const override;
|
||||
int64_t RangeEnd() const override;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "TracyMarkdown.hpp"
|
||||
#include "TracySourceContents.hpp"
|
||||
#include "TracyTimelineController.hpp"
|
||||
#include "TracyTimelineDraw.hpp"
|
||||
#include "TracyUserData.hpp"
|
||||
#include "TracyUtility.hpp"
|
||||
#include "TracyViewData.hpp"
|
||||
|
||||
@@ -372,15 +372,6 @@ struct LockMap
|
||||
TimeRange range[64];
|
||||
};
|
||||
|
||||
struct LockHighlight
|
||||
{
|
||||
int64_t id;
|
||||
int64_t begin;
|
||||
int64_t end;
|
||||
uint8_t thread;
|
||||
bool blocked;
|
||||
};
|
||||
|
||||
|
||||
struct GpuEvent
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user