LibreOffice Module vcl (master)  1
OpenGLContext.cxx
Go to the documentation of this file.
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 #include <chrono>
11 
15 #include <vcl/syschild.hxx>
16 #include <vcl/sysdata.hxx>
17 
18 #include <osl/thread.hxx>
19 #include <sal/log.hxx>
20 
21 #include <svdata.hxx>
22 #include <salgdi.hxx>
23 #include <salinst.hxx>
24 
25 #include <opengl/framebuffer.hxx>
26 #include <opengl/program.hxx>
27 #include <opengl/texture.hxx>
28 #include <opengl/zone.hxx>
29 
30 #include <opengl/RenderState.hxx>
31 
32 #include <config_features.h>
33 
34 using namespace com::sun::star;
35 
36 #define MAX_FRAMEBUFFER_COUNT 30
37 
38 static sal_Int64 nBufferSwapCounter = 0;
39 
41 {
42 }
43 
44 bool GLWindow::Synchronize(bool /*bOnoff*/) const
45 {
46  return false;
47 }
48 
50  mpWindow(nullptr),
51  m_pChildWindow(nullptr),
52  mbInitialized(false),
53  mnRefCount(0),
54  mbRequestLegacyContext(false),
55  mbVCLOnly(false),
56  mnFramebufferCount(0),
57  mpCurrentFramebuffer(nullptr),
58  mpFirstFramebuffer(nullptr),
59  mpLastFramebuffer(nullptr),
60  mpCurrentProgram(nullptr),
61  mpRenderState(new RenderState),
62  mpPrevContext(nullptr),
63  mpNextContext(nullptr)
64 {
65  VCL_GL_INFO("new context: " << this);
66 
67  ImplSVData* pSVData = ImplGetSVData();
68  if( pSVData->maGDIData.mpLastContext )
69  {
70  pSVData->maGDIData.mpLastContext->mpNextContext = this;
72  }
73  pSVData->maGDIData.mpLastContext = this;
74 
75  // FIXME: better hope we call 'makeCurrent' soon to preserve
76  // the invariant that the last item is the current context.
77 }
78 
80 {
81  assert (mnRefCount == 0);
82 
83  mnRefCount = 1; // guard the shutdown paths.
84  VCL_GL_INFO("delete context: " << this);
85 
86  reset();
87 
88  ImplSVData* pSVData = ImplGetSVData();
89  if( mpPrevContext )
91  if( mpNextContext )
93  else
95 
97  assert (mnRefCount == 1);
98 }
99 
100 // release associated child-window if we have one
102 {
103  reset();
105 }
106 
108 {
110 }
111 
113 {
114  mbRequestLegacyContext = true;
115 }
116 
117 #ifdef DBG_UTIL
118 
119 namespace {
120 
121 const char* getSeverityString(GLenum severity)
122 {
123  switch(severity)
124  {
125  case GL_DEBUG_SEVERITY_LOW:
126  return "low";
127  case GL_DEBUG_SEVERITY_MEDIUM:
128  return "medium";
129  case GL_DEBUG_SEVERITY_HIGH:
130  return "high";
131  default:
132  ;
133  }
134 
135  return "unknown";
136 }
137 
138 const char* getSourceString(GLenum source)
139 {
140  switch(source)
141  {
142  case GL_DEBUG_SOURCE_API:
143  return "API";
144  case GL_DEBUG_SOURCE_SHADER_COMPILER:
145  return "shader compiler";
146  case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
147  return "window system";
148  case GL_DEBUG_SOURCE_THIRD_PARTY:
149  return "third party";
150  case GL_DEBUG_SOURCE_APPLICATION:
151  return "Libreoffice";
152  case GL_DEBUG_SOURCE_OTHER:
153  return "unknown";
154  default:
155  ;
156  }
157 
158  return "unknown";
159 }
160 
161 const char* getTypeString(GLenum type)
162 {
163  switch(type)
164  {
165  case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
166  return "deprecated behavior";
167  case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
168  return "undefined behavior";
169  case GL_DEBUG_TYPE_PERFORMANCE:
170  return "performance";
171  case GL_DEBUG_TYPE_PORTABILITY:
172  return "portability";
173  case GL_DEBUG_TYPE_MARKER:
174  return "marker";
175  case GL_DEBUG_TYPE_PUSH_GROUP:
176  return "push group";
177  case GL_DEBUG_TYPE_POP_GROUP:
178  return "pop group";
179  case GL_DEBUG_TYPE_OTHER:
180  return "other";
181  case GL_DEBUG_TYPE_ERROR:
182  return "error";
183  default:
184  ;
185  }
186 
187  return "unknown";
188 }
189 
190 extern "C" void
191 #if defined _WIN32
192 APIENTRY
193 #endif
194 debug_callback(GLenum source, GLenum type, GLuint id,
195  GLenum severity, GLsizei , const GLchar* message,
196  const GLvoid*)
197 {
198  // ignore Nvidia's 131218: "Program/shader state performance warning: Fragment Shader is going to be recompiled because the shader key based on GL state mismatches."
199  // the GLSL compiler is a bit too aggressive in optimizing the state based on the current OpenGL state
200 
201  // ignore 131185: "Buffer detailed info: Buffer object x (bound to GL_ARRAY_BUFFER_ARB,
202  // usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations."
203  if (id == 131218 || id == 131185)
204  return;
205 
206  SAL_WARN("vcl.opengl", "OpenGL debug message: source: " << getSourceString(source) << ", type: "
207  << getTypeString(type) << ", id: " << id << ", severity: " << getSeverityString(severity) << ", with message: " << message);
208 }
209 
210 }
211 
212 #endif
213 
215 {
216  if(mbInitialized)
217  return true;
218 
219  OpenGLZone aZone;
220 
222  mpWindow = pParent ? pParent : m_xWindow.get();
223  if(m_xWindow)
224  m_xWindow->setPosSizePixel(0,0,0,0);
225  //tdf#108069 we may be initted twice, so dispose earlier effort
227  initWindow();
228  return ImplInit();
229 }
230 
232 {
233  VCL_GL_INFO("OpenGLContext not implemented for this platform");
234  return false;
235 }
236 
237 static OUString getGLString(GLenum eGlEnum)
238 {
239  OUString sString;
240  const GLubyte* pString = glGetString(eGlEnum);
241  if (pString)
242  {
243  sString = OUString::createFromAscii(reinterpret_cast<const sal_Char*>(pString));
244  }
245 
246  CHECK_GL_ERROR();
247  return sString;
248 }
249 
251 {
252  VCL_GL_INFO("OpenGLContext::ImplInit----end");
253  VCL_GL_INFO("Vendor: " << getGLString(GL_VENDOR) << " Renderer: " << getGLString(GL_RENDERER) << " GL version: " << OpenGLHelper::getGLVersion());
254  mbInitialized = true;
255 
256  // I think we need at least GL 3.0
257  if (epoxy_gl_version() < 30)
258  {
259  SAL_WARN("vcl.opengl", "We don't have at least OpenGL 3.0");
260  return false;
261  }
262 
263  // Check that some "optional" APIs that we use unconditionally are present
264  if (!glBindFramebuffer)
265  {
266  SAL_WARN("vcl.opengl", "We don't have glBindFramebuffer");
267  return false;
268  }
269 
270  return true;
271 }
272 
274 {
275 #ifdef DBG_UTIL
276  // only enable debug output in dbgutil build
277  if (epoxy_has_gl_extension("GL_ARB_debug_output"))
278  {
279  OpenGLZone aZone;
280 
281  if (glDebugMessageCallbackARB)
282  {
283  glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
284  glDebugMessageCallbackARB(&debug_callback, nullptr);
285 
286 #ifdef GL_DEBUG_SEVERITY_NOTIFICATION_ARB
287  // Ignore i965’s shader compiler notification flood.
288  glDebugMessageControlARB(GL_DEBUG_SOURCE_SHADER_COMPILER_ARB, GL_DEBUG_TYPE_OTHER_ARB, GL_DEBUG_SEVERITY_NOTIFICATION_ARB, 0, nullptr, true);
289 #endif
290  }
291  else if ( glDebugMessageCallback )
292  {
293  glEnable(GL_DEBUG_OUTPUT);
294  glDebugMessageCallback(&debug_callback, nullptr);
295 
296  // Ignore i965’s shader compiler notification flood.
297  glDebugMessageControl(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DEBUG_TYPE_OTHER, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, true);
298  }
299  }
300 
301  // Test hooks for inserting tracing messages into the stream
302  VCL_GL_INFO("LibreOffice GLContext initialized");
303 #endif
304 }
305 
307 {
308  glBindFramebuffer(GL_FRAMEBUFFER, 0);
309 }
310 
311 void OpenGLContext::setWinPosAndSize(const Point &rPos, const Size& rSize)
312 {
313  if (m_xWindow)
314  m_xWindow->SetPosSizePixel(rPos, rSize);
315  if (m_pChildWindow)
316  m_pChildWindow->SetPosSizePixel(rPos, rSize);
317 
319  rGLWin.Width = rSize.Width();
320  rGLWin.Height = rSize.Height();
321  adjustToNewSize();
322 }
323 
325 {
326  const GLWindow& rGLWin = getOpenGLWindow();
327  glViewport(0, 0, rGLWin.Width, rGLWin.Height);
328 }
329 
331 {
332  pChildWindow->SetMouseTransparent(true);
334  pChildWindow->EnableEraseBackground(false);
335  pChildWindow->SetControlForeground();
336  pChildWindow->SetControlBackground();
337 }
338 
340 {
341 }
342 
344 {
345  //nothing by default
346 }
347 
349 {
350  if( !mbInitialized )
351  return;
352 
353  OpenGLZone aZone;
354 
355  // reset the clip region
357  mpRenderState.reset(new RenderState);
358 
359  // destroy all framebuffers
360  if( mpLastFramebuffer )
361  {
362  OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
363 
364  makeCurrent();
365  while( pFramebuffer )
366  {
367  OpenGLFramebuffer* pPrevFramebuffer = pFramebuffer->mpPrevFramebuffer;
368  delete pFramebuffer;
369  pFramebuffer = pPrevFramebuffer;
370  }
371  mnFramebufferCount = 0;
372  mpFirstFramebuffer = nullptr;
373  mpLastFramebuffer = nullptr;
374  }
375 
376  // destroy all programs
377  if( !maPrograms.empty() )
378  {
379  makeCurrent();
380  maPrograms.clear();
381  }
382 
383  if( isCurrent() )
384  resetCurrent();
385 
386  mbInitialized = false;
387 
388  // destroy the context itself
390 }
391 
392 SystemWindowData OpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool /*bRequestLegacyContext*/)
393 {
394  SystemWindowData aWinData;
395  memset(&aWinData, 0, sizeof(aWinData));
396  return aWinData;
397 }
398 
400 {
401  (void) this; // loplugin:staticmethods
402  return false;
403 }
404 
406 {
407  if (isCurrent())
408  return;
409 
410  OpenGLZone aZone;
411 
412  clearCurrent();
413 
414  // by default nothing else to do
415 
417 }
418 
420 {
421  return false;
422 }
423 
425 {
426  ImplSVData* pSVData = ImplGetSVData();
428  return pCurrentCtx.is() && pCurrentCtx->isAnyCurrent();
429 }
430 
432 {
433  ImplSVData* pSVData = ImplGetSVData();
434 
435  // release all framebuffers from the old context so we can re-attach the
436  // texture in the new context
438  if( pCurrentCtx.is() && pCurrentCtx->isCurrent() )
439  pCurrentCtx->ReleaseFramebuffers();
440 }
441 
443 {
444  ImplSVData* pSVData = ImplGetSVData();
445 
446  // release all framebuffers from the old context so we can re-attach the
447  // texture in the new context
449 
450  if ( !pCurrentCtx.is() )
451  return; // Not using OpenGL
452 
453  SAL_INFO("vcl.opengl", "Unbinding contexts in preparation for yield");
454 
455  // Find the first context that is current and reset it.
456  // Usually the last context is the current, but not in case a new
457  // OpenGLContext is created already but not yet initialized.
458  while (pCurrentCtx.is())
459  {
460  if (pCurrentCtx->isCurrent())
461  {
462  pCurrentCtx->resetCurrent();
463  break;
464  }
465 
466  pCurrentCtx = pCurrentCtx->mpPrevContext;
467  }
468 
469  assert (!hasCurrent());
470 }
471 
473 {
474  ImplSVData* pSVData = ImplGetSVData();
475  OpenGLContext *pContext = pSVData->maGDIData.mpLastContext;
476  while( pContext )
477  {
478  // check if this context is usable
479  if( pContext->isInitialized() && pContext->isVCLOnly() )
480  break;
481  pContext = pContext->mpPrevContext;
482  }
484  vcl::Window* pDefWindow = !pContext && bMakeIfNecessary ? ImplGetDefaultWindow() : nullptr;
485  if (pDefWindow)
486  {
487  // create our magic fallback window context.
488 #if HAVE_FEATURE_OPENGL
489  xContext = pDefWindow->GetGraphics()->GetOpenGLContext();
490  assert(xContext.is());
491 #endif
492  }
493  else
494  xContext = pContext;
495 
496  if( xContext.is() )
497  xContext->makeCurrent();
498 
499  return xContext;
500 }
501 
502 /*
503  * We don't care what context we have, but we want one that is live,
504  * ie. not reset underneath us, and is setup for VCL usage - ideally
505  * not swapping context at all.
506  */
508 {
509  getVCLContext();
510 }
511 
513 {
514  ImplSVData* pSVData = ImplGetSVData();
515 
516  // move the context to the end of the contexts list
517  static int nSwitch = 0;
518  VCL_GL_INFO("******* CONTEXT SWITCH " << ++nSwitch << " *********");
519  if( mpNextContext )
520  {
521  if( mpPrevContext )
524 
526  mpNextContext = nullptr;
527  pSVData->maGDIData.mpLastContext->mpNextContext = this;
528  pSVData->maGDIData.mpLastContext = this;
529  }
530 
531  // sync the render state with the current context
532  mpRenderState->sync();
533 }
534 
536 {
537  clearCurrent();
538  // by default nothing else to do
539 }
540 
542 {
543  // by default nothing else to do
544  BuffersSwapped();
545 }
546 
548 {
550 
551  static bool bSleep = getenv("SAL_GL_SLEEP_ON_SWAP");
552  if (bSleep)
553  {
554  // half a second.
555  osl::Thread::wait( std::chrono::milliseconds(500) );
556  }
557 }
558 
559 
561 {
562  return nBufferSwapCounter;
563 }
564 
566 {
567  // default is nothing
568  (void) this; // loplugin:staticmethods
569 }
570 
572 {
573  if (m_pChildWindow)
574  m_pChildWindow->Show();
575  else if (m_xWindow)
576  m_xWindow->Show();
577 }
578 
580 {
581  return m_pChildWindow;
582 }
583 
585 {
586  return m_pChildWindow;
587 }
588 
590 {
591  OpenGLZone aZone;
592 
593  if( pFramebuffer != mpCurrentFramebuffer )
594  {
595  if( pFramebuffer )
596  pFramebuffer->Bind();
597  else
599  mpCurrentFramebuffer = pFramebuffer;
600  }
601 }
602 
604 {
605  BindFramebuffer( nullptr );
606 }
607 
609 {
610  OpenGLZone aZone;
611 
612  OpenGLFramebuffer* pFramebuffer = nullptr;
613  OpenGLFramebuffer* pFreeFbo = nullptr;
614  OpenGLFramebuffer* pSameSizeFbo = nullptr;
615 
616  // check if there is already a framebuffer attached to that texture
617  pFramebuffer = mpLastFramebuffer;
618  while( pFramebuffer )
619  {
620  if( pFramebuffer->IsAttached( rTexture ) )
621  break;
622  if( !pFreeFbo && pFramebuffer->IsFree() )
623  pFreeFbo = pFramebuffer;
624  if( !pSameSizeFbo &&
625  pFramebuffer->GetWidth() == rTexture.GetWidth() &&
626  pFramebuffer->GetHeight() == rTexture.GetHeight() )
627  pSameSizeFbo = pFramebuffer;
628  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
629  }
630 
631  // else use any framebuffer having the same size
632  if( !pFramebuffer && pSameSizeFbo )
633  pFramebuffer = pSameSizeFbo;
634 
635  // else use the first free framebuffer
636  if( !pFramebuffer && pFreeFbo )
637  pFramebuffer = pFreeFbo;
638 
639  // if there isn't any free one, create a new one if the limit isn't reached
640  if( !pFramebuffer && mnFramebufferCount < MAX_FRAMEBUFFER_COUNT )
641  {
643  pFramebuffer = new OpenGLFramebuffer();
644  if( mpLastFramebuffer )
645  {
646  pFramebuffer->mpPrevFramebuffer = mpLastFramebuffer;
647  mpLastFramebuffer = pFramebuffer;
648  }
649  else
650  {
651  mpFirstFramebuffer = pFramebuffer;
652  mpLastFramebuffer = pFramebuffer;
653  }
654  }
655 
656  // last try, use any framebuffer
657  // TODO order the list of framebuffers as a LRU
658  if( !pFramebuffer )
659  pFramebuffer = mpFirstFramebuffer;
660 
661  assert( pFramebuffer );
662  BindFramebuffer( pFramebuffer );
663  pFramebuffer->AttachTexture( rTexture );
664 
665  state().viewport(tools::Rectangle(Point(), Size(rTexture.GetWidth(), rTexture.GetHeight())));
666 
667  return pFramebuffer;
668 }
669 
670 // FIXME: this method is rather grim from a perf. perspective.
671 // We should instead (eventually) use pointers to associate the
672 // framebuffer and texture cleanly.
674 {
675  OpenGLFramebuffer* pFramebuffer;
676 
677  // see if there is a framebuffer attached to that texture
678  pFramebuffer = mpLastFramebuffer;
679  while( pFramebuffer )
680  {
681  if (pFramebuffer->IsAttached(nTexture))
682  {
683  BindFramebuffer(pFramebuffer);
684  pFramebuffer->DetachTexture();
685  }
686  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
687  }
688 
689  // Lets just check that no other context has a framebuffer
690  // with this texture - that would be bad ...
691  assert( !IsTextureAttachedAnywhere( nTexture ) );
692 }
693 
696 {
697  ImplSVData* pSVData = ImplGetSVData();
698  for( auto *pCheck = pSVData->maGDIData.mpLastContext; pCheck;
699  pCheck = pCheck->mpPrevContext )
700  {
701  for( auto pBuffer = pCheck->mpLastFramebuffer; pBuffer;
702  pBuffer = pBuffer->mpPrevFramebuffer )
703  {
704  if( pBuffer->IsAttached( nTexture ) )
705  return true;
706  }
707  }
708  return false;
709 }
710 
712 {
713  if( pFramebuffer )
714  pFramebuffer->DetachTexture();
715 }
716 
718 {
719  OpenGLZone aZone;
720 
721  if (!rTexture) // no texture to release.
722  return;
723 
724  OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
725 
726  while( pFramebuffer )
727  {
728  if( pFramebuffer->IsAttached( rTexture ) )
729  {
730  BindFramebuffer( pFramebuffer );
731  pFramebuffer->DetachTexture();
732  if (mpCurrentFramebuffer == pFramebuffer)
733  BindFramebuffer( nullptr );
734  }
735  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
736  }
737 }
738 
740 {
741  OpenGLZone aZone;
742 
743  OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
744  while( pFramebuffer )
745  {
746  if (!pFramebuffer->IsFree())
747  {
748  BindFramebuffer( pFramebuffer );
749  pFramebuffer->DetachTexture();
750  }
751  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
752  }
753  BindFramebuffer( nullptr );
754 }
755 
756 OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
757 {
758  OpenGLZone aZone;
759 
760  // We cache the shader programs in a per-process run-time cache
761  // based on only the names and the preamble. We don't expect
762  // shader source files to change during the lifetime of a
763  // LibreOffice process.
764  OString aNameBasedKey = OUStringToOString(rVertexShader + "+" + rFragmentShader, RTL_TEXTENCODING_UTF8) + "+" + preamble;
765  if( !aNameBasedKey.isEmpty() )
766  {
767  ProgramCollection::iterator it = maPrograms.find( aNameBasedKey );
768  if( it != maPrograms.end() )
769  return it->second.get();
770  }
771 
772  // Binary shader programs are cached persistently (between
773  // LibreOffice process instances) based on a hash of their source
774  // code, as the source code can and will change between
775  // LibreOffice versions even if the shader names don't change.
776  OString aPersistentKey = OpenGLHelper::GetDigest( rVertexShader, rFragmentShader, preamble );
777  std::shared_ptr<OpenGLProgram> pProgram = std::make_shared<OpenGLProgram>();
778  if( !pProgram->Load( rVertexShader, rFragmentShader, preamble, aPersistentKey ) )
779  return nullptr;
780 
781  maPrograms.insert(std::make_pair(aNameBasedKey, pProgram));
782  return pProgram.get();
783 }
784 
785 OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
786 {
787  OpenGLZone aZone;
788 
789  OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble );
790 
791  if (pProgram && pProgram == mpCurrentProgram)
792  {
793  VCL_GL_INFO("Context::UseProgram: Reusing existing program " << pProgram->Id());
794  pProgram->Reuse();
795  return pProgram;
796  }
797 
798  mpCurrentProgram = pProgram;
799 
800  if (!mpCurrentProgram)
801  {
802  SAL_WARN("vcl.opengl", "OpenGLContext::UseProgram: mpCurrentProgram is 0");
803  return nullptr;
804  }
805 
807 
808  return mpCurrentProgram;
809 }
810 
811 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< RenderState > mpRenderState
long Width() const
static void ReleaseFramebuffer(OpenGLFramebuffer *pFramebuffer)
static rtl::Reference< OpenGLContext > Create()
int GetHeight() const
Definition: framebuffer.hxx:30
static void clearCurrent()
release bound resources from the current context
virtual void sync()
rtl::Reference< OpenGLContext > GetOpenGLContext() const
Check that our mpImpl is OpenGL and return the context, otherwise NULL.
virtual OpenGLContext * CreateOpenGLContext()=0
virtual void restoreDefaultFramebuffer()
unbind the GL_FRAMEBUFFER to its default state, needed for gtk3
void setWinPosAndSize(const Point &rPos, const Size &rSize)
A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for refer...
Definition: button.hxx:32
long Height() const
WinBits const WB_NODIALOGCONTROL
RenderState & state()
OpenGLContext * mpNextContext
void Bind(GLenum eTarget=GL_FRAMEBUFFER)
vcl::Region maClipRegion
void disposeAndClear()
Definition: vclptr.hxx:200
unsigned int Height
static void BuffersSwapped()
static bool IsTextureAttachedAnywhere(GLuint nTexture)
Method for debugging; check texture is not already attached.
static sal_Int64 getBufferSwapCounter()
Returns the number of times OpenGL buffers have been swapped.
bool mbInitialized
void registerAsCurrent()
Put this GL context to the end of the context list.
void BindFramebuffer(OpenGLFramebuffer *pFramebuffer)
static void InitChildWindow(SystemChildWindow *pChildWindow)
void SetParentClipMode(ParentClipMode nMode=ParentClipMode::NONE)
static float getGLVersion()
Get OpenGL version (needs a context)
virtual void initWindow()
int GetWidth() const
ImplSVGDIData maGDIData
Definition: svdata.hxx:353
virtual bool isAnyCurrent()
Is any GL context the current context ?
OpenGLProgram * UseProgram(const OUString &rVertexShader, const OUString &rFragmentShader, const OString &preamble="")
virtual void setPosSizePixel(long nX, long nY, long nWidth, long nHeight, PosSizeFlags nFlags=PosSizeFlags::All)
Definition: window.cxx:2685
void requestLegacyContext()
static OUString getGLString(GLenum eGlEnum)
static OString GetDigest(const OUString &rVertexShaderName, const OUString &rFragmentShaderName, const OString &preamble)
void AttachTexture(const OpenGLTexture &rTexture)
OpenGLFramebuffer * AcquireFramebuffer(const OpenGLTexture &rTexture)
static void makeVCLCurrent()
make a VCL context (any context) current, create it if necessary.
bool mbRequestLegacyContext
bool isInitialized() const
void EnableEraseBackground(bool bEnable)
Definition: syschild.cxx:137
virtual GLWindow & getModifiableOpenGLWindow()=0
OpenGLProgram * GetProgram(const OUString &rVertexShader, const OUString &rFragmentShader, const OString &preamble="")
static sal_Int64 nBufferSwapCounter
OpenGLProgram * mpCurrentProgram
OpenGLFramebuffer * mpCurrentFramebuffer
virtual bool Synchronize(bool bOnoff) const
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:66
virtual void resetCurrent()
reset the GL context so this context is not implicit in subsequent GL calls.
VclPtr< vcl::Window > mpWindow
Holds the information of our new child window.
#define VCL_GL_INFO(stream)
Helper to do a SAL_INFO as well as a GL log.
static void InitGLDebugging()
void SetEmpty()
Definition: region.cxx:1417
virtual ~GLWindow()
OpenGLFramebuffer * mpLastFramebuffer
void SetControlBackground()
Definition: window2.cxx:497
static bool hasCurrent()
Is there a current GL context ?
void SetControlForeground()
Definition: window2.cxx:457
virtual void adjustToNewSize()
virtual void swapBuffers()
static void Unbind(GLenum eTarget=GL_FRAMEBUFFER)
void viewport(tools::Rectangle aViewPort)
bool isVCLOnly() const
virtual const GLWindow & getOpenGLWindow() const =0
#define MAX_FRAMEBUFFER_COUNT
WinBits const WB_NOBORDER
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1262
bool IsAttached(GLuint nTexture) const
void reset(reference_type *pBody)
Definition: vclptr.hxx:153
bool IsFree() const
We want to be able to detect if a given crash came from the OpenGL code, so use this helper to track ...
Definition: zone.hxx:24
virtual void makeCurrent()
make this GL context current - so it is implicit in subsequent GL calls
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
ProgramCollection maPrograms
OpenGLContext * mpPrevContext
void SetMouseTransparent(bool bTransparent)
Definition: mouse.cxx:426
virtual void destroyCurrentContext()
static rtl::Reference< OpenGLContext > getVCLContext(bool bMakeIfNecessary=true)
fetch any VCL context, creating one if bMakeIfNecessary is set.
virtual ~OpenGLContext()
unsigned int Width
#define SAL_INFO(area, stream)
VclPtr< vcl::Window > m_xWindow
SalGraphics const * GetGraphics() const
Get the graphic context that the output device uses to draw on.
Definition: outdev.cxx:198
SystemChildWindow * getChildWindow()
static void prepareForYield()
release contexts etc. before (potentially) allowing another thread run.
void ReleaseFramebuffers()
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
int GetHeight() const
#define SAL_WARN(area, stream)
virtual SystemWindowData generateWinData(vcl::Window *pParent, bool bRequestLegacyContext)
#define CHECK_GL_ERROR()
VclPtr< SystemChildWindow > m_pChildWindow
bool init(vcl::Window *pParent)
OpenGLFramebuffer * mpFirstFramebuffer
int GetWidth() const
Definition: framebuffer.hxx:29
OpenGLContext * mpLastContext
Definition: svdata.hxx:179
void UnbindTextureFromFramebuffers(GLuint nTexture)
vcl::Window * ImplGetDefaultWindow()
Returns either the application window, or the default GL context window.
Definition: svdata.cxx:201
void AcquireDefaultFramebuffer()
OpenGLFramebuffer * mpPrevFramebuffer
Definition: framebuffer.hxx:43
SalInstance * mpDefInst
Definition: svdata.hxx:341
GLuint Id()
Definition: program.hxx:69
virtual bool isCurrent()
Is this GL context the current context ?
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2150
VclPtr< vcl::Window > mpWindow
virtual bool ImplInit()
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo