qoffscreensurface.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/kernel/qoffscreensurface.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui 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 The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://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 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qoffscreensurface.h"-
41-
42#include "qguiapplication_p.h"-
43#include "qscreen.h"-
44#include "qplatformintegration.h"-
45#include "qplatformoffscreensurface.h"-
46#include "qwindow.h"-
47#include "qplatformwindow.h"-
48-
49QT_BEGIN_NAMESPACE-
50-
51/*!-
52 \class QOffscreenSurface-
53 \inmodule QtGui-
54 \since 5.1-
55 \brief The QOffscreenSurface class represents an offscreen surface in the underlying platform.-
56-
57 QOffscreenSurface is intended to be used with QOpenGLContext to allow rendering with OpenGL in-
58 an arbitrary thread without the need to create a QWindow.-
59-
60 Even though the surface is typically renderable, the surface's pixels are not accessible.-
61 QOffscreenSurface should only be used to create OpenGL resources such as textures-
62 or framebuffer objects.-
63-
64 An application will typically use QOffscreenSurface to perform some time-consuming tasks in a-
65 separate thread in order to avoid stalling the main rendering thread. Resources created in the-
66 QOffscreenSurface's context can be shared with the main OpenGL context. Some common use cases-
67 are asynchronous texture uploads or rendering into a QOpenGLFramebufferObject.-
68-
69 How the offscreen surface is implemented depends on the underlying platform, but it will-
70 typically use a pixel buffer (pbuffer). If the platform doesn't implement or support-
71 offscreen surfaces, QOffscreenSurface will use an invisible QWindow internally.-
72-
73 \note Due to the fact that QOffscreenSurface is backed by a QWindow on some platforms,-
74 cross-platform applications must ensure that create() is only called on the main (GUI)-
75 thread. The QOffscreenSurface is then safe to be used with-
76 \l{QOpenGLContext::makeCurrent()}{makeCurrent()} on other threads, but the-
77 initialization and destruction must always happen on the main (GUI) thread.-
78-
79 \note In order to create an offscreen surface that is guaranteed to be compatible with-
80 a given context and window, make sure to set the format to the context's or the-
81 window's actual format, that is, the QSurfaceFormat returned from-
82 QOpenGLContext::format() or QWindow::format() \e{after the context or window has been-
83 created}. Passing the format returned from QWindow::requestedFormat() to setFormat()-
84 may result in an incompatible offscreen surface since the underlying windowing system-
85 interface may offer a different set of configurations for window and pbuffer surfaces.-
86-
87 \note Some platforms may utilize a surfaceless context extension (for example-
88 EGL_KHR_surfaceless_context) when available. In this case there will be no underlying-
89 native surface. For the use cases of QOffscreenSurface (rendering to FBOs, texture-
90 upload) this is not a problem.-
91*/-
92class Q_GUI_EXPORT QOffscreenSurfacePrivate : public QObjectPrivate-
93{-
94 Q_DECLARE_PUBLIC(QOffscreenSurface)-
95-
96public:-
97 QOffscreenSurfacePrivate()-
98 : QObjectPrivate()-
99 , surfaceType(QSurface::OpenGLSurface)-
100 , platformOffscreenSurface(0)-
101 , offscreenWindow(0)-
102 , requestedFormat(QSurfaceFormat::defaultFormat())-
103 , screen(0)-
104 , size(1, 1)-
105 {-
106 }
never executed: end of block
0
107-
108 ~QOffscreenSurfacePrivate()-
109 {-
110 }-
111-
112 QSurface::SurfaceType surfaceType;-
113 QPlatformOffscreenSurface *platformOffscreenSurface;-
114 QWindow *offscreenWindow;-
115 QSurfaceFormat requestedFormat;-
116 QScreen *screen;-
117 QSize size;-
118};-
119-
120-
121/*!-
122 Creates an offscreen surface for the \a targetScreen.-
123-
124 The underlying platform surface is not created until create() is called.-
125-
126 \sa setScreen(), create()-
127*/-
128QOffscreenSurface::QOffscreenSurface(QScreen *targetScreen)-
129 : QObject(*new QOffscreenSurfacePrivate(), 0)-
130 , QSurface(Offscreen)-
131{-
132 Q_D(QOffscreenSurface);-
133 d->screen = targetScreen;-
134 if (!d->screen)
!d->screenDescription
TRUEnever evaluated
FALSEnever evaluated
0
135 d->screen = QGuiApplication::primaryScreen();
never executed: d->screen = QGuiApplication::primaryScreen();
0
136-
137 //if your applications aborts here, then chances are your creating a QOffscreenSurface before-
138 //the screen list is populated.-
139 Q_ASSERT(d->screen);-
140-
141 connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));-
142}
never executed: end of block
0
143-
144-
145/*!-
146 Destroys the offscreen surface.-
147*/-
148QOffscreenSurface::~QOffscreenSurface()-
149{-
150 destroy();-
151}
never executed: end of block
0
152-
153/*!-
154 Returns the surface type of the offscreen surface.-
155-
156 The surface type of an offscreen surface is always QSurface::OpenGLSurface.-
157*/-
158QOffscreenSurface::SurfaceType QOffscreenSurface::surfaceType() const-
159{-
160 Q_D(const QOffscreenSurface);-
161 return d->surfaceType;
never executed: return d->surfaceType;
0
162}-
163-
164/*!-
165 Allocates the platform resources associated with the offscreen surface.-
166-
167 It is at this point that the surface format set using setFormat() gets resolved-
168 into an actual native surface.-
169-
170 Call destroy() to free the platform resources if necessary.-
171-
172 \note Some platforms require this function to be called on the main (GUI) thread.-
173-
174 \sa destroy()-
175*/-
176void QOffscreenSurface::create()-
177{-
178 Q_D(QOffscreenSurface);-
179 if (!d->platformOffscreenSurface && !d->offscreenWindow) {
!d->platformOffscreenSurfaceDescription
TRUEnever evaluated
FALSEnever evaluated
!d->offscreenWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
180 d->platformOffscreenSurface = QGuiApplicationPrivate::platformIntegration()->createPlatformOffscreenSurface(this);-
181 // No platform offscreen surface, fallback to an invisible window-
182 if (!d->platformOffscreenSurface) {
!d->platformOffscreenSurfaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
183 if (QThread::currentThread() != qGuiApp->thread())
QThread::curre...()))->thread()Description
TRUEnever evaluated
FALSEnever evaluated
0
184 qWarning("Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures.");
never executed: QMessageLogger(__FILE__, 184, __PRETTY_FUNCTION__).warning("Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures.");
0
185 d->offscreenWindow = new QWindow(d->screen);-
186 d->offscreenWindow->setObjectName(QLatin1String("QOffscreenSurface"));-
187 // Remove this window from the global list since we do not want it to be destroyed when closing the app.-
188 // The QOffscreenSurface has to be usable even after exiting the event loop.-
189 QGuiApplicationPrivate::window_list.removeOne(d->offscreenWindow);-
190 d->offscreenWindow->setSurfaceType(QWindow::OpenGLSurface);-
191 d->offscreenWindow->setFormat(d->requestedFormat);-
192 d->offscreenWindow->setGeometry(0, 0, d->size.width(), d->size.height());-
193 d->offscreenWindow->create();-
194 }
never executed: end of block
0
195-
196 QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);-
197 QGuiApplication::sendEvent(this, &e);-
198 }
never executed: end of block
0
199}
never executed: end of block
0
200-
201/*!-
202 Releases the native platform resources associated with this offscreen surface.-
203-
204 \sa create()-
205*/-
206void QOffscreenSurface::destroy()-
207{-
208 Q_D(QOffscreenSurface);-
209-
210 QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);-
211 QGuiApplication::sendEvent(this, &e);-
212-
213 delete d->platformOffscreenSurface;-
214 d->platformOffscreenSurface = 0;-
215 if (d->offscreenWindow) {
d->offscreenWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
216 d->offscreenWindow->destroy();-
217 delete d->offscreenWindow;-
218 d->offscreenWindow = 0;-
219 }
never executed: end of block
0
220}
never executed: end of block
0
221-
222/*!-
223 Returns \c true if this offscreen surface is valid; otherwise returns \c false.-
224-
225 The offscreen surface is valid if the platform resources have been successfuly allocated.-
226-
227 \sa create()-
228*/-
229bool QOffscreenSurface::isValid() const-
230{-
231 Q_D(const QOffscreenSurface);-
232 return (d->platformOffscreenSurface && d->platformOffscreenSurface->isValid())
never executed: return (d->platformOffscreenSurface && d->platformOffscreenSurface->isValid()) || (d->offscreenWindow && d->offscreenWindow->handle());
0
233 || (d->offscreenWindow && d->offscreenWindow->handle());
never executed: return (d->platformOffscreenSurface && d->platformOffscreenSurface->isValid()) || (d->offscreenWindow && d->offscreenWindow->handle());
0
234}-
235-
236/*!-
237 Sets the offscreen surface \a format.-
238-
239 The surface format will be resolved in the create() function. Calling-
240 this function after create() will not re-resolve the surface format of the native surface.-
241-
242 \sa create(), destroy()-
243*/-
244void QOffscreenSurface::setFormat(const QSurfaceFormat &format)-
245{-
246 Q_D(QOffscreenSurface);-
247 d->requestedFormat = format;-
248}
never executed: end of block
0
249-
250/*!-
251 Returns the requested surfaceformat of this offscreen surface.-
252-
253 If the requested format was not supported by the platform implementation,-
254 the requestedFormat will differ from the actual offscreen surface format.-
255-
256 This is the value set with setFormat().-
257-
258 \sa setFormat(), format()-
259 */-
260QSurfaceFormat QOffscreenSurface::requestedFormat() const-
261{-
262 Q_D(const QOffscreenSurface);-
263 return d->requestedFormat;
never executed: return d->requestedFormat;
0
264}-
265-
266/*!-
267 Returns the actual format of this offscreen surface.-
268-
269 After the offscreen surface has been created, this function will return the actual-
270 surface format of the surface. It might differ from the requested format if the requested-
271 format could not be fulfilled by the platform.-
272-
273 \sa create(), requestedFormat()-
274*/-
275QSurfaceFormat QOffscreenSurface::format() const-
276{-
277 Q_D(const QOffscreenSurface);-
278 if (d->platformOffscreenSurface)
d->platformOffscreenSurfaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
279 return d->platformOffscreenSurface->format();
never executed: return d->platformOffscreenSurface->format();
0
280 if (d->offscreenWindow)
d->offscreenWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
281 return d->offscreenWindow->format();
never executed: return d->offscreenWindow->format();
0
282 return d->requestedFormat;
never executed: return d->requestedFormat;
0
283}-
284-
285/*!-
286 Returns the size of the offscreen surface.-
287*/-
288QSize QOffscreenSurface::size() const-
289{-
290 Q_D(const QOffscreenSurface);-
291 return d->size;
never executed: return d->size;
0
292}-
293-
294/*!-
295 Returns the screen to which the offscreen surface is connected.-
296-
297 \sa setScreen()-
298*/-
299QScreen *QOffscreenSurface::screen() const-
300{-
301 Q_D(const QOffscreenSurface);-
302 return d->screen;
never executed: return d->screen;
0
303}-
304-
305/*!-
306 Sets the screen to which the offscreen surface is connected.-
307-
308 If the offscreen surface has been created, it will be recreated on the \a newScreen.-
309-
310 \sa screen()-
311*/-
312void QOffscreenSurface::setScreen(QScreen *newScreen)-
313{-
314 Q_D(QOffscreenSurface);-
315 if (!newScreen)
!newScreenDescription
TRUEnever evaluated
FALSEnever evaluated
0
316 newScreen = QGuiApplication::primaryScreen();
never executed: newScreen = QGuiApplication::primaryScreen();
0
317 if (newScreen != d->screen) {
newScreen != d->screenDescription
TRUEnever evaluated
FALSEnever evaluated
0
318 const bool wasCreated = d->platformOffscreenSurface != 0 || d->offscreenWindow != 0;
d->platformOff...enSurface != 0Description
TRUEnever evaluated
FALSEnever evaluated
d->offscreenWindow != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
319 if (wasCreated)
wasCreatedDescription
TRUEnever evaluated
FALSEnever evaluated
0
320 destroy();
never executed: destroy();
0
321 if (d->screen)
d->screenDescription
TRUEnever evaluated
FALSEnever evaluated
0
322 disconnect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
never executed: disconnect(d->screen, qFlagLocation("2""destroyed(QObject*)" "\0" __FILE__ ":" "322"), this, qFlagLocation("1""screenDestroyed(QObject*)" "\0" __FILE__ ":" "322"));
0
323 d->screen = newScreen;-
324 if (newScreen) {
newScreenDescription
TRUEnever evaluated
FALSEnever evaluated
0
325 connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));-
326 if (wasCreated)
wasCreatedDescription
TRUEnever evaluated
FALSEnever evaluated
0
327 create();
never executed: create();
0
328 }
never executed: end of block
0
329 emit screenChanged(newScreen);-
330 }
never executed: end of block
0
331}
never executed: end of block
0
332-
333/*!-
334 Called when the offscreen surface's screen is destroyed.-
335-
336 \internal-
337*/-
338void QOffscreenSurface::screenDestroyed(QObject *object)-
339{-
340 Q_D(QOffscreenSurface);-
341 if (object == static_cast<QObject *>(d->screen))
object == stat... *>(d->screen)Description
TRUEnever evaluated
FALSEnever evaluated
0
342 setScreen(0);
never executed: setScreen(0);
0
343}
never executed: end of block
0
344-
345/*!-
346 \fn QOffscreenSurface::screenChanged(QScreen *screen)-
347-
348 This signal is emitted when an offscreen surface's \a screen changes, either-
349 by being set explicitly with setScreen(), or automatically when-
350 the window's screen is removed.-
351*/-
352-
353/*!-
354 Returns the platform offscreen surface corresponding to the offscreen surface.-
355-
356 \internal-
357*/-
358QPlatformOffscreenSurface *QOffscreenSurface::handle() const-
359{-
360 Q_D(const QOffscreenSurface);-
361 return d->platformOffscreenSurface;
never executed: return d->platformOffscreenSurface;
0
362}-
363-
364/*!-
365 Returns the platform surface corresponding to the offscreen surface.-
366-
367 \internal-
368*/-
369QPlatformSurface *QOffscreenSurface::surfaceHandle() const-
370{-
371 Q_D(const QOffscreenSurface);-
372 if (d->offscreenWindow)
d->offscreenWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
373 return d->offscreenWindow->handle();
never executed: return d->offscreenWindow->handle();
0
374-
375 return d->platformOffscreenSurface;
never executed: return d->platformOffscreenSurface;
0
376}-
377-
378QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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