Changeset 561 for trunk/src/opengl/qwindowsurface_gl.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/opengl/qwindowsurface_gl.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtOpenGL module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 50 50 #include <qcolormap.h> 51 51 #include <qdesktopwidget.h> 52 #include <private/qwidget_p.h> 52 53 #include "qdebug.h" 53 54 … … 55 56 #include <private/qt_x11_p.h> 56 57 #include <qx11info_x11.h> 57 #include <private/qwidget_p.h>58 58 59 59 #ifndef QT_OPENGL_ES … … 70 70 #include <private/qglpixelbuffer_p.h> 71 71 #include <private/qgraphicssystem_gl_p.h> 72 73 #include <private/qpaintengineex_opengl2_p.h> 74 #include <private/qpixmapdata_gl_p.h> 75 76 #ifndef QT_OPENGL_ES_2 72 77 #include <private/qpaintengine_opengl_p.h> 78 #endif 73 79 74 80 #ifndef GLX_ARB_multisample 75 81 #define GLX_SAMPLE_BUFFERS_ARB 100000 76 82 #define GLX_SAMPLES_ARB 100001 83 #endif 84 85 #ifdef QT_OPENGL_ES_1_CL 86 #include "qgl_cl_p.h" 87 #endif 88 89 #ifdef QT_OPENGL_ES 90 #include <private/qegl_p.h> 77 91 #endif 78 92 … … 83 97 // 84 98 #ifdef Q_WS_WIN 85 Q_GUI_EXPORT bool qt_win_owndc_required;99 extern Q_GUI_EXPORT bool qt_win_owndc_required; 86 100 #endif 87 101 QGLGraphicsSystem::QGLGraphicsSystem() … … 97 111 int spec[16]; 98 112 spec[i++] = GLX_RGBA; 99 #if 0100 113 spec[i++] = GLX_DOUBLEBUFFER; 101 spec[i++] = GLX_DEPTH_SIZE; 102 spec[i++] = 8; 103 spec[i++] = GLX_STENCIL_SIZE; 104 spec[i++] = 8; 105 spec[i++] = GLX_SAMPLE_BUFFERS_ARB; 106 spec[i++] = 1; 107 spec[i++] = GLX_SAMPLES_ARB; 108 spec[i++] = 4; 109 #endif 114 115 if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) { 116 spec[i++] = GLX_DEPTH_SIZE; 117 spec[i++] = 8; 118 spec[i++] = GLX_STENCIL_SIZE; 119 spec[i++] = 8; 120 spec[i++] = GLX_SAMPLE_BUFFERS_ARB; 121 spec[i++] = 1; 122 spec[i++] = GLX_SAMPLES_ARB; 123 spec[i++] = 4; 124 } 125 110 126 spec[i++] = XNone; 111 127 … … 161 177 } 162 178 #elif defined(Q_WS_WIN) 163 QGLWindowSurface::surfaceFormat.setDoubleBuffer( false);179 QGLWindowSurface::surfaceFormat.setDoubleBuffer(true); 164 180 165 181 qt_win_owndc_required = true; … … 174 190 { 175 191 public: 176 QGLGlobalShareWidget() : widget(0) {}192 QGLGlobalShareWidget() : widget(0), initializing(false) {} 177 193 178 194 QGLWidget *shareWidget() { 179 if (!widget && !cleanedUp) { 195 if (!initializing && !widget && !cleanedUp) { 196 initializing = true; 180 197 widget = new QGLWidget; 198 // We dont need this internal widget to appear in QApplication::topLevelWidgets() 199 if (QWidgetPrivate::allWidgets) 200 QWidgetPrivate::allWidgets->remove(widget); 201 initializing = false; 181 202 } 182 203 return widget; … … 184 205 185 206 void cleanup() { 186 delete widget; 207 QGLWidget *w = widget; 208 cleanedUp = true; 187 209 widget = 0; 188 cleanedUp = true;210 delete w; 189 211 } 190 212 … … 193 215 private: 194 216 QGLWidget *widget; 217 bool initializing; 195 218 }; 196 219 … … 215 238 } 216 239 240 217 241 struct QGLWindowSurfacePrivate 218 242 { … … 224 248 int tried_fbo : 1; 225 249 int tried_pb : 1; 250 int destructive_swap_buffers : 1; 251 int geometry_updated : 1; 226 252 227 253 QGLContext *ctx; … … 233 259 234 260 QList<QImage> buffers; 261 QGLWindowSurfaceGLPaintDevice glDevice; 262 QGLWindowSurface* q_ptr; 235 263 }; 236 264 237 265 QGLFormat QGLWindowSurface::surfaceFormat; 266 267 void QGLWindowSurfaceGLPaintDevice::endPaint() 268 { 269 glFlush(); 270 QGLPaintDevice::endPaint(); 271 } 272 273 QSize QGLWindowSurfaceGLPaintDevice::size() const 274 { 275 return d->size; 276 } 277 278 QGLContext* QGLWindowSurfaceGLPaintDevice::context() const 279 { 280 return d->ctx; 281 } 282 283 284 int QGLWindowSurfaceGLPaintDevice::metric(PaintDeviceMetric m) const 285 { 286 return qt_paint_device_metric(d->q_ptr->window(), m); 287 } 288 289 QPaintEngine *QGLWindowSurfaceGLPaintDevice::paintEngine() const 290 { 291 return qt_qgl_paint_engine(); 292 } 238 293 239 294 QGLWindowSurface::QGLWindowSurface(QWidget *window) … … 245 300 d_ptr->fbo = 0; 246 301 d_ptr->ctx = 0; 302 #if defined (QT_OPENGL_ES_2) 303 d_ptr->tried_fbo = true; 304 d_ptr->tried_pb = true; 305 #else 247 306 d_ptr->tried_fbo = false; 248 307 d_ptr->tried_pb = false; 308 #endif 309 d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull(); 310 d_ptr->glDevice.d = d_ptr; 311 d_ptr->q_ptr = this; 312 d_ptr->geometry_updated = false; 249 313 } 250 314 … … 263 327 } 264 328 329 void QGLWindowSurface::deleted(QObject *object) 330 { 331 // Make sure that the fbo is destroyed before destroying its context. 332 delete d_ptr->fbo; 333 d_ptr->fbo = 0; 334 335 QWidget *widget = qobject_cast<QWidget *>(object); 336 if (widget) { 337 QWidgetPrivate *widgetPrivate = widget->d_func(); 338 if (widgetPrivate->extraData()) { 339 union { QGLContext **ctxPtr; void **voidPtr; }; 340 voidPtr = &widgetPrivate->extraData()->glContext; 341 int index = d_ptr->contexts.indexOf(ctxPtr); 342 if (index != -1) { 343 delete *ctxPtr; 344 *ctxPtr = 0; 345 d_ptr->contexts.removeAt(index); 346 } 347 } 348 } 349 } 350 265 351 void QGLWindowSurface::hijackWindow(QWidget *widget) 266 352 { … … 272 358 QGLContext *ctx = new QGLContext(surfaceFormat, widget); 273 359 ctx->create(qt_gl_share_widget()->context()); 274 #ifdef Q_WS_MAC 275 ctx->updatePaintDevice(); 276 #endif 360 361 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES) 362 // Create the EGL surface to draw into. QGLContext::chooseContext() 363 // does not do this for X11/EGL, but does do it for other platforms. 364 // This probably belongs in qgl_x11egl.cpp. 365 QGLContextPrivate *ctxpriv = ctx->d_func(); 366 ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(widget); 367 if (ctxpriv->eglSurface == EGL_NO_SURFACE) { 368 qWarning() << "hijackWindow() could not create EGL surface"; 369 } 370 qDebug("QGLWindowSurface - using EGLConfig %d", reinterpret_cast<int>(ctxpriv->eglContext->config())); 371 #endif 372 277 373 widgetPrivate->extraData()->glContext = ctx; 278 374 279 375 union { QGLContext **ctxPtr; void **voidPtr; }; 376 377 connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*))); 280 378 281 379 voidPtr = &widgetPrivate->extraData()->glContext; … … 284 382 } 285 383 286 #if !defined(QT_OPENGL_ES_2)287 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_paintengine)288 #endif289 290 /*! \reimp */291 QPaintEngine *QGLWindowSurface::paintEngine() const292 {293 #if !defined(QT_OPENGL_ES_2)294 return qt_gl_window_surface_paintengine();295 #else296 return 0;297 #endif298 }299 300 int QGLWindowSurface::metric(PaintDeviceMetric m) const301 {302 return window()->metric(m);303 }304 305 384 QGLContext *QGLWindowSurface::context() const 306 385 { … … 310 389 QPaintDevice *QGLWindowSurface::paintDevice() 311 390 { 391 updateGeometry(); 392 312 393 if (d_ptr->pb) 313 394 return d_ptr->pb; 314 395 315 396 if (d_ptr->ctx) 316 return this;397 return &d_ptr->glDevice; 317 398 318 399 QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext); … … 337 418 void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) 338 419 { 420 if (context() && widget != window()) { 421 qWarning("No native child widget support in GL window surface without FBOs or pixel buffers"); 422 return; 423 } 424 425 //### Find out why d_ptr->geometry_updated isn't always false. 426 // flush() should not be called when d_ptr->geometry_updated is true. It assumes that either 427 // d_ptr->fbo or d_ptr->pb is allocated and has the correct size. 428 if (d_ptr->geometry_updated) 429 return; 430 339 431 QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); 340 432 Q_ASSERT(parent); 341 433 434 if (!geometry().isValid()) 435 return; 436 437 // Needed to support native child-widgets... 342 438 hijackWindow(parent); 343 439 … … 347 443 QRect rect = br.translated(-offset - wOffset); 348 444 349 const GLenum target = qt_gl_preferredTextureTarget(); 445 const GLenum target = GL_TEXTURE_2D; 446 Q_UNUSED(target); 350 447 351 448 if (context()) { … … 353 450 354 451 if (context()->format().doubleBuffer()) { 355 glBindTexture(target, d_ptr->tex_id); 356 357 QVector<QRect> rects = d_ptr->paintedRegion.rects();358 for (int i = 0; i < rects.size(); ++i) { 359 Q Rect br = rects.at(i);360 if (br.isEmpty())361 continue;362 363 const uint bottom = window()->height() - (br.y() + br.height());364 glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); 365 }366 367 glBindTexture(target, 0);368 369 QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion;370 371 if (!dirtyRegion.isEmpty()) {372 context()->makeCurrent(); 373 374 glMatrixMode(GL_MODELVIEW);375 glLoadIdentity();376 377 glMatrixMode(GL_PROJECTION);378 glLoadIdentity();452 #if !defined(QT_OPENGL_ES_2) 453 if (d_ptr->destructive_swap_buffers) { 454 glBindTexture(target, d_ptr->tex_id); 455 456 QVector<QRect> rects = d_ptr->paintedRegion.rects(); 457 for (int i = 0; i < rects.size(); ++i) { 458 QRect br = rects.at(i); 459 if (br.isEmpty()) 460 continue; 461 462 const uint bottom = window()->height() - (br.y() + br.height()); 463 glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); 464 } 465 466 glBindTexture(target, 0); 467 468 QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion; 469 470 if (!dirtyRegion.isEmpty()) { 471 glMatrixMode(GL_MODELVIEW); 472 glLoadIdentity(); 473 474 glMatrixMode(GL_PROJECTION); 475 glLoadIdentity(); 379 476 #ifndef QT_OPENGL_ES 380 glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999);477 glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999); 381 478 #else 382 glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999); 383 #endif 384 glViewport(0, 0, window()->width(), window()->height()); 385 386 QVector<QRect> rects = dirtyRegion.rects(); 387 glColor4f(1, 1, 1, 1); 388 for (int i = 0; i < rects.size(); ++i) { 389 QRect rect = rects.at(i); 390 if (rect.isEmpty()) 391 continue; 392 393 drawTexture(rect, d_ptr->tex_id, window()->size(), rect); 479 glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999); 480 #endif 481 glViewport(0, 0, window()->width(), window()->height()); 482 483 QVector<QRect> rects = dirtyRegion.rects(); 484 glColor4f(1, 1, 1, 1); 485 for (int i = 0; i < rects.size(); ++i) { 486 QRect rect = rects.at(i); 487 if (rect.isEmpty()) 488 continue; 489 490 drawTexture(rect, d_ptr->tex_id, window()->size(), rect); 491 } 394 492 } 395 493 } 494 #endif 396 495 d_ptr->paintedRegion = QRegion(); 397 398 496 context()->swapBuffers(); 399 497 } else { … … 404 502 } 405 503 504 QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext()); 406 505 QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext); 407 GLuint texture; 506 507 // QPainter::end() should have unbound the fbo, otherwise something is very wrong... 508 Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound()); 509 510 if (ctx != previous_ctx) { 511 ctx->makeCurrent(); 512 } 513 514 QSize size = widget->rect().size(); 515 if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) { 516 rect = parent->rect(); 517 br = rect.translated(wOffset + offset); 518 size = parent->size(); 519 } 520 521 glDisable(GL_SCISSOR_TEST); 522 523 if (d_ptr->fbo && (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit)) { 524 const int h = d_ptr->fbo->height(); 525 526 const int sx0 = br.left(); 527 const int sx1 = br.left() + br.width(); 528 const int sy0 = h - (br.top() + br.height()); 529 const int sy1 = h - br.top(); 530 531 const int tx0 = rect.left(); 532 const int tx1 = rect.left() + rect.width(); 533 const int ty0 = parent->height() - (rect.top() + rect.height()); 534 const int ty1 = parent->height() - rect.top(); 535 536 if (window() == parent || d_ptr->fbo->format().samples() <= 1) { 537 // glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); 538 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); 539 540 glBlitFramebufferEXT(sx0, sy0, sx1, sy1, 541 tx0, ty0, tx1, ty1, 542 GL_COLOR_BUFFER_BIT, 543 GL_NEAREST); 544 545 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0); 546 } else { 547 // can't do sub-region blits with multisample FBOs 548 QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat()); 549 550 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, temp->handle()); 551 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); 552 553 glBlitFramebufferEXT(0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(), 554 0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(), 555 GL_COLOR_BUFFER_BIT, 556 GL_NEAREST); 557 558 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, temp->handle()); 559 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); 560 561 glBlitFramebufferEXT(sx0, sy0, sx1, sy1, 562 tx0, ty0, tx1, ty1, 563 GL_COLOR_BUFFER_BIT, 564 GL_NEAREST); 565 566 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0); 567 568 qgl_fbo_pool()->release(temp); 569 } 570 } 571 #if !defined(QT_OPENGL_ES_2) 572 else { 573 GLuint texture; 408 574 if (d_ptr->fbo) { 409 575 texture = d_ptr->fbo->texture(); … … 417 583 } 418 584 419 QSize size = widget->rect().size(); 420 if (ctx->format().doubleBuffer()) { 421 rect = parent->rect(); 422 br = rect.translated(wOffset); 423 size = parent->size(); 424 } 425 426 ctx->makeCurrent(); 427 #ifdef Q_WS_MAC 428 ctx->updatePaintDevice(); 429 #endif 430 if (d_ptr->fbo) 431 d_ptr->fbo->release(); 432 433 glMatrixMode(GL_MODELVIEW); 434 glLoadIdentity(); 435 436 glMatrixMode(GL_PROJECTION); 437 glLoadIdentity(); 585 glDisable(GL_DEPTH_TEST); 586 587 if (d_ptr->fbo) { 588 d_ptr->fbo->release(); 589 } else { 590 ctx->makeCurrent(); 591 } 592 593 glMatrixMode(GL_MODELVIEW); 594 glLoadIdentity(); 595 596 glMatrixMode(GL_PROJECTION); 597 glLoadIdentity(); 438 598 #ifndef QT_OPENGL_ES 439 glOrtho(0, size.width(), size.height(), 0, -999999, 999999);599 glOrtho(0, size.width(), size.height(), 0, -999999, 999999); 440 600 #else 441 glOrthof(0, size.width(), size.height(), 0, -999999, 999999); 442 #endif 443 glViewport(0, 0, size.width(), size.height()); 444 445 glColor4f(1, 1, 1, 1); 446 drawTexture(rect, texture, window()->size(), br); 601 glOrthof(0, size.width(), size.height(), 0, -999999, 999999); 602 #endif 603 glViewport(0, 0, size.width(), size.height()); 604 605 glColor4f(1, 1, 1, 1); 606 drawTexture(rect, texture, window()->size(), br); 607 608 if (d_ptr->fbo) 609 d_ptr->fbo->bind(); 610 } 611 #else 612 // OpenGL/ES 2.0 version of the fbo blit. 613 else if (d_ptr->fbo) { 614 Q_UNUSED(target); 615 616 GLuint texture = d_ptr->fbo->texture(); 617 618 glDisable(GL_DEPTH_TEST); 619 620 if (d_ptr->fbo->isBound()) 621 d_ptr->fbo->release(); 622 623 glViewport(0, 0, size.width(), size.height()); 624 625 QGLShaderProgram *blitProgram = 626 QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram(); 627 blitProgram->bind(); 628 blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); 629 630 // The shader manager's blit program does not multiply the 631 // vertices by the pmv matrix, so we need to do the effect 632 // of the orthographic projection here ourselves. 633 QRectF r; 634 qreal w = size.width() ? size.width() : 1.0f; 635 qreal h = size.height() ? size.height() : 1.0f; 636 r.setLeft((rect.left() / w) * 2.0f - 1.0f); 637 if (rect.right() == (size.width() - 1)) 638 r.setRight(1.0f); 639 else 640 r.setRight((rect.right() / w) * 2.0f - 1.0f); 641 r.setBottom((rect.top() / h) * 2.0f - 1.0f); 642 if (rect.bottom() == (size.height() - 1)) 643 r.setTop(1.0f); 644 else 645 r.setTop((rect.bottom() / w) * 2.0f - 1.0f); 646 647 drawTexture(r, texture, window()->size(), br); 648 } 649 #endif 447 650 448 651 if (ctx->format().doubleBuffer()) … … 450 653 else 451 654 glFlush(); 452 453 if (d_ptr->fbo) 454 d_ptr->fbo->bind(); 455 } 655 } 656 456 657 457 658 void QGLWindowSurface::setGeometry(const QRect &rect) 458 659 { 459 660 QWindowSurface::setGeometry(rect); 460 461 const GLenum target = qt_gl_preferredTextureTarget(); 661 d_ptr->geometry_updated = true; 662 } 663 664 665 void QGLWindowSurface::updateGeometry() { 666 if (!d_ptr->geometry_updated) 667 return; 668 d_ptr->geometry_updated = false; 669 670 671 QRect rect = geometry(); 672 hijackWindow(window()); 673 QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext); 674 675 #ifdef Q_WS_MAC 676 ctx->updatePaintDevice(); 677 #endif 678 679 const GLenum target = GL_TEXTURE_2D; 462 680 463 681 if (rect.width() <= 0 || rect.height() <= 0) … … 470 688 471 689 if (d_ptr->ctx) { 472 glBindTexture(target, d_ptr->tex_id); 473 glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 474 glBindTexture(target, 0); 690 #ifndef QT_OPENGL_ES_2 691 if (d_ptr->destructive_swap_buffers) { 692 glBindTexture(target, d_ptr->tex_id); 693 glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 694 glBindTexture(target, 0); 695 } 696 #endif 475 697 return; 476 698 } 477 699 478 if (d_ptr->pb || !d_ptr->tried_pb) { 700 if (d_ptr->destructive_swap_buffers 701 && (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) 702 && (d_ptr->fbo || !d_ptr->tried_fbo) 703 && qt_gl_preferGL2Engine()) 704 { 705 d_ptr->tried_fbo = true; 706 ctx->d_ptr->internal_context = true; 707 ctx->makeCurrent(); 708 delete d_ptr->fbo; 709 710 QGLFramebufferObjectFormat format; 711 format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); 712 format.setInternalTextureFormat(GLenum(GL_RGBA)); 713 format.setTextureTarget(target); 714 715 if (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) 716 format.setSamples(8); 717 718 d_ptr->fbo = new QGLFramebufferObject(rect.size(), format); 719 720 if (d_ptr->fbo->isValid()) { 721 qDebug() << "Created Window Surface FBO" << rect.size() 722 << "with samples" << d_ptr->fbo->format().samples(); 723 return; 724 } else { 725 qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; 726 delete d_ptr->fbo; 727 d_ptr->fbo = 0; 728 } 729 } 730 731 #if !defined(QT_OPENGL_ES_2) 732 if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) { 479 733 d_ptr->tried_pb = true; 480 734 … … 491 745 492 746 if (d_ptr->pb->isValid()) { 493 qDebug() << " PBSample buffers:" << d_ptr->pb->format().sampleBuffers();747 qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers(); 494 748 d_ptr->pb->makeCurrent(); 495 749 … … 504 758 glMatrixMode(GL_PROJECTION); 505 759 glLoadIdentity(); 506 #ifndef QT_OPENGL_ES507 760 glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); 508 #else509 glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);510 #endif511 761 512 762 d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true; … … 518 768 } 519 769 } 520 521 if ((QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) && (d_ptr->fbo || !d_ptr->tried_fbo)) { 522 d_ptr->tried_fbo = true; 523 hijackWindow(window()); 524 QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext); 525 ctx->d_ptr->internal_context = true; 526 ctx->makeCurrent(); 527 delete d_ptr->fbo; 528 d_ptr->fbo = new QGLFramebufferObject(rect.size(), QGLFramebufferObject::CombinedDepthStencil, 529 GLenum(target), GLenum(GL_RGBA)); 530 531 d_ptr->fbo->bind(); 532 if (d_ptr->fbo->isValid()) { 533 return; 534 } else { 535 qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; 536 delete d_ptr->fbo; 537 d_ptr->fbo = 0; 538 } 539 } 540 541 hijackWindow(window()); 542 QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext); 770 #endif // !defined(QT_OPENGL_ES_2) 771 543 772 ctx->makeCurrent(); 544 773 545 glGenTextures(1, &d_ptr->tex_id); 546 glBindTexture(target, d_ptr->tex_id); 547 glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 548 549 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 550 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 551 glBindTexture(target, 0); 774 #ifndef QT_OPENGL_ES_2 775 if (d_ptr->destructive_swap_buffers) { 776 glGenTextures(1, &d_ptr->tex_id); 777 glBindTexture(target, d_ptr->tex_id); 778 glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 779 780 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 781 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 782 glBindTexture(target, 0); 783 } 784 #endif 552 785 553 786 qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;; … … 579 812 #endif 580 813 581 const GLenum target = qt_gl_preferredTextureTarget();814 const GLenum target = GL_TEXTURE_2D; 582 815 583 816 glBindTexture(target, d_ptr->tex_id); … … 592 825 static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br) 593 826 { 594 const GLenum target = qt_gl_preferredTextureTarget();827 const GLenum target = GL_TEXTURE_2D; 595 828 QRectF src = br.isEmpty() 596 829 ? QRectF(QPointF(), texSize) … … 620 853 qt_add_rect_to_array(rect, vertexArray); 621 854 855 #if !defined(QT_OPENGL_ES_2) 622 856 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); 623 857 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); … … 634 868 glDisable(target); 635 869 glBindTexture(target, 0); 870 #else 871 glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray); 872 glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray); 873 874 glBindTexture(target, tex_id); 875 876 glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); 877 glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); 878 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 879 glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); 880 glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); 881 882 glBindTexture(target, 0); 883 #endif 636 884 } 637 885
Note:
See TracChangeset
for help on using the changeset viewer.