Probe Apple GL extensions at runtime instead of assuming them on macOS. A macOS build of the GL renderer can run against a non-Apple GL - Mesa via the Wayland video driver, or Mesa GLX in a Cocoa-less X11 build - where GL_APPLE_ycbcr_422, GL_APPLE_texture_range and GL_APPLE_client_storage do not exist. Advertising UYVY unconditionally made ffplay/mpv negotiate a texture format whose glTexImage2D then failed with GL_INVALID_ENUM, leaving the window empty; the storage-hint glTexParameteri calls raised the same error on every texture. Gate all three paths on the extension string; Apple's own GL always advertises them, so CGL behavior is unchanged. --- src/render/opengl/SDL_render_gl.c +++ src/render/opengl/SDL_render_gl.c @@ -109,6 +109,14 @@ typedef struct bool GL_EXT_framebuffer_object_supported; GL_FBOList *framebuffers; +#ifdef SDL_PLATFORM_MACOS + /* A macOS build may run against a non-Apple GL, e.g. Mesa via the + Wayland video driver, which lacks the Apple extensions. */ + bool GL_APPLE_ycbcr_422_supported; + bool GL_APPLE_texture_range_supported; + bool GL_APPLE_client_storage_supported; +#endif + // OpenGL functions #define SDL_PROC(ret, func, params) ret (APIENTRY *func) params; #include "SDL_glfuncs.h" @@ -417,7 +425,7 @@ static bool GL_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode return true; } -static bool convert_format(Uint32 pixel_format, GLint *internalFormat, GLenum *format, GLenum *type) +static bool convert_format(GL_RenderData *renderdata, Uint32 pixel_format, GLint *internalFormat, GLenum *format, GLenum *type) { switch (pixel_format) { case SDL_PIXELFORMAT_BGRA32: @@ -443,6 +451,9 @@ static bool convert_format(Uint32 pixel_format, GLint *internalFormat, GLenum *f break; #ifdef SDL_PLATFORM_MACOS case SDL_PIXELFORMAT_UYVY: + if (!renderdata->GL_APPLE_ycbcr_422_supported) { + return false; + } *internalFormat = GL_RGB8; *format = GL_YCBCR_422_APPLE; *type = GL_UNSIGNED_SHORT_8_8_APPLE; @@ -574,7 +585,7 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P return SDL_SetError("Render targets not supported by OpenGL"); } - if (!convert_format(texture->format, &internalFormat, &format, &type)) { + if (!convert_format(renderdata, texture->format, &internalFormat, &format, &type)) { return SDL_SetError("Texture format %s not supported by OpenGL", SDL_GetPixelFormatName(texture->format)); } @@ -664,14 +675,17 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P #ifndef STORAGE_SHARED_APPLE #define STORAGE_SHARED_APPLE 0x85BF #endif - if (texture->access == SDL_TEXTUREACCESS_STREAMING) { - renderdata->glTexParameteri(textype, GL_TEXTURE_STORAGE_HINT_APPLE, - GL_STORAGE_SHARED_APPLE); - } else { - renderdata->glTexParameteri(textype, GL_TEXTURE_STORAGE_HINT_APPLE, - GL_STORAGE_CACHED_APPLE); + if (renderdata->GL_APPLE_texture_range_supported) { + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + renderdata->glTexParameteri(textype, GL_TEXTURE_STORAGE_HINT_APPLE, + GL_STORAGE_SHARED_APPLE); + } else { + renderdata->glTexParameteri(textype, GL_TEXTURE_STORAGE_HINT_APPLE, + GL_STORAGE_CACHED_APPLE); + } } - if (texture->access == SDL_TEXTUREACCESS_STREAMING && texture->format == SDL_PIXELFORMAT_ARGB8888 && (texture->w % 8) == 0) { + if (renderdata->GL_APPLE_client_storage_supported && + texture->access == SDL_TEXTUREACCESS_STREAMING && texture->format == SDL_PIXELFORMAT_ARGB8888 && (texture->w % 8) == 0) { renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, @@ -1625,7 +1639,7 @@ static SDL_Surface *GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect * GL_ActivateRenderer(renderer); - if (!convert_format(format, &internalFormat, &targetFormat, &type)) { + if (!convert_format(data, format, &internalFormat, &targetFormat, &type)) { SDL_SetError("Texture format %s not supported by OpenGL", SDL_GetPixelFormatName(format)); return NULL; } @@ -1994,7 +2008,12 @@ static bool GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pr } #endif #ifdef SDL_PLATFORM_MACOS - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_UYVY); + data->GL_APPLE_ycbcr_422_supported = SDL_GL_ExtensionSupported("GL_APPLE_ycbcr_422"); + data->GL_APPLE_texture_range_supported = SDL_GL_ExtensionSupported("GL_APPLE_texture_range"); + data->GL_APPLE_client_storage_supported = SDL_GL_ExtensionSupported("GL_APPLE_client_storage"); + if (data->GL_APPLE_ycbcr_422_supported) { + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_UYVY); + } #endif if (SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {