| 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::NoPartialUpdate| TRUE | never evaluated |  | FALSE | never evaluated |  
  ) { | 0 | 
| 93 |         if (!fbo| TRUE | never evaluated |  | FALSE | never evaluated |  
   || fbo->size() != deviceSize| TRUE | never evaluated |  | FALSE | never evaluated |  
  ) { | 0 | 
| 94 |             QOpenGLFramebufferObjectFormat fboFormat; | - | 
| 95 |             fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); | - | 
| 96 |             if (const int samples = q->requestedFormat().samples()(); | - | 
| 97 |             if (samples| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
   > 0| TRUE | never evaluated |  | FALSE | never evaluated |  
  ) { | 0 | 
| 98 |                 if (updateBehavior != QOpenGLWindow::PartialUpdateBlend| TRUE | 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::NoPartialUpdate| TRUE | 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 |  | - | 
 |  |  |