GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/utils/glxhelper.cpp Lines: 0 42 0.0 %
Date: 2017-11-29 Branches: 0 22 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2014-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "utils/glxhelper.h"
22
23
#if defined(USE_OPENGL) && defined(USE_X11)
24
25
#include "logger.h"
26
27
#include "render/opengl/mglcheck.h"
28
29
#include "render/openglx/mglx.h"
30
31
#include "render/opengl/mgldefines.h"
32
RENDER_OPENGL_MGLDEFINES_H
33
34
#include "debug.h"
35
36
static int ErrorHandler(Display *d A_UNUSED, XErrorEvent *e A_UNUSED)
37
{
38
    return 0;
39
}
40
41
void *GlxHelper::createContext(const unsigned long window,
42
                               void *const display0,
43
                               const int major,
44
                               const int minor,
45
                               const int profile)
46
{
47
    Display *const display = static_cast<Display*>(display0);
48
    XSync(display, false);
49
    int (*handler)(Display *, XErrorEvent *) = XSetErrorHandler(ErrorHandler);
50
    void *context = mglXGetCurrentContext();
51
    if (!display)
52
        return context;
53
    if (isGLNull(mglXGetCurrentContext)
54
        || isGLNull(mglXCreateContextAttribs)
55
        || isGLNull(mglXChooseFBConfig))
56
    {
57
        logger->log("Can't change context, functions in driver "
58
            "not implemented");
59
        XSetErrorHandler(handler);
60
        return context;
61
    }
62
    if (!context)
63
    {
64
        logger->log("Can't change context, because current "
65
            "context not created");
66
        XSetErrorHandler(handler);
67
        return context;
68
    }
69
    int glxAttribs[] =
70
    {
71
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
72
        GLX_RED_SIZE, 3,
73
        GLX_GREEN_SIZE, 3,
74
        GLX_BLUE_SIZE, 2,
75
        GLX_DOUBLEBUFFER, 1,
76
        0
77
    };
78
79
    int fbcount = 0;
80
    GLXFBConfig *framebuffer_config = mglXChooseFBConfig(display,
81
        DefaultScreen(display),
82
        glxAttribs,
83
        &fbcount);
84
85
    if (!framebuffer_config || !fbcount)
86
    {
87
        logger->log("No correct fb profile found");
88
        XSetErrorHandler(handler);
89
        return nullptr;
90
    }
91
    logger->log("Found %d frame buffer contexts.", fbcount);
92
93
    int attribs[] =
94
    {
95
        GLX_CONTEXT_MAJOR_VERSION_ARB, major,
96
        GLX_CONTEXT_MINOR_VERSION_ARB, minor,
97
        GLX_CONTEXT_PROFILE_MASK_ARB, profile,
98
        0, 0
99
    };
100
101
    void *const context2 = mglXCreateContextAttribs(display,
102
        framebuffer_config[0], context, true, attribs);
103
    if (!context2)
104
    {
105
        logger->log("context %d.%d creation failed", major, minor);
106
        XSetErrorHandler(handler);
107
        return nullptr;
108
    }
109
110
    XSync(display, false);
111
    XSetErrorHandler(handler);
112
113
    if (!mglXMakeCurrent(display, window, context2))
114
    {
115
        mglXDestroyContext(display, context2);
116
        logger->log("make current context %d.%d failed", major, minor);
117
        return nullptr;
118
    }
119
120
    if (mglXGetCurrentContext() != context2)
121
    {
122
        mglXDestroyContext(display, context2);
123
        logger->log("context cant be changed to %d.%d.", major, minor);
124
        return nullptr;
125
    }
126
127
//  do not delete SDL context, because on exit it will crash
128
//    mglXDestroyContext(display, context);
129
    logger->log("Context for %d.%d created", major, minor);
130
    return context2;
131
}
132
133
bool GlxHelper::makeCurrent(const unsigned long window,
134
                            void *const display,
135
                            void *const context)
136
{
137
    if (!display)
138
        return false;
139
    return mglXMakeCurrent(static_cast<Display*>(display), window, context);
140
}
141
142
#endif  // defined(USE_OPENGL) && defined(USE_X11)