BACKENDS: HiDPI support in OpenGL backend

This commit is contained in:
Eugene Sandulenko 2020-10-29 19:12:24 +01:00
parent b29f457548
commit 5e395d166a
7 changed files with 83 additions and 12 deletions

View File

@ -955,17 +955,13 @@ void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height,
overlayWidth = MAX<uint>(overlayWidth, 256);
overlayHeight = MAX<uint>(overlayHeight, 200);
// HACK: Reduce the size of the overlay on high DPI screens.
overlayWidth = fracToInt(overlayWidth * (intToFrac(90) / xdpi));
overlayHeight = fracToInt(overlayHeight * (intToFrac(90) / ydpi));
if (!_overlay || _overlay->getFormat() != _defaultFormatAlpha) {
delete _overlay;
_overlay = nullptr;
_overlay = createSurface(_defaultFormatAlpha);
assert(_overlay);
// We should NOT always filter the overlay with GL_LINEAR.
// We should NOT always filter the overlay with GL_LINEAR.
// In previous versions we always did use GL_LINEAR to assure the UI
// would be readable in case it needed to be scaled -- it would not affect it otherwise.
// However in modern devices due to larger screen size the UI display looks blurry

View File

@ -287,7 +287,7 @@ void OpenGLSdlGraphicsManager::updateScreen() {
void OpenGLSdlGraphicsManager::notifyVideoExpose() {
}
void OpenGLSdlGraphicsManager::notifyResize(const int width, const int height) {
void OpenGLSdlGraphicsManager::notifyResize(const int w, const int h) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
// We sometime get outdated resize events from SDL2. So check that the size we get
// is the actual current window size. If not ignore the resize.
@ -298,9 +298,14 @@ void OpenGLSdlGraphicsManager::notifyResize(const int width, const int height) {
// event is processed after recreating the window at the new resolution.
int currentWidth, currentHeight;
getWindowSizeFromSdl(&currentWidth, &currentHeight);
uint scale;
getDpiScalingFactor(&scale);
int width = w * scale;
int height = h * scale;
debug(3, "req: %d x %d cur: %d x %d, scale: %d", width, height, currentWidth, currentHeight, scale);
if (width != currentWidth || height != currentHeight)
return;
// TODO: Implement high DPI support
handleResize(width, height, 90, 90);
#else
if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) {
@ -422,7 +427,8 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
_glContext = nullptr;
}
uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
if (_wantsFullScreen) {
// On Linux/X11, when toggling to fullscreen, the window manager saves
// the window size to be able to restore it when going back to windowed mode.
@ -459,8 +465,8 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
notifyContextCreate(rgba8888, rgba8888);
int actualWidth, actualHeight;
getWindowSizeFromSdl(&actualWidth, &actualHeight);
// TODO: Implement high DPI support
handleResize(actualWidth, actualHeight, 90, 90);
handleResize(actualWidth, actualHeight, 72, 72);
return true;
#else
// WORKAROUND: Working around infamous SDL bugs when switching
@ -507,6 +513,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
if (_hwScreen) {
notifyContextCreate(rgba8888, rgba8888);
// TODO: hidpi
handleResize(_hwScreen->w, _hwScreen->h, 90, 90);
}

View File

@ -60,7 +60,11 @@ protected:
virtual bool saveScreenshot(const Common::String &filename) const override;
virtual int getGraphicsModeScale(int mode) const override { return 1; }
virtual int getGraphicsModeScale(int mode) const override {
uint scale;
getDpiScalingFactor(&scale);
return scale;
}
private:
bool setupMode(uint width, uint height);

View File

@ -208,6 +208,11 @@ bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
mouse.y = CLIP<int16>(mouse.y, 0, _windowHeight - 1);
int showCursor = SDL_DISABLE;
// DPI aware scaling to mouse position
uint scale;
getDpiScalingFactor(&scale);
mouse.x *= scale;
mouse.y *= scale;
bool valid = true;
if (_activeArea.drawRect.contains(mouse)) {
_cursorLastInActiveArea = true;
@ -267,6 +272,9 @@ bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint3
return false;
}
// width *=3;
// height *=3;
// We only update the actual window when flags change (which usually means
// fullscreen mode is entered/exited), when updates are forced so that we
// do not reset the window size whenever a game makes a call to change the

View File

@ -163,7 +163,8 @@ protected:
void getWindowSizeFromSdl(int *width, int *height) const {
#if SDL_VERSION_ATLEAST(2, 0, 0)
assert(_window);
SDL_GetWindowSize(_window->getSDLWindow(), width, height);
SDL_GL_GetDrawableSize(_window->getSDLWindow(), width, height);
// SDL_GetWindowSize(_window->getSDLWindow(), width, height);
#else
assert(_hwScreen);
@ -176,6 +177,57 @@ protected:
}
#endif
}
/**
* Gets the display index that the ScummVM window is on
*/
void getWindowDisplayIndexFromSdl(int *index) const {
#if SDL_VERSION_ATLEAST(2, 0, 0)
assert(_window);
*index = SDL_GetWindowDisplayIndex(_window->getSDLWindow());
#else
*index = 0;
#endif
}
void getDisplayDpiFromSdl(float *dpi, float *defaultDpi) const {
const float systemDpi =
#ifdef __APPLE__
72.0f;
#elif defined(_WIN32)
96.0f;
#else
90.0f; // ScummVM default
#endif
if (defaultDpi)
*defaultDpi = systemDpi;
#if SDL_VERSION_ATLEAST(2, 0, 0)
int displayIndex = 0;
getWindowDisplayIndexFromSdl(&displayIndex);
if (SDL_GetDisplayDPI(displayIndex, NULL, dpi, NULL) != 0) {
if (dpi)
*dpi = systemDpi;
}
#else
*dpi = systemDpi;
#endif
}
/**
* Returns the scaling mode based on the display DPI
*/
void getDpiScalingFactor(uint *scale) const {
float dpi, defaultDpi, ratio;
getDisplayDpiFromSdl(&dpi, &defaultDpi);
debug(4, "dpi: %g default: %g", dpi, defaultDpi);
ratio = dpi / defaultDpi;
if (ratio >= 2.0f) {
*scale = 2;
} else {
*scale = 1;
}
}
virtual void setSystemMousePosition(const int x, const int y) override;

View File

@ -78,5 +78,7 @@
<string>ScummVM saves and loads savegames in the Documents folder by default.</string>
<key>SUPublicDSAKeyFile</key>
<string>dsa_pub.pem</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

View File

@ -78,5 +78,7 @@
<string>ScummVM saves and loads savegames in the Documents folder by default.</string>
<key>SUPublicDSAKeyFile</key>
<string>dsa_pub.pem</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>