mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Extract frames timeline UI from View.
This commit is contained in:
parent
0d41a6c48b
commit
7b04d8c0b3
@ -145,6 +145,7 @@
|
|||||||
<ClCompile Include="..\..\..\server\TracyView_CpuData.cpp" />
|
<ClCompile Include="..\..\..\server\TracyView_CpuData.cpp" />
|
||||||
<ClCompile Include="..\..\..\server\TracyView_FindZone.cpp" />
|
<ClCompile Include="..\..\..\server\TracyView_FindZone.cpp" />
|
||||||
<ClCompile Include="..\..\..\server\TracyView_FrameOverview.cpp" />
|
<ClCompile Include="..\..\..\server\TracyView_FrameOverview.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\server\TracyView_FrameTimeline.cpp" />
|
||||||
<ClCompile Include="..\..\..\server\TracyView_FrameTree.cpp" />
|
<ClCompile Include="..\..\..\server\TracyView_FrameTree.cpp" />
|
||||||
<ClCompile Include="..\..\..\server\TracyView_Locks.cpp" />
|
<ClCompile Include="..\..\..\server\TracyView_Locks.cpp" />
|
||||||
<ClCompile Include="..\..\..\server\TracyView_Memory.cpp" />
|
<ClCompile Include="..\..\..\server\TracyView_Memory.cpp" />
|
||||||
|
|||||||
@ -312,6 +312,9 @@
|
|||||||
<ClCompile Include="..\..\..\server\TracyView_Locks.cpp">
|
<ClCompile Include="..\..\..\server\TracyView_Locks.cpp">
|
||||||
<Filter>server</Filter>
|
<Filter>server</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\server\TracyView_FrameTimeline.cpp">
|
||||||
|
<Filter>server</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\common\tracy_lz4.hpp">
|
<ClInclude Include="..\..\..\common\tracy_lz4.hpp">
|
||||||
|
|||||||
@ -59,7 +59,6 @@ namespace tracy
|
|||||||
double s_time = 0;
|
double s_time = 0;
|
||||||
|
|
||||||
enum { MinVisSize = 3 };
|
enum { MinVisSize = 3 };
|
||||||
enum { MinFrameSize = 5 };
|
|
||||||
|
|
||||||
static View* s_instance = nullptr;
|
static View* s_instance = nullptr;
|
||||||
|
|
||||||
@ -1412,72 +1411,6 @@ void View::HandleZoneViewMouse( int64_t timespan, const ImVec2& wpos, float w, d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::DrawZoneFramesHeader()
|
|
||||||
{
|
|
||||||
const auto wpos = ImGui::GetCursorScreenPos();
|
|
||||||
const auto dpos = wpos + ImVec2( 0.5f, 0.5f );
|
|
||||||
const auto w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize;
|
|
||||||
auto draw = ImGui::GetWindowDrawList();
|
|
||||||
const auto ty = ImGui::GetTextLineHeight();
|
|
||||||
const auto ty025 = round( ty * 0.25f );
|
|
||||||
const auto ty0375 = round( ty * 0.375f );
|
|
||||||
const auto ty05 = round( ty * 0.5f );
|
|
||||||
|
|
||||||
const auto timespan = m_vd.zvEnd - m_vd.zvStart;
|
|
||||||
const auto pxns = w / double( timespan );
|
|
||||||
const auto nspx = 1.0 / pxns;
|
|
||||||
const auto scale = std::max( 0.0, round( log10( nspx ) + 2 ) );
|
|
||||||
const auto step = pow( 10, scale );
|
|
||||||
|
|
||||||
ImGui::InvisibleButton( "##zoneFrames", ImVec2( w, ty * 1.5f ) );
|
|
||||||
TooltipIfHovered( TimeToStringExact( m_vd.zvStart + ( ImGui::GetIO().MousePos.x - wpos.x ) * nspx ) );
|
|
||||||
|
|
||||||
const auto dx = step * pxns;
|
|
||||||
double x = 0;
|
|
||||||
int tw = 0;
|
|
||||||
int tx = 0;
|
|
||||||
int64_t tt = 0;
|
|
||||||
while( x < w )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( x, 0 ), dpos + ImVec2( x, ty05 ), 0x66FFFFFF );
|
|
||||||
if( tw == 0 )
|
|
||||||
{
|
|
||||||
char buf[128];
|
|
||||||
auto txt = TimeToStringExact( m_vd.zvStart );
|
|
||||||
if( m_vd.zvStart >= 0 )
|
|
||||||
{
|
|
||||||
sprintf( buf, "+%s", txt );
|
|
||||||
txt = buf;
|
|
||||||
}
|
|
||||||
draw->AddText( wpos + ImVec2( x, ty05 ), 0x66FFFFFF, txt );
|
|
||||||
tw = ImGui::CalcTextSize( txt ).x;
|
|
||||||
}
|
|
||||||
else if( x > tx + tw + ty * 2 )
|
|
||||||
{
|
|
||||||
tx = x;
|
|
||||||
auto txt = TimeToString( tt );
|
|
||||||
draw->AddText( wpos + ImVec2( x, ty05 ), 0x66FFFFFF, txt );
|
|
||||||
tw = ImGui::CalcTextSize( txt ).x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( scale != 0 )
|
|
||||||
{
|
|
||||||
for( int i=1; i<5; i++ )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( x + i * dx / 10, 0 ), dpos + ImVec2( x + i * dx / 10, ty025 ), 0x33FFFFFF );
|
|
||||||
}
|
|
||||||
DrawLine( draw, dpos + ImVec2( x + 5 * dx / 10, 0 ), dpos + ImVec2( x + 5 * dx / 10, ty0375 ), 0x33FFFFFF );
|
|
||||||
for( int i=6; i<10; i++ )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( x + i * dx / 10, 0 ), dpos + ImVec2( x + i * dx / 10, ty025 ), 0x33FFFFFF );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x += dx;
|
|
||||||
tt += step;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t MixGhostColor( uint32_t c0, uint32_t c1 )
|
static uint32_t MixGhostColor( uint32_t c0, uint32_t c1 )
|
||||||
{
|
{
|
||||||
return 0xFF000000 |
|
return 0xFF000000 |
|
||||||
@ -1486,257 +1419,6 @@ static uint32_t MixGhostColor( uint32_t c0, uint32_t c1 )
|
|||||||
( ( ( ( ( c0 & 0x000000FF ) ) + 3 * ( ( c1 & 0x000000FF ) ) ) >> 2 ) );
|
( ( ( ( ( c0 & 0x000000FF ) ) + 3 * ( ( c1 & 0x000000FF ) ) ) >> 2 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t GetColorMuted( uint32_t color, bool active )
|
|
||||||
{
|
|
||||||
if( active )
|
|
||||||
{
|
|
||||||
return 0xFF000000 | color;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0x66000000 | color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void View::DrawZoneFrames( const FrameData& frames )
|
|
||||||
{
|
|
||||||
const auto wpos = ImGui::GetCursorScreenPos();
|
|
||||||
const auto dpos = wpos + ImVec2( 0.5f, 0.5f );
|
|
||||||
const auto w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize;
|
|
||||||
const auto wh = ImGui::GetContentRegionAvail().y;
|
|
||||||
auto draw = ImGui::GetWindowDrawList();
|
|
||||||
const auto ty = ImGui::GetTextLineHeight();
|
|
||||||
const auto ty025 = ty * 0.25f;
|
|
||||||
const auto ty05 = round( ty * 0.5f );
|
|
||||||
|
|
||||||
ImGui::InvisibleButton( "##zoneFrames", ImVec2( w, ty ) );
|
|
||||||
bool hover = ImGui::IsItemHovered();
|
|
||||||
|
|
||||||
auto timespan = m_vd.zvEnd - m_vd.zvStart;
|
|
||||||
auto pxns = w / double( timespan );
|
|
||||||
|
|
||||||
const auto nspx = 1.0 / pxns;
|
|
||||||
|
|
||||||
const std::pair <int, int> zrange = m_worker.GetFrameRange( frames, m_vd.zvStart, m_vd.zvEnd );
|
|
||||||
if( zrange.first < 0 ) return;
|
|
||||||
|
|
||||||
int64_t prev = -1;
|
|
||||||
int64_t prevEnd = -1;
|
|
||||||
int64_t endPos = -1;
|
|
||||||
bool tooltipDisplayed = false;
|
|
||||||
const auto activeFrameSet = m_frames == &frames;
|
|
||||||
const int64_t frameTarget = ( activeFrameSet && m_vd.drawFrameTargets ) ? 1000000000ll / m_vd.frameTarget : std::numeric_limits<int64_t>::max();
|
|
||||||
|
|
||||||
const auto inactiveColor = GetColorMuted( 0x888888, activeFrameSet );
|
|
||||||
const auto activeColor = GetColorMuted( 0xFFFFFF, activeFrameSet );
|
|
||||||
const auto redColor = GetColorMuted( 0x4444FF, activeFrameSet );
|
|
||||||
|
|
||||||
int i = zrange.first;
|
|
||||||
auto x1 = ( m_worker.GetFrameBegin( frames, i ) - m_vd.zvStart ) * pxns;
|
|
||||||
while( i < zrange.second )
|
|
||||||
{
|
|
||||||
const auto ftime = m_worker.GetFrameTime( frames, i );
|
|
||||||
const auto fbegin = m_worker.GetFrameBegin( frames, i );
|
|
||||||
const auto fend = m_worker.GetFrameEnd( frames, i );
|
|
||||||
const auto fsz = pxns * ftime;
|
|
||||||
|
|
||||||
if( hover )
|
|
||||||
{
|
|
||||||
const auto x0 = frames.continuous ? x1 : ( fbegin - m_vd.zvStart ) * pxns;
|
|
||||||
x1 = ( fend - m_vd.zvStart ) * pxns;
|
|
||||||
if( ImGui::IsMouseHoveringRect( wpos + ImVec2( x0, 0 ), wpos + ImVec2( x1, ty ) ) )
|
|
||||||
{
|
|
||||||
tooltipDisplayed = true;
|
|
||||||
if( IsMouseClickReleased( 1 ) ) m_setRangePopup = RangeSlim { fbegin, fend, true };
|
|
||||||
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::TextUnformatted( GetFrameText( frames, i, ftime, m_worker.GetFrameOffset() ) );
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextDisabled( "(%.1f FPS)", 1000000000.0 / ftime );
|
|
||||||
TextFocused( "Time from start of program:", TimeToStringExact( m_worker.GetFrameBegin( frames, i ) ) );
|
|
||||||
auto fi = m_worker.GetFrameImage( frames, i );
|
|
||||||
if( fi )
|
|
||||||
{
|
|
||||||
const auto scale = GetScale();
|
|
||||||
if( fi != m_frameTexturePtr )
|
|
||||||
{
|
|
||||||
if( !m_frameTexture ) m_frameTexture = MakeTexture();
|
|
||||||
UpdateTexture( m_frameTexture, m_worker.UnpackFrameImage( *fi ), fi->w, fi->h );
|
|
||||||
m_frameTexturePtr = fi;
|
|
||||||
}
|
|
||||||
ImGui::Separator();
|
|
||||||
if( fi->flip )
|
|
||||||
{
|
|
||||||
ImGui::Image( m_frameTexture, ImVec2( fi->w * scale, fi->h * scale ), ImVec2( 0, 1 ), ImVec2( 1, 0 ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui::Image( m_frameTexture, ImVec2( fi->w * scale, fi->h * scale ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ImGui::GetIO().KeyCtrl && IsMouseClicked( 0 ) )
|
|
||||||
{
|
|
||||||
m_showPlayback = true;
|
|
||||||
m_playback.pause = true;
|
|
||||||
SetPlaybackFrame( frames.frames[i].frameImage );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
|
|
||||||
if( IsMouseClicked( 2 ) )
|
|
||||||
{
|
|
||||||
ZoomToRange( fbegin, fend );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( activeFrameSet ) m_frameHover = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fsz < MinFrameSize )
|
|
||||||
{
|
|
||||||
if( !frames.continuous && prev != -1 )
|
|
||||||
{
|
|
||||||
if( ( fbegin - prevEnd ) * pxns >= MinFrameSize )
|
|
||||||
{
|
|
||||||
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( prevEnd - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
|
||||||
prev = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prevEnd = std::max<int64_t>( fend, fbegin + MinFrameSize * nspx );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( prev == -1 )
|
|
||||||
{
|
|
||||||
prev = fbegin;
|
|
||||||
prevEnd = std::max<int64_t>( fend, fbegin + MinFrameSize * nspx );
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto begin = frames.frames.begin() + i;
|
|
||||||
const auto end = frames.frames.begin() + zrange.second;
|
|
||||||
auto it = std::lower_bound( begin, end, int64_t( fbegin + MinVisSize * nspx ), [this, &frames] ( const auto& l, const auto& r ) { return m_worker.GetFrameEnd( frames, std::distance( frames.frames.begin(), &l ) ) < r; } );
|
|
||||||
if( it == begin ) ++it;
|
|
||||||
i += std::distance( begin, it );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( prev != -1 )
|
|
||||||
{
|
|
||||||
if( frames.continuous )
|
|
||||||
{
|
|
||||||
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( fbegin - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( prevEnd - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
|
||||||
}
|
|
||||||
prev = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( activeFrameSet )
|
|
||||||
{
|
|
||||||
if( fend - fbegin > frameTarget )
|
|
||||||
{
|
|
||||||
draw->AddRectFilled( wpos + ImVec2( ( fbegin + frameTarget - m_vd.zvStart ) * pxns, 0 ), wpos + ImVec2( ( fend - m_vd.zvStart ) * pxns, wh ), 0x224444FF );
|
|
||||||
}
|
|
||||||
if( fbegin >= m_vd.zvStart && endPos != fbegin )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns, 0 ), dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns, wh ), 0x22FFFFFF );
|
|
||||||
}
|
|
||||||
if( fend <= m_vd.zvEnd )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns, 0 ), dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns, wh ), 0x22FFFFFF );
|
|
||||||
}
|
|
||||||
endPos = fend;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto buf = GetFrameText( frames, i, ftime, m_worker.GetFrameOffset() );
|
|
||||||
auto tx = ImGui::CalcTextSize( buf ).x;
|
|
||||||
uint32_t color = ( frames.name == 0 && i == 0 ) ? redColor : activeColor;
|
|
||||||
|
|
||||||
if( fsz - 7 <= tx )
|
|
||||||
{
|
|
||||||
static char tmp[256];
|
|
||||||
sprintf( tmp, "%s (%s)", RealToString( i ), TimeToString( ftime ) );
|
|
||||||
buf = tmp;
|
|
||||||
tx = ImGui::CalcTextSize( buf ).x;
|
|
||||||
}
|
|
||||||
if( fsz - 7 <= tx )
|
|
||||||
{
|
|
||||||
buf = TimeToString( ftime );
|
|
||||||
tx = ImGui::CalcTextSize( buf ).x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fbegin >= m_vd.zvStart )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns + 2, 1 ), dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns + 2, ty - 1 ), color );
|
|
||||||
}
|
|
||||||
if( fend <= m_vd.zvEnd )
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns - 2, 1 ), dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns - 2, ty - 1 ), color );
|
|
||||||
}
|
|
||||||
if( fsz - 7 > tx )
|
|
||||||
{
|
|
||||||
const auto f0 = ( fbegin - m_vd.zvStart ) * pxns + 2;
|
|
||||||
const auto f1 = ( fend - m_vd.zvStart ) * pxns - 2;
|
|
||||||
const auto x0 = f0 + 1;
|
|
||||||
const auto x1 = f1 - 1;
|
|
||||||
const auto te = x1 - tx;
|
|
||||||
|
|
||||||
auto tpos = ( x0 + te ) / 2;
|
|
||||||
if( tpos < 0 )
|
|
||||||
{
|
|
||||||
tpos = std::min( std::min( 0., te - tpos ), te );
|
|
||||||
}
|
|
||||||
else if( tpos > w - tx )
|
|
||||||
{
|
|
||||||
tpos = std::max( double( w - tx ), x0 );
|
|
||||||
}
|
|
||||||
tpos = round( tpos );
|
|
||||||
|
|
||||||
DrawLine( draw, dpos + ImVec2( std::max( -10.0, f0 ), ty05 ), dpos + ImVec2( tpos, ty05 ), color );
|
|
||||||
DrawLine( draw, dpos + ImVec2( std::max( -10.0, tpos + tx + 1 ), ty05 ), dpos + ImVec2( std::min( w + 20.0, f1 ), ty05 ), color );
|
|
||||||
draw->AddText( wpos + ImVec2( tpos, 0 ), color, buf );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawLine( draw, dpos + ImVec2( std::max( -10.0, ( fbegin - m_vd.zvStart ) * pxns + 2 ), ty05 ), dpos + ImVec2( std::min( w + 20.0, ( fend - m_vd.zvStart ) * pxns - 2 ), ty05 ), color );
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( prev != -1 )
|
|
||||||
{
|
|
||||||
if( frames.continuous )
|
|
||||||
{
|
|
||||||
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( m_worker.GetFrameBegin( frames, zrange.second-1 ) - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto begin = ( prev - m_vd.zvStart ) * pxns;
|
|
||||||
const auto end = ( m_worker.GetFrameBegin( frames, zrange.second-1 ) - m_vd.zvStart ) * pxns;
|
|
||||||
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), begin, std::max( begin + MinFrameSize, end ), ty025, inactiveColor );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( hover )
|
|
||||||
{
|
|
||||||
if( !tooltipDisplayed )
|
|
||||||
{
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
TextDisabledUnformatted( "Frame set:" );
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextUnformatted( frames.name == 0 ? "Frames" : m_worker.GetString( frames.name ) );
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
if( IsMouseClicked( 0 ) )
|
|
||||||
{
|
|
||||||
m_frames = &frames;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float View::AdjustThreadPosition( View::VisData& vis, float wy, int& offset )
|
float View::AdjustThreadPosition( View::VisData& vis, float wy, int& offset )
|
||||||
{
|
{
|
||||||
if( vis.offset < offset )
|
if( vis.offset < offset )
|
||||||
|
|||||||
330
server/TracyView_FrameTimeline.cpp
Normal file
330
server/TracyView_FrameTimeline.cpp
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "TracyMouse.hpp"
|
||||||
|
#include "TracyPrint.hpp"
|
||||||
|
#include "TracyView.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
enum { MinVisSize = 3 };
|
||||||
|
enum { MinFrameSize = 5 };
|
||||||
|
|
||||||
|
static tracy_force_inline uint32_t GetColorMuted( uint32_t color, bool active )
|
||||||
|
{
|
||||||
|
if( active )
|
||||||
|
{
|
||||||
|
return 0xFF000000 | color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0x66000000 | color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::DrawZoneFramesHeader()
|
||||||
|
{
|
||||||
|
const auto wpos = ImGui::GetCursorScreenPos();
|
||||||
|
const auto dpos = wpos + ImVec2( 0.5f, 0.5f );
|
||||||
|
const auto w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize;
|
||||||
|
auto draw = ImGui::GetWindowDrawList();
|
||||||
|
const auto ty = ImGui::GetTextLineHeight();
|
||||||
|
const auto ty025 = round( ty * 0.25f );
|
||||||
|
const auto ty0375 = round( ty * 0.375f );
|
||||||
|
const auto ty05 = round( ty * 0.5f );
|
||||||
|
|
||||||
|
const auto timespan = m_vd.zvEnd - m_vd.zvStart;
|
||||||
|
const auto pxns = w / double( timespan );
|
||||||
|
const auto nspx = 1.0 / pxns;
|
||||||
|
const auto scale = std::max( 0.0, round( log10( nspx ) + 2 ) );
|
||||||
|
const auto step = pow( 10, scale );
|
||||||
|
|
||||||
|
ImGui::InvisibleButton( "##zoneFrames", ImVec2( w, ty * 1.5f ) );
|
||||||
|
TooltipIfHovered( TimeToStringExact( m_vd.zvStart + ( ImGui::GetIO().MousePos.x - wpos.x ) * nspx ) );
|
||||||
|
|
||||||
|
const auto dx = step * pxns;
|
||||||
|
double x = 0;
|
||||||
|
int tw = 0;
|
||||||
|
int tx = 0;
|
||||||
|
int64_t tt = 0;
|
||||||
|
while( x < w )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( x, 0 ), dpos + ImVec2( x, ty05 ), 0x66FFFFFF );
|
||||||
|
if( tw == 0 )
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
auto txt = TimeToStringExact( m_vd.zvStart );
|
||||||
|
if( m_vd.zvStart >= 0 )
|
||||||
|
{
|
||||||
|
sprintf( buf, "+%s", txt );
|
||||||
|
txt = buf;
|
||||||
|
}
|
||||||
|
draw->AddText( wpos + ImVec2( x, ty05 ), 0x66FFFFFF, txt );
|
||||||
|
tw = ImGui::CalcTextSize( txt ).x;
|
||||||
|
}
|
||||||
|
else if( x > tx + tw + ty * 2 )
|
||||||
|
{
|
||||||
|
tx = x;
|
||||||
|
auto txt = TimeToString( tt );
|
||||||
|
draw->AddText( wpos + ImVec2( x, ty05 ), 0x66FFFFFF, txt );
|
||||||
|
tw = ImGui::CalcTextSize( txt ).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( scale != 0 )
|
||||||
|
{
|
||||||
|
for( int i=1; i<5; i++ )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( x + i * dx / 10, 0 ), dpos + ImVec2( x + i * dx / 10, ty025 ), 0x33FFFFFF );
|
||||||
|
}
|
||||||
|
DrawLine( draw, dpos + ImVec2( x + 5 * dx / 10, 0 ), dpos + ImVec2( x + 5 * dx / 10, ty0375 ), 0x33FFFFFF );
|
||||||
|
for( int i=6; i<10; i++ )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( x + i * dx / 10, 0 ), dpos + ImVec2( x + i * dx / 10, ty025 ), 0x33FFFFFF );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x += dx;
|
||||||
|
tt += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::DrawZoneFrames( const FrameData& frames )
|
||||||
|
{
|
||||||
|
const auto wpos = ImGui::GetCursorScreenPos();
|
||||||
|
const auto dpos = wpos + ImVec2( 0.5f, 0.5f );
|
||||||
|
const auto w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize;
|
||||||
|
const auto wh = ImGui::GetContentRegionAvail().y;
|
||||||
|
auto draw = ImGui::GetWindowDrawList();
|
||||||
|
const auto ty = ImGui::GetTextLineHeight();
|
||||||
|
const auto ty025 = ty * 0.25f;
|
||||||
|
const auto ty05 = round( ty * 0.5f );
|
||||||
|
|
||||||
|
ImGui::InvisibleButton( "##zoneFrames", ImVec2( w, ty ) );
|
||||||
|
bool hover = ImGui::IsItemHovered();
|
||||||
|
|
||||||
|
auto timespan = m_vd.zvEnd - m_vd.zvStart;
|
||||||
|
auto pxns = w / double( timespan );
|
||||||
|
|
||||||
|
const auto nspx = 1.0 / pxns;
|
||||||
|
|
||||||
|
const std::pair <int, int> zrange = m_worker.GetFrameRange( frames, m_vd.zvStart, m_vd.zvEnd );
|
||||||
|
if( zrange.first < 0 ) return;
|
||||||
|
|
||||||
|
int64_t prev = -1;
|
||||||
|
int64_t prevEnd = -1;
|
||||||
|
int64_t endPos = -1;
|
||||||
|
bool tooltipDisplayed = false;
|
||||||
|
const auto activeFrameSet = m_frames == &frames;
|
||||||
|
const int64_t frameTarget = ( activeFrameSet && m_vd.drawFrameTargets ) ? 1000000000ll / m_vd.frameTarget : std::numeric_limits<int64_t>::max();
|
||||||
|
|
||||||
|
const auto inactiveColor = GetColorMuted( 0x888888, activeFrameSet );
|
||||||
|
const auto activeColor = GetColorMuted( 0xFFFFFF, activeFrameSet );
|
||||||
|
const auto redColor = GetColorMuted( 0x4444FF, activeFrameSet );
|
||||||
|
|
||||||
|
int i = zrange.first;
|
||||||
|
auto x1 = ( m_worker.GetFrameBegin( frames, i ) - m_vd.zvStart ) * pxns;
|
||||||
|
while( i < zrange.second )
|
||||||
|
{
|
||||||
|
const auto ftime = m_worker.GetFrameTime( frames, i );
|
||||||
|
const auto fbegin = m_worker.GetFrameBegin( frames, i );
|
||||||
|
const auto fend = m_worker.GetFrameEnd( frames, i );
|
||||||
|
const auto fsz = pxns * ftime;
|
||||||
|
|
||||||
|
if( hover )
|
||||||
|
{
|
||||||
|
const auto x0 = frames.continuous ? x1 : ( fbegin - m_vd.zvStart ) * pxns;
|
||||||
|
x1 = ( fend - m_vd.zvStart ) * pxns;
|
||||||
|
if( ImGui::IsMouseHoveringRect( wpos + ImVec2( x0, 0 ), wpos + ImVec2( x1, ty ) ) )
|
||||||
|
{
|
||||||
|
tooltipDisplayed = true;
|
||||||
|
if( IsMouseClickReleased( 1 ) ) m_setRangePopup = RangeSlim { fbegin, fend, true };
|
||||||
|
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::TextUnformatted( GetFrameText( frames, i, ftime, m_worker.GetFrameOffset() ) );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled( "(%.1f FPS)", 1000000000.0 / ftime );
|
||||||
|
TextFocused( "Time from start of program:", TimeToStringExact( m_worker.GetFrameBegin( frames, i ) ) );
|
||||||
|
auto fi = m_worker.GetFrameImage( frames, i );
|
||||||
|
if( fi )
|
||||||
|
{
|
||||||
|
const auto scale = GetScale();
|
||||||
|
if( fi != m_frameTexturePtr )
|
||||||
|
{
|
||||||
|
if( !m_frameTexture ) m_frameTexture = MakeTexture();
|
||||||
|
UpdateTexture( m_frameTexture, m_worker.UnpackFrameImage( *fi ), fi->w, fi->h );
|
||||||
|
m_frameTexturePtr = fi;
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if( fi->flip )
|
||||||
|
{
|
||||||
|
ImGui::Image( m_frameTexture, ImVec2( fi->w * scale, fi->h * scale ), ImVec2( 0, 1 ), ImVec2( 1, 0 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::Image( m_frameTexture, ImVec2( fi->w * scale, fi->h * scale ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ImGui::GetIO().KeyCtrl && IsMouseClicked( 0 ) )
|
||||||
|
{
|
||||||
|
m_showPlayback = true;
|
||||||
|
m_playback.pause = true;
|
||||||
|
SetPlaybackFrame( frames.frames[i].frameImage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
|
||||||
|
if( IsMouseClicked( 2 ) )
|
||||||
|
{
|
||||||
|
ZoomToRange( fbegin, fend );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( activeFrameSet ) m_frameHover = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fsz < MinFrameSize )
|
||||||
|
{
|
||||||
|
if( !frames.continuous && prev != -1 )
|
||||||
|
{
|
||||||
|
if( ( fbegin - prevEnd ) * pxns >= MinFrameSize )
|
||||||
|
{
|
||||||
|
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( prevEnd - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
||||||
|
prev = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevEnd = std::max<int64_t>( fend, fbegin + MinFrameSize * nspx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( prev == -1 )
|
||||||
|
{
|
||||||
|
prev = fbegin;
|
||||||
|
prevEnd = std::max<int64_t>( fend, fbegin + MinFrameSize * nspx );
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto begin = frames.frames.begin() + i;
|
||||||
|
const auto end = frames.frames.begin() + zrange.second;
|
||||||
|
auto it = std::lower_bound( begin, end, int64_t( fbegin + MinVisSize * nspx ), [this, &frames] ( const auto& l, const auto& r ) { return m_worker.GetFrameEnd( frames, std::distance( frames.frames.begin(), &l ) ) < r; } );
|
||||||
|
if( it == begin ) ++it;
|
||||||
|
i += std::distance( begin, it );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( prev != -1 )
|
||||||
|
{
|
||||||
|
if( frames.continuous )
|
||||||
|
{
|
||||||
|
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( fbegin - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( prevEnd - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
||||||
|
}
|
||||||
|
prev = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( activeFrameSet )
|
||||||
|
{
|
||||||
|
if( fend - fbegin > frameTarget )
|
||||||
|
{
|
||||||
|
draw->AddRectFilled( wpos + ImVec2( ( fbegin + frameTarget - m_vd.zvStart ) * pxns, 0 ), wpos + ImVec2( ( fend - m_vd.zvStart ) * pxns, wh ), 0x224444FF );
|
||||||
|
}
|
||||||
|
if( fbegin >= m_vd.zvStart && endPos != fbegin )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns, 0 ), dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns, wh ), 0x22FFFFFF );
|
||||||
|
}
|
||||||
|
if( fend <= m_vd.zvEnd )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns, 0 ), dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns, wh ), 0x22FFFFFF );
|
||||||
|
}
|
||||||
|
endPos = fend;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buf = GetFrameText( frames, i, ftime, m_worker.GetFrameOffset() );
|
||||||
|
auto tx = ImGui::CalcTextSize( buf ).x;
|
||||||
|
uint32_t color = ( frames.name == 0 && i == 0 ) ? redColor : activeColor;
|
||||||
|
|
||||||
|
if( fsz - 7 <= tx )
|
||||||
|
{
|
||||||
|
static char tmp[256];
|
||||||
|
sprintf( tmp, "%s (%s)", RealToString( i ), TimeToString( ftime ) );
|
||||||
|
buf = tmp;
|
||||||
|
tx = ImGui::CalcTextSize( buf ).x;
|
||||||
|
}
|
||||||
|
if( fsz - 7 <= tx )
|
||||||
|
{
|
||||||
|
buf = TimeToString( ftime );
|
||||||
|
tx = ImGui::CalcTextSize( buf ).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fbegin >= m_vd.zvStart )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns + 2, 1 ), dpos + ImVec2( ( fbegin - m_vd.zvStart ) * pxns + 2, ty - 1 ), color );
|
||||||
|
}
|
||||||
|
if( fend <= m_vd.zvEnd )
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns - 2, 1 ), dpos + ImVec2( ( fend - m_vd.zvStart ) * pxns - 2, ty - 1 ), color );
|
||||||
|
}
|
||||||
|
if( fsz - 7 > tx )
|
||||||
|
{
|
||||||
|
const auto f0 = ( fbegin - m_vd.zvStart ) * pxns + 2;
|
||||||
|
const auto f1 = ( fend - m_vd.zvStart ) * pxns - 2;
|
||||||
|
const auto x0 = f0 + 1;
|
||||||
|
const auto x1 = f1 - 1;
|
||||||
|
const auto te = x1 - tx;
|
||||||
|
|
||||||
|
auto tpos = ( x0 + te ) / 2;
|
||||||
|
if( tpos < 0 )
|
||||||
|
{
|
||||||
|
tpos = std::min( std::min( 0., te - tpos ), te );
|
||||||
|
}
|
||||||
|
else if( tpos > w - tx )
|
||||||
|
{
|
||||||
|
tpos = std::max( double( w - tx ), x0 );
|
||||||
|
}
|
||||||
|
tpos = round( tpos );
|
||||||
|
|
||||||
|
DrawLine( draw, dpos + ImVec2( std::max( -10.0, f0 ), ty05 ), dpos + ImVec2( tpos, ty05 ), color );
|
||||||
|
DrawLine( draw, dpos + ImVec2( std::max( -10.0, tpos + tx + 1 ), ty05 ), dpos + ImVec2( std::min( w + 20.0, f1 ), ty05 ), color );
|
||||||
|
draw->AddText( wpos + ImVec2( tpos, 0 ), color, buf );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawLine( draw, dpos + ImVec2( std::max( -10.0, ( fbegin - m_vd.zvStart ) * pxns + 2 ), ty05 ), dpos + ImVec2( std::min( w + 20.0, ( fend - m_vd.zvStart ) * pxns - 2 ), ty05 ), color );
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( prev != -1 )
|
||||||
|
{
|
||||||
|
if( frames.continuous )
|
||||||
|
{
|
||||||
|
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), ( prev - m_vd.zvStart ) * pxns, ( m_worker.GetFrameBegin( frames, zrange.second-1 ) - m_vd.zvStart ) * pxns, ty025, inactiveColor );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto begin = ( prev - m_vd.zvStart ) * pxns;
|
||||||
|
const auto end = ( m_worker.GetFrameBegin( frames, zrange.second-1 ) - m_vd.zvStart ) * pxns;
|
||||||
|
DrawZigZag( draw, wpos + ImVec2( 0, ty05 ), begin, std::max( begin + MinFrameSize, end ), ty025, inactiveColor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( hover )
|
||||||
|
{
|
||||||
|
if( !tooltipDisplayed )
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
TextDisabledUnformatted( "Frame set:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted( frames.name == 0 ? "Frames" : m_worker.GetString( frames.name ) );
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
if( IsMouseClicked( 0 ) )
|
||||||
|
{
|
||||||
|
m_frames = &frames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user