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