QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat) { QSurfaceFormat format; EGLint redSize = 0; EGLint greenSize = 0; EGLint blueSize = 0; EGLint alphaSize = 0; EGLint depthSize = 0; EGLint stencilSize = 0; EGLint sampleCount = 0; EGLint renderableType = 0; eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType); if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT)) format.setRenderableType(QSurfaceFormat::OpenVG); #ifdef EGL_VERSION_1_4 else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL && (renderableType & EGL_OPENGL_BIT)) format.setRenderableType(QSurfaceFormat::OpenGL); else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType #ifndef QT_NO_OPENGL && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL #endif && (renderableType & EGL_OPENGL_BIT)) format.setRenderableType(QSurfaceFormat::OpenGL); #endif else format.setRenderableType(QSurfaceFormat::OpenGLES); format.setRedBufferSize(redSize); format.setGreenBufferSize(greenSize); format.setBlueBufferSize(blueSize); format.setAlphaBufferSize(alphaSize); format.setDepthBufferSize(depthSize); format.setStencilBufferSize(stencilSize); format.setSamples(sampleCount); format.setStereo(false); // EGL doesn't support stereo buffers format.setSwapInterval(referenceFormat.swapInterval()); // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable // to the surface type. Such errors don't matter. eglGetError(); return format; }
void tst_QQuickGraphicsInfo::testProperties() { QQuickView view; view.setSource(QUrl("data/basic.qml")); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QSignalSpy spy(&view, SIGNAL(sceneGraphInitialized())); spy.wait(); QObject* obj = view.rootObject(); QVERIFY(obj); QSGRendererInterface *rif = view.rendererInterface(); const int expectedAPI = rif ? rif->graphicsApi() : QSGRendererInterface::Unknown; QCOMPARE(obj->property("api").toInt(), expectedAPI); #if QT_CONFIG(opengl) if (expectedAPI == QSGRendererInterface::OpenGL) { QCOMPARE(obj->property("shaderType").toInt(), int(QSGRendererInterface::GLSL)); QVERIFY(view.openglContext()); QSurfaceFormat format = view.openglContext()->format(); QCOMPARE(obj->property("majorVersion").toInt(), format.majorVersion()); QCOMPARE(obj->property("minorVersion").toInt(), format.minorVersion()); QCOMPARE(obj->property("profile").toInt(), static_cast<int>(format.profile())); QCOMPARE(obj->property("renderableType").toInt(), static_cast<int>(format.renderableType())); } #endif }
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()))); }
bool QOpenGLFunctions_ES2::isContextCompatible(QOpenGLContext *context) { Q_ASSERT(context); QSurfaceFormat f = context->format(); const QPair<int, int> v = qMakePair(f.majorVersion(), f.minorVersion()); if (v < qMakePair(2, 0)) return false; if (f.renderableType() != QSurfaceFormat::OpenGLES) return false; return true; }
void tst_QQuickOpenGLInfo::testProperties() { QQuickView view; view.setSource(testFileUrl("basic.qml")); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QSignalSpy spy(&view, SIGNAL(sceneGraphInitialized())); spy.wait(); QVERIFY(view.openglContext()); QSurfaceFormat format = view.openglContext()->format(); QObject* obj = view.rootObject(); QVERIFY(obj); QCOMPARE(obj->property("majorVersion").toInt(), format.majorVersion()); QCOMPARE(obj->property("minorVersion").toInt(), format.minorVersion()); QCOMPARE(obj->property("profile").toInt(), static_cast<int>(format.profile())); QCOMPARE(obj->property("renderableType").toInt(), static_cast<int>(format.renderableType())); }
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(); }
void HsQMLCanvasBackEnd::doRendering() { if (!mGL) { mGL = mWindow->openglContext(); QObject::connect( mGL, SIGNAL(aboutToBeDestroyed()), this, SLOT(doCleanup())); HsQMLGLCanvasType ctype; QSurfaceFormat format = mGL->format(); switch (format.renderableType()) { case QSurfaceFormat::OpenGL: ctype = HSQML_GL_DESKTOP; break; case QSurfaceFormat::OpenGLES: ctype = HSQML_GL_ES; break; default: setStatus(HsQMLCanvas::BadConfig); return; } mGLViewportFn = reinterpret_cast<GLViewportFn>( mGL->getProcAddress("glViewport")); mGLClearColorFn = reinterpret_cast<GLClearColorFn>( mGL->getProcAddress("glClearColor")); mGLClearFn = reinterpret_cast<GLClearFn>( mGL->getProcAddress("glClear")); if (!mGLViewportFn || !mGLClearColorFn || !mGLClearFn) { setStatus(HsQMLCanvas::BadProcs); return; } mGLCallbacks->mSetupCb( ctype, format.majorVersion(), format.minorVersion()); } // Reset OpenGL state before rendering #if QT_VERSION >= 0x050200 mWindow->resetOpenGLState(); #else #warning Resetting OpenGL state requires Qt 5.2 or later #endif // Clear window if painting below the scenegraph if (mWinInfo.needsBelowClear()) { QColor bg = mWindow->color(); mGLClearColorFn(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF()); mGLClearFn(GL_COLOR_BUFFER_BIT); } // Setup prior to paint callback QMatrix4x4 matrix; bool inlineMode = HsQMLCanvas::Inline == mDisplayMode; if (inlineMode) { if (!mFBO->bind()) { setStatus(HsQMLCanvas::BadBind); return; } mGLViewportFn(0, 0, qCeil(mCanvasWidth), qCeil(mCanvasHeight)); // Clear FBO to transparent mGLClearColorFn(0, 0, 0, 0); mGLClearFn(GL_COLOR_BUFFER_BIT); } else { // Calculate matrix for non-inline display modes QMatrix4x4 smatrix; QSGNode* node = mTransformNode; while (node) { if (QSGNode::TransformNodeType == node->type()) { QSGTransformNode* tnode = static_cast<QSGTransformNode*>(node); smatrix = tnode->matrix() * smatrix; } node = node->parent(); } matrix.translate(-1, 1); matrix.scale(2.0f/mWindow->width(), -2.0f/mWindow->height()); matrix *= smatrix; matrix.scale(mItemWidth/2.0f, mItemHeight/2.0f); matrix.translate(1, 1); mGLViewportFn(0, 0, mWindow->width(), mWindow->height()); } setStatus(HsQMLCanvas::Okay); mGLCallbacks->mPaintCb(matrix.data(), mItemWidth, mItemHeight); if (inlineMode) { mFBO->release(); } }