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; }
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; }
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; }
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()))); }
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; }
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; }
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); }
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; }
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); }
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; }