Skip to content

Commit 6766ca8

Browse files
authored
Merge pull request #118 from mihaip/upstream-hidpi
Enable HiDPI mode for SDL and ensure that we use nearest-neighbor scaling
2 parents 27d389c + fc13f68 commit 6766ca8

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

core/hostevents.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ class WindowEvent {
3535
uint32_t window_id;
3636
};
3737

38+
enum : uint16_t {
39+
// Standard SDL window event types are uint8_t's, we add our own custom
40+
// events after that.
41+
WINDOW_SCALE_QUALITY_TOGGLE = 1 << 8,
42+
};
43+
3844
enum : uint32_t {
3945
MOUSE_EVENT_MOTION = 1 << 0,
4046
MOUSE_EVENT_BUTTON = 1 << 1,

core/hostevents_sdl.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,24 @@ void EventManager::poll_events()
5454

5555
case SDL_KEYDOWN:
5656
case SDL_KEYUP: {
57-
// Internal shortcuts to trigger mouse grab, intentionally not
58-
// sent to the host.
57+
// Internal shortcuts, intentionally not sent to the host.
58+
// Control-G: mouse grab
5959
if (event.key.keysym.sym == SDLK_g && SDL_GetModState() & KMOD_LCTRL) {
6060
if (event.type == SDL_KEYUP) {
6161
toggle_mouse_grab(event.key);
6262
}
6363
return;
6464
}
65+
// Control-S: scale quality
66+
if (event.key.keysym.sym == SDLK_s && SDL_GetModState() & KMOD_LCTRL) {
67+
if (event.type == SDL_KEYUP) {
68+
WindowEvent we;
69+
we.sub_type = WINDOW_SCALE_QUALITY_TOGGLE;
70+
we.window_id = event.window.windowID;
71+
this->_window_signal.emit(we);
72+
}
73+
return;
74+
}
6575
int key_code = get_sdl_event_key_code(event.key);
6676
if (key_code != -1) {
6777
KeyboardEvent ke;

devices/video/display_sdl.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ class Display::Impl {
2929
uint32_t disp_wnd_id = 0;
3030
SDL_Window* display_wnd = 0;
3131
SDL_Renderer* renderer = 0;
32+
double renderer_scale_x; // scaling factor from guest OS to host OS
33+
double renderer_scale_y;
3234
SDL_Texture* disp_texture = 0;
3335
SDL_Texture* cursor_texture = 0;
3436
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
3537
};
3638

3739
Display::Display(): impl(std::make_unique<Impl>()) {
40+
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
3841
}
3942

4043
Display::~Display() {
@@ -61,7 +64,7 @@ bool Display::configure(int width, int height) {
6164
SDL_WINDOWPOS_UNDEFINED,
6265
SDL_WINDOWPOS_UNDEFINED,
6366
width, height,
64-
SDL_WINDOW_OPENGL
67+
SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
6568
);
6669

6770
impl->disp_wnd_id = SDL_GetWindowID(impl->display_wnd);
@@ -72,6 +75,11 @@ bool Display::configure(int width, int height) {
7275
if (impl->renderer == NULL)
7376
ABORT_F("Display: SDL_CreateRenderer failed with %s", SDL_GetError());
7477

78+
int drawable_width, drawable_height;
79+
SDL_GetRendererOutputSize(impl->renderer, &drawable_width, &drawable_height);
80+
impl->renderer_scale_x = static_cast<double>(drawable_width) / width;
81+
impl->renderer_scale_y = static_cast<float>(drawable_height) / height;
82+
7583
is_initialization = true;
7684
} else { // resize display window
7785
SDL_SetWindowSize(impl->display_wnd, width, height);
@@ -100,6 +108,16 @@ void Display::handle_events(const WindowEvent& wnd_event) {
100108
if (wnd_event.sub_type == SDL_WINDOWEVENT_EXPOSED &&
101109
wnd_event.window_id == impl->disp_wnd_id)
102110
SDL_RenderPresent(impl->renderer);
111+
if (wnd_event.sub_type == WINDOW_SCALE_QUALITY_TOGGLE &&
112+
wnd_event.window_id == impl->disp_wnd_id) {
113+
auto current_quality = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
114+
auto new_quality = current_quality == NULL || strcmp(current_quality, "nearest") == 0 ? "best" : "nearest";
115+
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, new_quality);
116+
// We need the window/texture to be recreated to pick up the hint change.
117+
int width, height;
118+
SDL_GetWindowSize(impl->display_wnd, &width, &height);
119+
this->configure(width, height);
120+
}
103121
}
104122

105123
void Display::blank() {
@@ -133,8 +151,8 @@ void Display::update(std::function<void(uint8_t *dst_buf, int dst_pitch)> conver
133151

134152
// draw HW cursor if enabled
135153
if (draw_hw_cursor) {
136-
impl->cursor_rect.x = cursor_x;
137-
impl->cursor_rect.y = cursor_y;
154+
impl->cursor_rect.x = cursor_x * impl->renderer_scale_x;
155+
impl->cursor_rect.y = cursor_y * impl->renderer_scale_y;
138156
SDL_RenderCopy(impl->renderer, impl->cursor_texture, NULL, &impl->cursor_rect);
139157
}
140158

@@ -170,6 +188,6 @@ void Display::setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch
170188

171189
impl->cursor_rect.x = 0;
172190
impl->cursor_rect.y = 0;
173-
impl->cursor_rect.w = cursor_width;
174-
impl->cursor_rect.h = cursor_height;
191+
impl->cursor_rect.w = cursor_width * impl->renderer_scale_x;
192+
impl->cursor_rect.h = cursor_height * impl->renderer_scale_y;
175193
}

0 commit comments

Comments
 (0)