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  return {};
395 }
396 
398 {
399  (void) this; // loplugin:staticmethods
400  return false;
401 }
402 
404 {
405  if (isCurrent())
406  return;
407 
408  OpenGLZone aZone;
409 
410  clearCurrent();
411 
412  // by default nothing else to do
413 
415 }
416 
418 {
419  return false;
420 }
421 
423 {
424  ImplSVData* pSVData = ImplGetSVData();
426  return pCurrentCtx.is() && pCurrentCtx->isAnyCurrent();
427 }
428 
430 {
431  ImplSVData* pSVData = ImplGetSVData();
432 
433  // release all framebuffers from the old context so we can re-attach the
434  // texture in the new context
436  if( pCurrentCtx.is() && pCurrentCtx->isCurrent() )
437  pCurrentCtx->ReleaseFramebuffers();
438 }
439 
441 {
442  ImplSVData* pSVData = ImplGetSVData();
443 
444  // release all framebuffers from the old context so we can re-attach the
445  // texture in the new context
447 
448  if ( !pCurrentCtx.is() )
449  return; // Not using OpenGL
450 
451  SAL_INFO("vcl.opengl", "Unbinding contexts in preparation for yield");
452 
453  // Find the first context that is current and reset it.
454  // Usually the last context is the current, but not in case a new
455  // OpenGLContext is created already but not yet initialized.
456  while (pCurrentCtx.is())
457  {
458  if (pCurrentCtx->isCurrent())
459  {
460  pCurrentCtx->resetCurrent();
461  break;
462  }
463 
464  pCurrentCtx = pCurrentCtx->mpPrevContext;
465  }
466 
467  assert (!hasCurrent());
468 }
469 
471 {
472  ImplSVData* pSVData = ImplGetSVData();
473  OpenGLContext *pContext = pSVData->maGDIData.mpLastContext;
474  while( pContext )
475  {
476  // check if this context is usable
477  if( pContext->isInitialized() && pContext->isVCLOnly() )
478  break;
479  pContext = pContext->mpPrevContext;
480  }
482  vcl::Window* pDefWindow = !pContext && bMakeIfNecessary ? ImplGetDefaultWindow() : nullptr;
483  if (pDefWindow)
484  {
485  // create our magic fallback window context.
486 #if HAVE_FEATURE_OPENGL
487  xContext = pDefWindow->GetGraphics()->GetOpenGLContext();
488  assert(xContext.is());
489 #endif
490  }
491  else
492  xContext = pContext;
493 
494  if( xContext.is() )
495  xContext->makeCurrent();
496 
497  return xContext;
498 }
499 
500 /*
501  * We don't care what context we have, but we want one that is live,
502  * ie. not reset underneath us, and is setup for VCL usage - ideally
503  * not swapping context at all.
504  */
506 {
507  getVCLContext();
508 }
509 
511 {
512  ImplSVData* pSVData = ImplGetSVData();
513 
514  // move the context to the end of the contexts list
515  static int nSwitch = 0;
516  VCL_GL_INFO("******* CONTEXT SWITCH " << ++nSwitch << " *********");
517  if( mpNextContext )
518  {
519  if( mpPrevContext )
522 
524  mpNextContext = nullptr;
525  pSVData->maGDIData.mpLastContext->mpNextContext = this;
526  pSVData->maGDIData.mpLastContext = this;
527  }
528 
529  // sync the render state with the current context
530  mpRenderState->sync();
531 }
532 
534 {
535  clearCurrent();
536  // by default nothing else to do
537 }
538 
540 {
541  // by default nothing else to do
542  BuffersSwapped();
543 }
544 
546 {
548 
549  static bool bSleep = getenv("SAL_GL_SLEEP_ON_SWAP");
550  if (bSleep)
551  {
552  // half a second.
553  osl::Thread::wait( std::chrono::milliseconds(500) );
554  }
555 }
556 
557 
558 sal_Int64 OpenGLWrapper::getBufferSwapCounter()
559 {
560  return nBufferSwapCounter;
561 }
562 
564 {
565  // default is nothing
566  (void) this; // loplugin:staticmethods
567 }
568 
570 {
571  if (m_pChildWindow)
572  m_pChildWindow->Show();
573  else if (m_xWindow)
574  m_xWindow->Show();
575 }
576 
578 {
579  return m_pChildWindow;
580 }
581 
583 {
584  return m_pChildWindow;
585 }
586 
588 {
589  OpenGLZone aZone;
590 
591  if( pFramebuffer != mpCurrentFramebuffer )
592  {
593  if( pFramebuffer )
594  pFramebuffer->Bind();
595  else
597  mpCurrentFramebuffer = pFramebuffer;
598  }
599 }
600 
602 {
603  BindFramebuffer( nullptr );
604 }
605 
607 {
608  OpenGLZone aZone;
609 
610  OpenGLFramebuffer* pFramebuffer = nullptr;
611  OpenGLFramebuffer* pFreeFbo = nullptr;
612  OpenGLFramebuffer* pSameSizeFbo = nullptr;
613 
614  // check if there is already a framebuffer attached to that texture
615  pFramebuffer = mpLastFramebuffer;
616  while( pFramebuffer )
617  {
618  if( pFramebuffer->IsAttached( rTexture ) )
619  break;
620  if( !pFreeFbo && pFramebuffer->IsFree() )
621  pFreeFbo = pFramebuffer;
622  if( !pSameSizeFbo &&
623  pFramebuffer->GetWidth() == rTexture.GetWidth() &&
624  pFramebuffer->GetHeight() == rTexture.GetHeight() )
625  pSameSizeFbo = pFramebuffer;
626  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
627  }
628 
629  // else use any framebuffer having the same size
630  if( !pFramebuffer && pSameSizeFbo )
631  pFramebuffer = pSameSizeFbo;
632 
633  // else use the first free framebuffer
634  if( !pFramebuffer && pFreeFbo )
635  pFramebuffer = pFreeFbo;
636 
637  // if there isn't any free one, create a new one if the limit isn't reached
638  if( !pFramebuffer && mnFramebufferCount < MAX_FRAMEBUFFER_COUNT )
639  {
641  pFramebuffer = new OpenGLFramebuffer();
642  if( mpLastFramebuffer )
643  {
644  pFramebuffer->mpPrevFramebuffer = mpLastFramebuffer;
645  mpLastFramebuffer = pFramebuffer;
646  }
647  else
648  {
649  mpFirstFramebuffer = pFramebuffer;
650  mpLastFramebuffer = pFramebuffer;
651  }
652  }
653 
654  // last try, use any framebuffer
655  // TODO order the list of framebuffers as a LRU
656  if( !pFramebuffer )
657  pFramebuffer = mpFirstFramebuffer;
658 
659  assert( pFramebuffer );
660  BindFramebuffer( pFramebuffer );
661  pFramebuffer->AttachTexture( rTexture );
662 
663  state().viewport(tools::Rectangle(Point(), Size(rTexture.GetWidth(), rTexture.GetHeight())));
664 
665  return pFramebuffer;
666 }
667 
668 // FIXME: this method is rather grim from a perf. perspective.
669 // We should instead (eventually) use pointers to associate the
670 // framebuffer and texture cleanly.
672 {
673  OpenGLFramebuffer* pFramebuffer;
674 
675  // see if there is a framebuffer attached to that texture
676  pFramebuffer = mpLastFramebuffer;
677  while( pFramebuffer )
678  {
679  if (pFramebuffer->IsAttached(nTexture))
680  {
681  BindFramebuffer(pFramebuffer);
682  pFramebuffer->DetachTexture();
683  }
684  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
685  }
686 
687  // Lets just check that no other context has a framebuffer
688  // with this texture - that would be bad ...
689  assert( !IsTextureAttachedAnywhere( nTexture ) );
690 }
691 
694 {
695  ImplSVData* pSVData = ImplGetSVData();
696  for( auto *pCheck = pSVData->maGDIData.mpLastContext; pCheck;
697  pCheck = pCheck->mpPrevContext )
698  {
699  for( auto pBuffer = pCheck->mpLastFramebuffer; pBuffer;
700  pBuffer = pBuffer->mpPrevFramebuffer )
701  {
702  if( pBuffer->IsAttached( nTexture ) )
703  return true;
704  }
705  }
706  return false;
707 }
708 
710 {
711  if( pFramebuffer )
712  pFramebuffer->DetachTexture();
713 }
714 
716 {
717  OpenGLZone aZone;
718 
719  if (!rTexture) // no texture to release.
720  return;
721 
722  OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
723 
724  while( pFramebuffer )
725  {
726  if( pFramebuffer->IsAttached( rTexture ) )
727  {
728  BindFramebuffer( pFramebuffer );
729  pFramebuffer->DetachTexture();
730  if (mpCurrentFramebuffer == pFramebuffer)
731  BindFramebuffer( nullptr );
732  }
733  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
734  }
735 }
736 
738 {
739  OpenGLZone aZone;
740 
741  OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
742  while( pFramebuffer )
743  {
744  if (!pFramebuffer->IsFree())
745  {
746  BindFramebuffer( pFramebuffer );
747  pFramebuffer->DetachTexture();
748  }
749  pFramebuffer = pFramebuffer->mpPrevFramebuffer;
750  }
751  BindFramebuffer( nullptr );
752 }
753 
754 OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
755 {
756  OpenGLZone aZone;
757 
758  // We cache the shader programs in a per-process run-time cache
759  // based on only the names and the preamble. We don't expect
760  // shader source files to change during the lifetime of a
761  // LibreOffice process.
762  OString aNameBasedKey = OUStringToOString(rVertexShader + "+" + rFragmentShader, RTL_TEXTENCODING_UTF8) + "+" + preamble;
763  if( !aNameBasedKey.isEmpty() )
764  {
765  ProgramCollection::iterator it = maPrograms.find( aNameBasedKey );
766  if( it != maPrograms.end() )
767  return it->second.get();
768  }
769 
770  // Binary shader programs are cached persistently (between
771  // LibreOffice process instances) based on a hash of their source
772  // code, as the source code can and will change between
773  // LibreOffice versions even if the shader names don't change.
774  OString aPersistentKey = OpenGLHelper::GetDigest( rVertexShader, rFragmentShader, preamble );
775  std::shared_ptr<OpenGLProgram> pProgram = std::make_shared<OpenGLProgram>();
776  if( !pProgram->Load( rVertexShader, rFragmentShader, preamble, aPersistentKey ) )
777  return nullptr;
778 
779  maPrograms.insert(std::make_pair(aNameBasedKey, pProgram));
780  return pProgram.get();
781 }
782 
783 OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
784 {
785  OpenGLZone aZone;
786 
787  OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble );
788 
789  if (pProgram && pProgram == mpCurrentProgram)
790  {
791  VCL_GL_INFO("Context::UseProgram: Reusing existing program " << pProgram->Id());
792  pProgram->Reuse();
793  return pProgram;
794  }
795 
796  mpCurrentProgram = pProgram;
797 
798  if (!mpCurrentProgram)
799  {
800  SAL_WARN("vcl.opengl", "OpenGLContext::UseProgram: mpCurrentProgram is 0");
801  return nullptr;
802  }
803 
805 
806  return mpCurrentProgram;
807 }
808 
809 /* 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.
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:348
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:2686
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:67
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:1257
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:27
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:427
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:202
void AcquireDefaultFramebuffer()
OpenGLFramebuffer * mpPrevFramebuffer
Definition: framebuffer.hxx:43
SalInstance * mpDefInst
Definition: svdata.hxx:336
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:2151
VclPtr< vcl::Window > mpWindow
virtual bool ImplInit()
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo