Merge branch 'master' into 12.0-development

This commit is contained in:
Alex Szpakowski
2020-12-26 22:48:08 -04:00
9 changed files with 149 additions and 55 deletions
@@ -4212,7 +4212,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = { 08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1000; LastUpgradeCheck = 1230;
TargetAttributes = { TargetAttributes = {
FA0B78DC1A958B90000E1D17 = { FA0B78DC1A958B90000E1D17 = {
CreatedOnToolsVersion = 6.1.1; CreatedOnToolsVersion = 6.1.1;
@@ -5397,6 +5397,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/ios/libraries/freetype", "$(PROJECT_DIR)/ios/libraries/freetype",
); );
MARKETING_VERSION = 11.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"-undefined", "-undefined",
dynamic_lookup, dynamic_lookup,
@@ -5440,6 +5441,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/ios/libraries/freetype", "$(PROJECT_DIR)/ios/libraries/freetype",
); );
MARKETING_VERSION = 11.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"-undefined", "-undefined",
dynamic_lookup, dynamic_lookup,
@@ -5484,6 +5486,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/ios/libraries/freetype", "$(PROJECT_DIR)/ios/libraries/freetype",
); );
MARKETING_VERSION = 11.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"-undefined", "-undefined",
dynamic_lookup, dynamic_lookup,
+8 -1
View File
@@ -148,7 +148,14 @@ bool openURL(const std::string &url)
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jclass activity = env->FindClass("org/love2d/android/GameActivity"); jclass activity = env->FindClass("org/love2d/android/GameActivity");
jmethodID openURL = env->GetStaticMethodID(activity, "openURL", "(Ljava/lang/String;)Z"); jmethodID openURL = env->GetStaticMethodID(activity, "openURLFromLOVE", "(Ljava/lang/String;)Z");
if (openURL == nullptr)
{
env->ExceptionClear();
openURL = env->GetStaticMethodID(activity, "openURL", "(Ljava/lang/String;)Z");
}
jstring url_jstring = (jstring) env->NewStringUTF(url.c_str()); jstring url_jstring = (jstring) env->NewStringUTF(url.c_str());
jboolean result = env->CallStaticBooleanMethod(activity, openURL, url_jstring); jboolean result = env->CallStaticBooleanMethod(activity, openURL, url_jstring);
+8 -4
View File
@@ -60,7 +60,11 @@ static const char global_syntax[] = R"(
#define DepthCubeImage samplerCubeShadow #define DepthCubeImage samplerCubeShadow
#endif #endif
#define extern uniform #define extern uniform
#ifdef GL_EXT_texture_array #if defined(GL_EXT_texture_array) && (!defined(GL_ES) || __VERSION__ > 100 || defined(GL_OES_gpu_shader5))
// Only used when !GLSLES1 to work around Ouya driver bug. But we still want it
// enabled for glslang validation when glsl 1-on-3 is used, so also enable it if
// OES_gpu_shader5 exists.
#define LOVE_EXT_TEXTURE_ARRAY_ENABLED
#extension GL_EXT_texture_array : enable #extension GL_EXT_texture_array : enable
#endif #endif
#ifdef GL_OES_texture_3D #ifdef GL_OES_texture_3D
@@ -122,7 +126,7 @@ void love_initializeBuiltinUniforms() {
static const char global_functions[] = R"( static const char global_functions[] = R"(
#ifdef GL_ES #ifdef GL_ES
#if __VERSION__ >= 300 || defined(GL_EXT_texture_array) #if __VERSION__ >= 300 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
precision lowp sampler2DArray; precision lowp sampler2DArray;
#endif #endif
#if __VERSION__ >= 300 || defined(GL_OES_texture_3D) #if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
@@ -158,7 +162,7 @@ static const char global_functions[] = R"(
#if __VERSION__ > 100 || defined(GL_OES_texture_3D) #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); } vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
#endif #endif
#if __VERSION__ >= 130 || defined(GL_EXT_texture_array) #if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); } vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
#endif #endif
#ifdef PIXEL #ifdef PIXEL
@@ -167,7 +171,7 @@ static const char global_functions[] = R"(
#if __VERSION__ > 100 || defined(GL_OES_texture_3D) #if __VERSION__ > 100 || defined(GL_OES_texture_3D)
vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); } vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
#endif #endif
#if __VERSION__ >= 130 || defined(GL_EXT_texture_array) #if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); } vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
#endif #endif
#endif #endif
+2 -2
View File
@@ -316,8 +316,8 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
// Set whether drawing converts input from linear -> sRGB colorspace. // Set whether drawing converts input from linear -> sRGB colorspace.
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB if (!gl.bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|| GLAD_ES_VERSION_3_0) || GLAD_EXT_framebuffer_sRGB || GLAD_ES_VERSION_3_0))
{ {
if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control) if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect()); gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
+30 -10
View File
@@ -150,6 +150,16 @@ bool OpenGL::initContext()
if (strstr(device, "HD Graphics 4000") || strstr(device, "HD Graphics 2500")) if (strstr(device, "HD Graphics 4000") || strstr(device, "HD Graphics 2500"))
bugs.clientWaitSyncStalls = true; bugs.clientWaitSyncStalls = true;
} }
if (getVendor() == VENDOR_INTEL)
{
const char *device = (const char *) glGetString(GL_RENDERER);
if (strstr(device, "HD Graphics 3000") || strstr(device, "HD Graphics 2000")
|| !strcmp(device, "Intel(R) HD Graphics") || !strcmp(device, "Intel(R) HD Graphics Family"))
{
bugs.brokenSRGB = true;
}
}
#endif #endif
#ifdef LOVE_WINDOWS #ifdef LOVE_WINDOWS
@@ -210,8 +220,8 @@ void OpenGL::setupContext()
setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]); setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]); setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB if (!bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|| GLAD_EXT_sRGB_write_control) || GLAD_EXT_framebuffer_sRGB || GLAD_EXT_sRGB_write_control))
{ {
setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]); setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
} }
@@ -391,15 +401,23 @@ void OpenGL::initOpenGLFunctions()
} }
} }
if (GLAD_ES_VERSION_2_0 && GLAD_OES_texture_3D && !GLAD_ES_VERSION_3_0) if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
{ {
// Function signatures don't match, we'll have to conditionally call it // The Nvidia Tegra 3 driver (used by Ouya) claims to support GL_EXT_texture_array but
//fp_glTexImage3D = fp_glTexImage3DOES; // segfaults if you actually try to use it. OpenGL ES 2.0 devices should use OES_texture_3D.
fp_glTexSubImage3D = fp_glTexSubImage3DOES; // GL_EXT_texture_array is for desktops.
fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES; GLAD_EXT_texture_array = false;
fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES; if (GLAD_OES_texture_3D)
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES; {
// Function signatures don't match, we'll have to conditionally call it
//fp_glTexImage3D = fp_glTexImage3DOES;
fp_glTexSubImage3D = fp_glTexSubImage3DOES;
fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES;
fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
}
} }
if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex) if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
@@ -1881,6 +1899,8 @@ bool OpenGL::isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget,
else else
return true; return true;
case PIXELFORMAT_sRGBA8_UNORM: case PIXELFORMAT_sRGBA8_UNORM:
if (gl.bugs.brokenSRGB)
return false;
if (rendertarget) if (rendertarget)
{ {
if (GLAD_VERSION_1_0) if (GLAD_VERSION_1_0)
+7
View File
@@ -178,6 +178,13 @@ public:
**/ **/
bool brokenR8PixelFormat; bool brokenR8PixelFormat;
/**
* Intel HD Graphics drivers on Windows prior to the HD 2500/4000 have
* completely broken sRGB support.
* https://github.com/love2d/love/issues/1592
**/
bool brokenSRGB;
/** /**
* Other bugs which have workarounds that don't use conditional code at * Other bugs which have workarounds that don't use conditional code at
* the moment: * the moment:
+51 -33
View File
@@ -34,7 +34,7 @@ namespace graphics
namespace opengl namespace opengl
{ {
static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat format, GLuint texture, int layers, bool clear) static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat format, GLuint texture, int mips, int layers, bool clear)
{ {
// get currently bound fbo to reset to it later // get currently bound fbo to reset to it later
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL); GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
@@ -68,37 +68,40 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
// Make sure all faces and layers of the texture are initialized to // Make sure all faces and layers of the texture are initialized to
// transparent black. This is unfortunately probably pretty slow for // transparent black. This is unfortunately probably pretty slow for
// 2D-array and 3D textures with a lot of layers... // 2D-array and 3D textures with a lot of layers...
for (int layer = layers - 1; layer >= 0; layer--) for (int mip = mips - 1; mip >= 0; mip--)
{ {
for (int face = faces - 1; face >= 0; face--) for (int layer = layers - 1; layer >= 0; layer--)
{ {
for (GLenum attachment : fmt.framebufferAttachments) for (int face = faces - 1; face >= 0; face--)
{ {
if (attachment == GL_NONE) for (GLenum attachment : fmt.framebufferAttachments)
continue;
gl.framebufferTexture(attachment, texType, texture, 0, layer, face);
}
if (clear)
{
if (isPixelFormatDepthStencil(format))
{ {
bool hadDepthWrites = gl.hasDepthWrites(); if (attachment == GL_NONE)
if (!hadDepthWrites) // glDepthMask also affects glClear. continue;
gl.setDepthWrites(true);
gl.clearDepth(1.0); gl.framebufferTexture(attachment, texType, texture, mip, layer, face);
glClearStencil(0);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
if (!hadDepthWrites)
gl.setDepthWrites(hadDepthWrites);
} }
else
if (clear)
{ {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); if (isPixelFormatDepthStencil(format))
glClear(GL_COLOR_BUFFER_BIT); {
bool hadDepthWrites = gl.hasDepthWrites();
if (!hadDepthWrites) // glDepthMask also affects glClear.
gl.setDepthWrites(true);
gl.clearDepth(1.0);
glClearStencil(0);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
if (!hadDepthWrites)
gl.setDepthWrites(hadDepthWrites);
}
else
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
} }
} }
} }
@@ -328,28 +331,43 @@ void Texture::createTexture()
bool hasdata = slices.get(0, 0) != nullptr; bool hasdata = slices.get(0, 0) != nullptr;
// All mipmap levels need to be initialized - for color formats we can clear
// the base mip and use glGenerateMipmap after that's done. Depth and
// stencil formats don't always support glGenerateMipmap so we need to
// individually clear each mip level in that case. We avoid doing that for
// color formats because of an Intel driver bug:
// https://github.com/love2d/love/issues/1585
int clearmips = 1;
if (isPixelFormatDepthStencil(format))
clearmips = mipmapCount;
// Create a local FBO used for glReadPixels as well as MSAA blitting. // Create a local FBO used for glReadPixels as well as MSAA blitting.
if (isRenderTarget()) if (isRenderTarget())
{ {
bool clear = !hasdata; bool clear = !hasdata;
int slices = texType == TEXTURE_VOLUME ? depth : layers; int slices = texType == TEXTURE_VOLUME ? depth : layers;
framebufferStatus = createFBO(fbo, texType, format, texture, slices, clear); framebufferStatus = createFBO(fbo, texType, format, texture, clearmips, slices, clear);
} }
else if (!hasdata) else if (!hasdata)
{ {
// Initialize all slices to transparent black. // Initialize all slices to transparent black.
std::vector<uint8> emptydata(getPixelFormatSliceSize(format, w, h)); for (int mip = 0; mip < clearmips; mip++)
{
int mipw = getPixelWidth(mip);
int miph = getPixelHeight(mip);
std::vector<uint8> emptydata(getPixelFormatSliceSize(format, mipw, miph));
Rect r = {0, 0, w, h}; Rect r = {0, 0, mipw, miph};
int slices = texType == TEXTURE_VOLUME ? depth : layers; int slices = texType == TEXTURE_VOLUME ? getDepth(mip) : layers;
slices = texType == TEXTURE_CUBE ? 6 : slices; slices = texType == TEXTURE_CUBE ? 6 : slices;
for (int i = 0; i < slices; i++) for (int i = 0; i < slices; i++)
uploadByteData(format, emptydata.data(), emptydata.size(), 0, i, r); uploadByteData(format, emptydata.data(), emptydata.size(), mip, i, r);
}
} }
// Non-readable textures can't have mipmaps (enforced in the base class), // Non-readable textures can't have mipmaps (enforced in the base class),
// so generateMipmaps here is fine - when they aren't already initialized. // so generateMipmaps here is fine - when they aren't already initialized.
if (getMipmapCount() > 1 && slices.getMipmapCount() <= 1) if (clearmips < mipmapCount && slices.getMipmapCount() <= 1 && getMipmapsMode() != MIPMAPS_NONE)
generateMipmaps(); generateMipmaps();
} }
+24
View File
@@ -371,6 +371,23 @@ static int w_deprecation__gc(lua_State *)
return 0; return 0;
} }
static void luax_addcompatibilityalias(lua_State *L, const char *module, const char *name, const char *alias)
{
lua_getglobal(L, module);
if (lua_istable(L, -1))
{
lua_getfield(L, -1, alias);
bool hasalias = !lua_isnoneornil(L, -1);
lua_pop(L, 1);
if (!hasalias)
{
lua_getfield(L, -1, name);
lua_setfield(L, -2, alias);
}
}
lua_pop(L, 1);
}
int luaopen_love(lua_State *L) int luaopen_love(lua_State *L)
{ {
love::luax_insistpinnedthread(L); love::luax_insistpinnedthread(L);
@@ -480,6 +497,13 @@ int luaopen_love(lua_State *L)
love::luax_require(L, "love.data"); love::luax_require(L, "love.data");
lua_pop(L, 1); lua_pop(L, 1);
#if LUA_VERSION_NUM <= 501
// These are deprecated in Lua 5.1. LuaJIT 2.1 removes them, but code
// written assuming LuaJIT 2.0 or Lua 5.1 is used might still rely on them.
luax_addcompatibilityalias(L, "math", "fmod", "mod");
luax_addcompatibilityalias(L, "string", "gmatch", "gfind");
#endif
#ifdef LOVE_ENABLE_LUASOCKET #ifdef LOVE_ENABLE_LUASOCKET
love::luasocket::__open(L); love::luasocket::__open(L);
#endif #endif
+15 -4
View File
@@ -443,15 +443,23 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
height = mode.h; height = mode.h;
} }
// On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP // On Android, disable fullscreen first on window creation so it's
// possible to change the orientation by specifying portait width and
// height, otherwise SDL will pick the current orientation dimensions when
// fullscreen flag is set. Don't worry, we'll set it back later when user
// also requested fullscreen after the window is created.
// See https://github.com/love2d/love-android/issues/196
#ifdef LOVE_ANDROID #ifdef LOVE_ANDROID
bool fullscreen = f.fullscreen;
f.fullscreen = false;
f.fstype = FULLSCREEN_DESKTOP; f.fstype = FULLSCREEN_DESKTOP;
#endif #endif
int x = f.x; int x = f.x;
int y = f.y; int y = f.y;
if (f.useposition && !f.fullscreen) if (f.useposition)
{ {
// The position needs to be in the global coordinate space. // The position needs to be in the global coordinate space.
SDL_Rect displaybounds = {}; SDL_Rect displaybounds = {};
@@ -544,7 +552,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
// Enforce minimum window dimensions. // Enforce minimum window dimensions.
SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight); SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
if (this->settings.display != f.display || ((f.useposition || f.centered) && !f.fullscreen)) if (this->settings.display != f.display || f.useposition || f.centered)
SDL_SetWindowPosition(window, x, y); SDL_SetWindowPosition(window, x, y);
SDL_RaiseWindow(window); SDL_RaiseWindow(window);
@@ -569,8 +577,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
} }
} }
// Set fullscreen when user requested it before.
// See above for explanation.
#ifdef LOVE_ANDROID #ifdef LOVE_ANDROID
love::android::setImmersive(f.fullscreen); setFullscreen(fullscreen);
love::android::setImmersive(fullscreen);
#endif #endif
return true; return true;