Qt 4.8
qglpixelbuffer.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 
96 #include <QtCore/qglobal.h>
97 
98 #if !defined(QT_OPENGL_ES_1)
99 #include <private/qpaintengineex_opengl2_p.h>
100 #endif
101 
102 #include <qglpixelbuffer.h>
103 #include <private/qglpixelbuffer_p.h>
104 #include <private/qfont_p.h>
105 #include <qimage.h>
106 
107 #ifndef QT_OPENGL_ES_2
108 #include <private/qpaintengine_opengl_p.h>
109 #endif
110 
112 
113 #if !defined(QT_OPENGL_ES_2)
114 extern void qgl_cleanup_glyph_cache(QGLContext *);
115 #else
117 #endif
118 
119 extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
120 
121 
123 {
124  return pbuf->d_func()->qctx;
125 }
126 
128  glFlush();
130 }
131 
133 {
134  pbuf = pb;
135 }
136 
138 {
140  if(init(size, format, shareWidget)) {
141  req_size = size;
142  req_format = format;
143  req_shareWidget = shareWidget;
144  invalid = false;
145  qctx = new QGLContext(format);
146  qctx->d_func()->sharing = (shareWidget != 0);
147  if (shareWidget != 0 && shareWidget->d_func()->glcx) {
148  QGLContextGroup::addShare(qctx, shareWidget->d_func()->glcx);
149  shareWidget->d_func()->glcx->d_func()->sharing = true;
150  }
151 
152  glDevice.setPBuffer(q);
153  qctx->d_func()->paintDevice = q;
154  qctx->d_func()->valid = true;
155 #if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES)
156  qctx->d_func()->dc = dc;
157  qctx->d_func()->rc = ctx;
158 #elif (defined(Q_WS_X11) && defined(QT_NO_EGL))
159  qctx->d_func()->cx = ctx;
160  qctx->d_func()->pbuf = (void *) pbuf;
161  qctx->d_func()->vi = 0;
162 #elif defined(Q_WS_MAC)
163  qctx->d_func()->cx = ctx;
164  qctx->d_func()->vi = 0;
165 #elif !defined(QT_NO_EGL)
166  qctx->d_func()->eglContext = ctx;
167  qctx->d_func()->eglSurface = pbuf;
168 #endif
169  }
170 }
171 
185  : d_ptr(new QGLPixelBufferPrivate(this))
186 {
188  d->common_init(size, format, shareWidget);
189 }
190 
191 
210  : d_ptr(new QGLPixelBufferPrivate(this))
211 {
213  d->common_init(QSize(width, height), format, shareWidget);
214 }
215 
216 
225 {
227 
228  // defined in qpaintengine_opengl.cpp
229  QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
230  if (current != d->qctx)
231  makeCurrent();
232  qgl_cleanup_glyph_cache(d->qctx);
233  d->cleanup();
234  delete d->qctx;
235  if (current && current != d->qctx)
236  current->makeCurrent();
237 }
238 
251 {
253  if (d->invalid)
254  return false;
255  d->qctx->makeCurrent();
256  return true;
257 }
258 
269 {
271  if (d->invalid)
272  return false;
273  d->qctx->doneCurrent();
274  return true;
275 }
276 
286 #if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL)
288 {
289  Q_D(const QGLPixelBuffer);
290  GLuint texture;
291  glGenTextures(1, &texture);
292  glBindTexture(GL_TEXTURE_2D, texture);
293  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0);
294  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
295  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
296  return texture;
297 }
298 #endif
299 
366 void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
367 {
368  Q_D(const QGLPixelBuffer);
369  if (d->invalid)
370  return;
371  glBindTexture(GL_TEXTURE_2D, texture_id);
372 #ifndef QT_OPENGL_ES
373  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0);
374 #else
375  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
376 #endif
377 }
378 
379 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
380 void QGLPixelBuffer::updateDynamicTexture(QMacCompatGLuint texture_id) const
381 {
382  updateDynamicTexture(GLuint(texture_id));
383 }
384 #endif
385 
390 {
391  Q_D(const QGLPixelBuffer);
392  return d->req_size;
393 }
394 
399 {
400  Q_D(const QGLPixelBuffer);
401  if (d->invalid)
402  return QImage();
403 
404  const_cast<QGLPixelBuffer *>(this)->makeCurrent();
405  return qt_gl_read_framebuffer(d->req_size, d->format.alpha(), true);
406 }
407 
412 {
413  Q_D(const QGLPixelBuffer);
414  if (d->invalid)
415  return 0;
416  return (Qt::HANDLE) d->pbuf;
417 }
418 
423 {
424  Q_D(const QGLPixelBuffer);
425  return !d->invalid;
426 }
427 
428 #if !defined(QT_OPENGL_ES_1)
430 #endif
431 
432 #ifndef QT_OPENGL_ES_2
434 #endif
435 
438 {
439 #if defined(QT_OPENGL_ES_1)
440  return qt_buffer_engine()->engine();
441 #elif defined(QT_OPENGL_ES_2)
442  return qt_buffer_2_engine()->engine();
443 #else
444  if (qt_gl_preferGL2Engine())
445  return qt_buffer_2_engine()->engine();
446  else
447  return qt_buffer_engine()->engine();
448 #endif
449 }
450 
453 {
454  Q_D(const QGLPixelBuffer);
455 
456  float dpmx = qt_defaultDpiX()*100./2.54;
457  float dpmy = qt_defaultDpiY()*100./2.54;
458  int w = d->req_size.width();
459  int h = d->req_size.height();
460  switch (metric) {
461  case PdmWidth:
462  return w;
463 
464  case PdmHeight:
465  return h;
466 
467  case PdmWidthMM:
468  return qRound(w * 1000 / dpmx);
469 
470  case PdmHeightMM:
471  return qRound(h * 1000 / dpmy);
472 
473  case PdmNumColors:
474  return 0;
475 
476  case PdmDepth:
477  return 32;//d->depth;
478 
479  case PdmDpiX:
480  return qRound(dpmx * 0.0254);
481 
482  case PdmDpiY:
483  return qRound(dpmy * 0.0254);
484 
485  case PdmPhysicalDpiX:
486  return qRound(dpmx * 0.0254);
487 
488  case PdmPhysicalDpiY:
489  return qRound(dpmy * 0.0254);
490 
491  default:
492  qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric);
493  break;
494  }
495  return 0;
496 }
497 
509 GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
510 {
512 #ifndef QT_OPENGL_ES
513  return d->qctx->bindTexture(image, target, GLint(GL_RGBA8));
514 #else
515  return d->qctx->bindTexture(image, target, GL_RGBA);
516 #endif
517 }
518 
519 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
520 
521 GLuint QGLPixelBuffer::bindTexture(const QImage &image, QMacCompatGLenum target)
522 {
524  return d->qctx->bindTexture(image, target, QMacCompatGLint(GL_RGBA8));
525 }
526 #endif
527 
539 GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
540 {
542 #ifndef QT_OPENGL_ES
543  return d->qctx->bindTexture(pixmap, target, GLint(GL_RGBA8));
544 #else
545  return d->qctx->bindTexture(pixmap, target, GL_RGBA);
546 #endif
547 }
548 
549 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
550 
551 GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target)
552 {
554  return d->qctx->bindTexture(pixmap, target, QMacCompatGLint(GL_RGBA8));
555 }
556 #endif
557 
571 {
573  return d->qctx->bindTexture(fileName);
574 }
575 
581 void QGLPixelBuffer::deleteTexture(GLuint texture_id)
582 {
584  d->qctx->deleteTexture(texture_id);
585 }
586 
587 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
588 
589 void QGLPixelBuffer::deleteTexture(QMacCompatGLuint texture_id)
590 {
592  d->qctx->deleteTexture(texture_id);
593 }
594 #endif
595 
608 void QGLPixelBuffer::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
609 {
611  d->qctx->drawTexture(target, textureId, textureTarget);
612 }
613 
614 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
615 
616 void QGLPixelBuffer::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
617 {
619  d->qctx->drawTexture(target, textureId, textureTarget);
620 }
621 #endif
622 
634 void QGLPixelBuffer::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
635 {
637  d->qctx->drawTexture(point, textureId, textureTarget);
638 }
639 
640 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
641 
642 void QGLPixelBuffer::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
643 {
645  d->qctx->drawTexture(point, textureId, textureTarget);
646 }
647 #endif
648 
654 {
655  Q_D(const QGLPixelBuffer);
656  return d->format;
657 }
658 
virtual QGLFormat format() const
QGLFormat format() const
Returns the format of the pbuffer.
virtual ~QGLPixelBuffer()
Destroys the pbuffer and frees any allocated resources.
double d
Definition: qnumeric_p.h:62
virtual QSize size() const
friend class QGLContext
Definition: qgl.h:600
static void addShare(const QGLContext *context, const QGLContext *share)
Definition: qgl.cpp:5846
void setPBuffer(QGLPixelBuffer *pb)
#define GL_TEXTURE_MIN_FILTER
QGLPixelBuffer(const QSize &size, const QGLFormat &format=QGLFormat::defaultFormat(), QGLWidget *shareWidget=0)
Constructs an OpenGL pbuffer of the given size.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
virtual QGLContext * context() const
bool doneCurrent()
Makes no context the current OpenGL context.
Q_GUI_EXPORT int qt_defaultDpiY()
Definition: qfont.cpp:201
int height() const
Definition: qpaintdevice.h:92
Q_GUI_EXPORT int qt_defaultDpiX()
Definition: qfont.cpp:162
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
The QString class provides a Unicode character string.
Definition: qstring.h:83
void updateDynamicTexture(GLuint texture_id) const
Copies the pbuffer contents into the texture specified with texture_id.
#define Q_D(Class)
Definition: qglobal.h:2482
#define GL_TEXTURE_2D
GLuint bindTexture(const QImage &image, GLenum target=GL_TEXTURE_2D)
Generates and binds a 2D GL texture to the current context, based on image.
bool makeCurrent()
Makes this pbuffer the current OpenGL rendering context.
QSize size() const
Returns the size of the pbuffer.
static const QGLContext * currentContext()
Returns the current context, i.e.
Definition: qgl.cpp:3545
#define Q_Q(Class)
Definition: qglobal.h:2483
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int width() const
Definition: qpaintdevice.h:91
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
void common_init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
The QGLFormat class specifies the display format of an OpenGL rendering context.
Definition: qgl.h:175
The QGLContext class encapsulates an OpenGL rendering context.
Definition: qgl.h:310
static bool init
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
Q_CORE_EXPORT void qWarning(const char *,...)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
#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.
The QGLPixelBuffer class encapsulates an OpenGL pbuffer.
void * HANDLE
Definition: qnamespace.h:1671
void qgl_cleanup_glyph_cache(QGLContext *)
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
QImage qt_gl_read_framebuffer(const QSize &, bool, bool)
Definition: qgl.cpp:1860
bool qt_gl_preferGL2Engine()
Definition: qgl.cpp:218
QScopedPointer< QGLPixelBufferPrivate > d_ptr
#define GL_LINEAR
The QGLWidget class is a widget for rendering OpenGL graphics.
Definition: qgl.h:474
void deleteTexture(GLuint texture_id)
Removes the texture identified by texture_id from the texture cache.
unsigned int GLenum
Definition: main.cpp:50
#define ctx
Definition: qgl.cpp:6094
int metric(PaintDeviceMetric metric) const
Reimplemented Function
virtual void makeCurrent()
Makes this context the current OpenGL rendering context.
Definition: qgl_egl.cpp:213
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
typedef GLint
Definition: glfunctions.h:67
#define GL_RGBA
QScopedPointer< QObjectData > d_ptr
Definition: qobject.h:320
GLuint generateDynamicTexture() const
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
#define GL_TEXTURE_MAG_FILTER
Qt::HANDLE handle() const
Returns the native pbuffer handle.
static QString fileName(const QString &fileUrl)
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget=GL_TEXTURE_2D)
Draws the given texture, textureId, to the given target rectangle, target, in OpenGL model space...
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
virtual void endPaint()
QPaintEngine * paintEngine() const
Reimplemented Function