Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / platform / graphics / GLContext.cpp
1 /*
2  * Copyright (C) 2011, 2012 Igalia, S.L.
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include "config.h"
20
21 #if ENABLE(GRAPHICS_CONTEXT_3D)
22
23 #include "GLContext.h"
24
25 #include "PlatformDisplay.h"
26 #include <wtf/ThreadSpecific.h>
27
28 #if USE(EGL)
29 #include "GLContextEGL.h"
30 #endif
31
32 #if USE(GLX)
33 #include "GLContextGLX.h"
34 #endif
35
36 using WTF::ThreadSpecific;
37
38 namespace WebCore {
39
40 class ThreadGlobalGLContext {
41 public:
42     static ThreadSpecific<ThreadGlobalGLContext>* staticGLContext;
43
44     void setContext(GLContext* context) { m_context = context; }
45     GLContext* context() { return m_context; }
46
47 private:
48     GLContext* m_context;
49 };
50
51 ThreadSpecific<ThreadGlobalGLContext>* ThreadGlobalGLContext::staticGLContext;
52
53 inline ThreadGlobalGLContext* currentContext()
54 {
55     if (!ThreadGlobalGLContext::staticGLContext)
56         ThreadGlobalGLContext::staticGLContext = new ThreadSpecific<ThreadGlobalGLContext>;
57     return *ThreadGlobalGLContext::staticGLContext;
58 }
59
60 GLContext* GLContext::sharingContext()
61 {
62     DEPRECATED_DEFINE_STATIC_LOCAL(std::unique_ptr<GLContext>, sharing, (createOffscreenContext()));
63     return sharing.get();
64 }
65
66 #if PLATFORM(X11)
67 // Because of driver bugs, exiting the program when there are active pbuffers
68 // can crash the X server (this has been observed with the official Nvidia drivers).
69 // We need to ensure that we clean everything up on exit. There are several reasons
70 // that GraphicsContext3Ds will still be alive at exit, including user error (memory
71 // leaks) and the page cache. In any case, we don't want the X server to crash.
72 typedef Vector<GLContext*> ActiveContextList;
73 static ActiveContextList& activeContextList()
74 {
75     DEPRECATED_DEFINE_STATIC_LOCAL(ActiveContextList, activeContexts, ());
76     return activeContexts;
77 }
78
79 void GLContext::addActiveContext(GLContext* context)
80 {
81     static bool addedAtExitHandler = false;
82     if (!addedAtExitHandler) {
83         atexit(&GLContext::cleanupActiveContextsAtExit);
84         addedAtExitHandler = true;
85     }
86     activeContextList().append(context);
87 }
88
89 static bool gCleaningUpAtExit = false;
90
91 void GLContext::removeActiveContext(GLContext* context)
92 {
93     // If we are cleaning up the context list at exit, don't bother removing the context
94     // from the list, since we don't want to modify the list while it's being iterated.
95     if (gCleaningUpAtExit)
96         return;
97
98     ActiveContextList& contextList = activeContextList();
99     size_t i = contextList.find(context);
100     if (i != notFound)
101         contextList.remove(i);
102 }
103
104 void GLContext::cleanupActiveContextsAtExit()
105 {
106     gCleaningUpAtExit = true;
107
108     ActiveContextList& contextList = activeContextList();
109     for (size_t i = 0; i < contextList.size(); ++i)
110         delete contextList[i];
111 }
112 #endif // PLATFORM(X11)
113
114
115 std::unique_ptr<GLContext> GLContext::createContextForWindow(GLNativeWindowType windowHandle, GLContext* sharingContext)
116 {
117 #if PLATFORM(WAYLAND) && USE(EGL)
118     if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland) {
119         if (auto eglContext = GLContextEGL::createContext(windowHandle, sharingContext))
120             return WTFMove(eglContext);
121         return nullptr;
122     }
123 #endif
124
125 #if USE(GLX)
126 #if PLATFORM(WAYLAND) // Building both X11 and Wayland targets
127     XID GLXWindowHandle = reinterpret_cast<XID>(windowHandle);
128 #else
129     XID GLXWindowHandle = static_cast<XID>(windowHandle);
130 #endif
131     if (auto glxContext = GLContextGLX::createContext(GLXWindowHandle, sharingContext))
132         return WTFMove(glxContext);
133 #endif
134 #if USE(EGL)
135     if (auto eglContext = GLContextEGL::createContext(windowHandle, sharingContext))
136         return WTFMove(eglContext);
137 #endif
138     return nullptr;
139 }
140
141 GLContext::GLContext()
142 {
143 #if PLATFORM(X11)
144     addActiveContext(this);
145 #endif
146 }
147
148 std::unique_ptr<GLContext> GLContext::createOffscreenContext(GLContext* sharingContext)
149 {
150     return createContextForWindow(0, sharingContext);
151 }
152
153 GLContext::~GLContext()
154 {
155     if (this == currentContext()->context())
156         currentContext()->setContext(0);
157 #if PLATFORM(X11)
158     removeActiveContext(this);
159 #endif
160 }
161
162 bool GLContext::makeContextCurrent()
163 {
164     currentContext()->setContext(this);
165     return true;
166 }
167
168 GLContext* GLContext::getCurrent()
169 {
170     return currentContext()->context();
171 }
172
173 } // namespace WebCore
174
175 #endif