Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #ifndef INCLUDED_VCL_OPENGL_OPENGLCONTEXT_HXX
11 : #define INCLUDED_VCL_OPENGL_OPENGLCONTEXT_HXX
12 :
13 : #include <string.h>
14 :
15 : #include <GL/glew.h>
16 :
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
32 :
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
53 :
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 :
60 : #include <set>
61 :
62 : class OpenGLFramebuffer;
63 : class OpenGLProgram;
64 : class OpenGLTexture;
65 : class SalGraphicsImpl;
66 :
67 : /// Holds the information of our new child window
68 : struct GLWindow
69 : {
70 : // Copy of gluCheckExtension(), from the Apache-licensed
71 : // https://code.google.com/p/glues/source/browse/trunk/glues/source/glues_registry.c
72 0 : static GLboolean checkExtension(const GLubyte* extName, const GLubyte* extString)
73 : {
74 0 : GLboolean flag=GL_FALSE;
75 : char* word;
76 : char* lookHere;
77 : char* deleteThis;
78 :
79 0 : if (extString==NULL)
80 : {
81 0 : return GL_FALSE;
82 : }
83 :
84 0 : deleteThis=lookHere=static_cast<char*>(malloc(strlen(reinterpret_cast<const char*>(extString))+1));
85 0 : if (lookHere==NULL)
86 : {
87 0 : return GL_FALSE;
88 : }
89 :
90 : /* strtok() will modify string, so copy it somewhere */
91 0 : strcpy(lookHere, reinterpret_cast<const char*>(extString));
92 :
93 0 : while ((word=strtok(lookHere, " "))!=NULL)
94 : {
95 0 : if (strcmp(word, reinterpret_cast<const char*>(extName))==0)
96 : {
97 0 : flag=GL_TRUE;
98 0 : break;
99 : }
100 0 : lookHere=NULL; /* get next token */
101 : }
102 0 : free(static_cast<void*>(deleteThis));
103 :
104 0 : return flag;
105 : }
106 :
107 : #if defined( _WIN32 )
108 : HWND hWnd;
109 : HDC hDC;
110 : HGLRC hRC;
111 : #elif defined( MACOSX )
112 : #elif defined( IOS )
113 : #elif defined( ANDROID )
114 : #elif defined( LIBO_HEADLESS )
115 : #elif defined( UNX )
116 : Display* dpy;
117 : int screen;
118 : Window win;
119 : Pixmap pix;
120 : #if defined( GLX_EXT_texture_from_pixmap )
121 : GLXFBConfig fbc;
122 : #endif
123 : XVisualInfo* vi;
124 : GLXContext ctx;
125 : GLXPixmap glPix;
126 :
127 0 : bool HasGLXExtension( const char* name ) { return checkExtension( reinterpret_cast<const GLubyte*>(name), reinterpret_cast<const GLubyte*>(GLXExtensions) ); }
128 : const char* GLXExtensions;
129 : #endif
130 : unsigned int bpp;
131 : unsigned int Width;
132 : unsigned int Height;
133 : const GLubyte* GLExtensions;
134 : bool bMultiSampleSupported;
135 :
136 18 : GLWindow()
137 : :
138 : #if defined( _WIN32 )
139 : #elif defined( MACOSX )
140 : #elif defined( IOS )
141 : #elif defined( ANDROID )
142 : #elif defined( LIBO_HEADLESS )
143 : #elif defined( UNX )
144 : dpy(NULL),
145 : screen(0),
146 : win(0),
147 : pix(0),
148 : #if defined( GLX_EXT_texture_from_pixmap )
149 : fbc(0),
150 : #endif
151 : vi(NULL),
152 : ctx(0),
153 : glPix(0),
154 : GLXExtensions(NULL),
155 : #endif
156 : bpp(0),
157 : Width(0),
158 : Height(0),
159 : GLExtensions(NULL),
160 18 : bMultiSampleSupported(false)
161 : {
162 18 : }
163 :
164 : ~GLWindow();
165 : };
166 :
167 : class VCL_DLLPUBLIC OpenGLContext
168 : {
169 : public:
170 : OpenGLContext();
171 : ~OpenGLContext();
172 :
173 : void requestLegacyContext();
174 : void requestSingleBufferedRendering();
175 : void requestVirtualDevice();
176 :
177 : bool init(vcl::Window* pParent = 0);
178 : bool init(SystemChildWindow* pChildWindow);
179 :
180 : // these methods are for the deep platform layer, don't use them in normal code
181 : // only in vcl's platform code
182 : #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
183 : bool init(Display* dpy, Window win, int screen);
184 : bool init(Display* dpy, Pixmap pix, unsigned int width, unsigned int height, int nScreen);
185 : #elif defined( _WIN32 )
186 : bool init( HDC hDC, HWND hWnd );
187 : #endif
188 : void reset();
189 :
190 : // use these methods right after setting a context to make sure drawing happens
191 : // in the right FBO (default one is for onscreen painting)
192 : bool BindFramebuffer( OpenGLFramebuffer* pFramebuffer );
193 : bool AcquireDefaultFramebuffer();
194 : OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
195 : static void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
196 : #ifdef DBG_UTIL
197 : void AddRef(SalGraphicsImpl*);
198 : void DeRef(SalGraphicsImpl*);
199 : #else
200 : void AddRef();
201 : void DeRef();
202 : #endif
203 : void ReleaseFramebuffer( const OpenGLTexture& rTexture );
204 : void ReleaseFramebuffers();
205 :
206 : // retrieve a program from the cache or compile/link it
207 : OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
208 : OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
209 :
210 : bool isCurrent();
211 : static void clearCurrent();
212 :
213 : /// make this GL context current - so it is implicit in subsequent GL calls
214 : void makeCurrent();
215 : /// reset the GL context so this context is not implicit in subsequent GL calls.
216 : void resetCurrent();
217 : void swapBuffers();
218 : void sync();
219 : void show();
220 :
221 : void setWinPosAndSize(const Point &rPos, const Size& rSize);
222 : void setWinSize(const Size& rSize);
223 0 : const GLWindow& getOpenGLWindow() const { return m_aGLWin;}
224 :
225 : SystemChildWindow* getChildWindow();
226 : const SystemChildWindow* getChildWindow() const;
227 :
228 : void renderToFile();
229 :
230 0 : bool isInitialized()
231 : {
232 0 : return mbInitialized;
233 : }
234 :
235 : bool supportMultiSampling() const;
236 :
237 : static SystemWindowData generateWinData(vcl::Window* pParent, bool bRequestLegacyContext);
238 :
239 : private:
240 : SAL_DLLPRIVATE bool InitGLEW();
241 : SAL_DLLPRIVATE bool initWindow();
242 : SAL_DLLPRIVATE bool ImplInit();
243 : #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
244 : SAL_DLLPRIVATE void initGLWindow(Visual* pVisual);
245 : #endif
246 :
247 : #if defined(MACOSX)
248 : NSOpenGLView* getOpenGLView();
249 : #endif
250 :
251 : GLWindow m_aGLWin;
252 : VclPtr<vcl::Window> m_xWindow;
253 : VclPtr<vcl::Window> mpWindow; //points to m_pWindow or the parent window, don't delete it
254 : VclPtr<SystemChildWindow> m_pChildWindow;
255 : bool mbInitialized;
256 : int mnRefCount;
257 : bool mbRequestLegacyContext;
258 : bool mbUseDoubleBufferedRendering;
259 : bool mbRequestVirtualDevice;
260 : #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
261 : bool mbPixmap; // is a pixmap instead of a window
262 : #endif
263 :
264 : int mnFramebufferCount;
265 : OpenGLFramebuffer* mpCurrentFramebuffer;
266 : OpenGLFramebuffer* mpFirstFramebuffer;
267 : OpenGLFramebuffer* mpLastFramebuffer;
268 :
269 0 : struct ProgramKey
270 : {
271 : ProgramKey( const OUString& vertexShader, const OUString& fragmentShader, const OString& preamble );
272 : bool operator< ( const ProgramKey& other ) const;
273 : OUString vertexShader;
274 : OUString fragmentShader;
275 : OString preamble;
276 : };
277 : std::map<ProgramKey, boost::shared_ptr<OpenGLProgram> > maPrograms;
278 : OpenGLProgram* mpCurrentProgram;
279 : #ifdef DBG_UTIL
280 : std::set<SalGraphicsImpl*> maParents;
281 : #endif
282 :
283 : public:
284 : vcl::Region maClipRegion;
285 : int mnPainting;
286 :
287 : OpenGLContext* mpPrevContext;
288 : OpenGLContext* mpNextContext;
289 : };
290 :
291 : #endif
292 :
293 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|