qopenglcompositorbackingstore.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the plugins of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include <QtGui/QOpenGLContext>-
35#include <QtGui/QWindow>-
36#include <QtGui/QPainter>-
37#include <QtGui/QOffscreenSurface>-
38#include <qpa/qplatformbackingstore.h>-
39#include <private/qwindow_p.h>-
40-
41#include "qopenglcompositorbackingstore_p.h"-
42#include "qopenglcompositor_p.h"-
43-
44#ifndef GL_UNPACK_ROW_LENGTH-
45#define GL_UNPACK_ROW_LENGTH 0x0CF2-
46#endif-
47-
48QT_BEGIN_NAMESPACE-
49-
50/*!-
51 \class QOpenGLCompositorBackingStore-
52 \brief A backing store implementation for OpenGL-
53 \since 5.4-
54 \internal-
55 \ingroup qpa-
56-
57 This implementation uploads raster-rendered widget windows into-
58 textures. It is meant to be used with QOpenGLCompositor that-
59 composites the textures onto a single native window using OpenGL.-
60 This means that multiple top-level widgets are supported without-
61 creating actual native windows for each of them.-
62-
63 \note It is important to call notifyComposited() from the-
64 corresponding platform window's endCompositing() callback-
65 (inherited from QOpenGLCompositorWindow).-
66-
67 \note When implementing QOpenGLCompositorWindow::textures() for-
68 windows of type RasterSurface or RasterGLSurface, simply return-
69 the list provided by this class' textures().-
70*/-
71-
72QOpenGLCompositorBackingStore::QOpenGLCompositorBackingStore(QWindow *window)-
73 : QPlatformBackingStore(window),-
74 m_window(window),-
75 m_bsTexture(0),-
76 m_bsTextureContext(0),-
77 m_textures(new QPlatformTextureList),-
78 m_lockedWidgetTextures(0)-
79{-
80}
never executed: end of block
0
81-
82QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore()-
83{-
84 if (m_bsTexture) {
m_bsTextureDescription
TRUEnever evaluated
FALSEnever evaluated
0
85 QOpenGLContext *ctx = QOpenGLContext::currentContext();-
86 // With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is-
87 // made current before destroying backingstores. That is however not the case for-
88 // windows with regular widgets only.-
89 QScopedPointer<QOffscreenSurface> tempSurface;-
90 if (!ctx) {
!ctxDescription
TRUEnever evaluated
FALSEnever evaluated
0
91 ctx = QOpenGLCompositor::instance()->context();-
92 tempSurface.reset(new QOffscreenSurface);-
93 tempSurface->setFormat(ctx->format());-
94 tempSurface->create();-
95 ctx->makeCurrent(tempSurface.data());-
96 }
never executed: end of block
0
97-
98 if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup())
ctxDescription
TRUEnever evaluated
FALSEnever evaluated
m_bsTextureContextDescription
TRUEnever evaluated
FALSEnever evaluated
ctx->shareGrou...->shareGroup()Description
TRUEnever evaluated
FALSEnever evaluated
0
99 glDeleteTextures(1, &m_bsTexture);
never executed: glDeleteTextures(1, &m_bsTexture);
0
100 else-
101 qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context");
never executed: QMessageLogger(__FILE__, 101, __PRETTY_FUNCTION__).warning("QOpenGLCompositorBackingStore: Texture is not valid in the current context");
0
102-
103 if (tempSurface)
tempSurfaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
104 ctx->doneCurrent();
never executed: ctx->doneCurrent();
0
105 }
never executed: end of block
0
106-
107 delete m_textures; // this does not actually own any GL resources-
108}
never executed: end of block
0
109-
110QPaintDevice *QOpenGLCompositorBackingStore::paintDevice()-
111{-
112 return &m_image;
never executed: return &m_image;
0
113}-
114-
115void QOpenGLCompositorBackingStore::updateTexture()-
116{-
117 if (!m_bsTexture) {
!m_bsTextureDescription
TRUEnever evaluated
FALSEnever evaluated
0
118 m_bsTextureContext = QOpenGLContext::currentContext();-
119 Q_ASSERT(m_bsTextureContext);-
120 glGenTextures(1, &m_bsTexture);-
121 glBindTexture(GL_TEXTURE_2D, m_bsTexture);-
122 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);-
123 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);-
124 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);-
125 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);-
126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);-
127 } else {
never executed: end of block
0
128 glBindTexture(GL_TEXTURE_2D, m_bsTexture);-
129 }
never executed: end of block
0
130-
131 if (!m_dirty.isNull()) {
!m_dirty.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
132 QRegion fixed;-
133 QRect imageRect = m_image.rect();-
134-
135 QOpenGLContext *ctx = QOpenGLContext::currentContext();-
136 if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
!ctx->isOpenGLES()Description
TRUEnever evaluated
FALSEnever evaluated
ctx->format()....Version() >= 3Description
TRUEnever evaluated
FALSEnever evaluated
0
137 foreach (const QRect &rect, m_dirty.rects()) {-
138 QRect r = imageRect & rect;-
139 glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image.width());-
140 glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y(), r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE,-
141 m_image.constScanLine(r.y()) + r.x() * 4);-
142 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);-
143 }
never executed: end of block
0
144 } else {
never executed: end of block
0
145 foreach (const QRect &rect, m_dirty.rects()) {-
146 // intersect with image rect to be sure-
147 QRect r = imageRect & rect;-
148-
149 // if the rect is wide enough it's cheaper to just-
150 // extend it instead of doing an image copy-
151 if (r.width() >= imageRect.width() / 2) {
r.width() >= i...ct.width() / 2Description
TRUEnever evaluated
FALSEnever evaluated
0
152 r.setX(0);-
153 r.setWidth(imageRect.width());-
154 }
never executed: end of block
0
155-
156 fixed |= r;-
157 }
never executed: end of block
0
158 foreach (const QRect &rect, fixed.rects()) {-
159 // if the sub-rect is full-width we can pass the image data directly to-
160 // OpenGL instead of copying, since there's no gap between scanlines-
161 if (rect.width() == imageRect.width()) {
rect.width() =...geRect.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
162 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,-
163 m_image.constScanLine(rect.y()));-
164 } else {
never executed: end of block
0
165 glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,-
166 m_image.copy(rect).constBits());-
167 }
never executed: end of block
0
168 }-
169 }
never executed: end of block
0
170-
171 m_dirty = QRegion();-
172 }
never executed: end of block
0
173}
never executed: end of block
0
174-
175void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)-
176{-
177 // Called for ordinary raster windows.-
178-
179 Q_UNUSED(region);-
180 Q_UNUSED(offset);-
181-
182 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();-
183 QOpenGLContext *dstCtx = compositor->context();-
184 Q_ASSERT(dstCtx);-
185-
186 QWindow *dstWin = compositor->targetWindow();-
187 if (!dstWin)
!dstWinDescription
TRUEnever evaluated
FALSEnever evaluated
0
188 return;
never executed: return;
0
189-
190 dstCtx->makeCurrent(dstWin);-
191 updateTexture();-
192 m_textures->clear();-
193 m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry());-
194-
195 compositor->update();-
196}
never executed: end of block
0
197-
198void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,-
199 QPlatformTextureList *textures, QOpenGLContext *context,-
200 bool translucentBackground)-
201{-
202 // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top.-
203-
204 Q_UNUSED(region);-
205 Q_UNUSED(offset);-
206 Q_UNUSED(context);-
207 Q_UNUSED(translucentBackground);-
208-
209 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();-
210 QOpenGLContext *dstCtx = compositor->context();-
211 Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow-
212-
213 // The compositor's context and the context to which QOpenGLWidget/QQuickWidget-
214 // textures belong are not the same. They share resources, though.-
215 Q_ASSERT(context->shareGroup() == dstCtx->shareGroup());-
216-
217 QWindow *dstWin = compositor->targetWindow();-
218 if (!dstWin)
!dstWinDescription
TRUEnever evaluated
FALSEnever evaluated
0
219 return;
never executed: return;
0
220-
221 dstCtx->makeCurrent(dstWin);-
222-
223 QWindowPrivate::get(window)->lastComposeTime.start();-
224-
225 m_textures->clear();-
226 for (int i = 0; i < textures->count(); ++i)
i < textures->count()Description
TRUEnever evaluated
FALSEnever evaluated
0
227 m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i),
never executed: m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i), textures->clipRect(i), textures->flags(i));
0
228 textures->clipRect(i), textures->flags(i));
never executed: m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i), textures->clipRect(i), textures->flags(i));
0
229-
230 updateTexture();-
231 m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry());-
232-
233 textures->lock(true);-
234 m_lockedWidgetTextures = textures;-
235-
236 compositor->update();-
237}
never executed: end of block
0
238-
239void QOpenGLCompositorBackingStore::notifyComposited()-
240{-
241 if (m_lockedWidgetTextures) {
m_lockedWidgetTexturesDescription
TRUEnever evaluated
FALSEnever evaluated
0
242 QPlatformTextureList *textureList = m_lockedWidgetTextures;-
243 m_lockedWidgetTextures = 0; // may reenter so null before unlocking-
244 textureList->lock(false);-
245 }
never executed: end of block
0
246}
never executed: end of block
0
247-
248void QOpenGLCompositorBackingStore::beginPaint(const QRegion &region)-
249{-
250 m_dirty |= region;-
251-
252 if (m_image.hasAlphaChannel()) {
m_image.hasAlphaChannel()Description
TRUEnever evaluated
FALSEnever evaluated
0
253 QPainter p(&m_image);-
254 p.setCompositionMode(QPainter::CompositionMode_Source);-
255 foreach (const QRect &r, region.rects())-
256 p.fillRect(r, Qt::transparent);
never executed: p.fillRect(r, Qt::transparent);
0
257 }
never executed: end of block
0
258}
never executed: end of block
0
259-
260void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &staticContents)-
261{-
262 Q_UNUSED(staticContents);-
263-
264 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();-
265 QOpenGLContext *dstCtx = compositor->context();-
266 QWindow *dstWin = compositor->targetWindow();-
267 if (!dstWin)
!dstWinDescription
TRUEnever evaluated
FALSEnever evaluated
0
268 return;
never executed: return;
0
269-
270 m_image = QImage(size, QImage::Format_RGBA8888);-
271-
272 m_window->create();-
273-
274 dstCtx->makeCurrent(dstWin);-
275 if (m_bsTexture) {
m_bsTextureDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 glDeleteTextures(1, &m_bsTexture);-
277 m_bsTexture = 0;-
278 m_bsTextureContext = Q_NULLPTR;-
279 }
never executed: end of block
0
280}
never executed: end of block
0
281-
282QImage QOpenGLCompositorBackingStore::toImage() const-
283{-
284 return m_image;
never executed: return m_image;
0
285}-
286-
287QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9