@@ -162,6 +162,8 @@ Private Const ANT_DASH_SIZE As Single = 4!
162162Private Const ANT_DASH_SPEED_SLOW As Long = 200 'Frame time for marching ants animation, in ms; 200 = 5 fps (which is plenty)
163163Private Const ANT_DASH_SPEED_NORMAL As Long = 67 '15 fps (which is plenty)
164164Private Const ANT_DASH_SPEED_FAST As Long = 33 '30 fps (which is overkill)
165+ Private Const ANT_DASH_SPEED_MIN As Long = 16 '60 fps (potentially nonsense)
166+ Private Const ANT_DASH_ADAPTIVE_SPEED As Boolean = True 'New experiment: auto-determine ant speed based on render performance
165167Private m_AntDashes() As Single , m_AntDashOffset As Single
166168
167169'When in outline or marching ant rendering mode, the current on-screen outline (e.g. the selection outline *already transformed*
@@ -2574,7 +2576,7 @@ Private Sub CreateSelectionMask()
25742576 Else
25752577 m_WandImage.ResetDIB 0
25762578 End If
2577-
2579+ m_WandImage.SetInitialAlphaPremultiplicationState True
25782580 m_parentPDImage.GetCompositedImage m_WandImage
25792581
25802582 'In layer mode, however, we want to use the wand image *not* to store a copy of the
@@ -2588,6 +2590,7 @@ Private Sub CreateSelectionMask()
25882590 Else
25892591 m_WandImage.ResetDIB 0
25902592 End If
2593+ m_WandImage.SetInitialAlphaPremultiplicationState True
25912594
25922595 End If
25932596
@@ -4953,6 +4956,11 @@ Private Sub m_AntTimer_Timer()
49534956 'Disallow animations if an external object has forcibly suspended them
49544957 If m_AnimationsAllowed Then
49554958
4959+ 'If rendering the outline takes too long (entirely possible on old PCs + complex magic wand selections),
4960+ ' we want to reduce animation frame rate to compensate.
4961+ Dim startTime As Currency
4962+ VBHacks.GetHighResTime startTime
4963+
49564964 'Advance the current offset
49574965 m_AntDashOffset = m_AntDashOffset + 1 !
49584966 If (m_AntDashOffset >= ANT_DASH_SIZE * 2 ) Then m_AntDashOffset = 0 !
@@ -4968,10 +4976,45 @@ Private Sub m_AntTimer_Timer()
49684976 End If
49694977
49704978 If okayToRender Then
4979+
49714980 Dim tmpViewportParams As PD_ViewportParams
49724981 tmpViewportParams = Viewport.GetDefaultParamObject()
49734982 tmpViewportParams.curPOI = poi_ReuseLast
49744983 Viewport.Stage3_CompositeCanvas PDImages.GetActiveImage(), FormMain.MainCanvas(0 ), VarPtr(tmpViewportParams)
4984+
4985+ 'If the rendering took longer than the timer frequency, reduce timer frequency to compensate
4986+ Dim timeTakenMS As Double
4987+ timeTakenMS = (VBHacks.GetTimerDifferenceNow(startTime) * 1000 #)
4988+
4989+ If ANT_DASH_ADAPTIVE_SPEED Then
4990+
4991+ 'Compare the render time to the current timer interval.
4992+ Dim intervalChange As Long , curInterval As Double
4993+ curInterval = m_AntTimer.Interval
4994+
4995+ 'We are now going to modify the timer in 5% increments (but with a little extra math
4996+ ' to ensure that at least 1 ms of time is added/removed, as relevant). Note that
4997+ ' built-in Windows power management features can prevent these changes from mattering,
4998+ ' but we'll potentially keep toying with the frame rate until a nice balance of
4999+ ' responsiveness and fluidity is reached.
5000+
5001+ 'If render time exceeds 75% of the timer interval, slow the animation to compensate.
5002+ If (timeTakenMS > curInterval * 0.75 ) Then
5003+ intervalChange = Int(curInterval * 1.05 - curInterval + 0.5 )
5004+ If (intervalChange < 1 ) Then intervalChange = 1
5005+
5006+ 'If render time takes less than 25% of the timer interval, increase animation fluidity
5007+ ElseIf (timeTakenMS < curInterval * 0.25 ) Then
5008+ intervalChange = Int(curInterval - curInterval * 0.95 + 0.5 )
5009+ If (intervalChange > -1 ) Then intervalChange = -1
5010+ If (curInterval <= ANT_DASH_SPEED_MIN) Then intervalChange = 0
5011+ End If
5012+
5013+ 'If a change was made, assign the new timer interval
5014+ If (intervalChange <> 0 ) Then m_AntTimer.Interval = curInterval + intervalChange
5015+
5016+ End If
5017+
49755018 Else
49765019 m_AntTimer.StopTimer
49775020 End If
0 commit comments