00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #if !defined SOGLCONTEXT_H
00024 #define SOGLCONTEXT_H
00025 
00026 #include <Inventor/devices/SoDeviceContext.h>
00027 #include <Inventor/devices/SoGLFormat.h>
00028 #include <Inventor/STL/vector>
00029 #include <Inventor/STL/list>
00030 #include <Inventor/STL/map>
00031 #include <Inventor/helpers/SbGlContextHelper.h>
00032 #include <Inventor/threads/SbThreadSpinlock.h>
00033 #include <Inventor/errors/SoError.h>
00034 #include <Inventor/image/SbRasterImage.h>
00035 #include <Inventor/threads/SbThreadLocalStorage.h>
00036 
00037 
00038 #include <Inventor/SbPList.h> 
00039 #include <Inventor/STL/stack>
00040 
00041 #include <Inventor/helpers/SbGPUCapabilities.h>
00042 
00043 #if defined(_WIN32)
00044 #include <windows.h>
00045 #endif
00046 
00047 
00048 #ifdef _MSC_VER
00049 #pragma warning( push )
00050 #pragma warning(disable:4251)
00051 #endif
00052 
00053 class SbThreadMutex;
00054 class FunctionRedirector;
00055 
00191 class  SoGLContext : public SoDeviceContext
00192 {
00193 public:
00194 
00199   enum SharedGroupPolicy
00200   {
00202     DISABLED,
00203     
00211     CONSERVATIVE,
00212     
00219    AGGRESSIVE
00220   };
00221 
00231   SoGLContext( bool shared );
00232 
00244   SoGLContext( SbGlContextHelper::Display dpy,
00245                SbGlContextHelper::VisualInfo vis,
00246                SbGlContextHelper::Drawable drawable,
00247                SbGlContextHelper::GLContext ctx );
00248 
00258   SoGLContext( const SoGLFormat& format, SbGlContextHelper::GLContext ctx, SbGlContextHelper::Drawable drawable = 0 );
00259 
00267   SoGLContext( const SoGLFormat& format, SbGlContextHelper::Drawable drawable = 0 );
00268 
00289   SoGLContext( SbGlContextHelper::Display dpy,
00290                SbGlContextHelper::VisualInfo vis,
00291                SbGlContextHelper::Drawable drawable,
00292                bool shared = true );
00293 
00300   SoGLContext( SoGLContext* context, bool shared );
00301 
00310   SoGLContext( SoGLContext* context, const SoGLFormat& format, SbGlContextHelper::Drawable drawable = 0 );
00311   
00316   virtual void bind();
00317 
00318 
00323   virtual bool tryBind();
00324 
00328   virtual void unbind();
00329 
00335   bool isSharedWith( const SoGLContext* context ) const;
00336 
00342   bool isValid() const;
00343 
00349   void invalidate();
00350 
00357   int getId() const;
00358 
00368   virtual bool isCompatible( SoDeviceContext* context ) const;
00369 
00374   virtual bool isCurrent() const;
00375 
00395   static SoGLContext* getCurrent( bool checkGLState = false );
00396 
00402   const SbGlContextHelper::GLContext& getGLContext() const;
00403 
00409   static SoGLContext* findGLContext( SbGlContextHelper::GLContext );
00410 
00416 #if defined(_WIN32)
00417   typedef int SharedGroupDescription;
00418 #else
00419   typedef SbGlContextHelper::Display SharedGroupDescription;
00420 #endif
00421   static SoGLContext* findSharedContext( SharedGroupDescription );
00422 
00428   const SbGlContextHelper::Display& getDisplay() const;
00429 
00435   const SbGlContextHelper::VisualInfo& getVisualInfo() const;
00436 
00443   const SoGLFormat& getFormat() const;
00444 
00451   static SoGLContext* getContextFromId( int id );
00452 
00459   static SoGLContext* getContextFromSharedId( int sharedIdGroup );
00460 
00465   bool isValidForCurrent() const;
00466 
00470   void assertContext() const;
00471 
00472 #if 1             SoDEPRECATED
00481   bool swapBuffers( int plane );
00482 #endif 
00487   bool swapBuffers();
00488 
00497   SbStringList getSupportedExtensions();
00498 
00500   static SharedGroupPolicy getSharedGroupPolicy();
00501 
00502 #if 1             SoDEPRECATED
00505   void applySharedGroupPolicy();
00506 #endif 
00514   void setNoGLContextDelete() { m_noOGLContextDelete = true; }
00515 
00520   const SbGPUCapabilities& getContextGraphicsCapabilities();
00521 
00526   static const SbGPUCapabilities& getGraphicsCapabilities();
00527 
00528   private:
00529 
00530   SB_THREAD_TLS_HEADER();
00531 
00532   static void initClass();
00533   static void exitClass();
00534 
00536   enum GPUVendorType
00537   {
00538     GPU_TYPE_NOT_INITIALIZED = -1,
00539     GPU_NVIDIA = 0,
00540     GPU_ATI = 1,
00541     GPU_INTEL = 2,
00542     GPU_FIREPRO_MAC = 3
00543   };
00544 
00545   
00546   static GPUVendorType getGPUVendorType();
00547 
00559   static SoGLContext* getActualCurrentContext( SoGLContext* supposedContext );
00560 
00562   static void lockListsMutex();
00563 
00565   static void unlockListsMutex();
00566 
00570   void setUserData( void* data )
00571   { m_userData = data; }
00572 
00574   void* getUserData() const
00575   { return m_userData; }
00576 
00579   bool setSharedWith( SoGLContext* sharedContext );
00580 
00581   
00582   void forceDisplay( const SbGlContextHelper::Display& display );
00583 
00584   
00585   void forceDrawable( const SbGlContextHelper::Drawable& drawable );
00586 
00587   
00588   
00589   void forceContext( const SbGlContextHelper::GLContext& context )
00590   { m_context = context; }
00591 
00592   
00593   inline void forceNoGLContextDelete(bool flag) { m_noOGLContextDelete = flag; }
00594 
00595   
00596   const SbGlContextHelper::Drawable& getDrawable() const
00597   { return m_drawable;}
00598 
00599   
00600   static void* glewGetCurrentContextIV(const bool printError=false)
00601   {
00602     SoGLContext* ctx = SoGLContext::getCurrent(true);
00603 
00604     if ( ctx )
00605       return ctx->glewGetContextIV();
00606     else
00607     {
00608       if (printError)
00609         SoError::post("SoGLContext : Trying to access a NULL context");
00610       return glewNullContext();
00611     }
00612   };
00613 
00614 #  if defined(_WIN32)
00615   static void* wglewGetCurrentContextIV(const bool printError=false)
00616   {
00617     SoGLContext* ctx = SoGLContext::getCurrent(true);
00618 
00619     if ( ctx )
00620       return ctx->wglewGetContextIV();
00621     else
00622     {
00623       if (printError)
00624         SoError::post("SoGLContext : Trying to access a NULL context");
00625       return NULL;
00626     }
00627   };
00628 #  elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
00629   static void* glxewGetCurrentContextIV(const bool printError=false)
00630   {
00631     SoGLContext* ctx = SoGLContext::getCurrent(true);
00632 
00633     if ( ctx )
00634       return ctx->glxewGetContextIV();
00635     else
00636     {
00637       if (printError)
00638         SoError::post("SoGLContext : Trying to access a NULL context");
00639       return NULL;
00640     }
00641   };
00642 #  endif // _WIN32
00643 
00644   
00645   struct GLEWContextStruct* glewGetContextIV() const
00646   { return m_glewContext; }
00647 
00648 #  if defined(_WIN32)
00649   void* wglewGetContextIV() const
00650   { return m_wglewContext; }
00651 
00652 #  elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
00653   void* glxewGetContextIV() const
00654   { return m_glxewContext; }
00655 
00656 #  endif // _WIN32
00657 
00658   bool isGLEWInitialized() { return m_glewInit; }
00659   bool initGLEW();
00660   void cleanGLEWContext();
00661 
00662   virtual SbString getInfos();
00663 
00664   
00665   SbString getDeviceName() const;
00666 
00670   void printInformation();
00671 
00675   static void printCurrentContextInformation();
00676 
00680   static void printContextsInformation();
00681 
00687   static void invalidateDrawable(SbGlContextHelper::Drawable drawable);
00688 
00694   static void invalidateDisplay(SbGlContextHelper::Display display);
00695 
00714   bool setVSyncEnabled(bool on);
00715 
00721   bool isVSyncEnabled();
00722 
00724   bool isBinded();
00725 
00726 private:
00730   virtual ~SoGLContext();
00731 
00732 SoINTERNAL private:
00733 
00734   
00735   
00736   
00737   void removeSharedObjects();
00738 
00739 private:
00740 
00741   
00742   static struct GLEWContextStruct* glewNullContext();
00743 
00744   virtual bool setSharedWith( SoDeviceContext* sourceCtx );
00745 
00751   void setSwapInterval(int interval);
00752 
00753   
00754   struct MTstruct
00755   {
00756     typedef std::vector<SoGLContext*> ContextVec;
00758     ContextVec* m_bindedContexts;
00759   };
00760 
00761   bool initContext( SoGLContext* sourceContext, bool shared );
00762   void initGLEWContext();
00763   void preInitContext();
00764   bool postInitContext();
00765 
00766   void checkContextParameters( const char* function );
00767 
00768   typedef std::list< SoGLContext* > SoGLContextList;
00769 
00771   static SoGLContextList s_contexts;
00772 
00774   static int s_firstAvailableId;
00775 
00777   static SbThreadSpinlock s_contextsMutex;
00778 
00780   int m_id;
00781 
00782   SbGlContextHelper::GLContext m_context;
00783   SbGlContextHelper::Drawable m_drawable;
00784 
00785   SoGLFormat m_format;
00786 
00787   void* m_userData;
00788 
00789   static GPUVendorType m_GpuVendorType;
00790 
00791   
00792   struct GLEWContextStruct* m_glewContext;
00793 
00794   
00795   static struct GLEWContextStruct* s_nullGlewContext;
00796 
00797 #  if defined(_WIN32)
00798   struct WGLEWContextStruct* m_wglewContext;
00799 #  elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
00800   void* m_glxewContext;
00801 #  endif // _WIN32
00802 
00803   bool m_glewInit;
00804   bool m_noOGLContextDelete;
00805 
00806   bool m_drawableIsValid;
00807   bool m_displayIsValid;
00808 
00809   static int s_checkContext;
00810 
00811   static int s_oivCompatibilityMode;
00812 
00814   static SharedGroupPolicy s_sharedGroupPolicy;
00815 
00816   
00817   bool m_sharedObjectsRemoved;
00818 
00819   static SoGLContext* findSoGLContext(SbGlContextHelper::GLContext ctx);
00820   void pushInBindedList();
00821   static void updateBindedList();
00822   static void updateBindedList(SbGlContextHelper::Display display, SbGlContextHelper::Drawable drawable, SbGlContextHelper::GLContext context);
00823   static SoGLContext* popBindedList();
00824 
00825   bool m_thirdPartyContext;
00826   bool m_isBeingDestroyed;
00827   SbGPUCapabilities* m_graphicCapabilities;
00828   static FunctionRedirector s_deleteContextRedirector;
00829   
00830   static bool callOriginalDeleteContext(SbGlContextHelper::Display display, SbGlContextHelper::GLContext context, int& returnValue);
00831   static int commonDeleteContextHook(SbGlContextHelper::Display dpy, SbGlContextHelper::GLContext ctx);
00832 
00833 #if defined(WIN32)
00834   static int _stdcall deleteContextHook(SbGlContextHelper::GLContext context);
00835 #elif defined(__APPLE__)
00836   static int deleteContextHook(SbGlContextHelper::GLContext context);
00837 #else
00838   static int deleteContextHook(SbGlContextHelper::Display dpy, SbGlContextHelper::GLContext ctx);
00839 #endif
00840     
00841   static MTstruct::ContextVec& getBindedContextsList();
00842 };
00843 
00844 #ifdef _MSC_VER
00845 #pragma warning( pop )
00846 #endif
00847 
00848 
00849 #endif //SOGLCONTEXT_H
00850 
00851