summaryrefslogtreecommitdiff
path: root/src/graphics/OGLHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/OGLHelper.cpp')
-rw-r--r--src/graphics/OGLHelper.cpp440
1 files changed, 440 insertions, 0 deletions
diff --git a/src/graphics/OGLHelper.cpp b/src/graphics/OGLHelper.cpp
new file mode 100644
index 0000000..3f8b537
--- /dev/null
+++ b/src/graphics/OGLHelper.cpp
@@ -0,0 +1,440 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OGLHelper.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include "GLContext.h"
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+#include <cstring>
+#include <cstdlib>
+#include <assert.h>
+
+#if defined(__APPLE__)
+#include <OpenGL/OpenGL.h>
+#endif
+
+using namespace std;
+
+namespace avg {
+
+namespace glproc {
+#ifndef AVG_ENABLE_EGL
+ PFNGLBUFFERSUBDATAPROC BufferSubData;
+ PFNGLGETBUFFERSUBDATAPROC GetBufferSubData;
+ PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer;
+ PFNGLDRAWBUFFERSPROC DrawBuffers;
+ PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements;
+ PFNGLGETOBJECTPARAMETERIVARBPROC GetObjectParameteriv;
+#endif
+ PFNGLGENBUFFERSPROC GenBuffers;
+ PFNGLBUFFERDATAPROC BufferData;
+ PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback;
+ PFNGLDELETEBUFFERSPROC DeleteBuffers;
+ PFNGLBINDBUFFERPROC BindBuffer;
+ PFNGLMAPBUFFERPROC MapBuffer;
+ PFNGLUNMAPBUFFERPROC UnmapBuffer;
+
+ PFNGLCREATESHADERPROC CreateShader;
+ PFNGLSHADERSOURCEPROC ShaderSource;
+ PFNGLCOMPILESHADERPROC CompileShader;
+ PFNGLCREATEPROGRAMPROC CreateProgram;
+ PFNGLATTACHSHADERPROC AttachShader;
+ PFNGLLINKPROGRAMPROC LinkProgram;
+ PFNGLGETSHADERIVPROC GetShaderiv;
+ PFNGLGETPROGRAMIVPROC GetProgramiv;
+ PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+ PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
+ PFNGLUSEPROGRAMPROC UseProgram;
+ PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
+ PFNGLUNIFORM1IPROC Uniform1i;
+ PFNGLUNIFORM1FPROC Uniform1f;
+ PFNGLUNIFORM2FPROC Uniform2f;
+ PFNGLUNIFORM3FPROC Uniform3f;
+ PFNGLUNIFORM4FPROC Uniform4f;
+ PFNGLUNIFORM1FVPROC Uniform1fv;
+ PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
+
+ PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
+ PFNGLBLENDEQUATIONPROC BlendEquation;
+ PFNGLBLENDCOLORPROC BlendColor;
+ PFNGLACTIVETEXTUREPROC ActiveTexture;
+ PFNGLGENERATEMIPMAPPROC GenerateMipmap;
+
+ PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus;
+ PFNGLGENFRAMEBUFFERSPROC GenFramebuffers;
+ PFNGLBINDFRAMEBUFFERPROC BindFramebuffer;
+ PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D;
+ PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers;
+ PFNGLGENRENDERBUFFERSPROC GenRenderbuffers;
+ PFNGLBINDRENDERBUFFERPROC BindRenderbuffer;
+ PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage;
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample;
+ PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer;
+ PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers;
+ PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
+ PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
+ PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation;
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+ PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
+#endif
+#ifdef _WIN32
+ PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
+ PFNWGLGETSWAPINTERVALEXTPROC GetSwapIntervalEXT;
+ PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
+#endif
+
+ void * s_hGLLib = 0;
+}
+
+bool queryOGLExtension(const char *extName)
+{
+ char *p;
+ size_t extNameLen = strlen(extName);
+
+ p = (char *)glGetString(GL_EXTENSIONS);
+ AVG_ASSERT(p != 0);
+ char * end = p + strlen(p);
+ while (p < end) {
+ size_t n = strcspn(p, " ");
+ if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
+ return true;
+ }
+ p += (n + 1);
+ }
+ return false;
+}
+
+bool queryGLXExtension(const char *extName)
+{
+#if (defined __APPLE__) || (defined _WIN32) || (defined AVG_ENABLE_EGL)
+ return false;
+#else
+ int extNameLen = strlen(extName);
+
+ Display * display = XOpenDisplay(0);
+ char * p = (char *)glXQueryExtensionsString(display, DefaultScreen(display));
+ if (NULL == p) {
+ throw Exception(AVG_ERR_VIDEO_GENERAL, "Couldn't get GLX extension string.");
+ }
+
+ char * end = p + strlen(p);
+
+ while (p < end) {
+ int n = strcspn(p, " ");
+ if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
+// If we close the display connection on some drivers (at least fglrx/Ubuntu 11.04),
+// libavg crashes soon afterwards.
+// XCloseDisplay(display);
+ return true;
+ }
+ p += (n + 1);
+ }
+// XCloseDisplay(display);
+ return false;
+#endif
+}
+
+string AVG_API oglModeToString(int mode)
+{
+ switch (mode) {
+ case GL_ALPHA:
+ return "GL_ALPHA";
+ case GL_RGB:
+ return "GL_RGB";
+ case GL_RGBA:
+ return "GL_RGBA";
+#ifdef AVG_ENABLE_EGL
+ case GL_BGRA_EXT:
+ return "GL_BGRA_EXT";
+#else
+ case GL_BGR:
+ return "GL_BGR";
+ case GL_BGRA:
+ return "GL_BGRA";
+#endif
+ default:
+ return "UNKNOWN";
+ }
+}
+
+#ifdef _WIN32
+#define GL_ALL_CLIENT_ATTRIB_BITS GL_CLIENT_ALL_ATTRIB_BITS
+#endif
+
+string oglMemoryMode2String(OGLMemoryMode mode)
+{
+ switch (mode) {
+ case MM_PBO:
+ return "PBO";
+ case MM_OGL:
+ return "OGL";
+ default:
+ return "invalid gl mem mode";
+ }
+}
+
+void AVG_API clearGLBuffers(GLbitfield mask, bool bOpaque)
+{
+ float alpha;
+ if (bOpaque) {
+ alpha = 1.0;
+ } else {
+ alpha = 0.0;
+ }
+ glClearColor(0.0, 0.0, 0.0, alpha);
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ glStencilMask(~0);
+ glClearStencil(0);
+ }
+ glClear(mask);
+ GLContext::checkError("clearGLBuffers()");
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ glStencilMask(0);
+ }
+}
+
+void invalidGLCall()
+{
+ assert(false);
+}
+
+void loadGLLibrary()
+{
+#ifdef _WIN32
+ const char * pszFName = "OPENGL32.DLL";
+ char szErr[512];
+
+ glproc::s_hGLLib = (void *)LoadLibrary(pszFName);
+
+ if (glproc::s_hGLLib == 0) {
+ FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
+ 0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ szErr, 512, 0);
+ throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
+ + szErr);
+ }
+#else
+#ifdef __APPLE__
+ const char * pszFName = "/System/Library/Frameworks/OpenGL.framework/OpenGL";
+#else
+#ifdef AVG_ENABLE_EGL
+ const char * pszFName = "libGLESv2.so";
+#else
+ const char * pszFName = "libGL.so.1";
+#endif
+#endif
+ glproc::s_hGLLib = dlopen(pszFName, RTLD_NOW);
+ if (glproc::s_hGLLib == 0) {
+ const char * pszErr = (char *)dlerror();
+ throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
+ + pszErr);
+ }
+#endif
+}
+
+GLfunction getProcAddress(const string& sName)
+{
+ AVG_ASSERT(glproc::s_hGLLib);
+#ifdef _WIN32
+ GLfunction pProc = (GLfunction)wglGetProcAddress(sName.c_str());
+/*
+ if (!pProc) {
+ char szErr[512];
+ FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
+ 0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ szErr, 512, 0);
+ throw Exception(AVG_ERR_VIDEO_GENERAL,
+ string("wglGetProcAddress("+sName+") failed: ") + szErr);
+ }
+*/
+#else
+ GLfunction pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName.c_str());
+ if (!pProc) {
+ // If the name didn't work, try using an underscore :-).
+ string sName_ = string("_")+sName;
+ pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName_.c_str());
+ }
+#endif
+ return(pProc);
+}
+
+GLfunction getFuzzyProcAddress(const char * psz)
+{
+ GLfunction pProc = getProcAddress(psz);
+ if (!pProc) {
+ string s = string(psz)+"EXT";
+ pProc = getProcAddress(s);
+ }
+ if (!pProc) {
+ string s = string(psz)+"ARB";
+ pProc = getProcAddress(s);
+ }
+ if (!pProc) {
+ string s = string(psz)+"OES";
+ pProc = getProcAddress(s);
+ }
+ if (!pProc) {
+ pProc = invalidGLCall;
+ }
+ return pProc;
+}
+
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+GLfunction getglXProcAddress(const char * psz)
+{
+ GLfunction pProc = (GLfunction)glXGetProcAddress((const GLubyte *)psz);
+ if (!pProc) {
+ pProc = invalidGLCall;
+ }
+ return pProc;
+}
+#endif
+
+#ifdef _WIN32
+GLfunction getwglProcAddress(const char * psz)
+{
+ GLfunction pProc = (GLfunction)wglGetProcAddress((LPCSTR)psz);
+ if (!pProc) {
+ pProc = invalidGLCall;
+ }
+ return pProc;
+}
+#endif
+
+namespace glproc {
+
+ void init() {
+ static bool s_bInitialized = false;
+ if (s_bInitialized) {
+ return;
+ }
+ s_bInitialized = true;
+ loadGLLibrary();
+
+ GenBuffers = (PFNGLGENBUFFERSPROC)getFuzzyProcAddress("glGenBuffers");
+ BufferData = (PFNGLBUFFERDATAPROC)getFuzzyProcAddress("glBufferData");
+ DeleteBuffers = (PFNGLDELETEBUFFERSPROC)getFuzzyProcAddress("glDeleteBuffers");
+ BindBuffer = (PFNGLBINDBUFFERPROC)getFuzzyProcAddress("glBindBuffer");
+ MapBuffer = (PFNGLMAPBUFFERPROC)getFuzzyProcAddress("glMapBuffer");
+ UnmapBuffer = (PFNGLUNMAPBUFFERPROC)getFuzzyProcAddress("glUnmapBuffer");
+
+ CreateShader = (PFNGLCREATESHADERPROC)getFuzzyProcAddress("glCreateShader");
+ ShaderSource = (PFNGLSHADERSOURCEPROC)getFuzzyProcAddress("glShaderSource");
+ CompileShader = (PFNGLCOMPILESHADERPROC)getFuzzyProcAddress("glCompileShader");
+ CreateProgram= (PFNGLCREATEPROGRAMPROC)getFuzzyProcAddress("glCreateProgram");
+ AttachShader = (PFNGLATTACHSHADERPROC)getFuzzyProcAddress("glAttachShader");
+ LinkProgram = (PFNGLLINKPROGRAMPROC)getFuzzyProcAddress("glLinkProgram");
+ GetShaderiv = (PFNGLGETSHADERIVPROC)getFuzzyProcAddress("glGetShaderiv");
+ GetProgramiv = (PFNGLGETPROGRAMIVPROC)getFuzzyProcAddress("glGetProgramiv");
+ GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
+ getFuzzyProcAddress("glGetShaderInfoLog");
+ GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
+ getFuzzyProcAddress("glGetProgramInfoLog");
+ UseProgram =(PFNGLUSEPROGRAMPROC) getFuzzyProcAddress("glUseProgram");
+ GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
+ getFuzzyProcAddress("glGetUniformLocation");
+ Uniform1i = (PFNGLUNIFORM1IPROC)getFuzzyProcAddress("glUniform1i");
+ Uniform1f = (PFNGLUNIFORM1FPROC)getFuzzyProcAddress("glUniform1f");
+ Uniform2f = (PFNGLUNIFORM2FPROC)getFuzzyProcAddress("glUniform2f");
+ Uniform3f = (PFNGLUNIFORM3FPROC)getFuzzyProcAddress("glUniform3f");
+ Uniform4f = (PFNGLUNIFORM4FPROC)getFuzzyProcAddress("glUniform4f");
+ Uniform1fv = (PFNGLUNIFORM1FVPROC)getFuzzyProcAddress("glUniform1fv");
+ UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
+ getFuzzyProcAddress("glUniformMatrix4fv");
+
+ BlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)
+ getFuzzyProcAddress("glBlendFuncSeparate");
+ BlendEquation = (PFNGLBLENDEQUATIONPROC)getFuzzyProcAddress("glBlendEquation");
+ BlendColor = (PFNGLBLENDCOLORPROC)getFuzzyProcAddress("glBlendColor");
+ ActiveTexture = (PFNGLACTIVETEXTUREPROC)getFuzzyProcAddress("glActiveTexture");
+ GenerateMipmap = (PFNGLGENERATEMIPMAPPROC)getFuzzyProcAddress
+ ("glGenerateMipmap");
+
+ CheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)
+ getFuzzyProcAddress("glCheckFramebufferStatus");
+ GenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)
+ getFuzzyProcAddress("glGenFramebuffers");
+ BindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)
+ getFuzzyProcAddress("glBindFramebuffer");
+ FramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)
+ getFuzzyProcAddress("glFramebufferTexture2D");
+ DeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)
+ getFuzzyProcAddress("glDeleteFramebuffers");
+ GenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)
+ getFuzzyProcAddress("glGenRenderbuffers");
+ BindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)
+ getFuzzyProcAddress("glBindRenderbuffer");
+ RenderbufferStorage= (PFNGLRENDERBUFFERSTORAGEPROC)
+ getFuzzyProcAddress("glRenderbufferStorage");
+ RenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)
+ getFuzzyProcAddress("glRenderbufferStorageMultisample");
+ FramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)
+ getFuzzyProcAddress("glFramebufferRenderbuffer");
+
+ DeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)
+ getFuzzyProcAddress("glDeleteRenderbuffers");
+#ifndef AVG_ENABLE_EGL
+ BufferSubData = (PFNGLBUFFERSUBDATAPROC)getFuzzyProcAddress("glBufferSubData");
+ GetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)getFuzzyProcAddress
+ ("glGetBufferSubData");
+ GetObjectParameteriv = (PFNGLGETOBJECTPARAMETERIVARBPROC)
+ getFuzzyProcAddress("glGetObjectParameteriv");
+
+ BlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)
+ getFuzzyProcAddress("glBlitFramebuffer");
+ DrawBuffers = (PFNGLDRAWBUFFERSPROC)getFuzzyProcAddress("glDrawBuffers");
+ DrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
+ getFuzzyProcAddress("glDrawRangeElements");
+ DebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKARBPROC)
+ getFuzzyProcAddress("glDebugMessageCallback");
+#endif
+ VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
+ getFuzzyProcAddress("glVertexAttribPointer");
+ EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
+ getFuzzyProcAddress("glEnableVertexAttribArray");
+ BindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
+ getFuzzyProcAddress("glBindAttribLocation");
+#if defined(linux) && !defined(AVG_ENABLE_EGL)
+ SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
+ getglXProcAddress("glXSwapIntervalEXT");
+#endif
+#ifdef _WIN32
+ GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
+ getwglProcAddress("wglGetExtensionsStringARB");
+ GetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)
+ getwglProcAddress("wglGetSwapIntervalEXT");
+ SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
+ getwglProcAddress("wglSwapIntervalEXT");
+#endif
+ }
+}
+
+}