@@ -29,12 +29,15 @@ class Display::Impl {
29
29
uint32_t disp_wnd_id = 0 ;
30
30
SDL_Window* display_wnd = 0 ;
31
31
SDL_Renderer* renderer = 0 ;
32
+ double renderer_scale_x; // scaling factor from guest OS to host OS
33
+ double renderer_scale_y;
32
34
SDL_Texture* disp_texture = 0 ;
33
35
SDL_Texture* cursor_texture = 0 ;
34
36
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
35
37
};
36
38
37
39
Display::Display (): impl(std::make_unique<Impl>()) {
40
+ SDL_SetHint (SDL_HINT_RENDER_SCALE_QUALITY, " nearest" );
38
41
}
39
42
40
43
Display::~Display () {
@@ -61,7 +64,7 @@ bool Display::configure(int width, int height) {
61
64
SDL_WINDOWPOS_UNDEFINED,
62
65
SDL_WINDOWPOS_UNDEFINED,
63
66
width, height,
64
- SDL_WINDOW_OPENGL
67
+ SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
65
68
);
66
69
67
70
impl->disp_wnd_id = SDL_GetWindowID (impl->display_wnd );
@@ -72,6 +75,11 @@ bool Display::configure(int width, int height) {
72
75
if (impl->renderer == NULL )
73
76
ABORT_F (" Display: SDL_CreateRenderer failed with %s" , SDL_GetError ());
74
77
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
+
75
83
is_initialization = true ;
76
84
} else { // resize display window
77
85
SDL_SetWindowSize (impl->display_wnd , width, height);
@@ -100,6 +108,16 @@ void Display::handle_events(const WindowEvent& wnd_event) {
100
108
if (wnd_event.sub_type == SDL_WINDOWEVENT_EXPOSED &&
101
109
wnd_event.window_id == impl->disp_wnd_id )
102
110
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
+ }
103
121
}
104
122
105
123
void Display::blank () {
@@ -133,8 +151,8 @@ void Display::update(std::function<void(uint8_t *dst_buf, int dst_pitch)> conver
133
151
134
152
// draw HW cursor if enabled
135
153
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 ;
138
156
SDL_RenderCopy (impl->renderer , impl->cursor_texture , NULL , &impl->cursor_rect );
139
157
}
140
158
@@ -170,6 +188,6 @@ void Display::setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch
170
188
171
189
impl->cursor_rect .x = 0 ;
172
190
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 ;
175
193
}
0 commit comments