Skip to content

Commit

Permalink
issue #18: Add support for DPI (at lauch time). Tested under Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
dfeneyrou committed Aug 18, 2021
1 parent 4e4ee16 commit 093b330
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 32 deletions.
4 changes: 2 additions & 2 deletions c++/palanteer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1297,8 +1297,8 @@ class plCliIo {
#if USE_PL==1 || PL_EXPORT==1

// Library version
#define PALANTEER_VERSION "0.3"
#define PALANTEER_VERSION_NUM 300 // Monotonic number. 100 per version component. Official release are multiples of 100
#define PALANTEER_VERSION "0.4.dev1"
#define PALANTEER_VERSION_NUM 301 // Monotonic number. 100 per version component. Official releases are multiple of 100

// Client-Server protocol version
#define PALANTEER_CLIENT_PROTOCOL_VERSION 1
Expand Down
6 changes: 3 additions & 3 deletions c++/test/test_instru_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def test_usepl1_nocontrol():
"""Config PL_NOCONTROL=1"""
build_target("testprogram", "USE_PL=1 PL_NOCONTROL=1")

data_configure_events(CRASH_SPEC+[spec_add_fruit])
data_configure_events(CRASH_SPEC + [spec_add_fruit])
try:
launch_testprogram()
CHECK(True, "Connection established")
Expand All @@ -88,7 +88,7 @@ def test_usepl1_noevent():
"""Config PL_NOEVENT=1"""
build_target("testprogram", "USE_PL=1 PL_NOEVENT=1")

data_configure_events(CRASH_SPEC+[spec_add_fruit])
data_configure_events(CRASH_SPEC + [spec_add_fruit])
try:
launch_testprogram()
CHECK(True, "Connection established")
Expand All @@ -111,7 +111,7 @@ def test_usepl1_noassert():
"""Config PL_NOASSERT=1"""
build_target("testprogram", "USE_PL=1 PL_NOASSERT=1")

data_configure_events(CRASH_SPEC+[spec_add_fruit])
data_configure_events(CRASH_SPEC + [spec_add_fruit])
try:
launch_testprogram(
pass_first_freeze_point=True
Expand Down
6 changes: 5 additions & 1 deletion docs/more.md.html
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,14 @@ <h1> @@ <a href="#">More</a> </h1>
- **Use asserts**
- They greatly speed up the bug investigation by crashing "nicely" close to the inconsistency.
- Their impact on performance is usually low because data is already in the cache/registers so a test is ~1 CPU cycle.
- Also, if `Palanteer` is used, groups of asserts can be enabled on demand at compile-time, which can greatly speed-up investigations
- Also, if `Palanteer` is used, groups of asserts can be enabled on demand at compile-time
- Keep the condition as a simple check, never perform actions inside an assertion as it may be disabled at compile time.
- Never assert on external inputs, as they are not under control.

- **For time related constant/variable, always include the unit in the name (exemple: `timeout_msec`)**
- Such bugs due to confusion on units are so frequent and so easy to avoid...
- Mistake on time units are the more representative, but this hint is applicable to all units as soon as there may be some ambiguity

- **Use address sanitizers (ASAN)** whenever possible
- It is built-in in `gcc` and `clang`, enabled with a few compilation/linking flags
- The reported issues (uninitialized memory read, leaks...) would be very hard to track without such class of tool.
Expand Down
2 changes: 1 addition & 1 deletion server/base/bsOs.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void osCreateWindow(const char* windowTitle, const char* configName,
bool overrideWindowManager=false);
void osDestroyWindow(void);
void osSetWindowTitle(const bsString& title);
void osGetWindowSize(int& width, int& height);
void osGetWindowSize(int& width, int& height, int& dpiWidth, int& dpiHeight);
void osProcessInputs(bsOsHandler* osHandler);
void osHideWindow(void);
void osShowWindow(void);
Expand Down
35 changes: 24 additions & 11 deletions server/base/bsOsLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ static struct {
Cursor noCursor = None;
Cursor defaultCursor = None;
Cursor currentCursor = None;
int wWidth = -1;
int wHeight = -1;
int wWidth = -1;
int wHeight = -1;
int dpiWidth = -1;
int dpiHeight = -1;
// Character inputs
XIM xInputMethod = 0; // Input method linked to the X display
XIC xInputContext = 0; // Input context used to gete unicode input in our window
Expand Down Expand Up @@ -167,13 +169,22 @@ osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft,
attr.override_redirect = gGlob.isDirectOverride;
attr.event_mask = StructureNotifyMask | EnterWindowMask | LeaveWindowMask | ExposureMask | ButtonPressMask | PointerMotionMask |
ButtonReleaseMask | OwnerGrabButtonMask | FocusChangeMask | KeyPressMask | KeyReleaseMask;
int attr_mask = CWBackPixmap | CWColormap | CWBorderPixel| CWEventMask | CWOverrideRedirect ;
int dWidth = DisplayWidth (gGlob.xDisplay, DefaultScreen(gGlob.xDisplay));
int dHeight = DisplayHeight(gGlob.xDisplay, DefaultScreen(gGlob.xDisplay));
int attr_mask = CWBackPixmap | CWColormap | CWBorderPixel| CWEventMask | CWOverrideRedirect;
int defaultScreenId = DefaultScreen(gGlob.xDisplay);
int dWidth = DisplayWidth (gGlob.xDisplay, defaultScreenId); // In pixel
int dHeight = DisplayHeight (gGlob.xDisplay, defaultScreenId);

// Compute DPI
#define COMPUTE_DPI(pix, mm) (int)(9.6*((int)(((double)pix)/((double)mm)*(254./96.)+0.5))) /* Quantize the DPI each 5%, to clean approximated values */
int dWidthMm = DisplayWidthMM (gGlob.xDisplay, defaultScreenId); // In millimeter
int dHeightMm = DisplayHeightMM(gGlob.xDisplay, defaultScreenId);
gGlob.dpiWidth = COMPUTE_DPI(dWidth, dWidthMm);
gGlob.dpiHeight = COMPUTE_DPI(dHeight, dHeightMm);

int x = (int)(ratioLeft *(float)dWidth);
int y = (int)(ratioTop *(float)dHeight);
gGlob.wWidth = (int)((ratioRight-ratioLeft)*(float)dWidth);
gGlob.wHeight = (int)((ratioBottom-ratioTop)*(float)dHeight);
gGlob.wWidth = (int)((ratioRight-ratioLeft)*(float)dWidth);
gGlob.wHeight = (int)((ratioBottom-ratioTop)*(float)dHeight);
gGlob.windowHandle = XCreateWindow(gGlob.xDisplay, Xroot, x, y, gGlob.wWidth, gGlob.wHeight,
0, visual->depth, InputOutput, visual->visual, attr_mask, &attr);
gGlob.glXWindowHandle = gGlob.windowHandle;
Expand Down Expand Up @@ -209,7 +220,7 @@ osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft,
gGlob.xInputMethod = XOpenIM(gGlob.xDisplay, NULL, NULL, NULL);
if(gGlob.xInputMethod) {
gGlob.xInputContext = XCreateIC(gGlob.xInputMethod, XNClientWindow, gGlob.glXWindowHandle, XNFocusWindow, gGlob.glXWindowHandle,
XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
}

// Create the OpenGL 3.0 context
Expand Down Expand Up @@ -272,10 +283,12 @@ osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft,
// ===============

void
osGetWindowSize(int& width, int& height)
osGetWindowSize(int& width, int& height, int& dpiWidth, int& dpiHeight)
{
width = gGlob.wWidth;
height = gGlob.wHeight;
width = gGlob.wWidth;
height = gGlob.wHeight;
dpiWidth = gGlob.dpiWidth;
dpiHeight = gGlob.dpiHeight;
}


Expand Down
34 changes: 31 additions & 3 deletions server/base/bsOsWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
static struct {
int windowWidth = -1;
int windowHeight = -1;
int dpiWidth = 96;
int dpiHeight = 96;
HINSTANCE hInstance = 0;
int nCmdShow = -1;
LPTSTR windowClass; // Window Class
Expand Down Expand Up @@ -101,6 +103,16 @@ showMessage(LPCWSTR message)
// Forward declaration
static LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// DPI awareness and getters from Dear Imgui, file backends/imgui_impl_win32.cpp
#ifndef DPI_ENUMS_DECLARED
typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE;
#endif
#ifndef _DPI_AWARENESS_CONTEXTS_
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3
#endif
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+


void
osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft, float ratioTop, float ratioRight, float ratioBottom, bool overrideWindowManager)
Expand All @@ -112,6 +124,9 @@ osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft,
plAssert(ratioLeft<ratioRight);
plAssert(ratioTop<ratioBottom);

// Enable DPI awareness (per application, else there are some display issue when resizing...)
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);

// Register the application class
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(wcex));
Expand Down Expand Up @@ -184,6 +199,17 @@ osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft,
gGlob.windowWidth = (int)((ratioRight-ratioLeft)*(float)dWidth);
gGlob.windowHeight = (int)((ratioBottom-ratioTop)*(float)dHeight);

// Compute the DPI
HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
if(GetDpiForMonitorFn) {
HMONITOR monitor = ::MonitorFromWindow(fakeWND, MONITOR_DEFAULTTONEAREST);
UINT xdpi = 96, ydpi = 96;
GetDpiForMonitorFn(monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
gGlob.dpiWidth = xdpi;
gGlob.dpiHeight = ydpi;
}

DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
DWORD dwStyle = WS_OVERLAPPEDWINDOW; // Windows Style
RECT WindowRect; // Set the desired window position and size
Expand Down Expand Up @@ -332,10 +358,12 @@ osCreateWindow(const char* windowTitle, const char* configName, float ratioLeft,
// ===============

void
osGetWindowSize(int& width, int& height)
osGetWindowSize(int& width, int& height, int& dpiWidth, int& dpiHeight)
{
width = gGlob.windowWidth;
height = gGlob.windowHeight;
width = gGlob.windowWidth;
height = gGlob.windowHeight;
dpiWidth = gGlob.dpiWidth;
dpiHeight = gGlob.dpiHeight;
}


Expand Down
2 changes: 1 addition & 1 deletion server/common/cmRecording.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ cmRecording::saveThreadMemorySnapshot(ThreadBuild& tc, s64 timeNs, u32 allocMIdx
if(allocatedScopeQty) {
if(_isCompressionEnabled) {
plgScope(REC, "Compression");
if(_workingCompressionBuffer.size()<writtenBufferSize) _workingCompressionBuffer.resize(writtenBufferSize*2); // With some margin
if(_workingCompressionBuffer.size()<writtenBufferSize*2) _workingCompressionBuffer.resize(writtenBufferSize*2); // With some margin
writtenBufferSize = _workingCompressionBuffer.size(); // Give some memory margin to the compression library (faster)
cmCompressChunk((u8*)&tc.memSSCurrentAlloc[0], allocatedScopeQty*sizeof(u32), &_workingCompressionBuffer[0], &writtenBufferSize);
}
Expand Down
22 changes: 13 additions & 9 deletions server/viewer/vwPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,9 @@ vwPlatform::vwPlatform(int rxPort, bool doLoadLastFile, const bsString& override
: _doExit(0), _isVisible(0), _dirtyRedrawCount(VW_REDRAW_PER_NTF)
{
// Update ImGui
osGetWindowSize(_displayWidth, _displayHeight);
int dpiWidth, dpiHeight;
osGetWindowSize(_displayWidth, _displayHeight, dpiWidth, dpiHeight);
_dpiScale = (float)dpiWidth/96.; // No support of dynamic DPI change

// Initialize the compression
cmInitChunkCompress();
Expand All @@ -331,11 +333,13 @@ vwPlatform::vwPlatform(int rxPort, bool doLoadLastFile, const bsString& override
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.DisplaySize = ImVec2(_displayWidth, _displayHeight);
io.DisplayFramebufferScale = ImVec2(1., 1.); // High DPI is handled with increased font size and Imgui spatial constants
io.IniFilename = 0; // Disable config file save
io.MouseDragThreshold = 1.; // 1 pixel threshold to detect that we are dragging
io.ConfigInputTextCursorBlink = false;
vwStyle();
_newFontSizeToInstall = _main->getConfig().getFontSize();
ImGui::GetStyle().ScaleAllSizes(_dpiScale);

// @#TODO: set window size & pos from config. And show the window only after that

Expand Down Expand Up @@ -465,16 +469,15 @@ vwPlatform::installFont(const void* fontData, int fontDataSize, int fontSize)
bool
vwPlatform::redraw(void)
{
// Filter out some redraw based on the dirtyness of the state.
// Due to imgui which requires several frames to handle user events properly, we batch the display.
// Also we do a "bounce" after a delay, which is needed for some tooltip to appear, even if no user event occurs.
// Filter out some redraw based on the dirtiness of the display state.
// Dear Imgui requires several frames to handle user events properly, so we display per batch.
// Also a "bounce" is required after a delay for some tooltip to appear, even if no user event occurs.
bsUs_t currentTimeUs = bsGetClockUs();
u64 tmp = _dirtyRedrawCount.load();
u64 tmp = _dirtyRedrawCount.load();
int dirtyRedrawCount = (int)(tmp&0xFFFFFFFF);
int bounceCount = (int)((tmp>>32)&0xFFFFFFFF);
if(dirtyRedrawCount<=0 && // Not a dirty display or...
!(bounceCount==1 && currentTimeUs-_lastRenderingTimeUs>=BOUNCE_RENDER_GAP_US)) { // not (we need a bounce and waited enough)
return false; // Nothing to display
if(dirtyRedrawCount<=0 && !(bounceCount==1 && currentTimeUs-_lastRenderingTimeUs>=BOUNCE_RENDER_GAP_US)) {
return false; // Display is not dirty and it is not a bounce time: nothing to display
}
#define WRITE_DIRTY_COUNT(drc,bc) _dirtyRedrawCount.store((((u64)bc)<<32) | ((u32)(drc&0xFFFFFFFF)))
if(dirtyRedrawCount>=0) {
Expand All @@ -492,7 +495,8 @@ vwPlatform::redraw(void)

// Change font, if needed
if(_newFontSizeToInstall>0) {
installFont(vwGetFontDataRobotoMedium(), vwGetFontDataSizeRobotoMedium(), _newFontSizeToInstall);
installFont(vwGetFontDataRobotoMedium(), vwGetFontDataSizeRobotoMedium(),
bsRound(_dpiScale*_newFontSizeToInstall));
_newFontSizeToInstall = -1;
}

Expand Down
1 change: 1 addition & 0 deletions server/viewer/vwPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class vwPlatform : public bsOsHandler {
// ImGui & OpenGL
int _displayWidth = -1;
int _displayHeight = -1;
float _dpiScale = 1.;
bsUs_t _lastUpdateDurationUs = 1; // Update only
bsUs_t _lastRenderingDurationUs = 1; // Update and OpenGL rendering
bsUs_t _lastRenderingTimeUs = 0;
Expand Down
5 changes: 4 additions & 1 deletion tools/testframework.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,10 @@ class _TestFailedError(Exception):


# Public CRASH_SPEC
CRASH_SPEC = [palanteer_scripting.EvtSpec("CRASH Stacktrace"), palanteer_scripting.EvtSpec(parent="CRASH Stacktrace", events=["*"])]
CRASH_SPEC = [
palanteer_scripting.EvtSpec("CRASH Stacktrace"),
palanteer_scripting.EvtSpec(parent="CRASH Stacktrace", events=["*"]),
]

# Used server port (better if different from the viewer's one)
SERVER_PORT = 59060
Expand Down

0 comments on commit 093b330

Please sign in to comment.