1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <private/qglpaintdevice_p.h>
43 #include <private/qgl_p.h>
44 #include <private/qglpixelbuffer_p.h>
45 #include <private/qglframebufferobject_p.h>
49 QGLPaintDevice::QGLPaintDevice()
54 QGLPaintDevice::~QGLPaintDevice()
58 int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
62 return size().width();
64 return size().height();
66 const QGLFormat f = format();
67 return f.redBufferSize() + f.greenBufferSize() + f.blueBufferSize() + f.alphaBufferSize();
70 qWarning("QGLPaintDevice::metric() - metric %d not known", metric);
75 void QGLPaintDevice::beginPaint()
77 // Make sure our context is the current one:
78 QGLContext *ctx = context();
79 if (ctx != QGLContext::currentContext())
82 // Record the currently bound FBO so we can restore it again
83 // in endPaint() and bind this device's FBO
85 // Note: m_thisFBO could be zero if the paint device is not
86 // backed by an FBO (e.g. window back buffer). But there could
87 // be a previous FBO bound to the context which we need to
88 // explicitly unbind. Otherwise the painting will go into
89 // the previous FBO instead of to the window.
90 m_previousFBO = ctx->d_func()->current_fbo;
92 if (m_previousFBO != m_thisFBO) {
93 ctx->d_ptr->current_fbo = m_thisFBO;
94 glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
97 // Set the default fbo for the context to m_thisFBO so that
98 // if some raw GL code between beginNativePainting() and
99 // endNativePainting() calls QGLFramebufferObject::release(),
100 // painting will revert to the window surface's fbo.
101 ctx->d_ptr->default_fbo = m_thisFBO;
104 void QGLPaintDevice::ensureActiveTarget()
106 QGLContext* ctx = context();
107 if (ctx != QGLContext::currentContext())
110 if (ctx->d_ptr->current_fbo != m_thisFBO) {
111 ctx->d_ptr->current_fbo = m_thisFBO;
112 glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
115 ctx->d_ptr->default_fbo = m_thisFBO;
118 void QGLPaintDevice::endPaint()
120 // Make sure the FBO bound at beginPaint is re-bound again here:
121 QGLContext *ctx = context();
122 if (m_previousFBO != ctx->d_func()->current_fbo) {
123 ctx->d_ptr->current_fbo = m_previousFBO;
124 glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_previousFBO);
127 ctx->d_ptr->default_fbo = 0;
130 QGLFormat QGLPaintDevice::format() const
132 return context()->format();
135 bool QGLPaintDevice::alphaRequested() const
137 return context()->d_func()->reqFormat.alpha();
140 bool QGLPaintDevice::isFlipped() const
145 ////////////////// QGLWidgetGLPaintDevice //////////////////
147 QGLWidgetGLPaintDevice::QGLWidgetGLPaintDevice()
151 QPaintEngine* QGLWidgetGLPaintDevice::paintEngine() const
153 return glWidget->paintEngine();
156 void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w)
161 void QGLWidgetGLPaintDevice::beginPaint()
163 QGLPaintDevice::beginPaint();
164 if (!glWidget->d_func()->disable_clear_on_painter_begin && glWidget->autoFillBackground()) {
165 if (glWidget->testAttribute(Qt::WA_TranslucentBackground))
166 glClearColor(0.0, 0.0, 0.0, 0.0);
168 const QColor &c = glWidget->palette().brush(glWidget->backgroundRole()).color();
169 float alpha = c.alphaF();
170 glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
172 if (context()->d_func()->workaround_needsFullClearOnEveryFrame)
173 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
175 glClear(GL_COLOR_BUFFER_BIT);
179 void QGLWidgetGLPaintDevice::endPaint()
181 if (glWidget->autoBufferSwap())
182 glWidget->swapBuffers();
183 QGLPaintDevice::endPaint();
187 QSize QGLWidgetGLPaintDevice::size() const
189 return glWidget->size();
192 QGLContext* QGLWidgetGLPaintDevice::context() const
194 return const_cast<QGLContext*>(glWidget->context());
197 // returns the QGLPaintDevice for the given QPaintDevice
198 QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd)
200 QGLPaintDevice* glpd = 0;
202 switch(pd->devType()) {
203 case QInternal::Widget:
204 // Should not be called on a non-gl widget:
205 Q_ASSERT(qobject_cast<QGLWidget*>(static_cast<QWidget*>(pd)));
206 glpd = &(static_cast<QGLWidget*>(pd)->d_func()->glDevice);
208 case QInternal::Pbuffer:
209 glpd = &(static_cast<QGLPixelBuffer*>(pd)->d_func()->glDevice);
211 case QInternal::FramebufferObject:
212 glpd = &(static_cast<QGLFramebufferObject*>(pd)->d_func()->glDevice);
214 case QInternal::Pixmap: {
215 qWarning("Pixmap type not supported for GL rendering");
219 qWarning("QGLPaintDevice::getDevice() - Unknown device type %d", pd->devType());