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

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