add in High DPI support (aka Retina)

- based on J?rgen's patch with a few bug fixes
This commit is contained in:
Edward Rudd
2013-09-20 13:43:00 -04:00
parent 0103bc0bff
commit 869a707612
12 changed files with 134 additions and 11 deletions

View File

@@ -117,7 +117,12 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
/* Window was resized, reset viewport */
int w, h;
SDL_GetWindowSize(window, &w, &h);
if (renderer->GetOutputSize) {
renderer->GetOutputSize(renderer, &w, &h);
} else {
SDL_GetWindowSize(renderer->window, &w, &h);
}
if (renderer->target) {
renderer->viewport_backup.x = 0;
renderer->viewport_backup.y = 0;
@@ -335,11 +340,11 @@ SDL_GetRendererOutputSize(SDL_Renderer * renderer, int *w, int *h)
if (renderer->target) {
return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
} else if (renderer->GetOutputSize) {
return renderer->GetOutputSize(renderer, w, h);
} else if (renderer->window) {
SDL_GetWindowSize(renderer->window, w, h);
return 0;
} else if (renderer->GetOutputSize) {
return renderer->GetOutputSize(renderer, w, h);
} else {
/* This should never happen */
SDL_SetError("Renderer doesn't support querying output size");

View File

@@ -47,6 +47,7 @@ static const float inv255f = 1.0f / 255.0f;
static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
static void GL_WindowEvent(SDL_Renderer * renderer,
const SDL_WindowEvent *event);
static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels,
@@ -399,6 +400,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
}
renderer->WindowEvent = GL_WindowEvent;
renderer->GetOutputSize = GL_GetOutputSize;
renderer->CreateTexture = GL_CreateTexture;
renderer->UpdateTexture = GL_UpdateTexture;
renderer->LockTexture = GL_LockTexture;
@@ -539,6 +541,14 @@ GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
}
}
static int
GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
{
SDL_GL_GetDrawableSize(renderer->window, w, h);
return 0;
}
SDL_FORCE_INLINE int
power_of_2(int input)
{

View File

@@ -27,7 +27,7 @@
#include <stdio.h>
#define VIDEO_USAGE \
"[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--logical WxH] [--scale N] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
"[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--logical WxH] [--scale N] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab] [--allow-hidpi]"
#define AUDIO_USAGE \
"[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
@@ -194,6 +194,10 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index)
state->num_windows = 1;
return 1;
}
if (SDL_strcasecmp(argv[index], "--allow-highdpi") == 0) {
state->window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
return 1;
}
if (SDL_strcasecmp(argv[index], "--windows") == 0) {
++index;
if (!argv[index] || !SDL_isdigit(*argv[index])) {

View File

@@ -224,6 +224,7 @@ struct SDL_VideoDevice
void (*GL_UnloadLibrary) (_THIS);
SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window);
int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context);
void (*GL_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h);
int (*GL_SetSwapInterval) (_THIS, int interval);
int (*GL_GetSwapInterval) (_THIS);
void (*GL_SwapWindow) (_THIS, SDL_Window * window);

View File

@@ -1187,6 +1187,7 @@ SDL_Window *
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
{
SDL_Window *window;
const char *hint;
if (!_this) {
/* Initialize the video system if needed */
@@ -1245,6 +1246,17 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
window->brightness = 1.0f;
window->next = _this->windows;
/* Unless the user has specified the high-DPI disabling hint, respect the
* SDL_WINDOW_ALLOW_HIGHDPI flag.
*/
hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED);
if (!hint || *hint != '1') {
if ((flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
window->flags |= SDL_WINDOW_ALLOW_HIGHDPI;
}
}
if (_this->windows) {
_this->windows->prev = window;
}
@@ -2813,6 +2825,17 @@ SDL_GL_GetCurrentContext(void)
return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls);
}
void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h)
{
CHECK_WINDOW_MAGIC(window, );
if (_this->GL_GetDrawableSize) {
_this->GL_GetDrawableSize(_this, window, w, h);
} else {
SDL_GetWindowSize(window, w, h);
}
}
int
SDL_GL_SetSwapInterval(int interval)
{

View File

@@ -54,6 +54,8 @@ extern void Cocoa_GL_UnloadLibrary(_THIS);
extern SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window);
extern int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context);
extern void Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window,
int * w, int * h);
extern int Cocoa_GL_SetSwapInterval(_THIS, int interval);
extern int Cocoa_GL_GetSwapInterval(_THIS);
extern void Cocoa_GL_SwapWindow(_THIS, SDL_Window * window);

View File

@@ -35,6 +35,18 @@
#define DEFAULT_OPENGL "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
/* New methods for converting to and from backing store pixels, taken from
* AppKite/NSView.h in 10.8 SDK. */
@interface NSView (Backing)
- (NSPoint)convertPointToBacking:(NSPoint)aPoint;
- (NSPoint)convertPointFromBacking:(NSPoint)aPoint;
- (NSSize)convertSizeToBacking:(NSSize)aSize;
- (NSSize)convertSizeFromBacking:(NSSize)aSize;
- (NSRect)convertRectToBacking:(NSRect)aRect;
- (NSRect)convertRectFromBacking:(NSRect)aRect;
@end
#endif
#ifndef kCGLPFAOpenGLProfile
#define kCGLPFAOpenGLProfile 99
@@ -294,6 +306,28 @@ Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
return 0;
}
void
Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
{
SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
NSView *contentView = [windata->nswindow contentView];
NSRect viewport = [contentView bounds];
/* This gives us the correct viewport for a Retina-enabled view, only
* supported on 10.7+. */
if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
viewport = [contentView convertRectToBacking:viewport];
}
if (w) {
*w = viewport.size.width;
}
if (h) {
*h = viewport.size.height;
}
}
int
Cocoa_GL_SetSwapInterval(_THIS, int interval)
{

View File

@@ -119,6 +119,7 @@ Cocoa_CreateDevice(int devindex)
device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
device->GL_CreateContext = Cocoa_GL_CreateContext;
device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize;
device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
device->GL_SwapWindow = Cocoa_GL_SwapWindow;

View File

@@ -34,6 +34,13 @@
#include "SDL_cocoamouse.h"
#include "SDL_cocoaopengl.h"
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
/* Taken from AppKit/NSOpenGLView.h in 10.8 SDK. */
@interface NSView (NSOpenGLSurfaceResolution)
- (BOOL)wantsBestResolutionOpenGLSurface;
- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
@end
#endif
static Uint32 s_moveHack;
@@ -739,6 +746,13 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
/* Create a default view for this window */
rect = [nswindow contentRectForFrameRect:[nswindow frame]];
NSView *contentView = [[SDLView alloc] initWithFrame:rect];
if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) > 0) {
if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
[contentView setWantsBestResolutionOpenGLSurface:YES];
}
}
[nswindow setContentView: contentView];
[contentView release];