Line | Source | Count |
1 | | - |
2 | | - |
3 | class QOpenGLWindowPaintDevice : public QOpenGLPaintDevice | - |
4 | { | - |
5 | public: | - |
6 | QOpenGLWindowPaintDevice(QOpenGLWindow *window) : m_window(window) { } | - |
7 | void ensureActiveTarget() override; | - |
8 | | - |
9 | QOpenGLWindow *m_window; | - |
10 | }; | - |
11 | | - |
12 | class QOpenGLWindowPrivate : public QPaintDeviceWindowPrivate | - |
13 | { | - |
14 | inline QOpenGLWindow* q_func() { return static_cast<QOpenGLWindow *>(q_ptr); } inline const QOpenGLWindow* q_func() const { return static_cast<const QOpenGLWindow *>(q_ptr); } friend class QOpenGLWindow; | - |
15 | public: | - |
16 | QOpenGLWindowPrivate(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior) | - |
17 | : updateBehavior(updateBehavior) | - |
18 | , hasFboBlit(false) | - |
19 | , shareContext(shareContext) | - |
20 | { | - |
21 | if (!shareContext) | - |
22 | this->shareContext = qt_gl_global_share_context(); | - |
23 | } | - |
24 | | - |
25 | ~QOpenGLWindowPrivate(); | - |
26 | | - |
27 | static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); } | - |
28 | | - |
29 | void bindFBO(); | - |
30 | void initialize(); | - |
31 | | - |
32 | void beginPaint(const QRegion ®ion) override; | - |
33 | void endPaint() override; | - |
34 | void flush(const QRegion ®ion) override; | - |
35 | | - |
36 | QOpenGLWindow::UpdateBehavior updateBehavior; | - |
37 | bool hasFboBlit; | - |
38 | QScopedPointer<QOpenGLContext> context; | - |
39 | QOpenGLContext *shareContext; | - |
40 | QScopedPointer<QOpenGLFramebufferObject> fbo; | - |
41 | QScopedPointer<QOpenGLWindowPaintDevice> paintDevice; | - |
42 | QOpenGLTextureBlitter blitter; | - |
43 | QColor backgroundColor; | - |
44 | QScopedPointer<QOffscreenSurface> offscreenSurface; | - |
45 | }; | - |
46 | | - |
47 | QOpenGLWindowPrivate::~QOpenGLWindowPrivate() | - |
48 | { | - |
49 | QOpenGLWindow * const q = q_func(); | - |
50 | if (q->isValid()) { | - |
51 | q->makeCurrent(); | - |
52 | paintDevice.reset(0); | - |
53 | fbo.reset(0); | - |
54 | blitter.destroy(); | - |
55 | q->doneCurrent(); | - |
56 | } | - |
57 | } | - |
58 | | - |
59 | void QOpenGLWindowPrivate::initialize() | - |
60 | { | - |
61 | QOpenGLWindow * const q = q_func(); | - |
62 | | - |
63 | if (context) | - |
64 | return; | - |
65 | | - |
66 | context.reset(new QOpenGLContext); | - |
67 | context->setShareContext(shareContext); | - |
68 | context->setFormat(q->requestedFormat()); | - |
69 | if (!context->create()) | - |
70 | QMessageLogger(__FILE__, 223229, __PRETTY_FUNCTION__).warning("QOpenGLWindow::beginPaint: Failed to create context"); | - |
71 | if (!context->makeCurrent(q)) | - |
72 | QMessageLogger(__FILE__, 225231, __PRETTY_FUNCTION__).warning("QOpenGLWindow::beginPaint: Failed to make context current"); | - |
73 | | - |
74 | paintDevice.reset(new QOpenGLWindowPaintDevice(q)); | - |
75 | if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) | - |
76 | hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); | - |
77 | | - |
78 | q->initializeGL(); | - |
79 | } | - |
80 | | - |
81 | void QOpenGLWindowPrivate::beginPaint(const QRegion ®ion) | - |
82 | { | - |
83 | (void)region;; | - |
84 | QOpenGLWindow * const q = q_func(); | - |
85 | | - |
86 | initialize(); | - |
87 | context->makeCurrent(q); | - |
88 | | - |
89 | const int deviceWidth = q->width() * q->devicePixelRatio(); | - |
90 | const int deviceHeight = q->height() * q->devicePixelRatio(); | - |
91 | const QSize deviceSize(deviceWidth, deviceHeight); | - |
92 | if (updateBehavior > QOpenGLWindow::NoPartialUpdateTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
93 | if (!fboTRUE | never evaluated | FALSE | never evaluated |
|| fbo->size() != deviceSizeTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
94 | QOpenGLFramebufferObjectFormat fboFormat; | - |
95 | fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); | - |
96 | if (const int samples = q->requestedFormat().samples()(); | - |
97 | if (samplesTRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
> 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
98 | if (updateBehavior != QOpenGLWindow::PartialUpdateBlendTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
99 | fboFormat.setSamples(q->requestedFormat().samples());); never executed: fboFormat.setSamples(samples); | 0 |
100 | else | - |
101 | QMessageLogger(__FILE__, 253260, __PRETTY_FUNCTION__).warning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); never executed: QMessageLogger(__FILE__, 260, __PRETTY_FUNCTION__).warning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); | 0 |
102 | } | - |
103 | fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); | - |
104 | markWindowAsDirty(); | - |
105 | } never executed: end of block | 0 |
106 | } never executed: end of block else { | 0 |
107 | markWindowAsDirty(); | - |
108 | } never executed: end of block | 0 |
109 | | - |
110 | paintDevice->setSize(QSize(deviceWidth, deviceHeight)); | - |
111 | paintDevice->setDevicePixelRatio(q->devicePixelRatio()); | - |
112 | context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); | - |
113 | | - |
114 | context->functions()->glBindFramebuffer(0x8D40, context->defaultFramebufferObject()); | - |
115 | | - |
116 | q->paintUnderGL(); | - |
117 | | - |
118 | if (updateBehavior > QOpenGLWindow::NoPartialUpdateTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
119 | fbo->bind(); never executed: fbo->bind(); | 0 |
120 | } never executed: end of block | 0 |
121 | | - |
122 | void QOpenGLWindowPrivate::endPaint() | - |
123 | { | - |
124 | QOpenGLWindow * const q = q_func(); | - |
125 | | - |
126 | if (updateBehavior > QOpenGLWindow::NoPartialUpdate) | - |
127 | fbo->release(); | - |
128 | | - |
129 | context->functions()->glBindFramebuffer(0x8D40, context->defaultFramebufferObject()); | - |
130 | | - |
131 | if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { | - |
132 | const int deviceWidth = q->width() * q->devicePixelRatio(); | - |
133 | const int deviceHeight = q->height() * q->devicePixelRatio(); | - |
134 | QOpenGLExtensions extensions(context.data()); | - |
135 | extensions.glBindFramebuffer(0x8CA8, fbo->handle()); | - |
136 | extensions.glBindFramebuffer(0x8CA9, context->defaultFramebufferObject()); | - |
137 | extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, | - |
138 | 0, 0, deviceWidth, deviceHeight, | - |
139 | 0x00004000, 0x2600); | - |
140 | } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { | - |
141 | if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { | - |
142 | context->functions()->glEnable(0x0BE2); | - |
143 | context->functions()->glBlendFunc(0x0302, 0x0303); | - |
144 | } | - |
145 | if (!blitter.isCreated()) | - |
146 | blitter.create(); | - |
147 | | - |
148 | QRect windowRect(QPoint(0, 0), fbo->size()); | - |
149 | QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); | - |
150 | blitter.bind(); | - |
151 | blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); | - |
152 | blitter.release(); | - |
153 | | - |
154 | if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) | - |
155 | context->functions()->glDisable(0x0BE2); | - |
156 | } | - |
157 | | - |
158 | q->paintOverGL(); | - |
159 | } | - |
160 | | - |
161 | void QOpenGLWindowPrivate::bindFBO() | - |
162 | { | - |
163 | if (updateBehavior > QOpenGLWindow::NoPartialUpdate) | - |
164 | fbo->bind(); | - |
165 | else | - |
166 | QOpenGLFramebufferObject::bindDefault(); | - |
167 | } | - |
168 | | - |
169 | void QOpenGLWindowPrivate::flush(const QRegion ®ion) | - |
170 | { | - |
171 | (void)region;; | - |
172 | QOpenGLWindow * const q = q_func(); | - |
173 | context->swapBuffers(q); | - |
174 | q->frameSwapped(); | - |
175 | } | - |
176 | | - |
177 | void QOpenGLWindowPaintDevice::ensureActiveTarget() | - |
178 | { | - |
179 | QOpenGLWindowPrivate::get(m_window)->bindFBO(); | - |
180 | } | - |
181 | | - |
182 | | - |
183 | | - |
184 | | - |
185 | | - |
186 | | - |
187 | QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior, QWindow *parent) | - |
188 | : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(nullptr, updateBehavior)), parent) | - |
189 | { | - |
190 | setSurfaceType(QSurface::OpenGLSurface); | - |
191 | } | - |
192 | | - |
193 | | - |
194 | | - |
195 | | - |
196 | | - |
197 | | - |
198 | QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior, QWindow *parent) | - |
199 | : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(shareContext, updateBehavior)), parent) | - |
200 | { | - |
201 | setSurfaceType(QSurface::OpenGLSurface); | - |
202 | } | - |
203 | QOpenGLWindow::~QOpenGLWindow() | - |
204 | { | - |
205 | makeCurrent(); | - |
206 | } | - |
207 | | - |
208 | | - |
209 | | - |
210 | | - |
211 | QOpenGLWindow::UpdateBehavior QOpenGLWindow::updateBehavior() const | - |
212 | { | - |
213 | const QOpenGLWindowPrivate * const d = d_func(); | - |
214 | return d->updateBehavior; | - |
215 | } | - |
216 | | - |
217 | | - |
218 | | - |
219 | | - |
220 | | - |
221 | | - |
222 | bool QOpenGLWindow::isValid() const | - |
223 | { | - |
224 | const QOpenGLWindowPrivate * const d = d_func(); | - |
225 | return d->context && d->context->isValid(); | - |
226 | } | - |
227 | void QOpenGLWindow::makeCurrent() | - |
228 | { | - |
229 | QOpenGLWindowPrivate * const d = d_func(); | - |
230 | | - |
231 | if (!isValid()) | - |
232 | return; | - |
233 | | - |
234 | | - |
235 | | - |
236 | if (handle()) { | - |
237 | d->context->makeCurrent(this); | - |
238 | } else { | - |
239 | if (!d->offscreenSurface) { | - |
240 | d->offscreenSurface.reset(new QOffscreenSurface); | - |
241 | d->offscreenSurface->setFormat(d->context->format()); | - |
242 | d->offscreenSurface->create(); | - |
243 | } | - |
244 | d->context->makeCurrent(d->offscreenSurface.data()); | - |
245 | } | - |
246 | | - |
247 | d->bindFBO(); | - |
248 | } | - |
249 | void QOpenGLWindow::doneCurrent() | - |
250 | { | - |
251 | QOpenGLWindowPrivate * const d = d_func(); | - |
252 | | - |
253 | if (!isValid()) | - |
254 | return; | - |
255 | | - |
256 | d->context->doneCurrent(); | - |
257 | } | - |
258 | | - |
259 | | - |
260 | | - |
261 | | - |
262 | QOpenGLContext *QOpenGLWindow::context() const | - |
263 | { | - |
264 | const QOpenGLWindowPrivate * const d = d_func(); | - |
265 | return d->context.data(); | - |
266 | } | - |
267 | | - |
268 | | - |
269 | | - |
270 | | - |
271 | QOpenGLContext *QOpenGLWindow::shareContext() const | - |
272 | { | - |
273 | const QOpenGLWindowPrivate * const d = d_func(); | - |
274 | return d->shareContext; | - |
275 | } | - |
276 | GLuint QOpenGLWindow::defaultFramebufferObject() const | - |
277 | { | - |
278 | const QOpenGLWindowPrivate * const d = d_func(); | - |
279 | if (d->updateBehavior > NoPartialUpdate && d->fbo) | - |
280 | return d->fbo->handle(); | - |
281 | else if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) | - |
282 | return ctx->defaultFramebufferObject(); | - |
283 | else | - |
284 | return 0; | - |
285 | } | - |
286 | | - |
287 | extern __attribute__((visibility("default"))) QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); | - |
288 | QImage QOpenGLWindow::grabFramebuffer() | - |
289 | { | - |
290 | if (!isValid()) | - |
291 | return QImage(); | - |
292 | | - |
293 | makeCurrent(); | - |
294 | return qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false); | - |
295 | } | - |
296 | void QOpenGLWindow::initializeGL() | - |
297 | { | - |
298 | } | - |
299 | void QOpenGLWindow::resizeGL(int w, int h) | - |
300 | { | - |
301 | (void)w;; | - |
302 | (void)h;; | - |
303 | } | - |
304 | void QOpenGLWindow::paintGL() | - |
305 | { | - |
306 | } | - |
307 | void QOpenGLWindow::paintUnderGL() | - |
308 | { | - |
309 | } | - |
310 | void QOpenGLWindow::paintOverGL() | - |
311 | { | - |
312 | } | - |
313 | | - |
314 | | - |
315 | | - |
316 | | - |
317 | | - |
318 | | - |
319 | void QOpenGLWindow::paintEvent(QPaintEvent *event) | - |
320 | { | - |
321 | (void)event;; | - |
322 | paintGL(); | - |
323 | } | - |
324 | | - |
325 | | - |
326 | | - |
327 | | - |
328 | | - |
329 | | - |
330 | void QOpenGLWindow::resizeEvent(QResizeEvent *event) | - |
331 | { | - |
332 | (void)event;; | - |
333 | QOpenGLWindowPrivate * const d = d_func(); | - |
334 | d->initialize(); | - |
335 | resizeGL(width(), height()); | - |
336 | } | - |
337 | | - |
338 | | - |
339 | | - |
340 | | - |
341 | int QOpenGLWindow::metric(PaintDeviceMetric metric) const | - |
342 | { | - |
343 | const QOpenGLWindowPrivate * const d = d_func(); | - |
344 | | - |
345 | switch (metric) { | - |
346 | case PdmDepth: | - |
347 | if (d->paintDevice) | - |
348 | return d->paintDevice->depth(); | - |
349 | break; | - |
350 | default: | - |
351 | break; | - |
352 | } | - |
353 | return QPaintDeviceWindow::metric(metric); | - |
354 | } | - |
355 | | - |
356 | | - |
357 | | - |
358 | | - |
359 | QPaintDevice *QOpenGLWindow::redirected(QPoint *) const | - |
360 | { | - |
361 | const QOpenGLWindowPrivate * const d = d_func(); | - |
362 | if (QOpenGLContext::currentContext() == d->context.data()) | - |
363 | return d->paintDevice.data(); | - |
364 | return 0; | - |
365 | } | - |
366 | | - |
367 | | - |
| | |