From 38fca90c6ffde05e3459c7021e823cef0b3b27ac Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 28 Oct 2012 18:48:25 +0100 Subject: [PATCH 1/1] Check required extensions at start. --- flat_input.h | 5 +++-- init.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ init.h | 7 +++++-- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/flat_input.h b/flat_input.h index cf6b0b9..8b5a3ce 100644 --- a/flat_input.h +++ b/flat_input.h @@ -2,6 +2,7 @@ #define _FLAT_INPUT_H 1 #include "input.h" +#include "init.h" // A FlatInput is the normal, “classic” case of an input, where everything // comes from a single 2D array with chunky pixels. @@ -17,9 +18,9 @@ public: // mipmap generation) at that point. void finalize(); - // TODO: Check that we actually have the required extension. virtual bool can_output_linear_gamma() const { - return (type == GL_UNSIGNED_BYTE && + return (movit_srgb_textures_supported && + type == GL_UNSIGNED_BYTE && (image_format.gamma_curve == GAMMA_LINEAR || image_format.gamma_curve == GAMMA_sRGB)); } diff --git a/init.cpp b/init.cpp index 129ee4c..ac52aa2 100644 --- a/init.cpp +++ b/init.cpp @@ -2,8 +2,12 @@ #include "opengl.h" #include "util.h" +#include +#include + bool movit_initialized = false; float movit_texel_subpixel_precision; +bool movit_srgb_textures_supported; namespace { @@ -119,6 +123,43 @@ void measure_texel_subpixel_precision() check_error(); } +void get_extensions(std::set *extensions) +{ + char *str = strdup(reinterpret_cast(glGetString(GL_EXTENSIONS))); + for (char *ptr = strtok(str, " "); ptr != NULL; ptr = strtok(NULL, " ")) { + extensions->insert(ptr); + } + free(str); +} + +void check_extensions() +{ + std::set extensions; + get_extensions(&extensions); + + // We fundamentally need FBOs and floating-point textures. + assert(extensions.count("GL_ARB_framebuffer_object") != 0); + assert(extensions.count("GL_ARB_texture_float") != 0); + + // We assume that we can use non-power-of-two textures without restrictions. + assert(extensions.count("GL_ARB_texture_non_power_of_two") != 0); + + // We also need GLSL fragment shaders. + assert(extensions.count("GL_ARB_fragment_shader") != 0); + assert(extensions.count("GL_ARB_shading_language_100") != 0); + + // FlatInput and YCbCrInput uses PBOs. (They could in theory do without, + // but no modern card would really not provide it.) + assert(extensions.count("GL_ARB_pixel_buffer_object") != 0); + + // ResampleEffect uses RG textures to encode a two-component LUT. + assert(extensions.count("GL_ARB_texture_rg") != 0); + + // sRGB texture decode would be nice, but are not mandatory + // (GammaExpansionEffect can do the same thing if needed). + movit_srgb_textures_supported = extensions.count("GL_EXT_texture_sRGB"); +} + } // namespace void init_movit() @@ -132,6 +173,7 @@ void init_movit() glPixelStorei(GL_UNPACK_ALIGNMENT, 1); measure_texel_subpixel_precision(); + check_extensions(); movit_initialized = true; } diff --git a/init.h b/init.h index e0dbe63..a1e71dd 100644 --- a/init.h +++ b/init.h @@ -2,8 +2,8 @@ #define _INIT_H // Initialize the library; in particular, will query the GPU for information -// that is needed by various components. (In time, for instance, we will query -// about extensions here.) +// that is needed by various components. For instance, it verifies that +// we have all the OpenGL extensions we need. void init_movit(); // GPU features. These are not intended for end-user use. @@ -18,4 +18,7 @@ extern bool movit_initialized; // We currently don't bother to test above 2^10. extern float movit_texel_subpixel_precision; +// Whether the GPU in use supports GL_EXT_texture_sRGB. +extern bool movit_srgb_textures_supported; + #endif // !defined(_INIT_H) -- 2.39.2