diff --git a/src/plugin/utility/filesystem_browser/FileSystemBrowser/xstudio/FileSystemBrowser.qml b/src/plugin/utility/filesystem_browser/FileSystemBrowser/xstudio/FileSystemBrowser.qml index 3dfeb190d..226fc5112 100644 --- a/src/plugin/utility/filesystem_browser/FileSystemBrowser/xstudio/FileSystemBrowser.qml +++ b/src/plugin/utility/filesystem_browser/FileSystemBrowser/xstudio/FileSystemBrowser.qml @@ -31,7 +31,7 @@ Item { property var previewing: previewMediaUuid != helpers.QVariantFromUuidString("") ? previewMediaUuid == currentPlayhead.mediaUuid : false - # uri requires triple slash before drive letter on Windows, since this is the root. + // uri requires triple slash before drive letter on Windows, since this is the root. property var thumbSrcRoot: Qt.platform.os === "windows" ? "image://thumbnail/file:///" : "image://thumbnail/file://" FileSystemBrowserScanResultsModel { diff --git a/src/ui/opengl/src/opengl_viewport_renderer.cpp b/src/ui/opengl/src/opengl_viewport_renderer.cpp index 5d6431a14..53af90059 100644 --- a/src/ui/opengl/src/opengl_viewport_renderer.cpp +++ b/src/ui/opengl/src/opengl_viewport_renderer.cpp @@ -479,6 +479,12 @@ void OpenGLViewportRenderer::draw_image( const Imath::M44f &viewport_to_image_space, const float viewport_du_dx) { + // active_shader_program_ can be null if even the fallback "no image" shader + // failed to compile/link (e.g. a driver issue) - bind_textures() already + // treats this as nothing-to-draw, so match that here rather than + // dereferencing a null program. + if (!active_shader_program_) + return; active_shader_program_->use(); diff --git a/src/ui/opengl/src/shader_program_base.cpp b/src/ui/opengl/src/shader_program_base.cpp index 0ebfb7676..dd18256a3 100644 --- a/src/ui/opengl/src/shader_program_base.cpp +++ b/src/ui/opengl/src/shader_program_base.cpp @@ -573,9 +573,15 @@ GLuint compile_frag_shader(const std::string fragmentSource) { GLint maxLength = 0; glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); - // The maxLength includes the NULL character - std::vector infoLog(maxLength); - glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); + // The maxLength includes the NULL character. Some drivers report a + // compile failure but leave the info log empty, so guard against + // that instead of dereferencing an empty vector's data(). + std::string info_log_str = "(no info log provided by driver)"; + if (maxLength > 0) { + std::vector infoLog(maxLength); + glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, infoLog.data()); + info_log_str.assign(infoLog.data()); + } // We don't need the shader anymore. glDeleteShader(fragmentShader); @@ -592,7 +598,7 @@ GLuint compile_frag_shader(const std::string fragmentSource) { // Use the infoLog as you see fit. std::stringstream e; e << "Fragment shader error:\n\n" - << infoLog.data() << "\n\nin program: \n\n" + << info_log_str << "\n\nin program: \n\n" << source_with_linenumbers; throw std::runtime_error(e.str().c_str()); } @@ -618,9 +624,15 @@ GLuint compile_vertex_shader(const std::string vertexSource) { GLint maxLength = 0; glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); - // The maxLength includes the NULL character - std::vector infoLog(maxLength); - glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); + // The maxLength includes the NULL character. Some drivers report a + // compile failure but leave the info log empty, so guard against + // that instead of dereferencing an empty vector's data(). + std::string info_log_str = "(no info log provided by driver)"; + if (maxLength > 0) { + std::vector infoLog(maxLength); + glGetShaderInfoLog(vertexShader, maxLength, &maxLength, infoLog.data()); + info_log_str.assign(infoLog.data()); + } // We don't need the shader anymore. glDeleteShader(vertexShader); @@ -628,7 +640,7 @@ GLuint compile_vertex_shader(const std::string vertexSource) { // Use the infoLog as you see fit. std::stringstream e; e << "Vertex shader error:\n\n" - << infoLog.data() << "\n\nin program: \n\n" + << info_log_str << "\n\nin program: \n\n" << vertexSource; throw std::runtime_error(e.str().c_str()); @@ -832,9 +844,15 @@ void GLShaderProgram::compile(const bool force_combine_frag_shaders) { GLint maxLength = 0; glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &maxLength); - // The maxLength includes the NULL character - std::vector infoLog(maxLength); - glGetProgramInfoLog(program_, maxLength, &maxLength, &infoLog[0]); + // The maxLength includes the NULL character. Some drivers report a + // link failure but leave the info log empty, so guard against that + // instead of dereferencing an empty vector's data(). + std::string info_log_str = "(no info log provided by driver)"; + if (maxLength > 0) { + std::vector infoLog(maxLength); + glGetProgramInfoLog(program_, maxLength, &maxLength, infoLog.data()); + info_log_str.assign(infoLog.data()); + } // Detach shaders after failed link .... (not clear if this is correct, // but no errors have been observed) @@ -861,7 +879,7 @@ void GLShaderProgram::compile(const bool force_combine_frag_shaders) { // Use the infoLog as you see fit. std::stringstream e; - e << "Shader link error:\n\n" << infoLog.data(); + e << "Shader link error:\n\n" << info_log_str; std::for_each( fragment_shaders_.begin(),