mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user