Branch libreoffice-5-0-4
[LibreOffice.git] / include / vcl / opengl / OpenGLContext.hxx
blobce44aefa24b72d50da3e572ac8c6973491cb177e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #ifndef INCLUDED_VCL_OPENGL_OPENGLCONTEXT_HXX
11 #define INCLUDED_VCL_OPENGL_OPENGLCONTEXT_HXX
13 #include <string.h>
15 #include <GL/glew.h>
17 #if defined( MACOSX )
18 #elif defined( IOS )
19 #elif defined( ANDROID )
20 #elif defined( LIBO_HEADLESS )
21 #elif defined( UNX )
22 # include <prex.h>
23 # include "GL/glxew.h"
24 # include <postx.h>
25 #elif defined( _WIN32 )
26 #ifndef INCLUDED_PRE_POST_WIN_H
27 #define INCLUDED_PRE_POST_WIN_H
28 # include "prewin.h"
29 # include "postwin.h"
30 #endif
31 #endif
33 #if defined( _WIN32 )
34 #include <GL/glext.h>
35 #include <GL/wglew.h>
36 #include <GL/wglext.h>
37 #elif defined( MACOSX )
38 #include <OpenGL/OpenGL.h>
39 #ifdef __OBJC__
40 @class NSOpenGLView;
41 #else
42 class NSOpenGLView;
43 #endif
44 #elif defined( IOS )
45 #elif defined( ANDROID )
46 #elif defined( LIBO_HEADLESS )
47 #elif defined( UNX )
48 #include <GL/glext.h>
49 #define GLX_GLXEXT_PROTOTYPES 1
50 #include <GL/glx.h>
51 #include <GL/glxext.h>
52 #endif
54 #include <vcl/dllapi.h>
55 #include <boost/ptr_container/ptr_map.hpp>
56 #include <vcl/window.hxx>
57 #include <tools/gen.hxx>
58 #include <vcl/syschild.hxx>
59 #include <rtl/crc.h>
60 #include <rtl/ref.hxx>
62 #include <map>
63 #include <memory>
64 #include <set>
65 #include <unordered_map>
67 class OpenGLFramebuffer;
68 class OpenGLProgram;
69 class OpenGLTexture;
70 class SalGraphicsImpl;
71 class OpenGLTests;
73 /// Holds the information of our new child window
74 struct GLWindow
76 // Copy of gluCheckExtension(), from the Apache-licensed
77 // https://code.google.com/p/glues/source/browse/trunk/glues/source/glues_registry.c
78 static GLboolean checkExtension(const GLubyte* extName, const GLubyte* extString)
80 GLboolean flag=GL_FALSE;
81 char* word;
82 char* lookHere;
83 char* deleteThis;
85 if (extString==NULL)
87 return GL_FALSE;
90 deleteThis=lookHere=static_cast<char*>(malloc(strlen(reinterpret_cast<const char*>(extString))+1));
91 if (lookHere==NULL)
93 return GL_FALSE;
96 /* strtok() will modify string, so copy it somewhere */
97 strcpy(lookHere, reinterpret_cast<const char*>(extString));
99 while ((word=strtok(lookHere, " "))!=NULL)
101 if (strcmp(word, reinterpret_cast<const char*>(extName))==0)
103 flag=GL_TRUE;
104 break;
106 lookHere=NULL; /* get next token */
108 free((void*)deleteThis);
110 return flag;
113 #if defined( _WIN32 )
114 HWND hWnd;
115 HDC hDC;
116 HGLRC hRC;
117 #elif defined( MACOSX )
118 #elif defined( IOS )
119 #elif defined( ANDROID )
120 #elif defined( LIBO_HEADLESS )
121 #elif defined( UNX )
122 Display* dpy;
123 int screen;
124 Window win;
125 Pixmap pix;
126 #if defined( GLX_EXT_texture_from_pixmap )
127 GLXFBConfig fbc;
128 #endif
129 XVisualInfo* vi;
130 GLXContext ctx;
131 GLXPixmap glPix;
133 bool HasGLXExtension( const char* name ) { return checkExtension( reinterpret_cast<const GLubyte*>(name), reinterpret_cast<const GLubyte*>(GLXExtensions) ); }
134 const char* GLXExtensions;
135 #endif
136 unsigned int bpp;
137 unsigned int Width;
138 unsigned int Height;
139 const GLubyte* GLExtensions;
140 bool bMultiSampleSupported;
142 GLWindow()
144 #if defined( _WIN32 )
145 hWnd(NULL),
146 hDC(NULL),
147 hRC(NULL),
148 #elif defined( MACOSX )
149 #elif defined( IOS )
150 #elif defined( ANDROID )
151 #elif defined( LIBO_HEADLESS )
152 #elif defined( UNX )
153 dpy(NULL),
154 screen(0),
155 win(0),
156 pix(0),
157 #if defined( GLX_EXT_texture_from_pixmap )
158 fbc(0),
159 #endif
160 vi(NULL),
161 ctx(0),
162 glPix(0),
163 GLXExtensions(NULL),
164 #endif
165 bpp(0),
166 Width(0),
167 Height(0),
168 GLExtensions(NULL),
169 bMultiSampleSupported(false)
173 ~GLWindow();
176 class VCL_DLLPUBLIC OpenGLContext
178 friend class OpenGLTests;
179 OpenGLContext();
180 public:
181 static rtl::Reference<OpenGLContext> Create();
182 ~OpenGLContext();
183 void acquire() { mnRefCount++; }
184 void release() { if ( --mnRefCount == 0 ) delete this; }
185 void dispose();
187 void requestLegacyContext();
188 void requestSingleBufferedRendering();
189 void requestVirtualDevice();
191 bool init(vcl::Window* pParent = 0);
192 bool init(SystemChildWindow* pChildWindow);
194 // these methods are for the deep platform layer, don't use them in normal code
195 // only in vcl's platform code
196 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
197 bool init(Display* dpy, Window win, int screen);
198 bool init(Display* dpy, Pixmap pix, unsigned int width, unsigned int height, int nScreen);
199 #elif defined( _WIN32 )
200 bool init( HDC hDC, HWND hWnd );
201 #endif
202 void reset();
204 // use these methods right after setting a context to make sure drawing happens
205 // in the right FBO (default one is for onscreen painting)
206 bool BindFramebuffer( OpenGLFramebuffer* pFramebuffer );
207 bool AcquireDefaultFramebuffer();
208 OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
209 static void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
210 void UnbindTextureFromFramebuffers( GLuint nTexture );
212 void ReleaseFramebuffer( const OpenGLTexture& rTexture );
213 void ReleaseFramebuffers();
215 // retrieve a program from the cache or compile/link it
216 OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
217 OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
219 /// Is this GL context the current context ?
220 bool isCurrent();
221 /// release bound resources from the current context
222 static void clearCurrent();
223 /// release contexts etc. before (potentially) allowing another thread run.
224 static void prepareForYield();
225 /// Is there a current GL context ?
226 static bool hasCurrent();
227 /// make this GL context current - so it is implicit in subsequent GL calls
228 void makeCurrent();
229 /// Put this GL context to the end of the context list.
230 void registerAsCurrent();
231 /// reset the GL context so this context is not implicit in subsequent GL calls.
232 void resetCurrent();
233 void swapBuffers();
234 void sync();
235 void show();
237 void setWinPosAndSize(const Point &rPos, const Size& rSize);
238 void setWinSize(const Size& rSize);
239 const GLWindow& getOpenGLWindow() const { return m_aGLWin;}
241 SystemChildWindow* getChildWindow();
242 const SystemChildWindow* getChildWindow() const;
244 void renderToFile();
246 bool isInitialized()
248 return mbInitialized;
251 bool requestedLegacy()
253 return mbRequestLegacyContext;
256 bool supportMultiSampling() const;
258 static SystemWindowData generateWinData(vcl::Window* pParent, bool bRequestLegacyContext);
260 private:
261 SAL_DLLPRIVATE bool InitGLEW();
262 SAL_DLLPRIVATE void InitGLEWDebugging();
263 SAL_DLLPRIVATE bool initWindow();
264 SAL_DLLPRIVATE bool ImplInit();
265 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
266 SAL_DLLPRIVATE void initGLWindow(Visual* pVisual);
267 #endif
269 #if defined(MACOSX)
270 NSOpenGLView* getOpenGLView();
271 #endif
273 GLWindow m_aGLWin;
274 VclPtr<vcl::Window> m_xWindow;
275 VclPtr<vcl::Window> mpWindow; //points to m_pWindow or the parent window, don't delete it
276 VclPtr<SystemChildWindow> m_pChildWindow;
277 bool mbInitialized;
278 int mnRefCount;
279 bool mbRequestLegacyContext;
280 bool mbUseDoubleBufferedRendering;
281 bool mbRequestVirtualDevice;
282 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
283 bool mbPixmap; // is a pixmap instead of a window
284 #endif
286 int mnFramebufferCount;
287 OpenGLFramebuffer* mpCurrentFramebuffer;
288 OpenGLFramebuffer* mpFirstFramebuffer;
289 OpenGLFramebuffer* mpLastFramebuffer;
291 struct ProgramHash
293 size_t operator()( const rtl::OString& aDigest ) const
295 return (size_t)( rtl_crc32( 0, aDigest.getStr(), aDigest.getLength() ) );
298 typedef std::unordered_map< rtl::OString, std::shared_ptr<OpenGLProgram>, ProgramHash > ProgramCollection;
299 ProgramCollection maPrograms;
300 OpenGLProgram* mpCurrentProgram;
301 #ifdef DBG_UTIL
302 std::set<SalGraphicsImpl*> maParents;
303 #endif
305 public:
306 vcl::Region maClipRegion;
307 int mnPainting;
309 // Don't hold references to ourselves:
310 OpenGLContext *mpPrevContext;
311 OpenGLContext *mpNextContext;
314 #endif
316 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */