0024516: Copyright information has been corrupted within some headers
[occt.git] / src / OpenGl / OpenGl_Context.hxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _OpenGl_Context_H__
17 #define _OpenGl_Context_H__
18
19 #include <Aspect_Handle.hxx>
20 #include <Aspect_Drawable.hxx>
21 #include <Aspect_Display.hxx>
22 #include <Aspect_RenderingContext.hxx>
23 #include <Handle_OpenGl_Context.hxx>
24 #include <Handle_OpenGl_ShaderManager.hxx>
25 #include <NCollection_DataMap.hxx>
26 #include <NCollection_Map.hxx>
27 #include <NCollection_Handle.hxx>
28 #include <NCollection_Queue.hxx>
29 #include <Message.hxx>
30 #include <OpenGl_Caps.hxx>
31 #include <OpenGl_Resource.hxx>
32 #include <Standard_Transient.hxx>
33 #include <TCollection_AsciiString.hxx>
34 #include <Handle_OpenGl_Context.hxx>
35 #include <OpenGl_Clipping.hxx>
36
37 //! Forward declarations
38 struct OpenGl_GlCore12;
39 struct OpenGl_GlCore13;
40 struct OpenGl_GlCore14;
41 struct OpenGl_GlCore15;
42 struct OpenGl_GlCore20;
43 struct OpenGl_ArbVBO;
44 struct OpenGl_ArbTBO;
45 struct OpenGl_ArbIns;
46 struct OpenGl_ArbDbg;
47 struct OpenGl_ExtFBO;
48 struct OpenGl_ExtGS;
49
50 //! This class generalize access to the GL context and available extensions.
51 //!
52 //! Functions are grouped into structures and accessed as fields.
53 //! You should check the group for NULL before usage (if group is not NULL
54 //! then all functions are available):
55 //! @code
56 //!   if (myContext->core20 != NULL)
57 //!   {
58 //!     myGlProgram = myContext->core20->glCreateProgram();
59 //!     .. do more stuff ..
60 //!   }
61 //!   else
62 //!   {
63 //!     .. compatibility with outdated configurations ..
64 //!   }
65 //! @endcode
66 //!
67 //! Current implementation provide access to OpenGL core functionality up to 2.0 version
68 //! (core12, core13, core14, core15, fields core20).
69 //! within several extensions (arbVBO, extFBO, etc.).
70 //!
71 //! Simplified extensions classification:
72 //!  - prefixed with NV, AMD, ATI are vendor-specific (however may be provided by other vendors in some cases);
73 //!  - prefixed with EXT are accepted by 2+ vendors;
74 //!  - prefixed with ARB are accepted by Architecture Review Board and are candidates
75 //!    for inclusion into GL core functionality.
76 //! Some functionality can be represented in several extensions simultaneously.
77 //! In this case developer should be careful because different specification may differ
78 //! in aspects (like enumeration values and error-handling).
79 //!
80 //! Notice that some systems provide mechanisms to simultaneously incorporate with GL contexts
81 //! with different capabilities. Thats why OpenGl_Context should be initialized and used
82 //! for each GL context individually.
83 class OpenGl_Context : public Standard_Transient
84 {
85 public:
86
87   //! Function for getting power of to number larger or equal to input number.
88   //! @param theNumber    number to 'power of two'
89   //! @param theThreshold upper threshold
90   //! @return power of two number
91   inline static Standard_Integer GetPowerOfTwo (const Standard_Integer theNumber,
92                                                 const Standard_Integer theThreshold)
93   {
94     for (Standard_Integer p2 = 2; p2 <= theThreshold; p2 <<= 1)
95     {
96       if (theNumber <= p2)
97       {
98         return p2;
99       }
100     }
101     return theThreshold;
102   }
103
104 public:
105
106   //! Empty constructor. You should call Init() to perform initialization with bound GL context.
107   Standard_EXPORT OpenGl_Context (const Handle(OpenGl_Caps)& theCaps = NULL);
108
109   //! Destructor.
110   Standard_EXPORT virtual ~OpenGl_Context();
111
112   //! Share GL context resources.
113   //! theShareCtx - handle to context to retrieve handles to shared resources.
114   Standard_EXPORT void Share (const Handle(OpenGl_Context)& theShareCtx);
115
116   //! Initialize available extensions.
117   //! GL context should be active!
118   Standard_EXPORT Standard_Boolean Init();
119
120   //! @return true if this context is valid (has been initialized)
121   inline Standard_Boolean IsValid() const
122   {
123     return myIsInitialized;
124   }
125
126 #if defined(_WIN32)
127   Standard_EXPORT Standard_Boolean Init (const Aspect_Handle           theWindow,
128                                          const Aspect_Handle           theWindowDC,
129                                          const Aspect_RenderingContext theGContext);
130 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
131   Standard_EXPORT Standard_Boolean Init (const void*                   theGContext);
132 #else
133   Standard_EXPORT Standard_Boolean Init (const Aspect_Drawable         theWindow,
134                                          const Aspect_Display          theDisplay,
135                                          const Aspect_RenderingContext theGContext);
136 #endif
137
138   //! Check if theExtName extension is supported by active GL context.
139   Standard_EXPORT Standard_Boolean CheckExtension (const char* theExtName) const;
140
141   //! Check if theExtName extension is in extensions string.
142   Standard_EXPORT static Standard_Boolean CheckExtension (const char* theExtString,
143                                                           const char* theExtName);
144
145   //! Auxiliary template to retrieve GL function pointer.
146   //! Pointer to function retrieved from library is statically casted
147   //! to requested type - there no way to check real signature of exported function.
148   //! The context should be bound before call.
149   template <typename FuncType_t>
150   Standard_Boolean FindProc (const char* theFuncName,
151                              FuncType_t& theFuncPtr)
152   {
153     theFuncPtr = (FuncType_t )findProc (theFuncName);
154     return (theFuncPtr != NULL);
155   }
156
157   //! @return true if detected GL version is greater or equal to requested one.
158   inline Standard_Boolean IsGlGreaterEqual (const Standard_Integer theVerMajor,
159                                             const Standard_Integer theVerMinor)
160   {
161     return (myGlVerMajor >  theVerMajor)
162         || (myGlVerMajor == theVerMajor && myGlVerMinor >= theVerMinor);
163   }
164
165   //! Clean up errors stack for this GL context (glGetError() in loop).
166   Standard_EXPORT void ResetErrors();
167
168   //! This method uses system-dependent API to retrieve information
169   //! about GL context bound to the current thread.
170   //! @return true if current thread is bound to this GL context
171   Standard_EXPORT Standard_Boolean IsCurrent() const;
172
173   //! Activates current context.
174   //! Class should be initialized with appropriate info.
175   Standard_EXPORT Standard_Boolean MakeCurrent();
176
177   //! Swap front/back buffers for this GL context (should be activated before!).
178   Standard_EXPORT void SwapBuffers();
179
180   //! Return true if active mode is GL_FEEDBACK (cached state)
181   Standard_EXPORT Standard_Boolean IsFeedback() const;
182
183   //! Setup feedback mode cached state
184   Standard_EXPORT void SetFeedback (const Standard_Boolean theFeedbackOn);
185
186   //! This function retrieves information from GL about free GPU memory that is:
187   //!  - OS-dependent. On some OS it is per-process and on others - for entire system.
188   //!  - Vendor-dependent. Currently available only on NVIDIA and AMD/ATi drivers only.
189   //!  - Numbers meaning may vary.
190   //! You should use this info only for diagnostics purposes.
191   //! @return free GPU dedicated memory in bytes.
192   Standard_EXPORT Standard_Size AvailableMemory() const;
193
194   //! This function retrieves information from GL about GPU memory
195   //! and contains more vendor-specific values than AvailableMemory().
196   Standard_EXPORT TCollection_AsciiString MemoryInfo() const;
197
198   //! Access shared resource by its name.
199   //! @param  theKey - unique identifier;
200   //! @return handle to shared resource or NULL.
201   Standard_EXPORT const Handle(OpenGl_Resource)& GetResource (const TCollection_AsciiString& theKey) const;
202
203   //! Access shared resource by its name.
204   //! @param  theKey   - unique identifier;
205   //! @param  theValue - handle to fill;
206   //! @return true if resource was shared.
207   template<typename TheHandleType>
208   Standard_Boolean GetResource (const TCollection_AsciiString& theKey,
209                                 TheHandleType&                 theValue) const
210   {
211     const Handle(OpenGl_Resource)& aResource = GetResource (theKey);
212     if (aResource.IsNull())
213     {
214       return Standard_False;
215     }
216
217     theValue = TheHandleType::DownCast (aResource);
218     return !theValue.IsNull();
219   }
220
221   //! Register shared resource.
222   //! Notice that after registration caller shouldn't release it by himself -
223   //! it will be automatically released on context destruction.
224   //! @param theKey      - unique identifier, shouldn't be empty;
225   //! @param theResource - new resource to register, shouldn't be NULL.
226   Standard_EXPORT Standard_Boolean ShareResource (const TCollection_AsciiString& theKey,
227                                                   const Handle(OpenGl_Resource)& theResource);
228
229   //! Release shared resource.
230   //! If there are more than one reference to this resource
231   //! (also used by some other existing object) then call will be ignored.
232   //! This means that current object itself should nullify handle before this call.
233   //! Notice that this is unrecommended operation at all and should be used
234   //! only in case of fat resources to release memory for other needs.
235   //! @param theKey     unique identifier
236   //! @param theToDelay postpone release until next redraw call
237   Standard_EXPORT void ReleaseResource (const TCollection_AsciiString& theKey,
238                                         const Standard_Boolean         theToDelay = Standard_False);
239
240   //! Append resource to queue for delayed clean up.
241   //! Resources in this queue will be released at next redraw call.
242   Standard_EXPORT void DelayedRelease (Handle(OpenGl_Resource)& theResource);
243
244   //! Clean up the delayed release queue.
245   Standard_EXPORT void ReleaseDelayed();
246
247   //! @return tool for management of clippings within this context.
248   inline OpenGl_Clipping& ChangeClipping() { return myClippingState; }
249
250   //! @return tool for management of clippings within this context.
251   inline const OpenGl_Clipping& Clipping() const { return myClippingState; }
252
253   //! @return tool for management of shader programs within this context.
254   inline const Handle(OpenGl_ShaderManager)& ShaderManager() const { return myShaderManager; }
255
256 public:
257
258   //! @return maximum degree of anisotropy texture filter
259   Standard_EXPORT Standard_Integer MaxDegreeOfAnisotropy() const;
260
261   //! @return value for GL_MAX_TEXTURE_SIZE
262   Standard_EXPORT Standard_Integer MaxTextureSize() const;
263
264   //! Get maximum number of clip planes supported by OpenGl.
265   //! This value is implementation dependant. At least 6
266   //! planes should be supported by OpenGl (see specs).
267   //! @return value for GL_MAX_CLIP_PLANES
268   Standard_EXPORT Standard_Integer MaxClipPlanes() const;
269
270 public:
271
272   //! @return messanger instance
273   inline const Handle_Message_Messenger& Messanger() const
274   {
275     return ::Message::DefaultMessenger();
276   }
277
278   //! Callback for GL_ARB_debug_output extension
279   //! @param theSource   message source   within GL_DEBUG_SOURCE_   enumeration
280   //! @param theType     message type     within GL_DEBUG_TYPE_     enumeration
281   //! @param theId       message ID       within source
282   //! @param theSeverity message severity within GL_DEBUG_SEVERITY_ enumeration
283   //! @param theMessage  the message itself
284   Standard_EXPORT void PushMessage (const unsigned int theSource,
285                                     const unsigned int theType,
286                                     const unsigned int theId,
287                                     const unsigned int theSeverity,
288                                     const TCollection_ExtendedString& theMessage);
289
290 private:
291
292   //! Wrapper to system function to retrieve GL function pointer by name.
293   Standard_EXPORT void* findProc (const char* theFuncName);
294
295   //! Read OpenGL version information from active context.
296   Standard_EXPORT void readGlVersion();
297
298   //! Private initialization function that should be called only once.
299   Standard_EXPORT void init();
300
301 public: // core profiles
302
303   OpenGl_GlCore12* core12;
304   OpenGl_GlCore13* core13;
305   OpenGl_GlCore14* core14;
306   OpenGl_GlCore15* core15;
307   OpenGl_GlCore20* core20;
308
309   Handle(OpenGl_Caps) caps; //!< context options
310
311 public: // extensions
312
313   Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two
314   OpenGl_ArbVBO*   arbVBO;  //!< GL_ARB_vertex_buffer_object
315   OpenGl_ArbTBO*   arbTBO;  //!< GL_ARB_texture_buffer_object
316   OpenGl_ArbIns*   arbIns;  //!< GL_ARB_draw_instanced
317   OpenGl_ArbDbg*   arbDbg;  //!< GL_ARB_debug_output
318   OpenGl_ExtFBO*   extFBO;  //!< GL_EXT_framebuffer_object
319   OpenGl_ExtGS*    extGS;   //!< GL_EXT_geometry_shader4
320   Standard_Boolean extBgra; //!< GL_EXT_bgra
321   Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic
322   Standard_Boolean extPDS;  //!< GL_EXT_packed_depth_stencil
323   Standard_Boolean atiMem;  //!< GL_ATI_meminfo
324   Standard_Boolean nvxMem;  //!< GL_NVX_gpu_memory_info
325
326 private: // system-dependent fields
327
328 #if defined(_WIN32)
329   Aspect_Handle           myWindow;   //!< window handle (owner of GL context) : HWND
330   Aspect_Handle           myWindowDC; //!< Device Descriptor handle : HDC
331   Aspect_RenderingContext myGContext; //!< Rendering Context handle : HGLRC
332 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
333   void*                   myGContext; //!< Rendering Context handle : NSOpenGLContext
334 #else
335   Aspect_Drawable         myWindow;   //!< window handle (owner of GL context) : GLXDrawable
336   Aspect_Display          myDisplay;  //!< connection to the X-server : Display*
337   Aspect_RenderingContext myGContext; //!< X-GLX rendering context : GLXContext
338 #endif
339
340 private: // context info
341
342   typedef NCollection_DataMap<TCollection_AsciiString, Standard_Integer> OpenGl_DelayReleaseMap;
343   typedef NCollection_Handle<OpenGl_DelayReleaseMap> Handle(OpenGl_DelayReleaseMap);
344   typedef NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)> OpenGl_ResourcesMap;
345   typedef NCollection_Handle<OpenGl_ResourcesMap> Handle(OpenGl_ResourcesMap);
346   typedef NCollection_Queue<Handle(OpenGl_Resource)> OpenGl_ResourcesQueue;
347   typedef NCollection_Handle<OpenGl_ResourcesQueue> Handle(OpenGl_ResourcesQueue);
348
349   Handle(OpenGl_ResourcesMap)    mySharedResources; //!< shared resources with unique identification key
350   Handle(OpenGl_DelayReleaseMap) myDelayed;         //!< shared resources for delayed release
351   Handle(OpenGl_ResourcesQueue)  myReleaseQueue;    //!< queue of resources for delayed clean up
352
353   OpenGl_Clipping myClippingState; //!< state of clip planes
354
355   void*            myGlLibHandle;   //!< optional handle to GL library
356   OpenGl_GlCore20* myGlCore20;      //!< common structure for GL core functions upto 2.0
357   Standard_Integer myAnisoMax;      //!< maximum level of anisotropy texture filter
358   Standard_Integer myMaxTexDim;     //!< value for GL_MAX_TEXTURE_SIZE
359   Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES
360   Standard_Integer myGlVerMajor;    //!< cached GL version major number
361   Standard_Integer myGlVerMinor;    //!< cached GL version minor number
362   Standard_Boolean myIsFeedback;    //!< flag indicates GL_FEEDBACK mode
363   Standard_Boolean myIsInitialized; //!< flag indicates initialization state
364
365   Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs
366
367 private:
368
369   //! Copying allowed only within Handles
370   OpenGl_Context            (const OpenGl_Context& );
371   OpenGl_Context& operator= (const OpenGl_Context& );
372
373 public:
374
375   DEFINE_STANDARD_RTTI(OpenGl_Context) // Type definition
376
377   friend class OpenGl_Window;
378
379 };
380
381 #endif // _OpenGl_Context_H__