From 52c4f2c119f9bea5b8d0e175af03761443042576 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 23 Feb 2015 17:55:30 -0400 Subject: [PATCH] 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 --- src/modules/audio/openal/Source.cpp | 4 +- src/modules/event/sdl/Event.cpp | 20 ++---- src/modules/keyboard/Keyboard.h | 2 +- src/modules/keyboard/sdl/Keyboard.cpp | 16 +++-- src/modules/keyboard/sdl/Keyboard.h | 2 +- src/modules/keyboard/wrap_Keyboard.cpp | 8 +-- src/modules/mouse/Mouse.h | 12 ++-- src/modules/mouse/sdl/Mouse.cpp | 56 ++++++++-------- src/modules/mouse/sdl/Mouse.h | 12 ++-- src/modules/mouse/wrap_Mouse.cpp | 14 ++-- .../sound/lullaby/CoreAudioDecoder.cpp | 2 +- src/modules/window/Window.h | 6 +- src/modules/window/sdl/Window.cpp | 66 +++++++++---------- src/modules/window/sdl/Window.h | 6 +- 14 files changed, 112 insertions(+), 114 deletions(-) diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index 79acb43f2..7132ad8f4 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -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 diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 595aa270c..96dabd461 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -46,11 +46,8 @@ namespace sdl static void windowToPixelCoords(double *x, double *y) { window::Window *window = Module::getInstance(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(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(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(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. diff --git a/src/modules/keyboard/Keyboard.h b/src/modules/keyboard/Keyboard.h index ab36eeda6..1eb3de35d 100644 --- a/src/modules/keyboard/Keyboard.h +++ b/src/modules/keyboard/Keyboard.h @@ -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. diff --git a/src/modules/keyboard/sdl/Keyboard.cpp b/src/modules/keyboard/sdl/Keyboard.cpp index e6c5a6d8b..266cf3648 100644 --- a/src/modules/keyboard/sdl/Keyboard.cpp +++ b/src/modules/keyboard/sdl/Keyboard.cpp @@ -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(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); diff --git a/src/modules/keyboard/sdl/Keyboard.h b/src/modules/keyboard/sdl/Keyboard.h index 27a16f67b..46d9d0fe4 100644 --- a/src/modules/keyboard/sdl/Keyboard.h +++ b/src/modules/keyboard/sdl/Keyboard.h @@ -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; diff --git a/src/modules/keyboard/wrap_Keyboard.cpp b/src/modules/keyboard/wrap_Keyboard.cpp index 136a3a0f1..58fefd3e8 100644 --- a/src/modules/keyboard/wrap_Keyboard.cpp +++ b/src/modules/keyboard/wrap_Keyboard.cpp @@ -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); } diff --git a/src/modules/mouse/Mouse.h b/src/modules/mouse/Mouse.h index 05f50f473..bf23018f7 100644 --- a/src/modules/mouse/Mouse.h +++ b/src/modules/mouse/Mouse.h @@ -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; diff --git a/src/modules/mouse/sdl/Mouse.cpp b/src/modules/mouse/sdl/Mouse.cpp index 0116365df..72ed2e787 100644 --- a/src/modules/mouse/sdl/Mouse.cpp +++ b/src/modules/mouse/sdl/Mouse.cpp @@ -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(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(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) diff --git a/src/modules/mouse/sdl/Mouse.h b/src/modules/mouse/sdl/Mouse.h index f63239d1b..7c285fd58 100644 --- a/src/modules/mouse/sdl/Mouse.h +++ b/src/modules/mouse/sdl/Mouse.h @@ -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; diff --git a/src/modules/mouse/wrap_Mouse.cpp b/src/modules/mouse/wrap_Mouse.cpp index d45fe41a4..cfee73f75 100644 --- a/src/modules/mouse/wrap_Mouse.cpp +++ b/src/modules/mouse/wrap_Mouse.cpp @@ -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; } diff --git a/src/modules/sound/lullaby/CoreAudioDecoder.cpp b/src/modules/sound/lullaby/CoreAudioDecoder.cpp index 0b5d4fba6..b176ba4ac 100644 --- a/src/modules/sound/lullaby/CoreAudioDecoder.cpp +++ b/src/modules/sound/lullaby/CoreAudioDecoder.cpp @@ -50,7 +50,7 @@ OSStatus readFunc(void *inClientData, SInt64 inPosition, UInt32 requestCount, vo else { *actualCount = 0; - return kAudioFileUnspecifiedError; + return kAudioFilePositionError; } return noErr; diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index 733df72b3..d451c63e0 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -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; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index fd6426a62..3b6676d3c 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -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(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(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 diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index bf623a005..7635b7467 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -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 icon;