Improved the performance of love.window.getPixelScale / toPixels / fromPixels by caching some values. Made some coordinate space-sensitive code use the proper conversions to get to the correct coordinate space.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2015-02-23 17:55:30 -04:00
parent 182792de85
commit 52c4f2c119
14 changed files with 112 additions and 114 deletions
+1 -3
View File
@@ -771,11 +771,9 @@ int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d)
void Source::setMinVolume(float volume)
{
if (valid)
{
alSourcef(source, AL_MIN_GAIN, volume);
}
this->minVolume = volume;
minVolume = volume;
}
float Source::getMinVolume() const
+7 -13
View File
@@ -46,11 +46,8 @@ namespace sdl
static void windowToPixelCoords(double *x, double *y)
{
window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
if (window && x)
*x = window->toPixels(*x);
if (window && y)
*y = window->toPixels(*y);
if (window)
window->windowToPixelCoords(x, y);
}
#ifndef LOVE_MACOSX
@@ -547,8 +544,6 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const
msg = new Message("visible", vargs);
break;
case SDL_WINDOWEVENT_RESIZED:
win = Module::getInstance<window::Window>(Module::M_WINDOW);
if (win)
{
int px_w = e.window.data1;
int px_h = e.window.data2;
@@ -557,12 +552,6 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const
if (sdlwin)
SDL_GL_GetDrawableSize(sdlwin, &px_w, &px_h);
win->onWindowResize(e.window.data1, e.window.data2);
graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
if (gfx)
gfx->setViewportSize(px_w, px_h);
vargs.push_back(new Variant((double) px_w));
vargs.push_back(new Variant((double) px_h));
vargs.push_back(new Variant((double) e.window.data1));
@@ -570,6 +559,11 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const
msg = new Message("resize", vargs);
}
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
win = Module::getInstance<window::Window>(Module::M_WINDOW);
if (win)
win->onSizeChanged(e.window.data1, e.window.data2);
break;
}
// We gave +1 refs to the StrongRef list, so we should release them.
+1 -1
View File
@@ -573,7 +573,7 @@ public:
* on the screen the text will appear. This is used as a hint so on-screen
* keyboards don't cover the text area.
**/
virtual void setTextInput(bool enable, int x, int y, int w, int h) = 0;
virtual void setTextInput(bool enable, double x, double y, double w, double h) = 0;
/**
* Gets whether text input events are enabled.
+12 -4
View File
@@ -19,6 +19,7 @@
**/
#include "Keyboard.h"
#include "window/Window.h"
namespace love
{
@@ -117,11 +118,18 @@ void Keyboard::setTextInput(bool enable)
SDL_StopTextInput();
}
void Keyboard::setTextInput(bool enable, int x, int y, int w, int h)
void Keyboard::setTextInput(bool enable, double x, double y, double w, double h)
{
// TODO: SetTextInputRect expects coordinates in window-space, but
// setTextInput uses pixels. We should convert here.
SDL_Rect rect = {x, y, w, h};
// SDL_SetTextInputRect expects coordinates in window-space but setTextInput
// takes pixels, so we should convert.
window::Window *window = Module::getInstance<window::Window>(M_WINDOW);
if (window)
{
window->pixelToWindowCoords(&x, &y);
window->pixelToWindowCoords(&w, &h);
}
SDL_Rect rect = {(int) x, (int) y, (int) w, (int) h};
SDL_SetTextInputRect(&rect);
setTextInput(enable);
+1 -1
View File
@@ -53,7 +53,7 @@ public:
Scancode getScancodeFromKey(Key key) const;
void setTextInput(bool enable);
void setTextInput(bool enable, int x, int y, int w, int h);
void setTextInput(bool enable, double x, double y, double w, double h);
bool hasTextInput() const;
bool hasScreenKeyboard() const;
+4 -4
View File
@@ -119,10 +119,10 @@ int w_setTextInput(lua_State *L)
instance()->setTextInput(enable);
else
{
int x = (int) luaL_checkinteger(L, 2);
int y = (int) luaL_checkinteger(L, 3);
int w = (int) luaL_checkinteger(L, 4);
int h = (int) luaL_checkinteger(L, 5);
double x = luaL_checknumber(L, 2);
double y = luaL_checknumber(L, 3);
double w = luaL_checknumber(L, 4);
double h = luaL_checknumber(L, 5);
instance()->setTextInput(enable, x, y, w, h);
}
+6 -6
View File
@@ -62,12 +62,12 @@ public:
virtual bool hasCursor() const = 0;
virtual int getX() const = 0;
virtual int getY() const = 0;
virtual void getPosition(int &x, int &y) const = 0;
virtual void setX(int x) = 0;
virtual void setY(int y) = 0;
virtual void setPosition(int x, int y) = 0;
virtual double getX() const = 0;
virtual double getY() const = 0;
virtual void getPosition(double &x, double &y) const = 0;
virtual void setX(double x) = 0;
virtual void setY(double y) = 0;
virtual void setPosition(double x, double y) = 0;
virtual void setVisible(bool visible) = 0;
virtual bool isDown(Button *buttonlist) const = 0;
virtual bool isVisible() const = 0;
+26 -30
View File
@@ -34,25 +34,19 @@ namespace sdl
// SDL reports mouse coordinates in the window coordinate system in OS X, but
// we want them in pixel coordinates (may be different with high-DPI enabled.)
static void windowToPixelCoords(int *x, int *y)
static void windowToPixelCoords(double *x, double *y)
{
window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
if (window && x)
*x = (int) window->toPixels(*x);
if (window && y)
*y = (int) window->toPixels(*y);
if (window)
window->windowToPixelCoords(x, y);
}
// And vice versa for setting mouse coordinates.
static void pixelToWindowCoords(int *x, int *y)
static void pixelToWindowCoords(double *x, double *y)
{
window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
if (window && x)
*x = (int) window->fromPixels(*x);
if (window && y)
*y = (int) window->fromPixels(*y);
if (window)
window->pixelToWindowCoords(x, y);
}
const char *Mouse::getName() const
@@ -118,35 +112,39 @@ bool Mouse::hasCursor() const
return SDL_GetDefaultCursor() != nullptr;
}
int Mouse::getX() const
double Mouse::getX() const
{
int x;
SDL_GetMouseState(&x, nullptr);
windowToPixelCoords(&x, nullptr);
return x;
double dx = (double) x;
windowToPixelCoords(&dx, nullptr);
return dx;
}
int Mouse::getY() const
double Mouse::getY() const
{
int y;
SDL_GetMouseState(nullptr, &y);
windowToPixelCoords(nullptr, &y);
return y;
double dy = (double) y;
windowToPixelCoords(nullptr, &dy);
return dy;
}
void Mouse::getPosition(int &x, int &y) const
void Mouse::getPosition(double &x, double &y) const
{
int mx, my;
SDL_GetMouseState(&mx, &my);
windowToPixelCoords(&mx, &my);
x = mx;
y = my;
x = (double) mx;
y = (double) my;
windowToPixelCoords(&x, &y);
}
void Mouse::setPosition(int x, int y)
void Mouse::setPosition(double x, double y)
{
love::window::Window *window = love::window::sdl::Window::getSingleton();
@@ -155,7 +153,7 @@ void Mouse::setPosition(int x, int y)
handle = (SDL_Window *) window->getHandle();
pixelToWindowCoords(&x, &y);
SDL_WarpMouseInWindow(handle, x, y);
SDL_WarpMouseInWindow(handle, (int) x, (int) y);
// SDL_WarpMouse doesn't directly update SDL's internal mouse state in Linux
// and Windows, so we call SDL_PumpEvents now to make sure the next
@@ -163,16 +161,14 @@ void Mouse::setPosition(int x, int y)
SDL_PumpEvents();
}
void Mouse::setX(int x)
void Mouse::setX(double x)
{
int y = getY();
setPosition(x, y);
setPosition(x, getY());
}
void Mouse::setY(int y)
void Mouse::setY(double y)
{
int x = getX();
setPosition(x, y);
setPosition(getX(), y);
}
void Mouse::setVisible(bool visible)
+6 -6
View File
@@ -55,12 +55,12 @@ public:
bool hasCursor() const;
int getX() const;
int getY() const;
void getPosition(int &x, int &y) const;
void setX(int x);
void setY(int y);
void setPosition(int x, int y);
double getX() const;
double getY() const;
void getPosition(double &x, double &y) const;
void setX(double x);
void setY(double y);
void setPosition(double x, double y);
void setVisible(bool visible);
bool isDown(Button *buttonlist) const;
bool isVisible() const;
+7 -7
View File
@@ -111,31 +111,31 @@ int w_getY(lua_State *L)
int w_getPosition(lua_State *L)
{
int x, y;
double x, y;
instance()->getPosition(x, y);
lua_pushinteger(L, x);
lua_pushinteger(L, y);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
return 2;
}
int w_setX(lua_State *L)
{
int x = luaL_checkint(L, 1);
double x = luaL_checknumber(L, 1);
instance()->setX(x);
return 0;
}
int w_setY(lua_State *L)
{
int y = luaL_checkint(L, 1);
double y = luaL_checknumber(L, 1);
instance()->setY(y);
return 0;
}
int w_setPosition(lua_State *L)
{
int x = luaL_checkint(L, 1);
int y = luaL_checkint(L, 2);
double x = luaL_checknumber(L, 1);
double y = luaL_checknumber(L, 2);
instance()->setPosition(x, y);
return 0;
}
@@ -50,7 +50,7 @@ OSStatus readFunc(void *inClientData, SInt64 inPosition, UInt32 requestCount, vo
else
{
*actualCount = 0;
return kAudioFileUnspecifiedError;
return kAudioFilePositionError;
}
return noErr;
+5 -1
View File
@@ -115,7 +115,7 @@ public:
virtual bool setFullscreen(bool fullscreen, FullscreenType fstype) = 0;
virtual bool setFullscreen(bool fullscreen) = 0;
virtual bool onWindowResize(int width, int height) = 0;
virtual bool onSizeChanged(int width, int height) = 0;
virtual int getDisplayCount() const = 0;
@@ -154,6 +154,10 @@ public:
virtual bool isMouseGrabbed() const = 0;
virtual void getPixelDimensions(int &w, int &h) const = 0;
// Note: window-space coordinates are not necessarily the same as
// density-independent units (which toPixels and fromPixels use.)
virtual void windowToPixelCoords(double *x, double *y) const = 0;
virtual void pixelToWindowCoords(double *x, double *y) const = 0;
virtual double getPixelScale() const = 0;
+30 -36
View File
@@ -470,18 +470,12 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
updateSettings(f);
if (gfx != nullptr)
{
int width = curMode.width;
int height = curMode.height;
SDL_GL_GetDrawableSize(window, &width, &height);
gfx->setMode(width, height, curMode.settings.sRGB);
}
gfx->setMode(curMode.pixelwidth, curMode.pixelheight, curMode.settings.sRGB);
return true;
}
bool Window::onWindowResize(int width, int height)
bool Window::onSizeChanged(int width, int height)
{
if (!window)
return false;
@@ -489,6 +483,12 @@ bool Window::onWindowResize(int width, int height)
curMode.width = width;
curMode.height = height;
SDL_GL_GetDrawableSize(window, &curMode.pixelwidth, &curMode.pixelheight);
graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
if (gfx != nullptr)
gfx->setViewportSize(curMode.pixelwidth, curMode.pixelheight);
return true;
}
@@ -498,6 +498,7 @@ void Window::updateSettings(const WindowSettings &newsettings)
// Set the new display mode as the current display mode.
SDL_GetWindowSize(window, &curMode.width, &curMode.height);
SDL_GL_GetDrawableSize(window, &curMode.pixelwidth, &curMode.pixelheight);
if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
@@ -604,13 +605,7 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
// Update the viewport size now instead of waiting for event polling.
graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
if (gfx != nullptr)
{
int width = curMode.width;
int height = curMode.height;
SDL_GL_GetDrawableSize(window, &width, &height);
gfx->setViewportSize(width, height);
}
gfx->setViewportSize(curMode.pixelwidth, curMode.pixelheight);
return true;
}
@@ -846,31 +841,30 @@ bool Window::isMouseGrabbed() const
void Window::getPixelDimensions(int &w, int &h) const
{
if (window)
SDL_GL_GetDrawableSize(window, &w, &h);
else
{
w = curMode.width;
h = curMode.height;
}
w = curMode.pixelwidth;
h = curMode.pixelheight;
}
void Window::windowToPixelCoords(double *x, double *y) const
{
if (x != nullptr)
*x = (*x) * ((double) curMode.pixelwidth / (double) curMode.width);
if (y != nullptr)
*y = (*y) * ((double) curMode.pixelheight / (double) curMode.height);
}
void Window::pixelToWindowCoords(double *x, double *y) const
{
if (x != nullptr)
*x = (*x) * ((double) curMode.width / (double) curMode.pixelwidth);
if (y != nullptr)
*y = (*y) * ((double) curMode.height / (double) curMode.pixelheight);
}
double Window::getPixelScale() const
{
double scale = 1.0;
if (window)
{
int wheight;
SDL_GetWindowSize(window, nullptr, &wheight);
int dheight = wheight;
SDL_GL_GetDrawableSize(window, nullptr, &dheight);
scale = (double) dheight / wheight;
}
return scale;
// TODO: Return the density display metric on Android.
return (double) curMode.pixelheight / (double) curMode.height;
}
double Window::toPixels(double x) const
+5 -1
View File
@@ -47,7 +47,7 @@ public:
bool setFullscreen(bool fullscreen, FullscreenType fstype);
bool setFullscreen(bool fullscreen);
bool onWindowResize(int width, int height);
bool onSizeChanged(int width, int height);
int getDisplayCount() const;
@@ -85,6 +85,8 @@ public:
bool isMouseGrabbed() const;
void getPixelDimensions(int &w, int &h) const;
void windowToPixelCoords(double *x, double *y) const;
void pixelToWindowCoords(double *x, double *y) const;
double getPixelScale() const;
@@ -129,6 +131,8 @@ private:
{
int width = 800;
int height = 600;
int pixelwidth = 800;
int pixelheight = 600;
WindowSettings settings;
StrongRef<love::image::ImageData> icon;