diff --git a/CMakeLists.txt b/CMakeLists.txt index c59b1f6fa1..95fb9c983f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,11 @@ if(OPENGL_FOUND) include_directories(${OPENGL_INCLUDE_DIR}) 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) include_directories(${OPENGLES_INCLUDE_DIR}) endif(OPENGLES_FOUND) @@ -110,7 +115,6 @@ set(kwin_KDEINIT_SRCS scene.cpp scene_xrender.cpp scene_opengl.cpp - eglonxbackend.cpp glxbackend.cpp thumbnailitem.cpp lanczosfilter.cpp @@ -152,6 +156,10 @@ if(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.Compositing.xml composite.h KWin::Compositor ) 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}) 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}) target_link_libraries(kdeinit_kwin ${kwinLibs}) diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp index 8797c8aaa2..dc5060b223 100644 --- a/eglonxbackend.cpp +++ b/eglonxbackend.cpp @@ -17,7 +17,6 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ -#ifdef KWIN_HAVE_OPENGLES #include "eglonxbackend.h" // kwin #include "options.h" @@ -67,9 +66,9 @@ void EglOnXBackend::init() return; } GLPlatform *glPlatform = GLPlatform::instance(); - glPlatform->detect(); + glPlatform->detect(EglPlatformInterface); glPlatform->printResults(); - initGL(); + initGL(EglPlatformInterface); if (!hasGLExtension("GL_OES_EGL_image")) { setFailed("Required extension GL_OES_EGL_image not found, disabling compositing"); return; @@ -99,7 +98,14 @@ bool EglOnXBackend::initRenderingContext() EGLint major, minor; if (eglInitialize(dpy, &major, &minor) == EGL_FALSE) return false; +#ifdef KWIN_HAVE_OPENGLES eglBindAPI(EGL_OPENGL_ES_API); +#else + if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) { + kError(1212) << "bind OpenGL API failed"; + return false; + } +#endif initBufferConfigs(); if (!overlayWindow()->create()) { kError(1212) << "Could not get overlay window"; @@ -111,18 +117,27 @@ bool EglOnXBackend::initRenderingContext() 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[] = { +#ifdef KWIN_HAVE_OPENGLES EGL_CONTEXT_CLIENT_VERSION, 2, +#endif EGL_NONE }; 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; - if (eglMakeCurrent(dpy, surface, surface, ctx) == EGL_FALSE) + } + if (eglMakeCurrent(dpy, surface, surface, ctx) == EGL_FALSE) { + kError(1212) << "Make Context Current failed"; return false; + } kDebug(1212) << "EGL version: " << major << "." << minor; EGLint error = eglGetError(); if (error != EGL_SUCCESS) { @@ -140,21 +155,30 @@ bool EglOnXBackend::initBufferConfigs() EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 0, +#ifdef KWIN_HAVE_OPENGLES EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, +#else + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, +#endif EGL_CONFIG_CAVEAT, EGL_NONE, EGL_NONE, }; EGLint count; 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()); config = configs[0]; for (int i = 0; i < count; i++) { 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) { config = configs[i]; break; @@ -189,14 +213,14 @@ SceneOpenGL::TexturePrivate *EglOnXBackend::createBackendTexture(SceneOpenGL::Te return new EglTexture(texture, this); } -void KWin::EglOnXBackend::prepareRenderingFrame() +void EglOnXBackend::prepareRenderingFrame() { if (!lastDamage().isEmpty()) flushBuffer(); startRenderTimer(); } -void KWin::EglOnXBackend::endRenderingFrame(int mask, const QRegion &damage) +void EglOnXBackend::endRenderingFrame(int mask, const QRegion &damage) { setLastDamage(damage); setLastMask(mask); @@ -281,4 +305,3 @@ void KWin::EglTexture::onDamage() } } // namespace -#endif diff --git a/glxbackend.cpp b/glxbackend.cpp index cef88d433a..a9228f73ee 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -89,9 +89,9 @@ void GlxBackend::init() } // Initialize OpenGL GLPlatform *glPlatform = GLPlatform::instance(); - glPlatform->detect(); + glPlatform->detect(GlxPlatformInterface); glPlatform->printResults(); - initGL(); + initGL(GlxPlatformInterface); // Check whether certain features are supported if (options->isGlVSync()) { if (glXGetVideoSync && glXSwapInterval && glXIsDirect(display(), ctxbuffer)) { diff --git a/libkwineffects/CMakeLists.txt b/libkwineffects/CMakeLists.txt index 14a2747d6e..4b99d2afed 100644 --- a/libkwineffects/CMakeLists.txt +++ b/libkwineffects/CMakeLists.txt @@ -33,8 +33,14 @@ set(kwin_GLUTILSLIB_SRCS macro( KWIN4_ADD_GLUTILS_BACKEND name 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}) 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 ) target_link_libraries(${name} ${ARGN}) target_link_libraries(${name} LINK_INTERFACE_LIBRARIES ${ARGN}) diff --git a/libkwineffects/kwinconfig.h.cmake b/libkwineffects/kwinconfig.h.cmake index a8586cc9b6..3e34723aea 100644 --- a/libkwineffects/kwinconfig.h.cmake +++ b/libkwineffects/kwinconfig.h.cmake @@ -19,5 +19,7 @@ /* KWIN_HAVE_XRENDER_COMPOSITING - whether XRender-based compositing support is available */ #cmakedefine KWIN_HAVE_XRENDER_COMPOSITING +#cmakedefine KWIN_HAVE_EGL + #endif diff --git a/libkwineffects/kwinglobals.h b/libkwineffects/kwinglobals.h index 8ea6872c5e..e1507d75bf 100644 --- a/libkwineffects/kwinglobals.h +++ b/libkwineffects/kwinglobals.h @@ -53,6 +53,12 @@ enum CompositingType { OpenGL2Compositing = 1<<3 | OpenGLCompositing }; +enum OpenGLPlatformInterface { + NoOpenGLPlatformInterface = 0, + GlxPlatformInterface, + EglPlatformInterface +}; + enum clientAreaOption { PlacementArea, // geometry where a window will be initially placed after being mapped MovementArea, // ??? window movement snapping area? ignore struts diff --git a/libkwineffects/kwinglplatform.cpp b/libkwineffects/kwinglplatform.cpp index 26341e4d8b..d5d498bf12 100644 --- a/libkwineffects/kwinglplatform.cpp +++ b/libkwineffects/kwinglplatform.cpp @@ -498,7 +498,7 @@ GLPlatform::~GLPlatform() { } -void GLPlatform::detect() +void GLPlatform::detect(OpenGLPlatformInterface platformInterface) { m_vendor = (const char*)glGetString(GL_VENDOR); m_renderer = (const char*)glGetString(GL_RENDERER); @@ -521,21 +521,32 @@ void GLPlatform::detect() m_mesaVersion = parseVersionString(version); } + if (platformInterface == EglPlatformInterface) { + m_directRendering = true; #ifdef KWIN_HAVE_OPENGLES - m_directRendering = true; - m_supportsGLSL = true; - m_textureNPOT = true; + m_supportsGLSL = true; + m_textureNPOT = true; #else - 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_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"); + m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two"); #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_kernelVersion = getKernelVersion(); @@ -728,14 +739,12 @@ void GLPlatform::detect() m_limitedGLSL = m_supportsGLSL && m_chipClass < I965; } -#ifdef KWIN_HAVE_OPENGLES - if (isMesaDriver()) { + if (isMesaDriver() && platformInterface == EglPlatformInterface) { // According to the reference implementation in // mesa/demos/src/egl/opengles1/texture_from_pixmap // the mesa egl implementation does not require a strict binding (so far). m_looseBinding = true; } -#endif // Loose binding is broken with Gallium drivers in Mesa 7.10 if (isGalliumDriver() && mesaVersion() == kVersionNumber(7, 10, 0)) diff --git a/libkwineffects/kwinglplatform.h b/libkwineffects/kwinglplatform.h index 14555a2bd4..cda141d9f9 100644 --- a/libkwineffects/kwinglplatform.h +++ b/libkwineffects/kwinglplatform.h @@ -21,6 +21,7 @@ along with this program. If not, see . #ifndef KWIN_GLPLATFORM_H #define KWIN_GLPLATFORM_H +#include #include #include @@ -139,7 +140,7 @@ public: /** * Runs the detection code using the current OpenGL context. */ - void detect(); + void detect(OpenGLPlatformInterface platformInterface); /** * Prints the results of the detection code. diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp index 5abae528fc..30ac03d78e 100644 --- a/libkwineffects/kwinglutils.cpp +++ b/libkwineffects/kwinglutils.cpp @@ -83,7 +83,7 @@ void initGLX() void initEGL() { -#ifdef KWIN_HAVE_OPENGLES +#ifdef KWIN_HAVE_EGL EGLDisplay dpy = eglGetCurrentDisplay(); int major, minor; eglInitialize(dpy, &major, &minor); @@ -94,7 +94,7 @@ void initEGL() #endif } -void initGL() +void initGL(OpenGLPlatformInterface platformInterface) { // Get OpenGL version QString glversionstring = QString((const char*)glGetString(GL_VERSION)); @@ -108,7 +108,7 @@ void initGL() glExtensions = QString((const char*)glGetString(GL_EXTENSIONS)).split(' '); // handle OpenGL extensions functions - glResolveFunctions(); + glResolveFunctions(platformInterface); GLTexturePrivate::initStatic(); GLRenderTarget::initStatic(); diff --git a/libkwineffects/kwinglutils.h b/libkwineffects/kwinglutils.h index 445ddc7ccc..cbdab15c92 100644 --- a/libkwineffects/kwinglutils.h +++ b/libkwineffects/kwinglutils.h @@ -58,7 +58,7 @@ void KWIN_EXPORT initGLX(); // Initializes OpenGL stuff. This includes resolving function pointers as // well as checking for GL version and extensions // 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 void KWIN_EXPORT initEGL(); // Cleans up all resources hold by the GL Context diff --git a/libkwineffects/kwinglutils_funcs.cpp b/libkwineffects/kwinglutils_funcs.cpp index a67c7203b3..5f084d5a1d 100644 --- a/libkwineffects/kwinglutils_funcs.cpp +++ b/libkwineffects/kwinglutils_funcs.cpp @@ -24,19 +24,41 @@ along with this program. If not, see . // 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 // 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 ) \ function = (function ## _func)getProcAddress( #function ); \ if ( !function ) \ function = (function ## _func)getProcAddress( #backup ); +#endif + +#define EGL_RESOLVE( function ) function = (function ## _func)eglGetProcAddress( #function ); -#ifndef KWIN_HAVE_OPENGLES namespace KWin { +#ifndef KWIN_HAVE_OPENGLES // Function pointers glXGetProcAddress_func glXGetProcAddress; // GLX 1.3 @@ -175,6 +197,7 @@ void glxResolveFunctions() glXSwapInterval = NULL; } + OpenGLPlatformInterface platformInterface = GlxPlatformInterface; GL_RESOLVE_WITH_EXT(glXGetFBConfigAttrib, glXGetFBConfigAttribSGIX); GL_RESOLVE_WITH_EXT(glXGetVisualFromFBConfig, glXGetVisualFromFBConfigSGIX); GL_RESOLVE(glXGetFBConfigs); @@ -183,9 +206,42 @@ void glxResolveFunctions() GL_RESOLVE(glXCreatePixmap); 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")) { GL_RESOLVE_WITH_EXT(glActiveTexture, glActiveTextureARB); // Get number of texture units @@ -195,31 +251,31 @@ void glResolveFunctions() glTextureUnitsCount = 0; } if (hasGLExtension("GL_EXT_framebuffer_object")) { - glIsRenderbuffer = (glIsRenderbuffer_func) getProcAddress("glIsRenderbufferEXT"); - glBindRenderbuffer = (glBindRenderbuffer_func) getProcAddress("glBindRenderbufferEXT"); - glDeleteRenderbuffers = (glDeleteRenderbuffers_func) getProcAddress("glDeleteRenderbuffersEXT"); - glGenRenderbuffers = (glGenRenderbuffers_func) getProcAddress("glGenRenderbuffersEXT"); + GL_RESOLVE_WITH_EXT(glIsRenderbuffer, glIsRenderbufferEXT); + GL_RESOLVE_WITH_EXT(glBindRenderbuffer, glBindRenderbufferEXT); + GL_RESOLVE_WITH_EXT(glDeleteRenderbuffers, glDeleteRenderbuffersEXT); + 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"); - glBindFramebuffer = (glBindFramebuffer_func) getProcAddress("glBindFramebufferEXT"); - glDeleteFramebuffers = (glDeleteFramebuffers_func) getProcAddress("glDeleteFramebuffersEXT"); - glGenFramebuffers = (glGenFramebuffers_func) getProcAddress("glGenFramebuffersEXT"); + GL_RESOLVE_WITH_EXT(glIsFramebuffer, glIsFramebufferEXT); + GL_RESOLVE_WITH_EXT(glBindFramebuffer, glBindFramebufferEXT); + GL_RESOLVE_WITH_EXT(glDeleteFramebuffers, glDeleteFramebuffersEXT); + GL_RESOLVE_WITH_EXT(glGenFramebuffers, glGenFramebuffersEXT); - glCheckFramebufferStatus = (glCheckFramebufferStatus_func) getProcAddress("glCheckFramebufferStatusEXT"); + GL_RESOLVE_WITH_EXT(glCheckFramebufferStatus, glCheckFramebufferStatusEXT); - glFramebufferTexture1D = (glFramebufferTexture1D_func) getProcAddress("glFramebufferTexture1DEXT"); - glFramebufferTexture2D = (glFramebufferTexture2D_func) getProcAddress("glFramebufferTexture2DEXT"); - glFramebufferTexture3D = (glFramebufferTexture3D_func) getProcAddress("glFramebufferTexture3DEXT"); + GL_RESOLVE_WITH_EXT(glFramebufferTexture1D, glFramebufferTexture1DEXT); + GL_RESOLVE_WITH_EXT(glFramebufferTexture2D, glFramebufferTexture2DEXT); + 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 { glIsRenderbuffer = NULL; glBindRenderbuffer = NULL; @@ -241,9 +297,9 @@ void glResolveFunctions() } if (hasGLExtension("GL_ARB_framebuffer_object")) { - glBlitFramebuffer = (glBlitFramebuffer_func) getProcAddress("glBlitFramebuffer"); + GL_RESOLVE(glBlitFramebuffer); } else if (hasGLExtension("GL_EXT_framebuffer_blit")) { - glBlitFramebuffer = (glBlitFramebuffer_func) getProcAddress("glBlitFramebufferEXT"); + GL_RESOLVE_WITH_EXT(glBlitFramebuffer, glBlitFramebufferEXT); } else { glBlitFramebuffer = NULL; } @@ -302,48 +358,17 @@ void glResolveFunctions() glBindBuffer = 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 + +#ifdef KWIN_HAVE_EGL + if (platformInterface == EglPlatformInterface) { + if (hasGLExtension("GL_OES_EGL_image")) { + glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_func)eglGetProcAddress("glEGLImageTargetTexture2DOES"); + } else { + glEGLImageTargetTexture2DOES = NULL; + } + } +#endif +} + +} // namespace diff --git a/libkwineffects/kwinglutils_funcs.h b/libkwineffects/kwinglutils_funcs.h index 4f8125ab16..b2b7f5ba3f 100644 --- a/libkwineffects/kwinglutils_funcs.h +++ b/libkwineffects/kwinglutils_funcs.h @@ -22,6 +22,8 @@ along with this program. If not, see . #define KWIN_GLUTILS_FUNCS_H #include +#include +#include #define KWIN_EXPORT KDE_EXPORT @@ -352,11 +354,17 @@ extern KWIN_EXPORT glVertexAttribPointer_func glVertexAttribPointer; } // namespace -#else +#endif // not KWIN_HAVE_OPENGLES + +#ifdef KWIN_HAVE_EGL #define EGL_EGLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES + +#ifdef KWIN_HAVE_OPENGLES #include #include +#endif + #include #include #include @@ -369,7 +377,7 @@ namespace KWin { void KWIN_EXPORT eglResolveFunctions(); -void KWIN_EXPORT glResolveFunctions(); +void KWIN_EXPORT glResolveFunctions(OpenGLPlatformInterface platformInterface); // EGL typedef EGLImageKHR(*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*); typedef EGLBoolean(*eglDestroyImageKHR_func)(EGLDisplay, EGLImageKHR); @@ -384,6 +392,6 @@ extern KWIN_EXPORT glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOE } // namespace -#endif +#endif // KWIN_HAVE_EGL -#endif +#endif // KWIN_GLUTILS_FUNCS_H diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 164d463eae..aa9bd15e1c 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -67,9 +67,10 @@ Sources and other compositing managers: */ #include "scene_opengl.h" -#ifdef KWIN_HAVE_OPENGLES +#ifdef KWIN_HAVE_EGL #include "eglonxbackend.h" -#else +#endif +#ifndef KWIN_HAVE_OPENGLES #include "glxbackend.h" #endif @@ -194,11 +195,41 @@ SceneOpenGL::~SceneOpenGL() SceneOpenGL *SceneOpenGL::createScene() { OpenGLBackend *backend = NULL; -#ifdef KWIN_HAVE_OPENGLES - backend = new EglOnXBackend(); -#else - backend = new GlxBackend(); + OpenGLPlatformInterface platformInterface = NoOpenGLPlatformInterface; + // should we use glx? +#ifndef KWIN_HAVE_OPENGLES + // on OpenGL we default to glx + platformInterface = GlxPlatformInterface; #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()) { delete backend; return NULL;