Provide OpenGL over Egl

The Egl backend is decoupled from the OpenGL ES build option which makes
it possible to use it as a replacement for glx.

To make this possible a new build flag is added when egl is available at
compile time and any egl specific code is now ifdefed with this flag
instead of the gles flag. In addition at runtime a windowing system enum
value is passed to the various detect methods to have egl/glx specific
detection for e.g. function pointer resolving.

By default egl is used if compiled with OpenGL ES, otherwise glx is used.
But in the non-gles case the windowing system can be selected through the
new environment variable KWIN_OPENGL_INTERFACE. Setting this variable to
"egl" the EglOnXBackend is used.

REVIEW: 106632
This commit is contained in:
Martin Gräßlin 2012-09-29 13:19:35 +02:00
parent 49cce8dede
commit a401558a43
13 changed files with 233 additions and 110 deletions

View file

@ -38,6 +38,11 @@ if(OPENGL_FOUND)
include_directories(${OPENGL_INCLUDE_DIR}) include_directories(${OPENGL_INCLUDE_DIR})
endif(OPENGL_FOUND) endif(OPENGL_FOUND)
if(OPENGL_EGL_FOUND)
include_directories(${OPENGLES_EGL_INCLUDE_DIR})
set(KWIN_HAVE_EGL 1)
endif(OPENGL_EGL_FOUND)
if(OPENGLES_FOUND) if(OPENGLES_FOUND)
include_directories(${OPENGLES_INCLUDE_DIR}) include_directories(${OPENGLES_INCLUDE_DIR})
endif(OPENGLES_FOUND) endif(OPENGLES_FOUND)
@ -110,7 +115,6 @@ set(kwin_KDEINIT_SRCS
scene.cpp scene.cpp
scene_xrender.cpp scene_xrender.cpp
scene_opengl.cpp scene_opengl.cpp
eglonxbackend.cpp
glxbackend.cpp glxbackend.cpp
thumbnailitem.cpp thumbnailitem.cpp
lanczosfilter.cpp lanczosfilter.cpp
@ -152,6 +156,10 @@ if(KWIN_BUILD_SCREENEDGES)
) )
endif(KWIN_BUILD_SCREENEDGES) endif(KWIN_BUILD_SCREENEDGES)
if(KWIN_HAVE_EGL)
set(kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} eglonxbackend.cpp)
endif(KWIN_HAVE_EGL)
qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml dbusinterface.h KWin::DBusInterface ) qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml dbusinterface.h KWin::DBusInterface )
qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Compositing.xml composite.h KWin::Compositor ) qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Compositing.xml composite.h KWin::Compositor )
qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Effects.xml effects.h KWin::EffectsHandlerImpl ) qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Effects.xml effects.h KWin::EffectsHandlerImpl )
@ -178,6 +186,10 @@ if(KWIN_BUILD_ACTIVITIES)
set(kwinLibs ${kwinLibs} ${KACTIVITIES_LIBRARY}) set(kwinLibs ${kwinLibs} ${KACTIVITIES_LIBRARY})
endif(KWIN_BUILD_ACTIVITIES) endif(KWIN_BUILD_ACTIVITIES)
if(OPENGL_EGL_FOUND)
set(kwinLibs ${kwinLibs} ${OPENGLES_EGL_LIBRARY})
endif(OPENGL_EGL_FOUND)
kde4_add_kdeinit_executable( kwin ${kwin_KDEINIT_SRCS}) kde4_add_kdeinit_executable( kwin ${kwin_KDEINIT_SRCS})
target_link_libraries(kdeinit_kwin ${kwinLibs}) target_link_libraries(kdeinit_kwin ${kwinLibs})

View file

