Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added: dwm scheduling of frames

  • Loading branch information...
commit de7b74524323ae758bf27a1c7939a93b2a9f97a0 1 parent 698543a
@elupus authored committed
View
80 xbmc/RenderSystemDX.cpp
@@ -36,6 +36,7 @@
#include "Util.h"
#include "win32/WIN32Util.h"
#include "LocalizeStrings.h"
+#include <dwmapi.h>
using namespace std;
@@ -74,6 +75,8 @@ CRenderSystemDX::CRenderSystemDX() : CRenderSystemBase()
m_useD3D9Ex = false;
m_defaultD3DUsage = 0;
m_defaultD3DPool = D3DPOOL_MANAGED;
+ m_scheduledPresent = false;
+ m_scheduledEnabled = false;
ZeroMemory(&m_D3DPP, sizeof(D3DPRESENT_PARAMETERS));
}
@@ -655,11 +658,88 @@ bool CRenderSystemDX::PresentRender()
if (!m_bRenderCreated)
return false;
+ if(m_scheduledEnabled && !m_scheduledPresent)
+ {
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - disabling present queue");
+
+ DWM_PRESENT_PARAMETERS params = {};
+ params.cbSize = sizeof(params);
+ params.fQueue = FALSE;
+
+ if(FAILED(DwmSetPresentParameters(m_hDeviceWnd, &params)))
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - failed to set present parameters");
+
+ if(FAILED(DwmEnableMMCSS(FALSE)))
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - failed to enable multimedia timers");
+
+ m_scheduledEnabled = false;
+ }
+
bool result = PresentRenderImpl();
+
+ m_scheduledPresent = false;
return result;
}
+bool CRenderSystemDX::SchedulePresent(int64_t timestamp)
+{
+ BOOL composing;
+ if(FAILED(DwmIsCompositionEnabled(&composing)) || !composing)
+ return false;
+
+ DWM_TIMING_INFO info = {};
+ info.cbSize = sizeof(info);
+ if(FAILED(DwmGetCompositionTimingInfo(m_hDeviceWnd, &info)))
+ {
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - failed to get timing info");
+ return false;
+ }
+
+ int64_t offset = (timestamp - (int64_t)info.qpcVBlank) / (int64_t)info.qpcRefreshPeriod;
+ if(offset < 1)
+ offset = 1;
+ if(offset * info.rateRefresh.uiDenominator > info.rateRefresh.uiNumerator)
+ offset = info.rateRefresh.uiNumerator / info.rateRefresh.uiDenominator;
+
+ if(m_scheduledEnabled)
+ {
+ int64_t error = offset + (int64_t)info.cRefresh - (int64_t)info.cRefreshNextPresented;
+ if(FAILED(DwmModifyPreviousDxFrameDuration(m_hDeviceWnd, (int)error, TRUE)))
+ {
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - failed update previous frame duration N:%"PRIu64" R:%"PRIu64" O:"PRId64" E:"PRId64, info.cRefreshNextPresented, info.cRefresh, offset, error);
+ return false;
+ }
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - enabling present queue at offset %"PRId64, offset);
+
+ if(FAILED(DwmEnableMMCSS(TRUE)))
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - failed to enable multimedia timers");
+
+ DWM_PRESENT_PARAMETERS params = {};
+ params.cbSize = sizeof(params);
+ params.fQueue = TRUE;
+ params.cBuffer = 4;
+ params.fUseSourceRate = FALSE;
+ params.cRefreshesPerFrame = 1;
+ if(offset > 0)
+ params.cRefreshStart = info.cRefresh + offset;
+ else
+ params.cRefreshStart = info.cRefresh;
+ params.eSampling = DWM_SOURCE_FRAME_SAMPLING_POINT;
+ if(FAILED(DwmSetPresentParameters(m_hDeviceWnd, &params)))
+ {
+ CLog::Log(LOGERROR, "CRenderSystemDX::SchedulePresent - failed to set present parameters");
+ return false;
+ }
+ m_scheduledEnabled = true;
+ }
+ m_scheduledPresent = true;
+ return true;
+}
+
void CRenderSystemDX::SetVSync(bool enable)
{
if (m_bVSync != enable)
View
5 xbmc/RenderSystemDX.h
@@ -44,6 +44,8 @@ class CRenderSystemDX : public CRenderSystemBase
virtual bool BeginRender();
virtual bool EndRender();
virtual bool PresentRender();
+ virtual bool SchedulePresent(int64_t timestamp);
+
virtual bool ClearBuffers(color_t color);
virtual bool ClearBuffers(float r, float g, float b, float a);
virtual bool IsExtSupported(const char* extension);
@@ -133,6 +135,9 @@ class CRenderSystemDX : public CRenderSystemBase
std::vector<ID3DResource*> m_resources;
bool m_inScene; ///< True if we're in a BeginScene()/EndScene() block
+ bool m_inScene; ///< True if we're in a BeginScene()/EndScene() block
+ bool m_scheduledPresent; // True if next present have been sheduled
+ bool m_scheduledEnabled;
};
#endif // RENDER_SYSTEM_DX
View
1  xbmc/cores/dvdplayer/DVDClock.h
@@ -70,6 +70,7 @@ class CDVDClock
bool SetMaxSpeedAdjust(double speed);
static double GetAbsoluteClock();
+ static int64_t GetAbsoluteTics(double dTime) { return (int64_t)(dTime * m_systemFrequency / DVD_TIME_BASE) + m_systemOffset; }
static double GetFrequency() { return (double)m_systemFrequency ; }
static double WaitAbsoluteClock(double target);
protected:
Please sign in to comment.
Something went wrong with that request. Please try again.