Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern/GHOST_WindowX11.cpp')
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp394
1 files changed, 110 insertions, 284 deletions
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 86c940b7396..97f8ae73d2d 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -30,23 +30,28 @@
*/
-#include <GL/glxew.h>
-
#include "GHOST_WindowX11.h"
#include "GHOST_SystemX11.h"
#include "STR_String.h"
#include "GHOST_Debug.h"
#ifdef WITH_XDND
-#include "GHOST_DropTargetX11.h"
+# include "GHOST_DropTargetX11.h"
+#endif
+
+#if defined(WITH_GL_EGL)
+# include "GHOST_ContextEGL.h"
+#else
+# include "GHOST_ContextGLX.h"
#endif
+
/* For standard X11 cursors */
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
-#include <strings.h>
+# include <strings.h>
#endif
#include <cstring>
@@ -65,14 +70,6 @@ typedef struct {
long input_mode;
} MotifWmHints;
-// Workaround for MESA bug #54080
-// https://bugs.freedesktop.org/show_bug.cgi?id=54080()
-#define SWAP_INTERVALS_WORKAROUND
-
-#ifdef SWAP_INTERVALS_WORKAROUND
-static bool g_swap_interval_disabled = false;
-#endif // SWAP_INTERVALS_WORKAROUND
-
#define MWM_HINTS_DECORATIONS (1L << 1)
@@ -157,13 +154,12 @@ static long BLENDER_ICON_48x48x32[] = {
};
-GLXContext GHOST_WindowX11::s_firstContext = NULL;
GHOST_WindowX11::
GHOST_WindowX11(
GHOST_SystemX11 *system,
Display *display,
- const STR_String& title,
+ const STR_String &title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -174,8 +170,7 @@ GHOST_WindowX11(
const bool stereoVisual,
const bool exclusive,
const GHOST_TUns16 numOfAASamples)
- : GHOST_Window(width, height, state, type, stereoVisual, exclusive, numOfAASamples),
- m_context(NULL),
+ : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
m_display(display),
m_normal_state(GHOST_kWindowStateNormal),
m_system(system),
@@ -185,97 +180,19 @@ GHOST_WindowX11(
m_custom_cursor(None),
m_visible_cursor(None)
{
-
- /* Set up the minimum attributes that we require and see if
- * X can find us a visual matching those requirements. */
-
- int attributes[40], i, samples;
int natom;
- int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */
-
- m_visual = NULL;
-
- if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
- printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
-
- /* exit if this is the first window */
- if (s_firstContext == NULL) {
- printf("initial window could not find the GLX extension, exit!\n");
- exit(1);
- }
-
- return;
- }
-
- /* Find the display with highest samples, starting at level requested */
- for (samples = m_numOfAASamples; samples >= 0; samples--) {
- i = 0; /* Reusing attributes array, so reset counter */
-
- if (m_stereoVisual)
- attributes[i++] = GLX_STEREO;
-
- attributes[i++] = GLX_RGBA;
- attributes[i++] = GLX_DOUBLEBUFFER;
- attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
- attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
- attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
- attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
-#ifdef GHOST_OPENGL_ALPHA
- attributes[i++] = GLX_ALPHA_SIZE; attributes[i++] = 1;
-#endif
- /* GLX >= 1.4 required for multi-sample */
- if (samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
- attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
- attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
- }
- attributes[i] = None;
-
- m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
-
- /* Any sample level or even zero, which means oversampling disabled, is good
- * but we need a valid visual to continue */
- if (m_visual == NULL) {
- if (samples == 0) {
- /* All options exhausted, cannot continue */
- printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
-
- if (s_firstContext == NULL) {
- printf("initial window could not find the GLX extension, exit!\n");
- exit(1);
- }
-
- return;
- }
- }
- else {
- if (m_numOfAASamples && (m_numOfAASamples > samples)) {
- printf("%s:%d: oversampling requested %i but using %i samples\n",
- __FILE__, __LINE__, m_numOfAASamples, samples);
- }
- break;
- }
- }
-
- /* Create a bunch of attributes needed to create an X window. */
-
- /* First create a colormap for the window and visual.
- * This seems pretty much a legacy feature as we are in rgba mode anyway. */
+ unsigned int xattributes_valuemask = 0;
XSetWindowAttributes xattributes;
- unsigned int xattributes_valuemask = (CWBorderPixel | CWColormap | CWEventMask);
memset(&xattributes, 0, sizeof(xattributes));
- xattributes.colormap = XCreateColormap(m_display,
- RootWindow(m_display, m_visual->screen),
- m_visual->visual,
- AllocNone
- );
-
+ xattributes_valuemask |= CWBorderPixel;
xattributes.border_pixel = 0;
/* Specify which events we are interested in hearing. */
+ xattributes_valuemask |= CWEventMask;
xattributes.event_mask =
ExposureMask | StructureNotifyMask |
KeyPressMask | KeyReleaseMask |
@@ -292,15 +209,15 @@ GHOST_WindowX11(
/* create the window! */
if (parentWindow == 0) {
m_window = XCreateWindow(m_display,
- RootWindow(m_display, m_visual->screen),
+ RootWindow(m_display, DefaultScreen(m_display)),
left,
top,
width,
height,
- 0, /* no border. */
- m_visual->depth,
+ 0, /* no border. */
+ CopyFromParent,
InputOutput,
- m_visual->visual,
+ CopyFromParent,
xattributes_valuemask,
&xattributes
);
@@ -321,15 +238,15 @@ GHOST_WindowX11(
m_window = XCreateWindow(m_display,
- parentWindow, /* reparent against embedder */
+ parentWindow, /* reparent against embedder */
left,
top,
width,
height,
- 0, /* no border. */
- m_visual->depth,
+ 0, /* no border. */
+ CopyFromParent,
InputOutput,
- m_visual->visual,
+ CopyFromParent,
xattributes_valuemask,
&xattributes
);
@@ -451,8 +368,6 @@ GHOST_WindowX11(
BLENDER_ICON_48x48x32[0] * BLENDER_ICON_48x48x32[1] + 2);
/* done setting the icon */
- setTitle(title);
-
#ifdef WITH_X11_XINPUT
initXInputDevices();
@@ -460,11 +375,13 @@ GHOST_WindowX11(
#endif
/* now set up the rendering context. */
- if (installDrawingContext(type) == GHOST_kSuccess) {
+ if (setDrawingContextType(type) == GHOST_kSuccess) {
m_valid_setup = true;
GHOST_PRINT("Created window\n");
}
+ setTitle(title);
+
if (exclusive) {
XMapRaised(m_display, m_window);
}
@@ -564,7 +481,7 @@ bool
GHOST_WindowX11::
getValid() const
{
- return m_valid_setup;
+ return GHOST_Window::getValid() && m_valid_setup;
}
void
@@ -685,7 +602,7 @@ screenToClient(
Window temp;
XTranslateCoordinates(m_display,
- RootWindow(m_display, m_visual->screen),
+ RootWindow(m_display, DefaultScreen(m_display)),
m_window,
inX, inY,
&ax, &ay,
@@ -708,7 +625,7 @@ clientToScreen(
XTranslateCoordinates(
m_display,
m_window,
- RootWindow(m_display, m_visual->screen),
+ RootWindow(m_display, DefaultScreen(m_display)),
inX, inY,
&ax, &ay,
&temp);
@@ -1052,7 +969,7 @@ setOrder(
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- root = RootWindow(m_display, m_visual->screen),
+ root = RootWindow(m_display, DefaultScreen(m_display)),
eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
XSendEvent(m_display, root, False, eventmask, &xev);
@@ -1079,34 +996,6 @@ setOrder(
GHOST_TSuccess
GHOST_WindowX11::
-swapBuffers()
-{
- if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
- glXSwapBuffers(m_display, m_window);
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
-}
-
-GHOST_TSuccess
-GHOST_WindowX11::
-activateDrawingContext()
-{
- if (m_context != NULL) {
- glXMakeCurrent(m_display, m_window, m_context);
- /* Disable AA by default */
- if (m_numOfAASamples > 0) {
- glDisable(GL_MULTISAMPLE_ARB);
- }
- return GHOST_kSuccess;
- }
- return GHOST_kFailure;
-}
-
-GHOST_TSuccess
-GHOST_WindowX11::
invalidate()
{
/* So the idea of this function is to generate an expose event
@@ -1172,10 +1061,6 @@ GHOST_WindowX11::
XFreeCursor(m_display, m_custom_cursor);
}
- if (m_context != s_firstContext) {
- glXDestroyContext(m_display, m_context);
- }
-
if (p_owner == m_window) {
XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
}
@@ -1193,88 +1078,98 @@ GHOST_WindowX11::
delete m_dropTarget;
#endif
+ releaseNativeHandles();
+
XDestroyWindow(m_display, m_window);
- XFree(m_visual);
}
-
-
-/**
- * Tries to install a rendering context in this window.
- * \param type The type of rendering context installed.
- * \return Indication as to whether installation has succeeded.
- */
-GHOST_TSuccess
-GHOST_WindowX11::
-installDrawingContext(
- GHOST_TDrawingContextType type)
+GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
{
- /* only support openGL for now. */
- GHOST_TSuccess success;
- switch (type) {
- case GHOST_kDrawingContextTypeOpenGL:
- {
-#ifdef WITH_X11_XINPUT
- /* use our own event handlers to avoid exiting blender,
- * this would happen for eg:
- * if you open blender, unplug a tablet, then open a new window. */
- XErrorHandler old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
- XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+#if !defined(WITH_GL_EGL)
+
+#if defined(WITH_GL_PROFILE_CORE)
+ GHOST_Context *context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ GLX_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ 3, 2,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS,
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+#elif defined(WITH_GL_PROFILE_ES20)
+ GHOST_Context *context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
+ 2, 0,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS,
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+#elif defined(WITH_GL_PROFILE_COMPAT)
+ GHOST_Context *context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ 0, // profile bit
+ 0, 0,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS,
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+#else
+# error
#endif
- m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
- if (m_context != NULL) {
- if (!s_firstContext) {
- s_firstContext = m_context;
- }
- glXMakeCurrent(m_display, m_window, m_context);
- glClearColor(0.447, 0.447, 0.447, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
+#else
+
+#if defined(WITH_GL_PROFILE_CORE)
+ GHOST_Context *context = new GHOST_ContextEGL(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ 3, 2,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_API);
+#elif defined(WITH_GL_PROFILE_ES20)
+ GHOST_Context *context = new GHOST_ContextEGL(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ 0, // profile bit
+ 2, 0,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_ES_API);
+#elif defined(WITH_GL_PROFILE_COMPAT)
+ GHOST_Context *context = new GHOST_ContextEGL(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ 0, // profile bit
+ 0, 0,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_API);
+#else
+# error
+#endif
-#ifdef WITH_X11_XINPUT
- /* Restore handler */
- (void) XSetErrorHandler(old_handler);
- (void) XSetIOErrorHandler(old_handler_io);
#endif
- break;
- }
- case GHOST_kDrawingContextTypeNone:
- {
- success = GHOST_kSuccess;
- break;
- }
- default:
- success = GHOST_kFailure;
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
}
- return success;
-}
-
-
-/**
- * Removes the current drawing context.
- * \return Indication as to whether removal has succeeded.
- */
-GHOST_TSuccess
-GHOST_WindowX11::
-removeDrawingContext()
-{
- GHOST_TSuccess success;
-
- if (m_context != NULL) {
- glXDestroyContext(m_display, m_context);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ return NULL;
}
@@ -1530,72 +1425,3 @@ endFullScreen() const
return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_WindowX11::
-setSwapInterval(int interval) {
- if (!GLX_EXT_swap_control || !glXSwapIntervalEXT
-#ifdef SWAP_INTERVALS_WORKAROUND
- || g_swap_interval_disabled
-#endif // SWAP_INTERVALS_WORKAROUND
- )
- {
- return GHOST_kFailure;
- }
- glXSwapIntervalEXT(m_display, m_window, interval);
- return GHOST_kSuccess;
-}
-
-#ifdef SWAP_INTERVALS_WORKAROUND
-static int QueryDrawable_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
-{
- fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
- theEvent->error_code, theEvent->request_code);
- if (!g_swap_interval_disabled) {
- fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
- g_swap_interval_disabled = true;
- }
- return 0;
-}
-
-static int QueryDrawable_ApplicationIOErrorHandler(Display *display)
-{
- fprintf(stderr, "Ignoring Xlib error: error IO\n");
- if (!g_swap_interval_disabled) {
- fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
- g_swap_interval_disabled = true;
- }
- return 0;
-}
-#endif // SWAP_INTERVALS_WORKAROUND
-
-int
-GHOST_WindowX11::
-getSwapInterval() {
- if (GLX_EXT_swap_control) {
-#ifdef SWAP_INTERVALS_WORKAROUND
- /* XXX: Current MESA driver will give GLXBadDrawable for all
- * the glXQueryDrawable requests with direct contexts.
- *
- * To prevent crashes and unexpected behaviors, we will
- * disable swap intervals extension if query fails here.
- * (because if we will override interval without having
- * old value we couldn't restore it properly).
- */
- XErrorHandler old_handler = XSetErrorHandler(QueryDrawable_ApplicationErrorHandler);
- XIOErrorHandler old_handler_io = XSetIOErrorHandler(QueryDrawable_ApplicationIOErrorHandler);
-#endif // SWAP_INTERVALS_WORKAROUND
-
- unsigned int value = 0;
- glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &value);
-
-#ifdef SWAP_INTERVALS_WORKAROUND
- /* Restore handler */
- (void) XSetErrorHandler(old_handler);
- (void) XSetIOErrorHandler(old_handler_io);
-#endif // SWAP_INTERVALS_WORKAROUND
-
- return (int)value;
- }
- return 0;
-}