25 #include "RConfigure.h"
42 Bool_t TGLContext::fgGlewInitDone = kFALSE;
51 TGLContext::TGLContext(TGLWidget *wid, Bool_t shareDefault,
52 const TGLContext *shareList)
59 shareList = TGLContextIdentity::GetDefaultContextAny();
61 if (!gVirtualX->IsCmdThread()) {
62 gROOT->ProcessLineFast(Form(
"((TGLContext *)0x%lx)->SetContext((TGLWidget *)0x%lx, (TGLContext *)0x%lx)",
63 (ULong_t)
this, (ULong_t)wid, (ULong_t)shareList));
66 R__LOCKGUARD(gROOTMutex);
68 SetContext(wid, shareList);
72 fIdentity = TGLContextIdentity::GetDefaultIdentity();
74 fIdentity = shareList ? shareList->GetIdentity() :
new TGLContextIdentity;
76 fIdentity->AddRef(
this);
85 void TGLContext::GlewInit()
89 GLenum status = glewInit();
90 if (status != GLEW_OK)
91 Warning(
"TGLContext::GlewInit",
"GLEW initalization failed.");
93 Info(
"TGLContext::GlewInit",
"GLEW initalization successful.");
94 fgGlewInitDone = kTRUE;
104 struct LayoutCompatible_t {
108 unsigned char fDummy2;
110 unsigned short fDummy4;
111 unsigned short fDummy5;
123 void TGLContext::SetContext(TGLWidget *widget,
const TGLContext *shareList)
126 Error(
"TGLContext::SetContext",
"SetContext must be called only from ctor");
130 fPimpl.reset(
new TGLContextPrivate);
131 LayoutCompatible_t *trick =
132 reinterpret_cast<LayoutCompatible_t *
>(widget->GetId());
133 HWND hWND = *trick->fPHwnd;
134 HDC hDC = GetWindowDC(hWND);
137 Error(
"TGLContext::SetContext",
"GetWindowDC failed");
138 throw std::runtime_error(
"GetWindowDC failed");
141 const Rgl::TGuardBase &dcGuard = Rgl::make_guard(ReleaseDC, hWND, hDC);
142 if (HGLRC glContext = wglCreateContext(hDC)) {
143 if (shareList && !wglShareLists(shareList->fPimpl->fGLContext, glContext)) {
144 wglDeleteContext(glContext);
145 Error(
"TGLContext::SetContext",
"Context sharing failed!");
146 throw std::runtime_error(
"Context sharing failed");
148 fPimpl->fHWND = hWND;
150 fPimpl->fGLContext = glContext;
152 Error(
"TGLContext::SetContext",
"wglCreateContext failed");
153 throw std::runtime_error(
"wglCreateContext failed");
158 fDevice->AddContext(
this);
159 TGLContextPrivate::RegisterContext(
this);
168 Bool_t TGLContext::MakeCurrent()
171 Error(
"TGLContext::MakeCurrent",
"This context is invalid.");
175 if (!gVirtualX->IsCmdThread())
176 return Bool_t(gROOT->ProcessLineFast(Form(
"((TGLContext *)0x%lx)->MakeCurrent()",
this)));
179 R__LOCKGUARD(gROOTMutex);
181 Bool_t rez = wglMakeCurrent(fPimpl->fHDC, fPimpl->fGLContext);
185 fIdentity->DeleteGLResources();
194 Bool_t TGLContext::ClearCurrent()
196 return wglMakeCurrent(0, 0);
203 void TGLContext::SwapBuffers()
206 Error(
"TGLContext::SwapBuffers",
"This context is invalid.");
210 if (!gVirtualX->IsCmdThread())
211 gROOT->ProcessLineFast(Form(
"((TGLContext *)0x%lx)->SwapBuffers()",
this));
214 R__LOCKGUARD(gROOTMutex);
217 wglSwapLayerBuffers(fPimpl->fHDC, WGL_SWAP_MAIN_PLANE);
227 void TGLContext::Release()
229 if (!gVirtualX->IsCmdThread()) {
230 gROOT->ProcessLineFast(Form(
"((TGLContext *)0x%lx)->Release()",
this));
234 R__LOCKGUARD(gROOTMutex);
237 ReleaseDC(fPimpl->fHWND, fPimpl->fHDC);
239 TGLContextPrivate::RemoveContext(
this);
240 wglDeleteContext(fPimpl->fGLContext);
244 #elif defined(R__HAS_COCOA)
249 void TGLContext::SetContext(TGLWidget *widget,
const TGLContext *shareList)
252 Error(
"TGLContext::SetContext",
"SetContext must be called only from ctor");
256 fPimpl.reset(
new TGLContextPrivate);
258 fPimpl->fGLContext = gVirtualX->CreateOpenGLContext(widget->GetId(), shareList ? shareList->fPimpl->fGLContext : 0);
259 fPimpl->fWindowID = widget->GetId();
262 fDevice->AddContext(
this);
263 TGLContextPrivate::RegisterContext(
this);
270 Bool_t TGLContext::MakeCurrent()
273 Error(
"TGLContext::MakeCurrent",
"This context is invalid.");
277 const Bool_t rez = gVirtualX->MakeOpenGLContextCurrent(fPimpl->fGLContext, fPimpl->fWindowID);
281 fIdentity->DeleteGLResources();
291 Bool_t TGLContext::ClearCurrent()
300 void TGLContext::SwapBuffers()
303 Error(
"TGLContext::SwapBuffers",
"This context is invalid.");
307 gVirtualX->FlushOpenGLBuffer(fPimpl->fGLContext);
313 void TGLContext::Release()
315 TGLContextPrivate::RemoveContext(
this);
316 gVirtualX->DeleteOpenGLContext(fPimpl->fGLContext);
329 void TGLContext::SetContext(TGLWidget *widget,
const TGLContext *shareList)
332 Error(
"TGLContext::SetContext",
"SetContext must be called only from ctor");
336 fPimpl.reset(
new TGLContextPrivate);
337 Display *dpy =
static_cast<Display *
>(widget->GetInnerData().first);
338 XVisualInfo *visInfo =
static_cast<XVisualInfo *
>(widget->GetInnerData().second);
340 GLXContext glCtx = shareList ? glXCreateContext(dpy, visInfo, shareList->fPimpl->fGLContext, True)
341 : glXCreateContext(dpy, visInfo, None, True);
344 Error(
"TGLContext::SetContext",
"glXCreateContext failed!");
345 throw std::runtime_error(
"glXCreateContext failed!");
349 fPimpl->fVisualInfo = visInfo;
350 fPimpl->fGLContext = glCtx;
351 fPimpl->fWindowID = widget->GetId();
354 fDevice->AddContext(
this);
355 TGLContextPrivate::RegisterContext(
this);
362 Bool_t TGLContext::MakeCurrent()
365 Error(
"TGLContext::MakeCurrent",
"This context is invalid.");
369 if (fPimpl->fWindowID != 0) {
370 const Bool_t rez = glXMakeCurrent(fPimpl->fDpy, fPimpl->fWindowID,
375 fIdentity->DeleteGLResources();
386 Bool_t TGLContext::ClearCurrent()
388 return glXMakeCurrent(fPimpl->fDpy, None, 0);
395 void TGLContext::SwapBuffers()
398 Error(
"TGLContext::SwapCurrent",
"This context is invalid.");
402 if (fPimpl->fWindowID != 0)
403 glXSwapBuffers(fPimpl->fDpy, fPimpl->fWindowID);
412 void TGLContext::Release()
414 TGLContextPrivate::RemoveContext(
this);
415 glXDestroyContext(fPimpl->fDpy, fPimpl->fGLContext);
428 TGLContext::~TGLContext()
432 fDevice->RemoveContext(
this);
435 fIdentity->Release(
this);
443 TGLContextIdentity *TGLContext::GetIdentity()
const
451 TGLContext *TGLContext::GetCurrent()
453 return TGLContextPrivate::GetCurrentContext();
464 ClassImp(TGLContextIdentity);
466 TGLContextIdentity* TGLContextIdentity::fgDefaultIdentity =
new TGLContextIdentity;
471 TGLContextIdentity::TGLContextIdentity():
472 fFontManager(0), fCnt(0), fClientCnt(0)
479 TGLContextIdentity::~TGLContextIdentity()
481 if (fFontManager)
delete fFontManager;
487 void TGLContextIdentity::AddRef(TGLContext* ctx)
490 fCtxs.push_back(ctx);
496 void TGLContextIdentity::Release(TGLContext* ctx)
498 CtxList_t::iterator i = std::find(fCtxs.begin(), fCtxs.end(), ctx);
499 if (i != fCtxs.end())
507 Error(
"TGLContextIdentity::Release",
"unregistered context.");
514 void TGLContextIdentity::RegisterDLNameRangeToWipe(UInt_t base, Int_t size)
516 fDLTrash.push_back(DLRange_t(base, size));
522 void TGLContextIdentity::DeleteGLResources()
524 if (!fDLTrash.empty())
526 for (DLTrashIt_t it = fDLTrash.begin(), e = fDLTrash.end(); it != e; ++it)
527 glDeleteLists(it->first, it->second);
532 fFontManager->ClearFontTrash();
538 TGLContextIdentity* TGLContextIdentity::GetCurrent()
540 TGLContext* ctx = TGLContext::GetCurrent();
541 return ctx ? ctx->GetIdentity() : 0;
547 TGLContextIdentity* TGLContextIdentity::GetDefaultIdentity()
549 if (fgDefaultIdentity == 0)
550 fgDefaultIdentity =
new TGLContextIdentity;
551 return fgDefaultIdentity;
558 TGLContext* TGLContextIdentity::GetDefaultContextAny()
560 if (fgDefaultIdentity == 0 || fgDefaultIdentity->fCtxs.empty())
562 return fgDefaultIdentity->fCtxs.front();
568 TGLFontManager* TGLContextIdentity::GetFontManager()
570 if(!fFontManager) fFontManager =
new TGLFontManager();
577 void TGLContextIdentity::CheckDestroy()
579 if (fCnt <= 0 && fClientCnt <= 0)
581 if (
this == fgDefaultIdentity)
582 fgDefaultIdentity = 0;