diff --git a/src/VideoShader.cpp b/src/VideoShader.cpp index ee2477b1..bd2c4d30 100644 --- a/src/VideoShader.cpp +++ b/src/VideoShader.cpp @@ -437,6 +437,10 @@ void VideoMaterial::bindPlane(int p, bool updateTexture) //qDebug("bind PBO %d", p); QOpenGLBuffer &pb = d.pbo[p]; pb.bind(); + // glMapBuffer() causes sync issue. + // Call glBufferData() with NULL pointer before glMapBuffer(), the previous data in PBO will be discarded and + // glMapBuffer() returns a new allocated pointer or an unused block immediately even if GPU is still working with the previous data. + // https://www.opengl.org/wiki/Buffer_Object_Streaming#Buffer_re-specification pb.allocate(pb.size()); GLubyte* ptr = (GLubyte*)pb.map(QOpenGLBuffer::WriteOnly); if (ptr) { @@ -757,7 +761,8 @@ bool VideoMaterialPrivate::updateTexturesIfNeeded() if (update_textures) { initTextures(fmt); // check pbo support - //try_pbo = try_pbo && OpenGLHelper::isPBOSupported(); + // TODO: complete pbo extension set + try_pbo = try_pbo && OpenGLHelper::isPBOSupported(); // check PBO support with bind() is fine, no need to check extensions if (try_pbo) { for (int i = 0; i < nb_planes; ++i) { diff --git a/src/utils/OpenGLHelper.cpp b/src/utils/OpenGLHelper.cpp index d18152c2..1941d3ac 100644 --- a/src/utils/OpenGLHelper.cpp +++ b/src/utils/OpenGLHelper.cpp @@ -20,15 +20,60 @@ ******************************************************************************/ #include "OpenGLHelper.h" +#include //strstr #include #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #include +#define QOpenGLContext QGLContext #endif #include "utils/Logger.h" namespace QtAV { namespace OpenGLHelper { +bool hasExtension(const char *exts[]) +{ + const QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx) + return false; +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + const char *ext = (const char*)glGetString(GL_EXTENSIONS); + if (!ext) + return false; +#endif + for (int i = 0; exts[i]; ++i) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + if (ctx->hasExtension(exts[i])) +#else + if (strstr(ext, exts[i])) +#endif + return true; + } + return false; +} + +bool isPBOSupported() { + // check pbo support + static bool support = false; + static bool pbo_checked = false; + if (pbo_checked) + return support; + const QOpenGLContext *ctx = QOpenGLContext::currentContext(); + Q_ASSERT(ctx); + if (!ctx) + return false; + const char* exts[] = { + "GL_ARB_pixel_buffer_object", + "GL_EXT_pixel_buffer_object", + "GL_NV_pixel_buffer_object", //OpenGL ES + NULL + }; + support = hasExtension(exts); + qDebug() << "PBO: " << support; + pbo_checked = true; + return support; +} + // glActiveTexture in Qt4 on windows release mode crash for me #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifndef QT_OPENGL_ES diff --git a/src/utils/OpenGLHelper.h b/src/utils/OpenGLHelper.h index 7d6e2aa2..a9e58c48 100644 --- a/src/utils/OpenGLHelper.h +++ b/src/utils/OpenGLHelper.h @@ -68,6 +68,13 @@ namespace QtAV { namespace OpenGLHelper { +/*! + * \brief hasExtension + * Current OpenGL context must be valid. + * \param exts Ends with NULL + */ +bool hasExtension(const char* exts[]); +bool isPBOSupported(); void glActiveTexture(GLenum texture); bool videoFormatToGL(const VideoFormat& fmt, GLint* internal_format, GLenum* data_format, GLenum* data_type); int bytesOfGLFormat(GLenum format, GLenum dataType = GL_UNSIGNED_BYTE);