Qt 4.8
qwindowsurface_gl.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenGL module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QtGui/QApplication>
43 #include <QtGui/QColormap>
44 #include <QtGui/QDesktopWidget>
45 #include <QtGui/QPaintDevice>
46 #include <QtGui/QWidget>
47 
48 #include <qglframebufferobject.h>
49 #include <qglpixelbuffer.h>
50 #include <qcolormap.h>
51 #include <qdesktopwidget.h>
52 #include <private/qwidget_p.h>
53 #include "qdebug.h"
54 
55 #ifdef Q_WS_X11
56 #include <private/qt_x11_p.h>
57 #include <qx11info_x11.h>
58 
59 #ifndef QT_OPENGL_ES
60 #include <GL/glx.h>
61 #include <X11/Xlib.h>
62 #endif
63 #endif //Q_WS_X11
64 
65 #include <private/qglextensions_p.h>
66 #include <private/qwindowsurface_gl_p.h>
67 
68 #include <private/qgl_p.h>
69 
70 #include <private/qglpixelbuffer_p.h>
71 #include <private/qgraphicssystem_gl_p.h>
72 
73 #include <private/qpaintengineex_opengl2_p.h>
74 #include <private/qpixmapdata_gl_p.h>
75 
76 #ifndef QT_OPENGL_ES_2
77 #include <private/qpaintengine_opengl_p.h>
78 #endif
79 
80 #ifndef GLX_ARB_multisample
81 #define GLX_SAMPLE_BUFFERS_ARB 100000
82 #define GLX_SAMPLES_ARB 100001
83 #endif
84 
85 #ifndef QT_NO_EGL
86 #include <private/qeglcontext_p.h>
87 #endif
88 
90 
91 //
92 // QGLGraphicsSystem
93 //
94 #ifdef Q_WS_WIN
96 #endif
98  : QGraphicsSystem(), m_useX11GL(useX11GL)
99 {
100 #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
101  // only override the system defaults if the user hasn't already
102  // picked a visual
103  if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) {
104  // find a double buffered, RGBA visual that supports OpenGL
105  // and set that as the default visual for windows in Qt
106  int i = 0;
107  int spec[16];
108  spec[i++] = GLX_RGBA;
109  spec[i++] = GLX_DOUBLEBUFFER;
110 
111  if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) {
112  spec[i++] = GLX_DEPTH_SIZE;
113  spec[i++] = 8;
114  spec[i++] = GLX_STENCIL_SIZE;
115  spec[i++] = 8;
116  spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
117  spec[i++] = 1;
118  spec[i++] = GLX_SAMPLES_ARB;
119  spec[i++] = 4;
120  }
121 
122  spec[i++] = XNone;
123 
124  XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec);
125  if (vi) {
126  X11->visual_id = vi->visualid;
127  X11->visual_class = vi->c_class;
128 
130  int res;
131  glXGetConfig(X11->display, vi, GLX_LEVEL, &res);
132  format.setPlane(res);
133  glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res);
134  format.setDoubleBuffer(res);
135  glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res);
136  format.setDepth(res);
137  if (format.depth())
138  format.setDepthBufferSize(res);
139  glXGetConfig(X11->display, vi, GLX_RGBA, &res);
140  format.setRgba(res);
141  glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res);
142  format.setRedBufferSize(res);
143  glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res);
144  format.setGreenBufferSize(res);
145  glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res);
146  format.setBlueBufferSize(res);
147  glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res);
148  format.setAlpha(res);
149  if (format.alpha())
150  format.setAlphaBufferSize(res);
151  glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res);
152  format.setAccum(res);
153  if (format.accum())
154  format.setAccumBufferSize(res);
155  glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res);
156  format.setStencil(res);
157  if (format.stencil())
158  format.setStencilBufferSize(res);
159  glXGetConfig(X11->display, vi, GLX_STEREO, &res);
160  format.setStereo(res);
161  glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res);
162  format.setSampleBuffers(res);
163  if (format.sampleBuffers()) {
164  glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res);
165  format.setSamples(res);
166  }
167 
169  XFree(vi);
170 
171  printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id);
172  }
173  }
174 #elif defined(Q_WS_WIN)
176 
177  qt_win_owndc_required = true;
178 #endif
179 }
180 
181 //
182 // QGLWindowSurface
183 //
185 {
186 public:
188  created = true;
189  }
190 
192  if (!init && !widget && !cleanedUp) {
193  init = true;
195 #ifdef Q_OS_SYMBIAN
196  if (!widget->context()->isValid()) {
197  delete widget;
198  widget = 0;
199  init = false;
200  return 0;
201  }
202 #endif
203 
204  widget->resize(1, 1);
205 
206  // We don't need this internal widget to appear in QApplication::topLevelWidgets()
209  init = false;
210  }
211  return widget;
212  }
213 
214  // destroys the share widget and prevents recreation
215  void cleanup() {
216  QGLWidget *w = widget;
217  cleanedUp = true;
218  widget = 0;
219  delete w;
220  }
221 
222  // destroys the share widget, but allows it to be recreated later on
223  void destroy() {
224  if (cleanedUp)
225  return;
226 
227  QGLWidget *w = widget;
228 
229  // prevent potential recursions
230  cleanedUp = true;
231  widget = 0;
232  delete w;
233  cleanedUp = false;
234  }
235 
237  {
238  return init;
239  }
240 
241  static bool cleanedUp;
242  static bool created;
243 
244 private:
246  bool init;
247 };
248 
250 bool QGLGlobalShareWidget::created = false;
251 
252 static void qt_cleanup_gl_share_widget();
254  {
256  })
257 
258 static void qt_cleanup_gl_share_widget()
259 {
261  _qt_gl_share_widget()->cleanup();
262 }
263 
265 {
267  return 0;
268  return _qt_gl_share_widget()->shareWidget();
269 }
270 
272 {
274  _qt_gl_share_widget()->destroy();
275 }
276 
278 {
280  return _qt_gl_share_widget()->initializing();
281  return false;
282 }
283 
285 {
287  if (widget)
288  return widget->context();
289  return 0;
290 }
291 
293 {
296  GLuint tex_id;
297  GLuint pb_tex_id;
298 
299  int tried_fbo : 1;
300  int tried_pb : 1;
303  int did_paint : 1;
304 
306 
308 
311 
313 
317 
319 };
320 
323 
325 {
326  return d->size;
327 }
328 
330 {
331  return d->ctx;
332 }
333 
334 
336 {
337  return qt_paint_device_metric(d->q_ptr->window(), m);
338 }
339 
341 {
342  return qt_qgl_paint_engine();
343 }
344 
346  : QWindowSurface(window), d_ptr(new QGLWindowSurfacePrivate)
347 {
348 // Q_ASSERT(window->isTopLevel());
349  d_ptr->pb = 0;
350  d_ptr->fbo = 0;
351  d_ptr->ctx = 0;
352  d_ptr->tex_id = 0;
353 #if defined (QT_OPENGL_ES_2)
354  d_ptr->tried_fbo = true;
355  d_ptr->tried_pb = true;
356 #else
357  d_ptr->tried_fbo = false;
358  d_ptr->tried_pb = false;
359 #endif
360  d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull();
361  d_ptr->glDevice.d = d_ptr;
362  d_ptr->q_ptr = this;
363  d_ptr->geometry_updated = false;
364  d_ptr->did_paint = false;
365  d_ptr->swap_region_support = false;
366 }
367 
369 {
370  if (d_ptr->ctx)
371  glDeleteTextures(1, &d_ptr->tex_id);
372 #ifndef Q_WS_QPA // Don't delete the contexts. Destroying the window does that for us
373  foreach(QGLContext **ctx, d_ptr->contexts) {
374  delete *ctx;
375  *ctx = 0;
376  }
377 #endif
378  delete d_ptr->pb;
379  delete d_ptr->fbo;
380  delete d_ptr;
381 
383  return;
384 
385 #ifdef Q_OS_SYMBIAN
386  // Destroy the context if necessary.
387  if (qt_gl_share_widget() && !qt_gl_share_context()->isSharing())
389 #endif
390 }
391 
393 {
394  QWidget *widget = qobject_cast<QWidget *>(object);
395  if (widget) {
396  if (widget == window()) {
397  // Make sure that the fbo is destroyed before destroying its context.
398  delete d_ptr->fbo;
399  d_ptr->fbo = 0;
400  }
401 
402 #ifndef Q_WS_QPA //no need to specifically delete the QGLContext as it will be deleted by QWidget
403  QWidgetPrivate *widgetPrivate = widget->d_func();
404  if (widgetPrivate->extraData()) {
405  union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
406  voidPtrPtr = &widgetPrivate->extraData()->glContext;
407  int index = d_ptr->contexts.indexOf(ctxPtrPtr);
408  if (index != -1) {
409  delete *ctxPtrPtr;
410  *ctxPtrPtr = 0;
411  d_ptr->contexts.removeAt(index);
412  }
413  }
414 #endif
415  }
416 }
417 
419 {
420  QWidgetPrivate *widgetPrivate = widget->d_func();
421  widgetPrivate->createExtra();
422  if (widgetPrivate->extraData()->glContext)
423  return;
424 
425  QGLContext *ctx = NULL;
426 
427  // For translucent top-level widgets we need alpha in the format.
429  QGLFormat modFormat(surfaceFormat);
430  modFormat.setSampleBuffers(false);
431  modFormat.setSamples(0);
432  modFormat.setAlpha(true);
433  ctx = new QGLContext(modFormat, widget);
434  } else
435  ctx = new QGLContext(surfaceFormat, widget);
436 
437  ctx->create(qt_gl_share_context());
438 #ifdef Q_OS_SYMBIAN
439  if (!ctx->isValid()) {
440  delete ctx;
441  return;
442  }
443 #endif
444 #ifndef QT_NO_EGL
445  static bool checkedForNOKSwapRegion = false;
446  static bool haveNOKSwapRegion = false;
447 
448  if (!checkedForNOKSwapRegion) {
449  haveNOKSwapRegion = QEgl::hasExtension("EGL_NOK_swap_region2");
450  checkedForNOKSwapRegion = true;
451 
452  if (haveNOKSwapRegion)
453  qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates.";
454  }
455 
457  if (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
458  EGLint swapBehavior;
459  if (eglQuerySurface(ctx->d_func()->eglContext->display(), ctx->d_func()->eglSurface
460  , EGL_SWAP_BEHAVIOR, &swapBehavior)) {
461  d_ptr->destructive_swap_buffers = (swapBehavior != EGL_BUFFER_PRESERVED);
462  }
463  }
464 
465  d_ptr->swap_region_support = haveNOKSwapRegion;
466 #endif
467 
468  widgetPrivate->extraData()->glContext = ctx;
469 
470  union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
471 
472  connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*)));
473 
474  voidPtrPtr = &widgetPrivate->extraData()->glContext;
475  d_ptr->contexts << ctxPtrPtr;
476 
477 #ifndef Q_OS_SYMBIAN
478  qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
479 #endif
480 }
481 
483 {
484  return d_ptr->ctx;
485 }
486 
488 {
489  updateGeometry();
490 
491 #ifdef Q_OS_SYMBIAN
492  // On symbian we always return glDevice, even if it's invalid
493  return &d_ptr->glDevice;
494 #else
495  if (d_ptr->pb)
496  return d_ptr->pb;
497 
498  if (d_ptr->ctx)
499  return &d_ptr->glDevice;
500 
501  QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
502  ctx->makeCurrent();
503 
504  Q_ASSERT(d_ptr->fbo);
505  return d_ptr->fbo;
506 #endif
507 }
508 
509 static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &src = QRectF());
510 
512 {
513  d_ptr->did_paint = true;
514  updateGeometry();
515 
516  int clearFlags = 0;
517 
518  QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
519 
520  if (!ctx)
521  return;
522 
523  if (ctx->d_func()->workaround_needsFullClearOnEveryFrame)
525  else if (ctx->format().alpha())
526  clearFlags = GL_COLOR_BUFFER_BIT;
527 
528  if (clearFlags) {
529  if (d_ptr->fbo)
530  d_ptr->fbo->bind();
531 
532  glClearColor(0.0, 0.0, 0.0, 0.0);
533  glClear(clearFlags);
534 
535  if (d_ptr->fbo)
536  d_ptr->fbo->release();
537  }
538 }
539 
541 {
542  if (context())
543  d_ptr->paintedRegion |= rgn;
544 
545  d_ptr->buffers.clear();
546 }
547 
548 static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
549 {
550  glDisable(GL_DEPTH_TEST);
551  glDisable(GL_SCISSOR_TEST);
552  glDisable(GL_BLEND);
553 
554  glViewport(0, 0, viewport.width(), viewport.height());
555 
556  QGLShaderProgram *blitProgram =
558  blitProgram->bind();
559  blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/);
560 
561  // The shader manager's blit program does not multiply the
562  // vertices by the pmv matrix, so we need to do the effect
563  // of the orthographic projection here ourselves.
564  QRectF r;
565  qreal w = viewport.width();
566  qreal h = viewport.height();
567  r.setLeft((targetRect.left() / w) * 2.0f - 1.0f);
568  if (targetRect.right() == (viewport.width() - 1))
569  r.setRight(1.0f);
570  else
571  r.setRight((targetRect.right() / w) * 2.0f - 1.0f);
572  r.setBottom((targetRect.top() / h) * 2.0f - 1.0f);
573  if (targetRect.bottom() == (viewport.height() - 1))
574  r.setTop(1.0f);
575  else
576  r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f);
577 
578  drawTexture(r, texture, texSize, sourceRect);
579 }
580 
581 
583 {
584  //### Find out why d_ptr->geometry_updated isn't always false.
585  // flush() should not be called when d_ptr->geometry_updated is true. It assumes that either
586  // d_ptr->fbo or d_ptr->pb is allocated and has the correct size.
587  if (d_ptr->geometry_updated)
588  return;
589 
590  // did_paint is set to true in ::beginPaint. ::beginPaint means that we
591  // at least cleared the background (= painted something). In EGL API it's a
592  // mistake to call swapBuffers if nothing was painted unless
593  // EGL_BUFFER_PRESERVED is set. This check protects the flush func from
594  // being executed if it's for nothing.
596  return;
597 
598 #ifdef Q_OS_SYMBIAN
599  if (window() != widget) {
600  // For performance reasons we don't support
601  // flushing native child widgets on Symbian.
602  // It breaks overlapping native child widget
603  // rendering in some cases but we prefer performance.
604  return;
605  }
606 #endif
607 
608 
609  QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
610  Q_ASSERT(parent);
611 
612 #if !defined(Q_WS_QPA)
613  if (!geometry().isValid())
614  return;
615 #else
616  if (!size().isValid())
617  return;
618 #endif
619 
620  // Needed to support native child-widgets...
621  hijackWindow(parent);
622 
623  QRect br = rgn.boundingRect().translated(offset);
624  br = br.intersected(window()->rect());
625  QPoint wOffset = qt_qwidget_data(parent)->wrect.topLeft();
626  QRect rect = br.translated(-offset - wOffset);
627 
628  const GLenum target = GL_TEXTURE_2D;
629  Q_UNUSED(target);
630 
631  if (QGLWindowSurface::swapBehavior == QGLWindowSurface::KillSwap)
632  return;
633 
634  if (context()) {
635  context()->makeCurrent();
636 
637  if (context()->format().doubleBuffer()) {
638 #if !defined(QT_OPENGL_ES_2)
640  glBindTexture(target, d_ptr->tex_id);
641 
643  for (int i = 0; i < rects.size(); ++i) {
644  QRect br = rects.at(i);
645  if (br.isEmpty())
646  continue;
647 
648  const uint bottom = window()->height() - (br.y() + br.height());
649  glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
650  }
651 
652  glBindTexture(target, 0);
653 
654  QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion;
655 
656  if (!dirtyRegion.isEmpty()) {
657  glMatrixMode(GL_MODELVIEW);
658  glLoadIdentity();
659 
660  glMatrixMode(GL_PROJECTION);
661  glLoadIdentity();
662 #ifndef QT_OPENGL_ES
663  glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999);
664 #else
665  glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999);
666 #endif
667  glViewport(0, 0, window()->width(), window()->height());
668 
669  QVector<QRect> rects = dirtyRegion.rects();
670  glColor4f(1, 1, 1, 1);
671  for (int i = 0; i < rects.size(); ++i) {
672  QRect rect = rects.at(i);
673  if (rect.isEmpty())
674  continue;
675 
676  drawTexture(rect, d_ptr->tex_id, window()->size(), rect);
677  }
678  }
679  }
680 #endif
681  bool doingPartialUpdate = false;
682  if (d_ptr->swap_region_support) {
683  if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap)
684  doingPartialUpdate = br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2;
685  else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap)
686  doingPartialUpdate = true;
687  }
688 
689  QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
690 #ifdef Q_OS_SYMBIAN
691  if (!ctx)
692  return;
693 #endif
694 
695  if (widget != window()) {
696  if (initializeOffscreenTexture(window()->size()))
697  qWarning() << "QGLWindowSurface: Flushing to native child widget, may lead to significant performance loss";
698  glBindTexture(target, d_ptr->tex_id);
699 
700  const uint bottom = window()->height() - (br.y() + br.height());
701  glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
702 
703  glBindTexture(target, 0);
704 
705  ctx->makeCurrent();
706  if (doingPartialUpdate)
707  blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), rect, br);
708  else
709  blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), parent->rect(), parent->rect().translated(offset + wOffset));
710  }
711 
712  if (doingPartialUpdate)
713  ctx->d_func()->swapRegion(br);
714  else
715  ctx->swapBuffers();
716 
718  } else {
719  glFlush();
720  }
721  return;
722  }
723 
724  QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext());
725  QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
726 #ifdef Q_OS_SYMBIAN
727  if (!ctx)
728  return;
729 #endif
730 
731  // QPainter::end() should have unbound the fbo, otherwise something is very wrong...
732  Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound());
733 
734  if (ctx != previous_ctx) {
735  ctx->makeCurrent();
736  }
737 
738  QSize size = widget->rect().size();
740  rect = parent->rect();
741  br = rect.translated(wOffset + offset);
742  size = parent->size();
743  }
744 
745  glDisable(GL_SCISSOR_TEST);
746 
748  const int h = d_ptr->fbo->height();
749 
750  const int sx0 = br.left();
751  const int sx1 = br.left() + br.width();
752  const int sy0 = h - (br.top() + br.height());
753  const int sy1 = h - br.top();
754 
755  const int tx0 = rect.left();
756  const int tx1 = rect.left() + rect.width();
757  const int ty0 = parent->height() - (rect.top() + rect.height());
758  const int ty1 = parent->height() - rect.top();
759 
760  if (window() == parent || d_ptr->fbo->format().samples() <= 1) {
761  if (ctx->d_ptr->current_fbo != 0)
763 
765 
766  glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
767  tx0, ty0, tx1, ty1,
769  GL_NEAREST);
770 
772  } else {
773 #ifndef Q_OS_SYMBIAN // We don't have FBO pool on Symbian
774  // can't do sub-region blits with multisample FBOs
776 
779 
781  0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
783  GL_NEAREST);
784 
787 
788  glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
789  tx0, ty0, tx1, ty1,
791  GL_NEAREST);
792 
794 
795  qgl_fbo_pool()->release(temp);
796 #endif // Q_OS_SYMBIAN
797  }
798 
799  ctx->d_ptr->current_fbo = 0;
800  }
801 #if !defined(QT_OPENGL_ES_2)
802  else {
803  GLuint texture;
804  if (d_ptr->fbo) {
805  texture = d_ptr->fbo->texture();
806  } else {
807  d_ptr->pb->makeCurrent();
808  glBindTexture(target, d_ptr->pb_tex_id);
809  const uint bottom = window()->height() - (br.y() + br.height());
810  glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
811  texture = d_ptr->pb_tex_id;
812  glBindTexture(target, 0);
813  }
814 
815  glDisable(GL_DEPTH_TEST);
816 
817  if (d_ptr->fbo) {
818  d_ptr->fbo->release();
819  } else {
820  ctx->makeCurrent();
821  }
822 
823  glMatrixMode(GL_MODELVIEW);
824  glLoadIdentity();
825 
826  glMatrixMode(GL_PROJECTION);
827  glLoadIdentity();
828 #ifndef QT_OPENGL_ES
829  glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
830 #else
831  glOrthof(0, size.width(), size.height(), 0, -999999, 999999);
832 #endif
833  glViewport(0, 0, size.width(), size.height());
834 
835  glColor4f(1, 1, 1, 1);
836  drawTexture(rect, texture, window()->size(), br);
837 
838  if (d_ptr->fbo)
839  d_ptr->fbo->bind();
840  }
841 #else
842  // OpenGL/ES 2.0 version of the fbo blit.
843  else if (d_ptr->fbo) {
844  Q_UNUSED(target);
845 
846  if (d_ptr->fbo->isBound())
847  d_ptr->fbo->release();
848 
849  blitTexture(ctx, d_ptr->fbo->texture(), size, window()->size(), rect, br);
850  }
851 #endif
852 
853  if (ctx->format().doubleBuffer())
854  ctx->swapBuffers();
855  else
856  glFlush();
857 
858  d_ptr->did_paint = false;
859 }
860 
861 
862 #if !defined(Q_WS_QPA)
864 {
866  d_ptr->geometry_updated = true;
867 }
868 #else
869 void QGLWindowSurface::resize(const QSize &size)
870 {
871  QWindowSurface::resize(size);
872  d_ptr->geometry_updated = true;
873 }
874 #endif
875 
877  if (!d_ptr->geometry_updated)
878  return;
879  d_ptr->geometry_updated = false;
880 
881  bool hijack(true);
882  QWidgetPrivate *wd = window()->d_func();
883  if (wd->extraData() && wd->extraData()->glContext) {
884 #ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
885  if (d_ptr->size != geometry().size()) {
886  QGLContext *ctx = reinterpret_cast<QGLContext *>(wd->extraData()->glContext);
887 
888  if (ctx == QGLContext::currentContext())
889  ctx->doneCurrent();
890 
891  ctx->d_func()->destroyEglSurfaceForDevice();
892 
893  // Delete other contexts (shouldn't happen too often, if at all)
894  while (d_ptr->contexts.size()) {
895  QGLContext **ctxPtrPtr = d_ptr->contexts.takeFirst();
896  if ((*ctxPtrPtr) != ctx)
897  delete *ctxPtrPtr;
898  }
899  union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
900  voidPtrPtr = &wd->extraData()->glContext;
901  d_ptr->contexts << ctxPtrPtr;
902 
903  ctx->d_func()->eglSurface = ctx->d_func()->eglContext->createSurface(window());
904 
905  // Swap behaviour has been checked already in previous hijackWindow call.
906  // Reset swap behaviour based on that flag.
908  eglSurfaceAttrib(QEgl::display(), ctx->d_func()->eglSurfaceForDevice(),
909  EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
910 
911  if (eglGetError() != EGL_SUCCESS)
912  qWarning("QGLWindowSurface::updateGeometry() - could not re-enable destroyed swap behaviour");
913  } else {
914  eglSurfaceAttrib(QEgl::display(), ctx->d_func()->eglSurfaceForDevice(),
915  EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
916 
917  if (eglGetError() != EGL_SUCCESS)
918  qWarning("QGLWindowSurface::updateGeometry() - could not re-enable preserved swap behaviour");
919  }
920  }
921 #endif
922  hijack = false; // we already have gl context for widget
923  }
924 
925  if (hijack)
926  hijackWindow(window());
927 
928  QGLContext *ctx = reinterpret_cast<QGLContext *>(wd->extraData()->glContext);
929 #ifdef Q_OS_SYMBIAN
930  if (!ctx)
931  return;
932 #endif
933 #ifdef Q_WS_MAC
934  ctx->updatePaintDevice();
935 #endif
936 
937  QSize surfSize = geometry().size();
938 
939  if (surfSize.width() <= 0 || surfSize.height() <= 0)
940  return;
941 
942  if (d_ptr->size == surfSize)
943  return;
944 
945  d_ptr->size = surfSize;
946 
947  if (d_ptr->ctx) {
948 #ifndef QT_OPENGL_ES_2
950  initializeOffscreenTexture(surfSize);
951 #endif
952  return;
953  }
954 
955  const GLenum target = GL_TEXTURE_2D;
958  && (d_ptr->fbo || !d_ptr->tried_fbo)
960  {
961  d_ptr->tried_fbo = true;
962  ctx->d_ptr->internal_context = true;
963  ctx->makeCurrent();
964  delete d_ptr->fbo;
965 
969  format.setTextureTarget(target);
970 
972  format.setSamples(8);
973 
974  d_ptr->fbo = new QGLFramebufferObject(surfSize, format);
975 
976  if (d_ptr->fbo->isValid()) {
977  qDebug() << "Created Window Surface FBO" << surfSize
978  << "with samples" << d_ptr->fbo->format().samples();
979  return;
980  } else {
981  qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back";
982  delete d_ptr->fbo;
983  d_ptr->fbo = 0;
984  }
985  }
986 
987 #if !defined(QT_OPENGL_ES_2) && !defined(Q_WS_QPA) //QPA doesn't support pixelbuffers
989  d_ptr->tried_pb = true;
990 
991  if (d_ptr->pb) {
992  d_ptr->pb->makeCurrent();
993  glDeleteTextures(1, &d_ptr->pb_tex_id);
994  }
995 
996  delete d_ptr->pb;
997 
998  d_ptr->pb = new QGLPixelBuffer(surfSize.width(), surfSize.height(),
1000  qt_gl_share_widget());
1001 
1002  if (d_ptr->pb->isValid()) {
1003  qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers();
1004  d_ptr->pb->makeCurrent();
1005 
1006  glGenTextures(1, &d_ptr->pb_tex_id);
1007  glBindTexture(target, d_ptr->pb_tex_id);
1008  glTexImage2D(target, 0, GL_RGBA, surfSize.width(), surfSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1009 
1010  glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1011  glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1012  glBindTexture(target, 0);
1013 
1014  glMatrixMode(GL_PROJECTION);
1015  glLoadIdentity();
1016  glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
1017 
1018  d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true;
1019  return;
1020  } else {
1021  qDebug() << "QGLWindowSurface: Failed to create valid pixelbuffer, falling back";
1022  delete d_ptr->pb;
1023  d_ptr->pb = 0;
1024  }
1025  }
1026 #endif // !defined(QT_OPENGL_ES_2) !defined(Q_WS_QPA)
1027 
1028  ctx->makeCurrent();
1029 
1030 #ifndef QT_OPENGL_ES_2
1032  initializeOffscreenTexture(surfSize);
1033 #endif
1034 #ifndef Q_OS_SYMBIAN
1035  qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;
1036 #endif
1037  d_ptr->ctx = ctx;
1038  d_ptr->ctx->d_ptr->internal_context = true;
1039 }
1040 
1042 {
1043  if (size == d_ptr->textureSize)
1044  return false;
1045 
1046  glGenTextures(1, &d_ptr->tex_id);
1047  glBindTexture(GL_TEXTURE_2D, d_ptr->tex_id);
1048  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1049 
1050  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1051  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1052  glBindTexture(GL_TEXTURE_2D, 0);
1053 
1054  d_ptr->textureSize = size;
1055  return true;
1056 }
1057 
1058 bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy)
1059 {
1060  // this code randomly fails currently for unknown reasons
1061  return false;
1062 
1063  if (!d_ptr->pb)
1064  return false;
1065 
1066  d_ptr->pb->makeCurrent();
1067 
1068  QRect br = area.boundingRect();
1069 
1070 #if 0
1071  // ## workaround driver issue (scrolling by these deltas is unbearably slow for some reason)
1072  // ## maybe we should use glCopyTexSubImage insteadk
1073  if (dx == 1 || dx == -1 || dy == 1 || dy == -1 || dy == 2)
1074  return false;
1075 
1076  glRasterPos2i(br.x() + dx, br.y() + br.height() + dy);
1077  glCopyPixels(br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), GL_COLOR);
1078  return true;
1079 #endif
1080 
1081  const GLenum target = GL_TEXTURE_2D;
1082 
1083  glBindTexture(target, d_ptr->tex_id);
1084  glCopyTexImage2D(target, 0, GL_RGBA, br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), 0);
1085  glBindTexture(target, 0);
1086 
1087  drawTexture(br.translated(dx, dy), d_ptr->tex_id, window()->size());
1088 
1089  return true;
1090 }
1091 
1092 static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
1093 {
1094  const GLenum target = GL_TEXTURE_2D;
1095  QRectF src = br.isEmpty()
1096  ? QRectF(QPointF(), texSize)
1097  : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
1098 
1099  if (target == GL_TEXTURE_2D) {
1100  qreal width = texSize.width();
1101  qreal height = texSize.height();
1102 
1103  src.setLeft(src.left() / width);
1104  src.setRight(src.right() / width);
1105  src.setTop(src.top() / height);
1106  src.setBottom(src.bottom() / height);
1107  }
1108 
1109  const GLfloat tx1 = src.left();
1110  const GLfloat tx2 = src.right();
1111  const GLfloat ty1 = src.top();
1112  const GLfloat ty2 = src.bottom();
1113 
1114  GLfloat texCoordArray[4*2] = {
1115  tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
1116  };
1117 
1118  GLfloat vertexArray[4*2];
1119  extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); // qpaintengine_opengl.cpp
1120  qt_add_rect_to_array(rect, vertexArray);
1121 
1122 #if !defined(QT_OPENGL_ES_2)
1123  glVertexPointer(2, GL_FLOAT, 0, vertexArray);
1124  glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
1125 
1126  glBindTexture(target, tex_id);
1127  glEnable(target);
1128 
1129  glEnableClientState(GL_VERTEX_ARRAY);
1130  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1131  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1132  glDisableClientState(GL_VERTEX_ARRAY);
1133  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1134 
1135  glDisable(target);
1136  glBindTexture(target, 0);
1137 #else
1140 
1141  glBindTexture(target, tex_id);
1142 
1145  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1148 
1149  glBindTexture(target, 0);
1150 #endif
1151 }
1152 
1154 {
1155  QImage image;
1156 
1157  if (d_ptr->pb)
1158  image = d_ptr->pb->toImage();
1159  else if (d_ptr->fbo)
1160  image = d_ptr->fbo->toImage();
1161 
1162  if (image.isNull())
1163  return 0;
1164 
1165  QRect rect = widget->rect();
1166  rect.translate(widget->mapTo(widget->window(), QPoint()));
1167 
1168  QImage subImage = image.copy(rect);
1169  d_ptr->buffers << subImage;
1170  return &d_ptr->buffers.last();
1171 }
1172 
1173 QWindowSurface::WindowSurfaceFeatures QGLWindowSurface::features() const
1174 {
1175  WindowSurfaceFeatures features = 0;
1177  features |= PartialUpdates;
1179  features |= PreservedContents;
1180  return features;
1181 }
1182 
1184 
QGLFormat format() const
Returns the format of the pbuffer.
QPaintDevice * paintDevice()
Implement this function to return the appropriate paint device.
double d
Definition: qnumeric_p.h:62
virtual void swapBuffers() const
Swaps the screen contents with an off-screen buffer.
Definition: qgl_egl.cpp:287
QSize size() const
Returns the size of the texture attached to this framebuffer object.
QRect geometry() const
Returns the currently allocated area on the screen.
bool initializeOffscreenTexture(const QSize &size)
QGLFramebufferObjectPool * qgl_fbo_pool()
GLuint texture() const
Returns the texture id for the texture attached as the default rendering target in this framebuffer o...
int samples() const
Returns the number of samples per pixel if a framebuffer object is a multisample framebuffer object...
QScopedPointer< QGLContextPrivate > d_ptr
Definition: qgl.h:430
qreal right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:527
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
Definition: qimage.cpp:1410
void setAttachment(QGLFramebufferObject::Attachment attachment)
Sets the attachment configuration of a framebuffer object to attachment.
#define GL_RGB
void setSamples(int numSamples)
Set the preferred number of samples per pixel when multisampling is enabled to numSamples.
Definition: qgl.cpp:836
#define GL_TEXTURE_MIN_FILTER
double qreal
Definition: qglobal.h:1193
void setStencil(bool enable)
If enable is true enables the stencil buffer; otherwise disables the stencil buffer.
Definition: qgl.cpp:724
const QGLContext * qt_gl_share_context()
void setAccumBufferSize(int size)
Set the preferred accumulation buffer size, where size is the bit depth for each RGBA component...
Definition: qgl.cpp:1143
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Q_GUI_EXPORT bool qt_win_owndc_required
void deleted(QObject *object)
QPointer< QWidget > widget
void setLeft(qreal pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:670
QPoint mapTo(QWidget *, const QPoint &) const
Translates the widget coordinate pos to the coordinate system of parent.
Definition: qwidget.cpp:4409
#define GL_DEPTH_TEST
QRect rect(const QWidget *widget) const
Returns the rectangle for widget in the coordinates of this window surface.
void qAddPostRoutine(QtCleanUpFunction p)
void setRedBufferSize(int size)
Set the preferred red buffer size to size.
Definition: qgl.cpp:1015
QGLWindowSurface(QWidget *window)
QImage toImage() const
Returns the contents of this framebuffer object as a QImage.
The QGLFramebufferObject class encapsulates an OpenGL framebuffer object.
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
#define GL_STENCIL_BUFFER_BIT
bool isValid() const
Returns true if the framebuffer object is valid.
int height() const
Definition: qpaintdevice.h:92
bool remove(const T &value)
Definition: qset.h:89
void setInternalTextureFormat(GLenum internalTextureFormat)
Sets the internal format of a framebuffer object&#39;s texture or multisample framebuffer object&#39;s color ...
#define SLOT(a)
Definition: qobjectdefs.h:226
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
qreal left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:525
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
QRect translated(int dx, int dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:328
virtual void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
const QGLContext * context() const
Returns the context of this widget.
Definition: qgl.cpp:5303
void setTop(qreal pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:674
QGLShaderProgram * blitProgram()
#define glVertexAttribPointer
Definition: glfunctions.h:71
bool qt_initializing_gl_share_widget()
void setBottom(qreal pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:676
virtual QPoint offset(const QWidget *widget) const
Returns the offset of widget in the coordinates of this window surface.
void setAlpha(bool enable)
If enable is true enables the alpha buffer; otherwise disables the alpha buffer.
Definition: qgl.cpp:664
QRect intersected(const QRect &other) const
Returns the intersection of this rectangle and the given rectangle.
Definition: qrect.h:481
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
void endPaint(const QRegion &region)
This function is called after painting onto the surface has ended, with the region in which the paint...
void setSampleBuffers(bool enable)
If enable is true, a GL context with multisample buffer support is picked; otherwise ignored...
Definition: qgl.cpp:812
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
QList< QGLContext ** > contexts
#define glEnableVertexAttribArray
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
T * qobject_cast(QObject *object)
Definition: qobject.h:375
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
void updatePaintDevice()
Definition: qgl_mac.mm:583
#define X11
Definition: qt_x11_p.h:724
#define glBindFramebuffer
uint internal_context
Definition: qgl_p.h:426
#define GL_TEXTURE_2D
static QGLEngineSharedShaders * shadersForContext(const QGLContext *context)
bool makeCurrent()
Makes this pbuffer the current OpenGL rendering context.
void setRight(qreal pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:672
#define GL_SCISSOR_TEST
static const QGLContext * currentContext()
Returns the current context, i.e.
Definition: qgl.cpp:3545
QGLFramebufferObject * acquire(const QSize &size, const QGLFramebufferObjectFormat &format, bool strictSize=false)
#define glBlitFramebufferEXT
Q_CORE_EXPORT void qDebug(const char *,...)
QGLGraphicsSystem(bool useX11GL)
bool sampleBuffers() const
Returns true if multisample buffer support is enabled; otherwise returns false.
Definition: qgl.h:658
#define SIGNAL(a)
Definition: qobjectdefs.h:227
#define GL_FALSE
QPaintEngine * paintEngine() const
NSWindow * window
int width() const
Returns the width.
Definition: qsize.h:126
void createExtra()
Creates the widget extra data.
Definition: qwidget.cpp:1802
void setAlphaBufferSize(int size)
Set the preferred alpha buffer size to size.
Definition: qgl.cpp:1116
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QWidget * nativeParentWidget() const
Returns the native parent for this widget, i.
Definition: qwidget.cpp:4514
bool depth() const
Returns true if the depth buffer is enabled; otherwise returns false.
Definition: qgl.h:618
int width() const
Definition: qpaintdevice.h:91
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
static SwapMode swapBehavior
void destroyed(QObject *=0)
This signal is emitted immediately before the object obj is destroyed, and can not be blocked...
#define GLX_SAMPLE_BUFFERS_ARB
QGLFormat format() const
Returns the frame buffer format that was obtained (this may be a subset of what was requested)...
Definition: qgl.cpp:3495
void qt_add_rect_to_array(const QRectF &r, GLfloat *array)
Definition: qgl.cpp:2972
The QGLFormat class specifies the display format of an OpenGL rendering context.
Definition: qgl.h:175
virtual bool create(const QGLContext *shareContext=0)
Creates the GL context.
Definition: qgl.cpp:3454
T takeFirst()
Removes the first item in the list and returns it.
Definition: qlist.h:489
The QGLContext class encapsulates an OpenGL rendering context.
Definition: qgl.h:310
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
static bool init
void flush(QWidget *widget, const QRegion &region, const QPoint &offset)
Flushes the given region from the specified widget onto the screen.
void setDepthBufferSize(int size)
Set the minimum depth buffer size to size.
Definition: qgl.cpp:984
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
void setSamples(int samples)
Sets the number of samples per pixel for a multisample framebuffer object to samples.
QGLFramebufferObjectFormat format() const
Returns the format of this framebuffer object.
void release(QGLFramebufferObject *fbo)
bool stencil() const
Returns true if the stencil buffer is enabled; otherwise returns false.
Definition: qgl.h:638
static QGLFormat surfaceFormat
Q_CORE_EXPORT void qWarning(const char *,...)
#define GL_COLOR_BUFFER_BIT
void setDoubleBuffer(bool enable)
If enable is true sets double buffering; otherwise sets single buffering.
Definition: qgl.cpp:566
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
unsigned int uint
Definition: qglobal.h:996
#define GL_TRIANGLE_FAN
void setGreenBufferSize(int size)
Set the preferred green buffer size to size.
Definition: qgl.cpp:1050
#define GL_FLOAT
QImage toImage() const
Returns the contents of the pbuffer as a QImage.
bool isValid() const
Returns true if this pbuffer is valid; otherwise returns false.
static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
The QGLPixelBuffer class encapsulates an OpenGL pbuffer.
QSize size
the size of the widget excluding any window frame
Definition: qwidget.h:165
bool accum() const
Returns true if the accumulation buffer is enabled; otherwise returns false.
Definition: qgl.h:633
void setDepth(bool enable)
If enable is true enables the depth buffer; otherwise disables the depth buffer.
Definition: qgl.cpp:599
void clear()
Removes all items from the list.
Definition: qlist.h:764
QRect wrect
Definition: qwidget.h:145
bool isNull() const
Returns true if this byte array is null; otherwise returns false.
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
GLuint handle() const
Returns the GL framebuffer object handle for this framebuffer object (returned by the glGenFrameBuffe...
static void qt_cleanup_gl_share_widget()
int metric(PaintDeviceMetric m) const
static QWidgetSet * allWidgets
Definition: qwidget_p.h:715
#define GL_DRAW_FRAMEBUFFER_EXT
static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &src=QRectF())
bool qt_gl_preferGL2Engine()
Definition: qgl.cpp:218
Q_OPENGL_EXPORT QPaintEngine * qt_qgl_paint_engine()
Definition: qgl.cpp:5530
The QWindowSurface class provides the drawing area for top-level windows.
#define GL_READ_FRAMEBUFFER_EXT
Q_GUI_EXPORT bool hasExtension(const char *extensionName)
Definition: qegl.cpp:791
QScopedPointer< QGLPixelBufferPrivate > d_ptr
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
#define GL_DEPTH_BUFFER_BIT
Q_GLOBAL_STATIC_WITH_INITIALIZER(QGLGlobalShareWidget, _qt_gl_share_widget, { qAddPostRoutine(qt_cleanup_gl_share_widget);}) static void qt_cleanup_gl_share_widget()
#define GL_BLEND
void setRgba(bool enable)
If enable is true sets RGBA mode.
Definition: qgl.cpp:633
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
void setTextureTarget(GLenum target)
Sets the texture target of the texture attached to a framebuffer object to target.
void beginPaint(const QRegion &region)
This function is called before painting onto the surface begins, with the region in which the paintin...
GLuint current_fbo
Definition: qgl_p.h:456
#define GLX_SAMPLES_ARB
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
The QGLWidget class is a widget for rendering OpenGL graphics.
Definition: qgl.h:474
void qt_destroy_gl_share_widget()
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int indexOf(const T &t, int from=0) const
Returns the index position of the first occurrence of value in the list, searching forward from index...
Definition: qlist.h:847
void resize(int w, int h)
This corresponds to resize(QSize(w, h)).
Definition: qwidget.h:1014
unsigned int GLenum
Definition: main.cpp:50
bool bind()
Switches rendering from the default, windowing system provided framebuffer to this framebuffer object...
bool isValid() const
Returns true if a GL rendering context has been successfully created; otherwise returns false...
Definition: qgl.cpp:3477
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
void hijackWindow(QWidget *widget)
#define GL_UNSIGNED_BYTE
#define glDisableVertexAttribArray
QGLContext * context() const
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
#define ctx
Definition: qgl.cpp:6094
virtual void doneCurrent()
Makes no GL context the current context.
Definition: qgl_egl.cpp:277
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
void * glContext
Definition: qwidget_p.h:248
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool alpha() const
Returns true if the alpha buffer in the framebuffer is enabled; otherwise returns false...
Definition: qgl.h:628
int height() const
Returns the height.
Definition: qsize.h:129
static const GLuint QT_TEXTURE_COORDS_ATTR
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool release()
Switches rendering back to the default, windowing system provided framebuffer.
QGLFramebufferObject * fbo
QGLWindowSurfacePrivate * d
virtual void makeCurrent()
Makes this context the current OpenGL rendering context.
Definition: qgl_egl.cpp:213
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
QSizeF size() const
Returns the size of the rectangle.
Definition: qrect.h:713
bool doubleBuffer() const
Returns true if double buffering is enabled; otherwise returns false.
Definition: qgl.h:613
static Extensions glExtensions()
Definition: qgl.cpp:5781
quint16 index
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
#define GL_RGBA
qreal top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:526
WindowSurfaceFeatures features() const
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
void setStereo(bool enable)
If enable is true enables stereo buffering; otherwise disables stereo buffering.
Definition: qgl.cpp:754
QWExtra * extraData() const
Definition: qwidget_p.h:999
bool scroll(const QRegion &area, int dx, int dy)
Scrolls the given area dx pixels to the right and dy downward; both dx and dy may be negative...
QImage * buffer(const QWidget *widget)
Returns a QImage pointer which represents the actual buffer the widget is drawn into or 0 if this is ...
bool isBound() const
Returns true if the framebuffer object is currently bound to a context, otherwise false is returned...
qreal bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:528
#define GL_TEXTURE_MAG_FILTER
QGLWidget * qt_gl_share_widget()
static const GLuint QT_VERTEX_COORDS_ATTR
bool bind()
Binds this shader program to the active QGLContext and makes it the current shader program...
void setBlueBufferSize(int size)
Set the preferred blue buffer size to size.
Definition: qgl.cpp:1085
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:658
void setPlane(int plane)
Sets the requested plane to plane.
Definition: qgl.cpp:942
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
The QGLFramebufferObjectFormat class specifies the format of an OpenGL framebuffer object...
Q_GUI_EXPORT QWidgetData * qt_qwidget_data(QWidget *widget)
Definition: qwidget.cpp:12915
QGLWindowSurfacePrivate * d_ptr
The QGLShaderProgram class allows OpenGL shader programs to be linked and used.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition: qwidget.h:158
void setStencilBufferSize(int size)
Set the preferred stencil buffer size to size.
Definition: qgl.cpp:1169
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QWidget * window() const
Returns a pointer to the top-level window associated with this surface.
Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric)
QGLWindowSurfaceGLPaintDevice glDevice
void setAccum(bool enable)
If enable is true enables the accumulation buffer; otherwise disables the accumulation buffer...
Definition: qgl.cpp:694
static bool isNull(const QVariant::Private *d)
Definition: qvariant.cpp:300
void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static int area(const QSize &s)
Definition: qicon.cpp:155
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
#define GL_NEAREST
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480