@ -17,7 +17,6 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/ *********************************************************************/
#ifdef KWIN_HAVE_OPENGLES
#include "eglonxbackend.h" #include "eglonxbackend.h"
// kwin // kwin
#include "options.h" #include "options.h"
@ -67,9 +66,9 @@ void EglOnXBackend::init()
return; return;
} }
GLPlatform *glPlatform = GLPlatform::instance(); GLPlatform *glPlatform = GLPlatform::instance();
glPlatform->detect(); glPlatform->detect(EglPlatformInterface);
glPlatform->printResults(); glPlatform->printResults();
initGL(); initGL(EglPlatformInterface);
if (!hasGLExtension("GL_OES_EGL_image")) { if (!hasGLExtension("GL_OES_EGL_image")) {
setFailed("Required extension GL_OES_EGL_image not found, disabling compositing"); setFailed("Required extension GL_OES_EGL_image not found, disabling compositing");
return; return;
@ -99,7 +98,14 @@ bool EglOnXBackend::initRenderingContext()
EGLint major, minor; EGLint major, minor;
if (eglInitialize(dpy, &major, &minor) == EGL_FALSE) if (eglInitialize(dpy, &major, &minor) == EGL_FALSE)
return false; return false;
#ifdef KWIN_HAVE_OPENGLES
eglBindAPI(EGL_OPENGL_ES_API); eglBindAPI(EGL_OPENGL_ES_API);
#else
if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) {
kError(1212) << "bind OpenGL API failed";
return false;
}
#endif
initBufferConfigs(); initBufferConfigs();
if (!overlayWindow()->create()) { if (!overlayWindow()->create()) {
kError(1212) << "Could not get overlay window"; kError(1212) << "Could not get overlay window";
@ -111,18 +117,27 @@ bool EglOnXBackend::initRenderingContext()
eglSurfaceAttrib(dpy, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); eglSurfaceAttrib(dpy, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
eglQuerySurface(dpy, surface, EGL_POST_SUB_BUFFER_SUPPORTED_NV, &surfaceHasSubPost); if (eglQuerySurface(dpy, surface, EGL_POST_SUB_BUFFER_SUPPORTED_NV, &surfaceHasSubPost) == EGL_FALSE) {
kError(1212) << "query surface failed";
return false;
}
const EGLint context_attribs[] = { const EGLint context_attribs[] = {
#ifdef KWIN_HAVE_OPENGLES
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
EGL_NONE EGL_NONE
}; };
ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, context_attribs); ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, context_attribs);
if (ctx == EGL_NO_CONTEXT) if (ctx == EGL_NO_CONTEXT) {
kError(1212) << "Create Context failed";
return false; return false;
if (eglMakeCurrent(dpy, surface, surface, ctx) == EGL_FALSE) }
if (eglMakeCurrent(dpy, surface, surface, ctx) == EGL_FALSE) {
kError(1212) << "Make Context Current failed";
return false; return false;
}
kDebug(1212) << "EGL version: " << major << "." << minor; kDebug(1212) << "EGL version: " << major << "." << minor;
EGLint error = eglGetError(); EGLint error = eglGetError();
if (error != EGL_SUCCESS) { if (error != EGL_SUCCESS) {
@ -140,21 +155,30 @@ bool EglOnXBackend::initBufferConfigs()
EGL_GREEN_SIZE, 1, EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1, EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 0, EGL_ALPHA_SIZE, 0,
#ifdef KWIN_HAVE_OPENGLES
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
#endif
EGL_CONFIG_CAVEAT, EGL_NONE, EGL_CONFIG_CAVEAT, EGL_NONE,
EGL_NONE, EGL_NONE,
}; };
EGLint count; EGLint count;
EGLConfig configs[1024]; EGLConfig configs[1024];
eglChooseConfig(dpy, config_attribs, configs, 1024, &count); if (eglChooseConfig(dpy, config_attribs, configs, 1024, &count) == EGL_FALSE) {
kError(1212) << "choose config failed";
return false;
}
EGLint visualId = XVisualIDFromVisual((Visual*)QX11Info::appVisual()); EGLint visualId = XVisualIDFromVisual((Visual*)QX11Info::appVisual());
config = configs[0]; config = configs[0];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
EGLint val; EGLint val;
eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &val); if (eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &val) == EGL_FALSE) {
kError(1212) << "egl get config attrib failed";
}
if (visualId == val) { if (visualId == val) {
config = configs[i]; config = configs[i];
break; break;
@ -189,14 +213,14 @@ SceneOpenGL::TexturePrivate *EglOnXBackend::createBackendTexture(SceneOpenGL::Te
return new EglTexture(texture, this); return new EglTexture(texture, this);
} }
void KWin::EglOnXBackend::prepareRenderingFrame() void EglOnXBackend::prepareRenderingFrame()
{ {
if (!lastDamage().isEmpty()) if (!lastDamage().isEmpty())
flushBuffer(); flushBuffer();
startRenderTimer(); startRenderTimer();
} }
void KWin::EglOnXBackend::endRenderingFrame(int mask, const QRegion &damage) void EglOnXBackend::endRenderingFrame(int mask, const QRegion &damage)
{ {
setLastDamage(damage); setLastDamage(damage);
setLastMask(mask); setLastMask(mask);
@ -281,4 +305,3 @@ void KWin::EglTexture::onDamage()
} }
} // namespace } // namespace
#endif

