Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/opengl/qwindowsurface_gl.cpp

    r2 r561  
    22**
    33** 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)
    56**
    67** This file is part of the QtOpenGL module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** 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.
    3838** $QT_END_LICENSE$
    3939**
     
    5050#include <qcolormap.h>
    5151#include <qdesktopwidget.h>
     52#include <private/qwidget_p.h>
    5253#include "qdebug.h"
    5354
     
    5556#include <private/qt_x11_p.h>
    5657#include <qx11info_x11.h>
    57 #include <private/qwidget_p.h>
    5858
    5959#ifndef QT_OPENGL_ES
     
    7070#include <private/qglpixelbuffer_p.h>
    7171#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
    7277#include <private/qpaintengine_opengl_p.h>
     78#endif
    7379
    7480#ifndef GLX_ARB_multisample
    7581#define GLX_SAMPLE_BUFFERS_ARB  100000
    7682#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>
    7791#endif
    7892
     
    8397//
    8498#ifdef Q_WS_WIN
    85 Q_GUI_EXPORT bool qt_win_owndc_required;
     99extern Q_GUI_EXPORT bool qt_win_owndc_required;
    86100#endif
    87101QGLGraphicsSystem::QGLGraphicsSystem()
     
    97111        int spec[16];
    98112        spec[i++] = GLX_RGBA;
    99 #if 0
    100113        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
    110126        spec[i++] = XNone;
    111127
     
    161177    }
    162178#elif defined(Q_WS_WIN)
    163     QGLWindowSurface::surfaceFormat.setDoubleBuffer(false);
     179    QGLWindowSurface::surfaceFormat.setDoubleBuffer(true);
    164180
    165181    qt_win_owndc_required = true;
     
    174190{
    175191public:
    176     QGLGlobalShareWidget() : widget(0) {}
     192    QGLGlobalShareWidget() : widget(0), initializing(false) {}
    177193
    178194    QGLWidget *shareWidget() {
    179         if (!widget && !cleanedUp) {
     195        if (!initializing && !widget && !cleanedUp) {
     196            initializing = true;
    180197            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;
    181202        }
    182203        return widget;
     
    184205
    185206    void cleanup() {
    186         delete widget;
     207        QGLWidget *w = widget;
     208        cleanedUp = true;
    187209        widget = 0;
    188         cleanedUp = true;
     210        delete w;
    189211    }
    190212
     
    193215private:
    194216    QGLWidget *widget;
     217    bool initializing;
    195218};
    196219
     
    215238}
    216239
     240
    217241struct QGLWindowSurfacePrivate
    218242{
     
    224248    int tried_fbo : 1;
    225249    int tried_pb : 1;
     250    int destructive_swap_buffers : 1;
     251    int geometry_updated : 1;
    226252
    227253    QGLContext *ctx;
     
    233259
    234260    QList<QImage> buffers;
     261    QGLWindowSurfaceGLPaintDevice glDevice;
     262    QGLWindowSurface* q_ptr;
    235263};
    236264
    237265QGLFormat QGLWindowSurface::surfaceFormat;
     266
     267void QGLWindowSurfaceGLPaintDevice::endPaint()
     268{
     269    glFlush();
     270    QGLPaintDevice::endPaint();
     271}
     272
     273QSize QGLWindowSurfaceGLPaintDevice::size() const
     274{
     275    return d->size;
     276}
     277
     278QGLContext* QGLWindowSurfaceGLPaintDevice::context() const
     279{
     280    return d->ctx;
     281}
     282
     283
     284int QGLWindowSurfaceGLPaintDevice::metric(PaintDeviceMetric m) const
     285{
     286    return qt_paint_device_metric(d->q_ptr->window(), m);
     287}
     288
     289QPaintEngine *QGLWindowSurfaceGLPaintDevice::paintEngine() const
     290{
     291    return qt_qgl_paint_engine();
     292}
    238293
    239294QGLWindowSurface::QGLWindowSurface(QWidget *window)
     
    245300    d_ptr->fbo = 0;
    246301    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
    247306    d_ptr->tried_fbo = false;
    248307    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;
    249313}
    250314
     
    263327}
    264328
     329void 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
    265351void QGLWindowSurface::hijackWindow(QWidget *widget)
    266352{
     
    272358    QGLContext *ctx = new QGLContext(surfaceFormat, widget);
    273359    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
    277373    widgetPrivate->extraData()->glContext = ctx;
    278374
    279375    union { QGLContext **ctxPtr; void **voidPtr; };
     376
     377    connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*)));
    280378
    281379    voidPtr = &widgetPrivate->extraData()->glContext;
     
    284382}
    285383
    286 #if !defined(QT_OPENGL_ES_2)
    287 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_paintengine)
    288 #endif
    289 
    290 /*! \reimp */
    291 QPaintEngine *QGLWindowSurface::paintEngine() const
    292 {
    293 #if !defined(QT_OPENGL_ES_2)
    294     return qt_gl_window_surface_paintengine();
    295 #else
    296     return 0;
    297 #endif
    298 }
    299 
    300 int QGLWindowSurface::metric(PaintDeviceMetric m) const
    301 {
    302     return window()->metric(m);
    303 }
    304 
    305384QGLContext *QGLWindowSurface::context() const
    306385{
     
    310389QPaintDevice *QGLWindowSurface::paintDevice()
    311390{
     391    updateGeometry();
     392
    312393    if (d_ptr->pb)
    313394        return d_ptr->pb;
    314395
    315396    if (d_ptr->ctx)
    316         return this;
     397        return &d_ptr->glDevice;
    317398
    318399    QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
     
    337418void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
    338419{
     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
    339431    QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
    340432    Q_ASSERT(parent);
    341433
     434    if (!geometry().isValid())
     435        return;
     436
     437    // Needed to support native child-widgets...
    342438    hijackWindow(parent);
    343439
     
    347443    QRect rect = br.translated(-offset - wOffset);
    348444
    349     const GLenum target = qt_gl_preferredTextureTarget();
     445    const GLenum target = GL_TEXTURE_2D;
     446    Q_UNUSED(target);
    350447
    351448    if (context()) {
     
    353450
    354451        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                 QRect 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();
    379476#ifndef QT_OPENGL_ES
    380                 glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999);
     477                    glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999);
    381478#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                    }
    394492                }
    395493            }
     494#endif
    396495            d_ptr->paintedRegion = QRegion();
    397 
    398496            context()->swapBuffers();
    399497        } else {
     
    404502    }
    405503
     504    QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    406505    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;
    408574    if (d_ptr->fbo) {
    409575        texture = d_ptr->fbo->texture();
     
    417583    }
    418584
    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();
    438598#ifndef QT_OPENGL_ES
    439     glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
     599        glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
    440600#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
    447650
    448651    if (ctx->format().doubleBuffer())
     
    450653    else
    451654        glFlush();
    452 
    453     if (d_ptr->fbo)
    454         d_ptr->fbo->bind();
    455 }
     655}
     656
    456657
    457658void QGLWindowSurface::setGeometry(const QRect &rect)
    458659{
    459660    QWindowSurface::setGeometry(rect);
    460 
    461     const GLenum target = qt_gl_preferredTextureTarget();
     661    d_ptr->geometry_updated = true;
     662}
     663
     664
     665void 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;
    462680
    463681    if (rect.width() <= 0 || rect.height() <= 0)
     
    470688
    471689    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
    475697        return;
    476698    }
    477699
    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)) {
    479733        d_ptr->tried_pb = true;
    480734
     
    491745
    492746        if (d_ptr->pb->isValid()) {
    493             qDebug() << "PB Sample buffers:" << d_ptr->pb->format().sampleBuffers();
     747            qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers();
    494748            d_ptr->pb->makeCurrent();
    495749
     
    504758            glMatrixMode(GL_PROJECTION);
    505759            glLoadIdentity();
    506 #ifndef QT_OPENGL_ES
    507760            glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
    508 #else
    509             glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
    510 #endif
    511761
    512762            d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true;
     
    518768        }
    519769    }
    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
    543772    ctx->makeCurrent();
    544773
    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
    552785
    553786    qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;;
     
    579812#endif
    580813
    581     const GLenum target = qt_gl_preferredTextureTarget();
     814    const GLenum target = GL_TEXTURE_2D;
    582815
    583816    glBindTexture(target, d_ptr->tex_id);
     
    592825static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
    593826{
    594     const GLenum target = qt_gl_preferredTextureTarget();
     827    const GLenum target = GL_TEXTURE_2D;
    595828    QRectF src = br.isEmpty()
    596829        ? QRectF(QPointF(), texSize)
     
    620853    qt_add_rect_to_array(rect, vertexArray);
    621854
     855#if !defined(QT_OPENGL_ES_2)
    622856    glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);
    623857    glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);
     
    634868    glDisable(target);
    635869    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
    636884}
    637885
Note: See TracChangeset for help on using the changeset viewer.