Exemple #1
0
QT_BEGIN_NAMESPACE

/*!
    Returns an OpenGL format for the window format specified by \a format.
*/
QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format)
{
    QGLFormat retFormat;
    if (format.alphaBufferSize() >= 0)
        retFormat.setAlphaBufferSize(format.alphaBufferSize());
    if (format.blueBufferSize() >= 0)
        retFormat.setBlueBufferSize(format.blueBufferSize());
    if (format.greenBufferSize() >= 0)
        retFormat.setGreenBufferSize(format.greenBufferSize());
    if (format.redBufferSize() >= 0)
        retFormat.setRedBufferSize(format.redBufferSize());
    if (format.depthBufferSize() >= 0)
        retFormat.setDepthBufferSize(format.depthBufferSize());
    if (format.samples() > 1) {
        retFormat.setSampleBuffers(format.samples());
        retFormat.setSamples(true);
    }
    if (format.stencilBufferSize() > 0) {
        retFormat.setStencil(true);
        retFormat.setStencilBufferSize(format.stencilBufferSize());
    }
    retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer);
    retFormat.setStereo(format.stereo());
    return retFormat;
}
Exemple #2
0
XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format)
{
    Q_ASSERT(format);

    XVisualInfo *visualInfo = 0;

    GLXFBConfig config = qglx_findConfig(display,screen,*format);
    if (config) {
        visualInfo = glXGetVisualFromFBConfig(display, config);
        *format = qglx_surfaceFormatFromGLXFBConfig(display, config);
    }

    // attempt to fall back to glXChooseVisual
    bool reduced = true;
    QSurfaceFormat reducedFormat = *format;
    while (!visualInfo && reduced) {
        QVarLengthArray<int, 13> attribs;
        attribs.append(GLX_RGBA);

        if (reducedFormat.redBufferSize() > 0) {
            attribs.append(GLX_RED_SIZE);
            attribs.append(reducedFormat.redBufferSize());
        }

        if (reducedFormat.greenBufferSize() > 0) {
            attribs.append(GLX_GREEN_SIZE);
            attribs.append(reducedFormat.greenBufferSize());
        }

        if (reducedFormat.blueBufferSize() > 0) {
            attribs.append(GLX_BLUE_SIZE);
            attribs.append(reducedFormat.blueBufferSize());
        }

        if (reducedFormat.stencilBufferSize() > 0) {
            attribs.append(GLX_STENCIL_SIZE);
            attribs.append(reducedFormat.stencilBufferSize());
        }

        if (reducedFormat.depthBufferSize() > 0) {
            attribs.append(GLX_DEPTH_SIZE);
            attribs.append(reducedFormat.depthBufferSize());
        }

        if (reducedFormat.swapBehavior() != QSurfaceFormat::SingleBuffer)
            attribs.append(GLX_DOUBLEBUFFER);

        attribs.append(XNone);

        visualInfo = glXChooseVisual(display, screen, attribs.data());
        if (visualInfo)
            *format = reducedFormat;

        reducedFormat = qglx_reduceSurfaceFormat(reducedFormat, &reduced);
    }

    return visualInfo;
}
Exemple #3
0
QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced)
{
    QSurfaceFormat retFormat = format;
    *reduced = true;

    if (retFormat.redBufferSize() > 1) {
        retFormat.setRedBufferSize(1);
    } else if (retFormat.greenBufferSize() > 1) {
        retFormat.setGreenBufferSize(1);
    } else if (retFormat.blueBufferSize() > 1) {
        retFormat.setBlueBufferSize(1);
    } else if (retFormat.samples() > 1) {
        retFormat.setSamples(qMin(retFormat.samples() / 2, 16));
    } else if (retFormat.stereo()) {
        retFormat.setStereo(false);
    }else if (retFormat.stencilBufferSize() > 0) {
        retFormat.setStencilBufferSize(0);
    }else if (retFormat.hasAlpha()) {
        retFormat.setAlphaBufferSize(0);
    }else if (retFormat.depthBufferSize() > 0) {
        retFormat.setDepthBufferSize(0);
    }else if (retFormat.swapBehavior() != QSurfaceFormat::SingleBuffer) {
        retFormat.setSwapBehavior(QSurfaceFormat::SingleBuffer);
    }else{
        *reduced = false;
    }
    return retFormat;
}
Exemple #4
0
void Widget::printFormat(const QSurfaceFormat &format)
{
    m_output->append(tr("OpenGL version: %1.%2").arg(format.majorVersion()).arg(format.minorVersion()));

    for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
        if (profiles[i].profile == format.profile()) {
            m_output->append(tr("Profile: %1").arg(QString::fromLatin1(profiles[i].str)));
            break;
        }

    QString opts;
    for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
        if (format.testOption(options[i].option))
            opts += QString::fromLatin1(options[i].str) + QLatin1Char(' ');
    m_output->append(tr("Options: %1").arg(opts));

    for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
        if (renderables[i].renderable == format.renderableType()) {
            m_output->append(tr("Renderable type: %1").arg(QString::fromLatin1(renderables[i].str)));
            break;
        }

    m_output->append(tr("Depth buffer size: %1").arg(QString::number(format.depthBufferSize())));
    m_output->append(tr("Stencil buffer size: %1").arg(QString::number(format.stencilBufferSize())));
    m_output->append(tr("Samples: %1").arg(QString::number(format.samples())));
    m_output->append(tr("Red buffer size: %1").arg(QString::number(format.redBufferSize())));
    m_output->append(tr("Green buffer size: %1").arg(QString::number(format.greenBufferSize())));
    m_output->append(tr("Blue buffer size: %1").arg(QString::number(format.blueBufferSize())));
    m_output->append(tr("Alpha buffer size: %1").arg(QString::number(format.alphaBufferSize())));
    m_output->append(tr("Swap interval: %1").arg(QString::number(format.swapInterval())));
}
static QSurface *createSurface(int surfaceClass)
{
    if (surfaceClass == int(QSurface::Window)) {
        QWindow *window = new QWindow;
        window->setSurfaceType(QWindow::OpenGLSurface);
        window->setGeometry(0, 0, 10, 10);
        window->create();
        return window;
    } else if (surfaceClass == int(QSurface::Offscreen)) {
        // Create a window and get the format from that.  For example, if an EGL
        // implementation provides 565 and 888 configs for PBUFFER_BIT but only
        // 888 for WINDOW_BIT, we may end up with a pbuffer surface that is
        // incompatible with the context since it could choose the 565 while the
        // window and the context uses a config with 888.
        static QSurfaceFormat format;
        if (format.redBufferSize() == -1) {
            QWindow *window = new QWindow;
            window->setSurfaceType(QWindow::OpenGLSurface);
            window->setGeometry(0, 0, 10, 10);
            window->create();
            format = window->format();
            delete window;
        }
        QOffscreenSurface *offscreenSurface = new QOffscreenSurface;
        offscreenSurface->setFormat(format);
        offscreenSurface->create();
        return offscreenSurface;
    }
    return 0;
}
Exemple #6
0
size_t evalGLFormatSwapchainPixelSize(const QSurfaceFormat& format) {
    size_t pixelSize = format.redBufferSize() + format.greenBufferSize() + format.blueBufferSize() + format.alphaBufferSize();
    // We don't apply the length of the swap chain into this pixelSize since it is not vsible for the Process (on windows).
    // Let s keep this here remember that:
    // if (format.swapBehavior() > 0) {
    //     pixelSize *= format.swapBehavior(); // multiply the color buffer pixel size by the actual swapchain depth
    // }
    pixelSize += format.stencilBufferSize() + format.depthBufferSize();
    return pixelSize;
}
Exemple #7
0
QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit)
{
    QVector<int> spec(48);
    int i = 0;

    spec[i++] = GLX_LEVEL;
    spec[i++] = 0;
    spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit;

    spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;

    spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
    spec[i++] = GLX_GREEN_SIZE; spec[i++] =  (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
    spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
    if (format.hasAlpha()) {
        spec[i++] = GLX_ALPHA_SIZE; spec[i++] = format.alphaBufferSize();
    }

    spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.swapBehavior() != QSurfaceFormat::SingleBuffer ? True : False;

    spec[i++] = GLX_STEREO; spec[i++] =  format.stereo() ? True : False;

    if (format.depthBufferSize() > 0) {
        spec[i++] = GLX_DEPTH_SIZE; spec[i++] = format.depthBufferSize();
    }

    if (format.stencilBufferSize() > 0) {
        spec[i++] = GLX_STENCIL_SIZE; spec[i++] =  (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
    }

    if (format.samples() > 1) {
        spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
        spec[i++] = 1;
        spec[i++] = GLX_SAMPLES_ARB;
        spec[i++] = format.samples();
    }

    spec[i++] = XNone;
    return spec;
}
Exemple #8
0
void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
{
    Q_D(QSGContext);

    d->mutex.lock();
    if (d->antialiasingMethod == UndecidedAntialiasing) {
        if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) {
            const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD");
            if (aaType == "msaa")
                d->antialiasingMethod = MsaaAntialiasing;
            else if (aaType == "vertex")
                d->antialiasingMethod = VertexAntialiasing;
        }
        if (d->antialiasingMethod == UndecidedAntialiasing) {
            if (renderContext->openglContext()->format().samples() > 0)
                d->antialiasingMethod = MsaaAntialiasing;
            else
                d->antialiasingMethod = VertexAntialiasing;
        }
    }

    // With OpenGL ES, except for Angle on Windows, use GrayAntialiasing, unless
    // some value had been requested explicitly. This could not be decided
    // before without a context. Now the context is ready.
    if (!d->distanceFieldAntialiasingDecided) {
        d->distanceFieldAntialiasingDecided = true;
#ifndef Q_OS_WIN32
        if (renderContext->openglContext()->isOpenGLES())
            d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
#endif
    }

    static bool dumped = false;
    if (!dumped && QSG_LOG_INFO().isDebugEnabled()) {
        dumped = true;
        QSurfaceFormat format = renderContext->openglContext()->format();
        QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
        qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers:   " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
        qCDebug(QSG_LOG_INFO) << "Depth Buffer:      " << format.depthBufferSize();
        qCDebug(QSG_LOG_INFO) << "Stencil Buffer:    " << format.stencilBufferSize();
        qCDebug(QSG_LOG_INFO) << "Samples:           " << format.samples();
        qCDebug(QSG_LOG_INFO) << "GL_VENDOR:         " << (const char *) funcs->glGetString(GL_VENDOR);
        qCDebug(QSG_LOG_INFO) << "GL_RENDERER:       " << (const char *) funcs->glGetString(GL_RENDERER);
        qCDebug(QSG_LOG_INFO) << "GL_VERSION:        " << (const char *) funcs->glGetString(GL_VERSION);
        QSet<QByteArray> exts = renderContext->openglContext()->extensions();
        QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e;
        qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS:    " << all.constData();
        qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << renderContext->maxTextureSize();
        qCDebug(QSG_LOG_INFO) << "Debug context:    " << format.testOption(QSurfaceFormat::DebugContext);
    }
Exemple #9
0
QT_BEGIN_NAMESPACE

QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format)
{
    int redSize     = format.redBufferSize();
    int greenSize   = format.greenBufferSize();
    int blueSize    = format.blueBufferSize();
    int alphaSize   = format.alphaBufferSize();
    int depthSize   = format.depthBufferSize();
    int stencilSize = format.stencilBufferSize();
    int sampleCount = format.samples();

    QVector<EGLint> configAttributes;

    // Map default, unspecified values (-1) to 0. This is important due to sorting rule #3
    // in section 3.4.1 of the spec and allows picking a potentially faster 16-bit config
    // over 32-bit ones when there is no explicit request for the color channel sizes:
    //
    // The red/green/blue sizes have a sort priority of 3, so they are sorted by
    // first. (unless a caveat like SLOW or NON_CONFORMANT is present) The sort order is
    // Special and described as "by larger _total_ number of color bits.". So EGL will put
    // 32-bit configs in the list before the 16-bit configs. However, the spec also goes
    // on to say "If the requested number of bits in attrib_list for a particular
    // component is 0, then the number of bits for that component is not considered". This
    // part of the spec also seems to imply that setting the red/green/blue bits to zero
    // means none of the components are considered and EGL disregards the entire sorting
    // rule. It then looks to the next highest priority rule, which is
    // EGL_BUFFER_SIZE. Despite the selection criteria being "AtLeast" for
    // EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are put in the
    // list before 32-bit configs.
    //
    // This also means that explicitly specifying a size like 565 will still result in
    // having larger (888) configs first in the returned list. We need to handle this
    // ourselves later by manually filtering the list, instead of just blindly taking the
    // first config from it.

    configAttributes.append(EGL_RED_SIZE);
    configAttributes.append(redSize > 0 ? redSize : 0);

    configAttributes.append(EGL_GREEN_SIZE);
    configAttributes.append(greenSize > 0 ? greenSize : 0);

    configAttributes.append(EGL_BLUE_SIZE);
    configAttributes.append(blueSize > 0 ? blueSize : 0);

    configAttributes.append(EGL_ALPHA_SIZE);
    configAttributes.append(alphaSize > 0 ? alphaSize : 0);

    configAttributes.append(EGL_DEPTH_SIZE);
    configAttributes.append(depthSize > 0 ? depthSize : 0);

    configAttributes.append(EGL_STENCIL_SIZE);
    configAttributes.append(stencilSize > 0 ? stencilSize : 0);

    configAttributes.append(EGL_SAMPLES);
    configAttributes.append(sampleCount > 0 ? sampleCount : 0);

    configAttributes.append(EGL_SAMPLE_BUFFERS);
    configAttributes.append(sampleCount > 0);

    return configAttributes;
}
Exemple #10
0
QString VariantHandler::displayString(const QVariant& value)
{
  switch (value.type()) {
#ifndef QT_NO_CURSOR
  case QVariant::Cursor:
  {
    const QCursor cursor = value.value<QCursor>();
    return Util::enumToString(QVariant::fromValue<int>(cursor.shape()), "Qt::CursorShape");
  }
#endif
  case QVariant::Icon:
  {
    const QIcon icon = value.value<QIcon>();
    if (icon.isNull()) {
      return QObject::tr("<no icon>");
    }
    QStringList l;
    foreach (const QSize &size, icon.availableSizes()) {
      l.push_back(displayString(size));
    }
    return l.join(QLatin1String(", "));
  }
  case QVariant::Line:
    return
      QString::fromUtf8("%1 x %2 → %3 x %4").
        arg(value.toLine().x1()).arg(value.toLine().y1()).
        arg(value.toLine().x2()).arg(value.toLine().y2());

  case QVariant::LineF:
    return
      QString::fromUtf8("%1 x %2 → %3 x %4").
        arg(value.toLineF().x1()).arg(value.toLineF().y1()).
        arg(value.toLineF().x2()).arg(value.toLineF().y2());

  case QVariant::Locale:
    return value.value<QLocale>().name();

  case QVariant::Point:
    return
      QString::fromLatin1("%1x%2").
        arg(value.toPoint().x()).
        arg(value.toPoint().y());

  case QVariant::PointF:
    return
      QString::fromLatin1("%1x%2").
        arg(value.toPointF().x()).
        arg(value.toPointF().y());

  case QVariant::Rect:
    return
      QString::fromLatin1("%1x%2 %3x%4").
        arg(value.toRect().x()).
        arg(value.toRect().y()).
        arg(value.toRect().width()).
        arg(value.toRect().height());

  case QVariant::RectF:
    return
      QString::fromLatin1("%1x%2 %3x%4").
        arg(value.toRectF().x()).
        arg(value.toRectF().y()).
        arg(value.toRectF().width()).
        arg(value.toRectF().height());

  case QVariant::Region:
  {
    const QRegion region = value.value<QRegion>();
    if (region.isEmpty()) {
      return QLatin1String("<empty>");
    }
    if (region.rectCount() == 1) {
      return displayString(region.rects().first());
    } else {
      return QString::fromLatin1("<%1 rects>").arg(region.rectCount());
    }
  }

  case QVariant::Palette:
  {
    const QPalette pal = value.value<QPalette>();
    if (pal == qApp->palette()) {
      return QLatin1String("<inherited>");
    }
    return QLatin1String("<custom>");
  }

  case QVariant::Size:
    return
      QString::fromLatin1("%1x%2").
        arg(value.toSize().width()).
        arg(value.toSize().height());

  case QVariant::SizeF:
    return
      QString::fromLatin1("%1x%2").
        arg(value.toSizeF().width()).
        arg(value.toSizeF().height());

  case QVariant::StringList:
    return value.toStringList().join(", ");

  case QVariant::Transform:
  {
    const QTransform t = value.value<QTransform>();
    return
      QString::fromLatin1("[%1 %2 %3, %4 %5 %6, %7 %8 %9]").
        arg(t.m11()).arg(t.m12()).arg(t.m13()).
        arg(t.m21()).arg(t.m22()).arg(t.m23()).
        arg(t.m31()).arg(t.m32()).arg(t.m33());
  }
  default:
    break;
  }

  // types with dynamic type ids
  if (value.type() == (QVariant::Type)qMetaTypeId<QTextLength>()) {
    const QTextLength l = value.value<QTextLength>();
    QString typeStr;
    switch (l.type()) {
    case QTextLength::VariableLength:
      typeStr = QObject::tr("variable");
      break;
    case QTextLength::FixedLength:
      typeStr = QObject::tr("fixed");
      break;
    case QTextLength::PercentageLength:
      typeStr = QObject::tr("percentage");
      break;
    }
    return QString::fromLatin1("%1 (%2)").arg(l.rawValue()).arg(typeStr);
  }

  if (value.userType() == qMetaTypeId<QPainterPath>()) {
    const QPainterPath path = value.value<QPainterPath>();
    if (path.isEmpty()) {
      return QObject::tr("<empty>");
    }
    return QObject::tr("<%1 elements>").arg(path.elementCount());
  }

  if (value.userType() == qMetaTypeId<QMargins>()) {
    const QMargins margins = value.value<QMargins>();
    return QObject::tr("left: %1, top: %2, right: %3, bottom: %4")
       .arg(margins.left()).arg(margins.top())
       .arg(margins.right()).arg(margins.bottom());
  }

  if (value.canConvert<QObject*>()) {
    return Util::displayString(value.value<QObject*>());
  }

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
  if (value.userType() == qMetaTypeId<QSet<QByteArray> >()) {
    const QSet<QByteArray> set = value.value<QSet<QByteArray> >();
    QStringList l;
    foreach (const QByteArray &b, set)
      l.push_back(QString::fromUtf8(b));
    return l.join(", ");
  }

  if (value.userType() == qMetaTypeId<QSurfaceFormat>()) {
    const QSurfaceFormat format = value.value<QSurfaceFormat>();
    QString s;
    switch (format.renderableType()) {
      case QSurfaceFormat::DefaultRenderableType: s += "Default"; break;
      case QSurfaceFormat::OpenGL: s += "OpenGL"; break;
      case QSurfaceFormat::OpenGLES: s += "OpenGL ES"; break;
      case QSurfaceFormat::OpenVG: s += "OpenVG"; break;
    }

    s += " (" + QString::number(format.majorVersion()) + "." + QString::number(format.minorVersion());
    switch (format.profile()) {
      case QSurfaceFormat::CoreProfile: s += " core"; break;
      case QSurfaceFormat::CompatibilityProfile: s += " compat"; break;
      case QSurfaceFormat::NoProfile: break;
    }
    s += ")";

    s += " RGBA: " + QString::number(format.redBufferSize()) + "/" + QString::number(format.greenBufferSize())
      + "/" + QString::number(format.blueBufferSize()) + "/" + QString::number(format.alphaBufferSize());

    s += " Depth: " + QString::number(format.depthBufferSize());
    s += " Stencil: " + QString::number(format.stencilBufferSize());

    s += " Buffer: ";
    switch (format.swapBehavior()) {
      case QSurfaceFormat::DefaultSwapBehavior: s += "default"; break;
      case QSurfaceFormat::SingleBuffer: s += "single"; break;
      case QSurfaceFormat::DoubleBuffer: s += "double"; break;
      case QSurfaceFormat::TripleBuffer: s += "triple"; break;
      default: s += "unknown";
    }

    return s;
  }

  if (value.userType() == qMetaTypeId<QSurface::SurfaceClass>()) {
    const QSurface::SurfaceClass sc = value.value<QSurface::SurfaceClass>();
    switch (sc) {
      case QSurface::Window: return QObject::tr("Window");
#if QT_VERSION > QT_VERSION_CHECK(5, 1, 0)
      case QSurface::Offscreen: return QObject::tr("Offscreen");
#endif
      default: return QObject::tr("Unknown Surface Class");
    }
  }

  if (value.userType() == qMetaTypeId<QSurface::SurfaceType>()) {
    const QSurface::SurfaceType type = value.value<QSurface::SurfaceType>();
    switch (type) {
      case QSurface::RasterSurface: return QObject::tr("Raster");
      case QSurface::OpenGLSurface: return QObject::tr("OpenGL");
      default: return QObject::tr("Unknown Surface Type");
    }
  }

#endif

  // enums
  const QString enumStr = Util::enumToString(value);
  if (!enumStr.isEmpty()) {
    return enumStr;
  }

  // custom converters
  const QHash<int, Converter<QString>*>::const_iterator it = s_variantHandlerRepository()->stringConverters.constFind(value.userType());
  if (it != s_variantHandlerRepository()->stringConverters.constEnd()) {
    return (*it.value())(value);
  }

  return value.toString();
}
// Choose a suitable pixelformat using ARB extension functions.
static int choosePixelFormat(HDC hdc,
                             const QOpenGLStaticContext &staticContext,
                             const QSurfaceFormat &format,
                             const QWindowsOpenGLAdditionalFormat &additional,
                             PIXELFORMATDESCRIPTOR *obtainedPfd)
{
    enum { attribSize =40 };
    if ((additional.formatFlags & QWindowsGLRenderToPixmap) || !staticContext.hasExtensions())
        return 0;

    int iAttributes[attribSize];
    qFill(iAttributes, iAttributes + attribSize, int(0));
    int i = 0;
    iAttributes[i++] = WGL_ACCELERATION_ARB;
    iAttributes[i++] = testFlag(additional.formatFlags, QWindowsGLDirectRendering) ?
                       WGL_FULL_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB;
    iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB;
    iAttributes[i++] = TRUE;
    iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
    iAttributes[i++] = TRUE;
    iAttributes[i++] = WGL_COLOR_BITS_ARB;
    iAttributes[i++] = 24;
    switch (format.swapBehavior()) {
    case QSurfaceFormat::DefaultSwapBehavior:
        break;
    case QSurfaceFormat::SingleBuffer:
        iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
        iAttributes[i++] = FALSE;
        break;
    case QSurfaceFormat::DoubleBuffer:
    case QSurfaceFormat::TripleBuffer:
        iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
        iAttributes[i++] = TRUE;
        break;
    }
    if (format.stereo()) {
        iAttributes[i++] = WGL_STEREO_ARB;
        iAttributes[i++] = TRUE;
    }
    if (format.depthBufferSize() >= 0) {
        iAttributes[i++] = WGL_DEPTH_BITS_ARB;
        iAttributes[i++] = format.depthBufferSize();
    }
    iAttributes[i++] = WGL_PIXEL_TYPE_ARB;
    iAttributes[i++] = WGL_TYPE_RGBA_ARB;
    if (format.redBufferSize() >= 0) {
        iAttributes[i++] = WGL_RED_BITS_ARB;
        iAttributes[i++] = format.redBufferSize();
    }
    if (format.greenBufferSize() >= 0) {
        iAttributes[i++] = WGL_GREEN_BITS_ARB;
        iAttributes[i++] = format.greenBufferSize();
    }
    if (format.blueBufferSize() >= 0) {
        iAttributes[i++] = WGL_BLUE_BITS_ARB;
        iAttributes[i++] = format.blueBufferSize();
    }
    iAttributes[i++] = WGL_ALPHA_BITS_ARB;
    iAttributes[i++] = format.alphaBufferSize() >= 0 ? format.alphaBufferSize() : 8;
    if (additional.formatFlags & QWindowsGLAccumBuffer) {
        iAttributes[i++] = WGL_ACCUM_BITS_ARB;
        iAttributes[i++] = 16;
    }
    iAttributes[i++] = WGL_STENCIL_BITS_ARB;
    iAttributes[i++] = 8;
    if (additional.formatFlags & QWindowsGLOverlay) {
        iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
        iAttributes[i++] = 1;
    }
    const int samples = format.samples();
    const bool sampleBuffersRequested = samples > 1
            && testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
    int samplesValuePosition = 0;
    if (sampleBuffersRequested) {
        iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
        iAttributes[i++] = TRUE;
        iAttributes[i++] = WGL_SAMPLES_ARB;
        samplesValuePosition = i;
        iAttributes[i++] = format.samples();
    } else if (samples == 0 || samples == 1 ) {
        iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
        iAttributes[i++] = FALSE;
    }
    // If sample buffer request cannot be satisfied, reduce request.
    int pixelFormat = 0;
    uint numFormats = 0;
    while (true) {
        const bool valid =
            staticContext.wglChoosePixelFormatARB(hdc, iAttributes, 0, 1,
                                               &pixelFormat, &numFormats)
                && numFormats >= 1;
        if (valid || !sampleBuffersRequested)
            break;
        if (iAttributes[samplesValuePosition] > 1) {
            iAttributes[samplesValuePosition] /= 2;
        } else {
            break;
        }
    }
    // Verify if format is acceptable. Note that the returned
    // formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
    initPixelFormatDescriptor(obtainedPfd);
    DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
    if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
        if (QWindowsContext::verboseGL)
            qDebug() << __FUNCTION__ << " obtained px #" << pixelFormat
                     << " not acceptable=" << *obtainedPfd;
        pixelFormat = 0;
    }

#ifndef QT_NO_DEBUG_OUTPUT
    if (QWindowsContext::verboseGL) {
        QDebug nsp = qDebug().nospace();
        nsp << __FUNCTION__;
        if (sampleBuffersRequested)
            nsp << " samples=" << iAttributes[samplesValuePosition];
        nsp << " Attributes: " << hex << showbase;
        for (int ii = 0; ii < i; ++ii)
            nsp << iAttributes[ii] << ',';
        nsp << noshowbase << dec << "\n    obtained px #" << pixelFormat
            << " of " << numFormats << "\n    " << *obtainedPfd;
    } // Debug
#endif

    return pixelFormat;
}
QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
    : QPlatformOpenGLContext(),
      m_glContext(glContext),
      m_currentEglSurface(EGL_NO_SURFACE)
{
    qGLContextDebug() << Q_FUNC_INFO;
    QSurfaceFormat format = m_glContext->format();

    // Set current rendering API
    EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
    if (eglResult != EGL_TRUE)
        qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());

    // Get colour channel sizes from window format
    int alphaSize = format.alphaBufferSize();
    int redSize = format.redBufferSize();
    int greenSize = format.greenBufferSize();
    int blueSize = format.blueBufferSize();

    // Check if all channels are don't care
    if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) {
        // Set colour channels based on depth of window's screen
        QQnxScreen *screen = static_cast<QQnxScreen*>(glContext->screen()->handle());
        int depth = screen->depth();
        if (depth == 32) {
            // SCREEN_FORMAT_RGBA8888
            alphaSize = 8;
            redSize = 8;
            greenSize = 8;
            blueSize = 8;
        } else {
            // SCREEN_FORMAT_RGB565
            alphaSize = 0;
            redSize = 5;
            greenSize = 6;
            blueSize = 5;
        }
    } else {
        // Choose best match based on supported pixel formats
        if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) {
            // SCREEN_FORMAT_RGB565
            alphaSize = 0;
            redSize = 5;
            greenSize = 6;
            blueSize = 5;
        } else {
            // SCREEN_FORMAT_RGBA8888
            alphaSize = 8;
            redSize = 8;
            greenSize = 8;
            blueSize = 8;
        }
    }

    // Update colour channel sizes in window format
    format.setAlphaBufferSize(alphaSize);
    format.setRedBufferSize(redSize);
    format.setGreenBufferSize(greenSize);
    format.setBlueBufferSize(blueSize);

    // Select EGL config based on requested window format
    m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format);
    if (m_eglConfig == 0)
        qFatal("QQnxGLContext: failed to find EGL config");

    QQnxGLContext *glShareContext = static_cast<QQnxGLContext*>(m_glContext->shareHandle());
    m_eglShareContext = glShareContext ? glShareContext->m_eglContext : EGL_NO_CONTEXT;

    m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, m_eglShareContext,
                                    contextAttrs(format));
    if (m_eglContext == EGL_NO_CONTEXT) {
        checkEGLError("eglCreateContext");
        qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
    }

    // Query/cache window format of selected EGL config
    m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig);
}
Exemple #13
0
    void init()
    {
        LOG_AS("GLInfo");

        if (inited) return;

        if (!initializeOpenGLFunctions())
        {
            throw InitError("GLInfo::init", "Failed to initialize OpenGL");
        }

        // Extensions.
        ext.ARB_draw_instanced             = query("GL_ARB_draw_instanced");
        ext.ARB_instanced_arrays           = query("GL_ARB_instanced_arrays");
        ext.ARB_texture_env_combine        = query("GL_ARB_texture_env_combine") || query("GL_EXT_texture_env_combine");
        ext.ARB_texture_non_power_of_two   = query("GL_ARB_texture_non_power_of_two");

        ext.EXT_blend_subtract             = query("GL_EXT_blend_subtract");
        ext.EXT_framebuffer_blit           = query("GL_EXT_framebuffer_blit");
        ext.EXT_framebuffer_multisample    = query("GL_EXT_framebuffer_multisample");
        ext.EXT_framebuffer_object         = query("GL_EXT_framebuffer_object");
        ext.EXT_packed_depth_stencil       = query("GL_EXT_packed_depth_stencil");
        ext.EXT_texture_compression_s3tc   = query("GL_EXT_texture_compression_s3tc");
        ext.EXT_texture_filter_anisotropic = query("GL_EXT_texture_filter_anisotropic");
        ext.EXT_timer_query                = query("GL_EXT_timer_query");

        ext.ATI_texture_env_combine3       = query("GL_ATI_texture_env_combine3");
        ext.NV_framebuffer_multisample_coverage
                                           = query("GL_NV_framebuffer_multisample_coverage");
        ext.NV_texture_env_combine4        = query("GL_NV_texture_env_combine4");
        ext.SGIS_generate_mipmap           = query("GL_SGIS_generate_mipmap");

#ifdef WIN32
        ext.Windows_ARB_multisample        = query("WGL_ARB_multisample");
        ext.Windows_EXT_swap_control       = query("WGL_EXT_swap_control");

        if (ext.Windows_EXT_swap_control)
        {
            wglSwapIntervalEXT = de::function_cast<decltype(wglSwapIntervalEXT)>
                (QOpenGLContext::currentContext()->getProcAddress("wglSwapIntervalEXT"));
        }
#endif

#ifdef DENG_X11
        ext.X11_EXT_swap_control           = query("GLX_EXT_swap_control");
        ext.X11_SGI_swap_control           = query("GLX_SGI_swap_control");
        ext.X11_MESA_swap_control          = query("GLX_MESA_swap_control");

        if (ext.X11_EXT_swap_control)
        {
            glXSwapIntervalEXT = de::function_cast<decltype(glXSwapIntervalEXT)>
                    (glXGetProcAddress(reinterpret_cast<GLubyte const *>("glXSwapIntervalEXT")));
        }
        if (ext.X11_SGI_swap_control)
        {
            glXSwapIntervalSGI = de::function_cast<decltype(glXSwapIntervalSGI)>
                    (glXGetProcAddress(reinterpret_cast<GLubyte const *>("glXSwapIntervalSGI")));
        }
        if (ext.X11_MESA_swap_control)
        {
            glXSwapIntervalMESA = de::function_cast<decltype(glXSwapIntervalMESA)>
                    (glXGetProcAddress(reinterpret_cast<GLubyte const *>("glXSwapIntervalMESA")));
        }
#endif

        if (ext.ARB_draw_instanced)
        {
            ARB_draw_instanced.reset(new QOpenGLExtension_ARB_draw_instanced);
            ARB_draw_instanced->initializeOpenGLFunctions();
        }
        if (ext.ARB_instanced_arrays)
        {
            ARB_instanced_arrays.reset(new QOpenGLExtension_ARB_instanced_arrays);
            ARB_instanced_arrays->initializeOpenGLFunctions();
        }
        if (ext.EXT_framebuffer_blit)
        {
            EXT_framebuffer_blit.reset(new QOpenGLExtension_EXT_framebuffer_blit);
            EXT_framebuffer_blit->initializeOpenGLFunctions();
        }
        if (ext.EXT_framebuffer_multisample)
        {
            EXT_framebuffer_multisample.reset(new QOpenGLExtension_EXT_framebuffer_multisample);
            EXT_framebuffer_multisample->initializeOpenGLFunctions();
        }
        if (ext.EXT_framebuffer_object)
        {
            EXT_framebuffer_object.reset(new QOpenGLExtension_EXT_framebuffer_object);
            EXT_framebuffer_object->initializeOpenGLFunctions();
        }
        if (ext.NV_framebuffer_multisample_coverage)
        {
            NV_framebuffer_multisample_coverage.reset(new QOpenGLExtension_NV_framebuffer_multisample_coverage);
            NV_framebuffer_multisample_coverage->initializeOpenGLFunctions();
        }

        // Limits.
        glGetIntegerv(GL_MAX_TEXTURE_SIZE,  (GLint *) &lim.maxTexSize);
        glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint *) &lim.maxTexUnits);

        if (ext.EXT_texture_filter_anisotropic)
        {
            glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint *) &lim.maxTexFilterAniso);
        }

        // Set a custom maximum size?
        if (CommandLine_CheckWith("-maxtex", 1))
        {
            lim.maxTexSize = min(ceilPow2(String(CommandLine_Next()).toInt()),
                                 lim.maxTexSize);

            LOG_GL_NOTE("Using requested maximum texture size of %i x %i") << lim.maxTexSize << lim.maxTexSize;
        }

        // Check default OpenGL format attributes.
        QOpenGLContext const *ctx = QOpenGLContext::currentContext();
        QSurfaceFormat form = ctx->format();

        LOGDEV_GL_MSG("Initial OpenGL format:");
        LOGDEV_GL_MSG(" - version: %i.%i") << form.majorVersion() << form.minorVersion();
        LOGDEV_GL_MSG(" - profile: %s") << (form.profile() == QSurfaceFormat::CompatibilityProfile? "Compatibility" : "Core");
        LOGDEV_GL_MSG(" - color: R%i G%i B%i A%i bits") << form.redBufferSize() << form.greenBufferSize() << form.blueBufferSize() << form.alphaBufferSize();
        LOGDEV_GL_MSG(" - depth: %i bits") << form.depthBufferSize();
        LOGDEV_GL_MSG(" - stencil: %i bits") << form.stencilBufferSize();
        LOGDEV_GL_MSG(" - samples: %i") << form.samples();
        LOGDEV_GL_MSG(" - swap behavior: %i") << form.swapBehavior();

        inited = true;
    }