View file

@ -89,9 +89,9 @@ void GlxBackend::init()
} }
// Initialize OpenGL // Initialize OpenGL
GLPlatform *glPlatform = GLPlatform::instance(); GLPlatform *glPlatform = GLPlatform::instance();
glPlatform->detect(); glPlatform->detect(GlxPlatformInterface);
glPlatform->printResults(); glPlatform->printResults();
initGL(); initGL(GlxPlatformInterface);
// Check whether certain features are supported // Check whether certain features are supported
if (options->isGlVSync()) { if (options->isGlVSync()) {
if (glXGetVideoSync && glXSwapInterval && glXIsDirect(display(), ctxbuffer)) { if (glXGetVideoSync && glXSwapInterval && glXIsDirect(display(), ctxbuffer)) {

View file

@ -33,8 +33,14 @@ set(kwin_GLUTILSLIB_SRCS
macro( KWIN4_ADD_GLUTILS_BACKEND name glinclude ) macro( KWIN4_ADD_GLUTILS_BACKEND name glinclude )
include_directories(${glinclude}) include_directories(${glinclude})
if(OPENGL_EGL_FOUND)
include_directories(OPENGLES_EGL_INCLUDE_DIR)
endif(OPENGL_EGL_FOUND)
kde4_add_library(${name} SHARED ${kwin_GLUTILSLIB_SRCS}) kde4_add_library(${name} SHARED ${kwin_GLUTILSLIB_SRCS})
target_link_libraries(${name} ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY} ${X11_LIBRARIES} kwineffects) target_link_libraries(${name} ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY} ${X11_LIBRARIES} kwineffects)
if(OPENGL_EGL_FOUND)
target_link_libraries(${name} ${OPENGLES_EGL_LIBRARY})
endif(OPENGL_EGL_FOUND)
set_target_properties(${name} PROPERTIES VERSION 1.0.0 SOVERSION 1 ) set_target_properties(${name} PROPERTIES VERSION 1.0.0 SOVERSION 1 )
target_link_libraries(${name} ${ARGN}) target_link_libraries(${name} ${ARGN})
target_link_libraries(${name} LINK_INTERFACE_LIBRARIES ${ARGN}) target_link_libraries(${name} LINK_INTERFACE_LIBRARIES ${ARGN})

View file

@ -19,5 +19,7 @@
/* KWIN_HAVE_XRENDER_COMPOSITING - whether XRender-based compositing support is available */ /* KWIN_HAVE_XRENDER_COMPOSITING - whether XRender-based compositing support is available */
#cmakedefine KWIN_HAVE_XRENDER_COMPOSITING #cmakedefine KWIN_HAVE_XRENDER_COMPOSITING
#cmakedefine KWIN_HAVE_EGL
#endif #endif

View file

@ -53,6 +53,12 @@ enum CompositingType {
OpenGL2Compositing = 1<<3 | OpenGLCompositing OpenGL2Compositing = 1<<3 | OpenGLCompositing
}; };
enum OpenGLPlatformInterface {
NoOpenGLPlatformInterface = 0,
GlxPlatformInterface,
EglPlatformInterface
};
enum clientAreaOption { enum clientAreaOption {
PlacementArea, // geometry where a window will be initially placed after being mapped PlacementArea, // geometry where a window will be initially placed after being mapped
MovementArea, // ??? window movement snapping area? ignore struts MovementArea, // ??? window movement snapping area? ignore struts

View file

@ -498,7 +498,7 @@ GLPlatform::~GLPlatform()
{ {
} }
void GLPlatform::detect() void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
{ {
m_vendor = (const char*)glGetString(GL_VENDOR); m_vendor = (const char*)glGetString(GL_VENDOR);
m_renderer = (const char*)glGetString(GL_RENDERER); m_renderer = (const char*)glGetString(GL_RENDERER);
@ -521,21 +521,32 @@ void GLPlatform::detect()
m_mesaVersion = parseVersionString(version); m_mesaVersion = parseVersionString(version);
} }
if (platformInterface == EglPlatformInterface) {
m_directRendering = true;
#ifdef KWIN_HAVE_OPENGLES #ifdef KWIN_HAVE_OPENGLES
m_directRendering = true; m_supportsGLSL = true;
m_supportsGLSL = true; m_textureNPOT = true;
m_textureNPOT = true;
#else #else
GLXContext ctx = glXGetCurrentContext(); m_supportsGLSL = m_extensions.contains("GL_ARB_shading_language_100") &&
m_directRendering = glXIsDirect(display(), ctx); m_extensions.contains("GL_ARB_shader_objects") &&
m_extensions.contains("GL_ARB_fragment_shader") &&
m_extensions.contains("GL_ARB_vertex_shader");
m_supportsGLSL = m_extensions.contains("GL_ARB_shading_language_100") && m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two");
m_extensions.contains("GL_ARB_shader_objects") &&
m_extensions.contains("GL_ARB_fragment_shader") &&
m_extensions.contains("GL_ARB_vertex_shader");
m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two");
#endif #endif
} else if (platformInterface == GlxPlatformInterface) {
#ifndef KWIN_HAVE_OPENGLES
GLXContext ctx = glXGetCurrentContext();
m_directRendering = glXIsDirect(display(), ctx);
m_supportsGLSL = m_extensions.contains("GL_ARB_shading_language_100") &&
m_extensions.contains("GL_ARB_shader_objects") &&
m_extensions.contains("GL_ARB_fragment_shader") &&
m_extensions.contains("GL_ARB_vertex_shader");
m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two");
#endif
}
m_serverVersion = getXServerVersion(); m_serverVersion = getXServerVersion();
m_kernelVersion = getKernelVersion(); m_kernelVersion = getKernelVersion();
@ -728,14 +739,12 @@ void GLPlatform::detect()
m_limitedGLSL = m_supportsGLSL && m_chipClass < I965; m_limitedGLSL = m_supportsGLSL && m_chipClass < I965;
} }
#ifdef KWIN_HAVE_OPENGLES if (isMesaDriver() && platformInterface == EglPlatformInterface) {
if (isMesaDriver()) {
// According to the reference implementation in // According to the reference implementation in
// mesa/demos/src/egl/opengles1/texture_from_pixmap // mesa/demos/src/egl/opengles1/texture_from_pixmap
// the mesa egl implementation does not require a strict binding (so far). // the mesa egl implementation does not require a strict binding (so far).
m_looseBinding = true; m_looseBinding = true;
} }
#endif
// Loose binding is broken with Gallium drivers in Mesa 7.10 // Loose binding is broken with Gallium drivers in Mesa 7.10
if (isGalliumDriver() && mesaVersion() == kVersionNumber(7, 10, 0)) if (isGalliumDriver() && mesaVersion() == kVersionNumber(7, 10, 0))

View file

@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KWIN_GLPLATFORM_H #ifndef KWIN_GLPLATFORM_H
#define KWIN_GLPLATFORM_H #define KWIN_GLPLATFORM_H
#include <kwinglobals.h>
#include <kwinglutils_funcs.h> #include <kwinglutils_funcs.h>
#include <QSet> #include <QSet>
@ -139,7 +140,7 @@ public:
/** /**
* Runs the detection code using the current OpenGL context. * Runs the detection code using the current OpenGL context.
*/ */
void detect(); void detect(OpenGLPlatformInterface platformInterface);
/** /**
* Prints the results of the detection code. * Prints the results of the detection code.

View file

@ -83,7 +83,7 @@ void initGLX()
void initEGL() void initEGL()
{ {
#ifdef KWIN_HAVE_OPENGLES #ifdef KWIN_HAVE_EGL
EGLDisplay dpy = eglGetCurrentDisplay(); EGLDisplay dpy = eglGetCurrentDisplay();
int major, minor; int major, minor;
eglInitialize(dpy, &major, &minor); eglInitialize(dpy, &major, &minor);
@ -94,7 +94,7 @@ void initEGL()
#endif #endif
} }
void initGL() void initGL(OpenGLPlatformInterface platformInterface)
{ {
// Get OpenGL version // Get OpenGL version
QString glversionstring = QString((const char*)glGetString(GL_VERSION)); QString glversionstring = QString((const char*)glGetString(GL_VERSION));
@ -108,7 +108,7 @@ void initGL()
glExtensions = QString((const char*)glGetString(GL_EXTENSIONS)).split(' '); glExtensions = QString((const char*)glGetString(GL_EXTENSIONS)).split(' ');
// handle OpenGL extensions functions // handle OpenGL extensions functions
glResolveFunctions(); glResolveFunctions(platformInterface);
GLTexturePrivate::initStatic(); GLTexturePrivate::initStatic();
GLRenderTarget::initStatic(); GLRenderTarget::initStatic();

View file

@ -58,7 +58,7 @@ void KWIN_EXPORT initGLX();
// Initializes OpenGL stuff. This includes resolving function pointers as // Initializes OpenGL stuff. This includes resolving function pointers as
// well as checking for GL version and extensions // well as checking for GL version and extensions
// Note that GL context has to be created by the time this function is called // Note that GL context has to be created by the time this function is called
void KWIN_EXPORT initGL(); void KWIN_EXPORT initGL(OpenGLPlatformInterface platformInterface);
// Initializes EGL function pointers // Initializes EGL function pointers
void KWIN_EXPORT initEGL(); void KWIN_EXPORT initEGL();
// Cleans up all resources hold by the GL Context // Cleans up all resources hold by the GL Context

View file

@ -24,19 +24,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Resolves given function, using getProcAddress // Resolves given function, using getProcAddress
#define GL_RESOLVE( function ) function = (function ## _func)getProcAddress( #function ); #ifdef KWIN_HAVE_EGL
#define GL_RESOLVE( function ) \
if (platformInterface == GlxPlatformInterface) \
function = (function ## _func)getProcAddress( #function ); \
else if (platformInterface == EglPlatformInterface) \
function = (function ## _func)eglGetProcAddress( #function );
// Same as above but tries to use function "backup" if "function" doesn't exist // Same as above but tries to use function "backup" if "function" doesn't exist
// Useful when same functionality is also defined in an extension // Useful when same functionality is also defined in an extension
#define GL_RESOLVE_WITH_EXT( function, backup ) \
if (platformInterface == GlxPlatformInterface) { \
function = (function ## _func)getProcAddress( #function ); \
if ( !function ) \
function = (function ## _func)getProcAddress( #backup ); \
} else if (platformInterface == EglPlatformInterface) { \
function = (function ## _func)eglGetProcAddress( #function ); \
if ( !function ) \
function = (function ## _func)eglGetProcAddress( #backup ); \
}
#else
// same without the switch to egl
#define GL_RESOLVE( function ) function = (function ## _func)getProcAddress( #function );
#define GL_RESOLVE_WITH_EXT( function, backup ) \ #define GL_RESOLVE_WITH_EXT( function, backup ) \
function = (function ## _func)getProcAddress( #function ); \ function = (function ## _func)getProcAddress( #function ); \
if ( !function ) \ if ( !function ) \
function = (function ## _func)getProcAddress( #backup ); function = (function ## _func)getProcAddress( #backup );
#endif
#define EGL_RESOLVE( function ) function = (function ## _func)eglGetProcAddress( #function );
#ifndef KWIN_HAVE_OPENGLES
namespace KWin namespace KWin
{ {
#ifndef KWIN_HAVE_OPENGLES
// Function pointers // Function pointers
glXGetProcAddress_func glXGetProcAddress; glXGetProcAddress_func glXGetProcAddress;
// GLX 1.3 // GLX 1.3
@ -175,6 +197,7 @@ void glxResolveFunctions()
glXSwapInterval = NULL; glXSwapInterval = NULL;
} }
OpenGLPlatformInterface platformInterface = GlxPlatformInterface;
GL_RESOLVE_WITH_EXT(glXGetFBConfigAttrib, glXGetFBConfigAttribSGIX); GL_RESOLVE_WITH_EXT(glXGetFBConfigAttrib, glXGetFBConfigAttribSGIX);
GL_RESOLVE_WITH_EXT(glXGetVisualFromFBConfig, glXGetVisualFromFBConfigSGIX); GL_RESOLVE_WITH_EXT(glXGetVisualFromFBConfig, glXGetVisualFromFBConfigSGIX);
GL_RESOLVE(glXGetFBConfigs); GL_RESOLVE(glXGetFBConfigs);
@ -183,9 +206,42 @@ void glxResolveFunctions()
GL_RESOLVE(glXCreatePixmap); GL_RESOLVE(glXCreatePixmap);
GL_RESOLVE(glXDestroyPixmap); GL_RESOLVE(glXDestroyPixmap);
} }
#endif
void glResolveFunctions()
#ifdef KWIN_HAVE_EGL
// EGL
eglCreateImageKHR_func eglCreateImageKHR;
eglDestroyImageKHR_func eglDestroyImageKHR;
eglPostSubBufferNV_func eglPostSubBufferNV;
// GLES
glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOES;
void eglResolveFunctions()
{ {
if (hasGLExtension("EGL_KHR_image") ||
(hasGLExtension("EGL_KHR_image_base") &&
hasGLExtension("EGL_KHR_image_pixmap"))) {
eglCreateImageKHR = (eglCreateImageKHR_func)eglGetProcAddress("eglCreateImageKHR");
eglDestroyImageKHR = (eglDestroyImageKHR_func)eglGetProcAddress("eglDestroyImageKHR");
} else {
eglCreateImageKHR = NULL;
eglDestroyImageKHR = NULL;
}
if (hasGLExtension("EGL_NV_post_sub_buffer")) {
eglPostSubBufferNV = (eglPostSubBufferNV_func)eglGetProcAddress("eglPostSubBufferNV");
} else {
eglPostSubBufferNV = NULL;
}
}
#endif
void glResolveFunctions(OpenGLPlatformInterface platformInterface)
{
#ifndef KWIN_HAVE_OPENGLES
if (hasGLExtension("GL_ARB_multitexture")) { if (hasGLExtension("GL_ARB_multitexture")) {
GL_RESOLVE_WITH_EXT(glActiveTexture, glActiveTextureARB); GL_RESOLVE_WITH_EXT(glActiveTexture, glActiveTextureARB);
// Get number of texture units // Get number of texture units
@ -195,31 +251,31 @@ void glResolveFunctions()
glTextureUnitsCount = 0; glTextureUnitsCount = 0;
} }
if (hasGLExtension("GL_EXT_framebuffer_object")) { if (hasGLExtension("GL_EXT_framebuffer_object")) {
glIsRenderbuffer = (glIsRenderbuffer_func) getProcAddress("glIsRenderbufferEXT"); GL_RESOLVE_WITH_EXT(glIsRenderbuffer, glIsRenderbufferEXT);
glBindRenderbuffer = (glBindRenderbuffer_func) getProcAddress("glBindRenderbufferEXT"); GL_RESOLVE_WITH_EXT(glBindRenderbuffer, glBindRenderbufferEXT);
glDeleteRenderbuffers = (glDeleteRenderbuffers_func) getProcAddress("glDeleteRenderbuffersEXT"); GL_RESOLVE_WITH_EXT(glDeleteRenderbuffers, glDeleteRenderbuffersEXT);
glGenRenderbuffers = (glGenRenderbuffers_func) getProcAddress("glGenRenderbuffersEXT"); GL_RESOLVE_WITH_EXT(glGenRenderbuffers, glGenRenderbuffersEXT);
glRenderbufferStorage = (glRenderbufferStorage_func) getProcAddress("glRenderbufferStorageEXT"); GL_RESOLVE_WITH_EXT(glRenderbufferStorage, glRenderbufferStorageEXT);
glGetRenderbufferParameteriv = (glGetRenderbufferParameteriv_func) getProcAddress("glGetRenderbufferParameterivEXT"); GL_RESOLVE_WITH_EXT(glGetRenderbufferParameteriv, glGetRenderbufferParameterivEXT);
glIsFramebuffer = (glIsFramebuffer_func) getProcAddress("glIsFramebufferEXT"); GL_RESOLVE_WITH_EXT(glIsFramebuffer, glIsFramebufferEXT);
glBindFramebuffer = (glBindFramebuffer_func) getProcAddress("glBindFramebufferEXT"); GL_RESOLVE_WITH_EXT(glBindFramebuffer, glBindFramebufferEXT);
glDeleteFramebuffers = (glDeleteFramebuffers_func) getProcAddress("glDeleteFramebuffersEXT"); GL_RESOLVE_WITH_EXT(glDeleteFramebuffers, glDeleteFramebuffersEXT);
glGenFramebuffers = (glGenFramebuffers_func) getProcAddress("glGenFramebuffersEXT"); GL_RESOLVE_WITH_EXT(glGenFramebuffers, glGenFramebuffersEXT);
glCheckFramebufferStatus = (glCheckFramebufferStatus_func) getProcAddress("glCheckFramebufferStatusEXT"); GL_RESOLVE_WITH_EXT(glCheckFramebufferStatus, glCheckFramebufferStatusEXT);
glFramebufferTexture1D = (glFramebufferTexture1D_func) getProcAddress("glFramebufferTexture1DEXT"); GL_RESOLVE_WITH_EXT(glFramebufferTexture1D, glFramebufferTexture1DEXT);
glFramebufferTexture2D = (glFramebufferTexture2D_func) getProcAddress("glFramebufferTexture2DEXT"); GL_RESOLVE_WITH_EXT(glFramebufferTexture2D, glFramebufferTexture2DEXT);
glFramebufferTexture3D = (glFramebufferTexture3D_func) getProcAddress("glFramebufferTexture3DEXT"); GL_RESOLVE_WITH_EXT(glFramebufferTexture3D, glFramebufferTexture3DEXT);
glFramebufferRenderbuffer = (glFramebufferRenderbuffer_func) getProcAddress("glFramebufferRenderbufferEXT"); GL_RESOLVE_WITH_EXT(glFramebufferRenderbuffer, glFramebufferRenderbufferEXT);
glGetFramebufferAttachmentParameteriv = (glGetFramebufferAttachmentParameteriv_func) getProcAddress("glGetFramebufferAttachmentParameterivEXT"); GL_RESOLVE_WITH_EXT(glGetFramebufferAttachmentParameteriv, glGetFramebufferAttachmentParameterivEXT);
glGenerateMipmap = (glGenerateMipmap_func) getProcAddress("glGenerateMipmapEXT"); GL_RESOLVE_WITH_EXT(glGenerateMipmap, glGenerateMipmapEXT);
} else { } else {
glIsRenderbuffer = NULL; glIsRenderbuffer = NULL;
glBindRenderbuffer = NULL; glBindRenderbuffer = NULL;
@ -241,9 +297,9 @@ void glResolveFunctions()
} }
if (hasGLExtension("GL_ARB_framebuffer_object")) { if (hasGLExtension("GL_ARB_framebuffer_object")) {
glBlitFramebuffer = (glBlitFramebuffer_func) getProcAddress("glBlitFramebuffer"); GL_RESOLVE(glBlitFramebuffer);
} else if (hasGLExtension("GL_EXT_framebuffer_blit")) { } else if (hasGLExtension("GL_EXT_framebuffer_blit")) {
glBlitFramebuffer = (glBlitFramebuffer_func) getProcAddress("glBlitFramebufferEXT"); GL_RESOLVE_WITH_EXT(glBlitFramebuffer, glBlitFramebufferEXT);
} else { } else {
glBlitFramebuffer = NULL; glBlitFramebuffer = NULL;
} }
@ -302,48 +358,17 @@ void glResolveFunctions()
glBindBuffer = NULL; glBindBuffer = NULL;
glBufferData = NULL; glBufferData = NULL;
} }
}
} // namespace
#else
namespace KWin
{
// EGL
eglCreateImageKHR_func eglCreateImageKHR;
eglDestroyImageKHR_func eglDestroyImageKHR;
eglPostSubBufferNV_func eglPostSubBufferNV;
// GLES
glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOES;
void eglResolveFunctions()
{
if (hasGLExtension("EGL_KHR_image") ||
(hasGLExtension("EGL_KHR_image_base") &&
hasGLExtension("EGL_KHR_image_pixmap"))) {
eglCreateImageKHR = (eglCreateImageKHR_func)eglGetProcAddress("eglCreateImageKHR");
eglDestroyImageKHR = (eglDestroyImageKHR_func)eglGetProcAddress("eglDestroyImageKHR");
} else {
eglCreateImageKHR = NULL;
eglDestroyImageKHR = NULL;
}
if (hasGLExtension("EGL_NV_post_sub_buffer")) {
eglPostSubBufferNV = (eglPostSubBufferNV_func)eglGetProcAddress("eglPostSubBufferNV");
} else {
eglPostSubBufferNV = NULL;
}
}
void glResolveFunctions()
{
if (hasGLExtension("GL_OES_EGL_image")) {
glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_func)eglGetProcAddress("glEGLImageTargetTexture2DOES");
} else {
glEGLImageTargetTexture2DOES = NULL;
}
}
} // namespace
#endif #endif
#ifdef KWIN_HAVE_EGL
if (platformInterface == EglPlatformInterface) {
if (hasGLExtension("GL_OES_EGL_image")) {
glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_func)eglGetProcAddress("glEGLImageTargetTexture2DOES");
} else {
glEGLImageTargetTexture2DOES = NULL;
}
}
#endif
}
} // namespace

View file

@ -22,6 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KWIN_GLUTILS_FUNCS_H #define KWIN_GLUTILS_FUNCS_H
#include <kdemacros.h> #include <kdemacros.h>
#include <kwinconfig.h>
#include <kwinglobals.h>
#define KWIN_EXPORT KDE_EXPORT #define KWIN_EXPORT KDE_EXPORT
@ -352,11 +354,17 @@ extern KWIN_EXPORT glVertexAttribPointer_func glVertexAttribPointer;
} // namespace } // namespace
#else #endif // not KWIN_HAVE_OPENGLES
#ifdef KWIN_HAVE_EGL
#define EGL_EGLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#ifdef KWIN_HAVE_OPENGLES
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#endif
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include <fixx11h.h> #include <fixx11h.h>
@ -369,7 +377,7 @@ namespace KWin
{ {
void KWIN_EXPORT eglResolveFunctions(); void KWIN_EXPORT eglResolveFunctions();
void KWIN_EXPORT glResolveFunctions(); void KWIN_EXPORT glResolveFunctions(OpenGLPlatformInterface platformInterface);
// EGL // EGL
typedef EGLImageKHR(*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*); typedef EGLImageKHR(*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
typedef EGLBoolean(*eglDestroyImageKHR_func)(EGLDisplay, EGLImageKHR); typedef EGLBoolean(*eglDestroyImageKHR_func)(EGLDisplay, EGLImageKHR);
@ -384,6 +392,6 @@ extern KWIN_EXPORT glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOE
} // namespace } // namespace
#endif #endif // KWIN_HAVE_EGL
#endif #endif // KWIN_GLUTILS_FUNCS_H

View file

@ -67,9 +67,10 @@ Sources and other compositing managers:
*/ */
#include "scene_opengl.h" #include "scene_opengl.h"
#ifdef KWIN_HAVE_OPENGLES #ifdef KWIN_HAVE_EGL
#include "eglonxbackend.h" #include "eglonxbackend.h"
#else #endif
#ifndef KWIN_HAVE_OPENGLES
#include "glxbackend.h" #include "glxbackend.h"
#endif #endif
@ -194,11 +195,41 @@ SceneOpenGL::~SceneOpenGL()
SceneOpenGL *SceneOpenGL::createScene() SceneOpenGL *SceneOpenGL::createScene()
{ {
OpenGLBackend *backend = NULL; OpenGLBackend *backend = NULL;
#ifdef KWIN_HAVE_OPENGLES OpenGLPlatformInterface platformInterface = NoOpenGLPlatformInterface;
backend = new EglOnXBackend(); // should we use glx?
#else #ifndef KWIN_HAVE_OPENGLES
backend = new GlxBackend(); // on OpenGL we default to glx
platformInterface = GlxPlatformInterface;
#endif #endif
#ifdef KWIN_HAVE_EGL
#ifdef KWIN_HAVE_OPENGLES
// for OpenGL ES we need to use the Egl Backend
platformInterface = EglPlatformInterface;
#else
// check environment variable
if (qstrcmp(qgetenv("KWIN_OPENGL_INTERFACE"), "egl") == 0) {
kDebug(1212) << "Forcing EGL native interface through environment variable";
platformInterface = EglPlatformInterface;
}
#endif
#endif
switch (platformInterface) {
case GlxPlatformInterface:
#ifndef KWIN_HAVE_OPENGLES
backend = new GlxBackend();
#endif
break;
case EglPlatformInterface:
#ifdef KWIN_HAVE_EGL
backend = new EglOnXBackend();
#endif
break;
default:
// no backend available
return NULL;
}
if (!backend || backend->isFailed()) { if (!backend || backend->isFailed()) {
delete backend; delete backend;
return NULL; return NULL;