Merge branch 'wip/scenegraphng' into dev

Change-Id: If8577edb361748535159375c68238845220921a8
This commit is contained in:
Laszlo Agocs 2016-06-10 21:12:28 +02:00
commit 0c5a9ff987
26 changed files with 327 additions and 112 deletions

View File

@ -16,7 +16,6 @@ SUBDIRS = quick-accessibility \
scenegraph \
shadereffects \
text \
textureprovider \
threading \
touchinteraction \
tutorials \
@ -29,7 +28,9 @@ SUBDIRS = quick-accessibility \
#OpenGL Support Required
contains(QT_CONFIG, opengl(es1|es2)?) {
SUBDIRS += rendercontrol
SUBDIRS += \
textureprovider \
rendercontrol
}
# Widget dependent examples

View File

@ -83,7 +83,7 @@ void D3D12RenderNode::init()
D3D12_ROOT_PARAMETER rootParameter;
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
rootParameter.Descriptor.ShaderRegister = 0; // b0
rootParameter.Descriptor.RegisterSpace = 0;
@ -123,11 +123,19 @@ void D3D12RenderNode::init()
rastDesc.CullMode = D3D12_CULL_MODE_BACK;
rastDesc.FrontCounterClockwise = TRUE; // Vertices are given CCW
// No blending, just enable color write.
D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = {};
defaultRenderTargetBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
// Enable color write and blending (premultiplied alpha). The latter is
// needed because the example changes the item's opacity and we pass
// inheritedOpacity() into the pixel shader. If that wasn't the case,
// blending could have stayed disabled.
const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = {
TRUE, FALSE,
D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL
};
D3D12_BLEND_DESC blendDesc = {};
blendDesc.RenderTarget[0] = defaultRenderTargetBlendDesc;
blendDesc.RenderTarget[0] = premulBlendDesc;
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
@ -177,7 +185,7 @@ void D3D12RenderNode::init()
}
vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress();
vertexBufferView.StrideInBytes = (2 + 3) * sizeof(float);
vertexBufferView.StrideInBytes = vertexBufferSize / 3;
vertexBufferView.SizeInBytes = vertexBufferSize;
bufDesc.Width = 256;
@ -198,6 +206,14 @@ void D3D12RenderNode::init()
qWarning("Map failed (constant buffer)");
return;
}
float *vp = reinterpret_cast<float *>(vbPtr);
vp += 2;
*vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f;
vp += 2;
*vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f;
vp += 2;
*vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f;
}
void D3D12RenderNode::render(const RenderState *state)
@ -212,6 +228,8 @@ void D3D12RenderNode::render(const RenderState *state)
const int msize = 16 * sizeof(float);
memcpy(cbPtr, matrix()->constData(), msize);
memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize);
const float opacity = inheritedOpacity();
memcpy(cbPtr + 2 * msize, &opacity, sizeof(float));
const QPointF p0(m_item->width() - 1, m_item->height() - 1);
const QPointF p1(0, 0);
@ -220,15 +238,12 @@ void D3D12RenderNode::render(const RenderState *state)
float *vp = reinterpret_cast<float *>(vbPtr);
*vp++ = p0.x();
*vp++ = p0.y();
*vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f;
vp += 3;
*vp++ = p1.x();
*vp++ = p1.y();
*vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f;
vp += 3;
*vp++ = p2.x();
*vp++ = p2.y();
*vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f;
commandList->SetPipelineState(pipelineState.Get());
commandList->SetGraphicsRootSignature(rootSignature.Get());
@ -237,8 +252,9 @@ void D3D12RenderNode::render(const RenderState *state)
commandList->IASetVertexBuffers(0, 1, &vertexBufferView);
commandList->DrawInstanced(3, 1, 0, 0);
// we won't implement changedStates() since no viewport/scissor/stencil/blend related commands were added
}
// No need to reimplement changedStates() because no relevant commands are
// added to the command list in render().
#endif // HAS_D3D12

View File

@ -71,9 +71,9 @@ Item {
NumberAnimation { target: rotation; property: "angle"; to: 80; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: rotation; property: "angle"; to: -80; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: rotation; property: "angle"; to: 0; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: renderer; property: "opacity"; to: 0.5; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: renderer; property: "opacity"; to: 0.1; duration: 1000; easing.type: Easing.InOutCubic }
PauseAnimation { duration: 1000 }
NumberAnimation { target: renderer; property: "opacity"; to: 0.8; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: renderer; property: "opacity"; to: 1.0; duration: 1000; easing.type: Easing.InOutCubic }
ParallelAnimation {
NumberAnimation { target: scale; property: "xScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack }
NumberAnimation { target: scale; property: "yScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack }

View File

@ -57,9 +57,6 @@ OpenGLRenderNode::~OpenGLRenderNode()
releaseResources();
}
// No need to reimplement changedStates() since our rendering is so simple,
// without involving any state changes.
void OpenGLRenderNode::releaseResources()
{
delete m_program;
@ -84,8 +81,9 @@ void OpenGLRenderNode::init()
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"uniform lowp float opacity;\n"
"void main() {\n"
" gl_FragColor = col;\n"
" gl_FragColor = col * opacity;\n"
"}\n";
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
@ -95,6 +93,7 @@ void OpenGLRenderNode::init()
m_program->link();
m_matrixUniform = m_program->uniformLocation("matrix");
m_opacityUniform = m_program->uniformLocation("opacity");
const int VERTEX_SIZE = 6 * sizeof(GLfloat);
@ -123,6 +122,7 @@ void OpenGLRenderNode::render(const RenderState *state)
m_program->bind();
m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix());
m_program->setUniformValue(m_opacityUniform, float(inheritedOpacity()));
m_vbo->bind();
@ -140,7 +140,15 @@ void OpenGLRenderNode::render(const RenderState *state)
m_program->enableAttributeArray(0);
m_program->enableAttributeArray(1);
f->glEnable(GL_BLEND);
f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
f->glDrawArrays(GL_TRIANGLES, 0, 3);
}
QSGRenderNode::StateFlags OpenGLRenderNode::changedStates() const
{
return BlendState;
}
#endif // QT_NO_OPENGL

View File

@ -57,6 +57,7 @@ public:
void render(const RenderState *state) override;
void releaseResources() override;
StateFlags changedStates() const override;
private:
void init();
@ -64,6 +65,7 @@ private:
QQuickItem *m_item;
QOpenGLShaderProgram *m_program = nullptr;
int m_matrixUniform;
int m_opacityUniform;
QOpenGLBuffer *m_vbo = nullptr;
};

View File

@ -2,15 +2,16 @@ cbuffer ConstantBuffer : register(b0)
{
float4x4 modelview;
float4x4 projection;
float opacity;
};
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
float3 color : COLOR;
};
PSInput VS_Simple(float4 position : POSITION, float4 color : COLOR)
PSInput VS_Simple(float4 position : POSITION, float3 color : COLOR)
{
PSInput result;
@ -23,5 +24,5 @@ PSInput VS_Simple(float4 position : POSITION, float4 color : COLOR)
float4 PS_Simple(PSInput input) : SV_TARGET
{
return input.color;
return float4(input.color, 1.0) * opacity;
}

View File

@ -45,6 +45,8 @@
#include "vs_vertexcolor.hlslh"
#include "ps_vertexcolor.hlslh"
#include "vs_flatcolor.hlslh"
#include "ps_flatcolor.hlslh"
#include "vs_smoothcolor.hlslh"
#include "ps_smoothcolor.hlslh"
#include "vs_texture.hlslh"
@ -66,6 +68,31 @@ QT_BEGIN_NAMESPACE
// importantly, it is packed so that it does not cross a 16-byte (float4)
// boundary. Hence the need for padding in some cases.
static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity)
{
const float o = c.w() * globalOpacity;
return QVector4D(c.x() * o, c.y() * o, c.z() * o, o);
}
static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity)
{
const float o = c.alphaF() * globalOpacity;
return QVector4D(c.redF() * o, c.greenF() * o, c.blueF() * o, o);
}
static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b)
{
if (a.x() != b.x())
return a.x() > b.x() ? 1 : -1;
if (a.y() != b.y())
return a.y() > b.y() ? 1 : -1;
if (a.z() != b.z())
return a.z() > b.z() ? 1 : -1;
if (a.w() != b.w())
return a.w() > b.w() ? 1 : -1;
return 0;
}
QSGMaterialType QSGD3D12VertexColorMaterial::mtype;
QSGMaterialType *QSGD3D12VertexColorMaterial::type() const
@ -121,6 +148,67 @@ QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(cons
return r;
}
QSGMaterialType QSGD3D12FlatColorMaterial::mtype;
QSGMaterialType *QSGD3D12FlatColorMaterial::type() const
{
return &QSGD3D12FlatColorMaterial::mtype;
}
int QSGD3D12FlatColorMaterial::compare(const QSGMaterial *other) const
{
Q_ASSERT(other && type() == other->type());
const QSGD3D12FlatColorMaterial *o = static_cast<const QSGD3D12FlatColorMaterial *>(other);
return m_color.rgba() - o->color().rgba();
}
static const int FLAT_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
static const int FLAT_COLOR_CB_SIZE_1 = 4 * sizeof(float); // float4
static const int FLAT_COLOR_CB_SIZE = FLAT_COLOR_CB_SIZE_0 + FLAT_COLOR_CB_SIZE_1;
int QSGD3D12FlatColorMaterial::constantBufferSize() const
{
return QSGD3D12Engine::alignedConstantBufferSize(FLAT_COLOR_CB_SIZE);
}
void QSGD3D12FlatColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
{
pipelineState->shaders.vs = g_VS_FlatColor;
pipelineState->shaders.vsSize = sizeof(g_VS_FlatColor);
pipelineState->shaders.ps = g_PS_FlatColor;
pipelineState->shaders.psSize = sizeof(g_PS_FlatColor);
}
QSGD3D12Material::UpdateResults QSGD3D12FlatColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
QSGD3D12PipelineState *,
ExtraState *,
quint8 *constantBuffer)
{
QSGD3D12Material::UpdateResults r = 0;
quint8 *p = constantBuffer;
if (state.isMatrixDirty()) {
memcpy(p, state.combinedMatrix().constData(), FLAT_COLOR_CB_SIZE_0);
r |= UpdatedConstantBuffer;
}
p += FLAT_COLOR_CB_SIZE_0;
const QVector4D color = qsg_premultiply(m_color, state.opacity());
const float f[] = { color.x(), color.y(), color.z(), color.w() };
if (state.isOpacityDirty() || memcmp(p, f, FLAT_COLOR_CB_SIZE_1)) {
memcpy(p, f, FLAT_COLOR_CB_SIZE_1);
r |= UpdatedConstantBuffer;
}
return r;
}
void QSGD3D12FlatColorMaterial::setColor(const QColor &color)
{
m_color = color;
setFlag(Blending, m_color.alpha() != 0xFF);
}
QSGD3D12SmoothColorMaterial::QSGD3D12SmoothColorMaterial()
{
setFlag(RequiresFullMatrixExceptTranslate, true);
@ -356,25 +444,6 @@ QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(co
return r;
}
static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity)
{
float o = c.w() * globalOpacity;
return QVector4D(c.x() * o, c.y() * o, c.z() * o, o);
}
static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b)
{
if (a.x() != b.x())
return a.x() > b.x() ? 1 : -1;
if (a.y() != b.y())
return a.y() > b.y() ? 1 : -1;
if (a.z() != b.z())
return a.z() > b.z() ? 1 : -1;
if (a.w() != b.w())
return a.w() > b.w() ? 1 : -1;
return 0;
}
QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc,
const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
: m_styleType(styleType),
@ -503,56 +572,60 @@ QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const QSGD3
}
p += TEXT_CB_SIZE_0;
if (state.isCachedMaterialDataDirty() || m_lastGlyphCacheSize != glyphCache()->currentSize()) {
m_lastGlyphCacheSize = glyphCache()->currentSize();
const float textureScale[2] = { 1.0f / m_lastGlyphCacheSize.width(),
1.0f / m_lastGlyphCacheSize.height() };
const QSize sz = glyphCache()->currentSize();
const float textureScale[] = { 1.0f / sz.width(), 1.0f / sz.height() };
if (state.isCachedMaterialDataDirty() || memcmp(p, textureScale, TEXT_CB_SIZE_1)) {
memcpy(p, textureScale, TEXT_CB_SIZE_1);
r |= UpdatedConstantBuffer;
}
p += TEXT_CB_SIZE_1;
const float dpr = m_rc->engine()->windowDevicePixelRatio();
if (state.isCachedMaterialDataDirty() || m_lastDpr != dpr) {
m_lastDpr = dpr;
if (state.isCachedMaterialDataDirty() || memcmp(p, &dpr, TEXT_CB_SIZE_2)) {
memcpy(p, &dpr, TEXT_CB_SIZE_2);
r |= UpdatedConstantBuffer;
}
p += TEXT_CB_SIZE_2;
if (state.isOpacityDirty() || m_lastColor != m_color) {
m_lastColor = m_color;
if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
const QVector4D color = qsg_premultiply(m_color, state.opacity());
const float alpha = color.w();
if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
const QVector4D color = qsg_premultiply(m_color, state.opacity());
const float alpha = color.w();
if (state.isOpacityDirty() || memcmp(p, &alpha, TEXT_CB_SIZE_3)) {
memcpy(p, &alpha, TEXT_CB_SIZE_3);
} else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) {
const float opacity = m_color.w() * state.opacity();
memcpy(p, &opacity, TEXT_CB_SIZE_3);
} else {
const QVector4D color = qsg_premultiply(m_color, state.opacity());
const float f[4] = { color.x(), color.y(), color.z(), color.w() };
memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4);
r |= UpdatedConstantBuffer;
}
} else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) {
const float opacity = m_color.w() * state.opacity();
if (state.isOpacityDirty() || memcmp(p, &opacity, TEXT_CB_SIZE_3)) {
memcpy(p, &opacity, TEXT_CB_SIZE_3);
r |= UpdatedConstantBuffer;
}
} else {
const QVector4D color = qsg_premultiply(m_color, state.opacity());
const float f[] = { color.x(), color.y(), color.z(), color.w() };
if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_4)) {
memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4);
r |= UpdatedConstantBuffer;
}
r |= UpdatedConstantBuffer;
}
p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4;
if (m_styleType == Styled && (state.isCachedMaterialDataDirty() || m_lastStyleShift != m_styleShift)) {
m_lastStyleShift = m_styleShift;
const float f[2] = { m_styleShift.x(), m_styleShift.y() };
memcpy(p, f, TEXT_CB_SIZE_5);
r |= UpdatedConstantBuffer;
if (m_styleType == Styled) {
const float f[] = { m_styleShift.x(), m_styleShift.y() };
if (state.isCachedMaterialDataDirty() || memcmp(p, f, TEXT_CB_SIZE_5)) {
memcpy(p, f, TEXT_CB_SIZE_5);
r |= UpdatedConstantBuffer;
}
}
p += TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING;
if ((m_styleType == Styled || m_styleType == Outlined)
&& (state.isOpacityDirty() || m_lastStyleColor != m_styleColor)) {
m_lastStyleColor = m_styleColor;
if (m_styleType == Styled || m_styleType == Outlined) {
const QVector4D color = qsg_premultiply(m_styleColor, state.opacity());
const float f[4] = { color.x(), color.y(), color.z(), color.w() };
memcpy(p, f, TEXT_CB_SIZE_6);
r |= UpdatedConstantBuffer;
const float f[] = { color.x(), color.y(), color.z(), color.w() };
if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_6)) {
memcpy(p, f, TEXT_CB_SIZE_6);
r |= UpdatedConstantBuffer;
}
}
QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);

View File

@ -77,6 +77,27 @@ private:
static QSGMaterialType mtype;
};
class QSGD3D12FlatColorMaterial : public QSGD3D12Material
{
public:
QSGMaterialType *type() const override;
int compare(const QSGMaterial *other) const override;
int constantBufferSize() const override;
void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
QSGD3D12PipelineState *pipelineState,
ExtraState *extraState,
quint8 *constantBuffer) override;
void setColor(const QColor &color);
QColor color() const { return m_color; }
private:
static QSGMaterialType mtype;
QColor m_color;
};
class QSGD3D12SmoothColorMaterial : public QSGD3D12Material
{
public:
@ -224,11 +245,6 @@ private:
QVector4D m_styleColor;
QRawFont m_font;
QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache;
QSize m_lastGlyphCacheSize;
float m_lastDpr = 0;
QVector4D m_lastColor;
QVector2D m_lastStyleShift;
QVector4D m_lastStyleColor;
};
QT_END_NAMESPACE

View File

@ -0,0 +1,27 @@
struct VSInput
{
float4 position : POSITION;
};
cbuffer ConstantBuffer : register(b0)
{
float4x4 mvp;
float4 color;
};
struct PSInput
{
float4 position : SV_POSITION;
};
PSInput VS_FlatColor(VSInput input)
{
PSInput result;
result.position = mul(mvp, input.position);
return result;
}
float4 PS_FlatColor(PSInput input) : SV_TARGET
{
return color;
}

View File

@ -8,6 +8,16 @@ vertexcolor_pshader.header = ps_vertexcolor.hlslh
vertexcolor_pshader.entry = PS_VertexColor
vertexcolor_pshader.type = ps_5_0
flatcolor_VSPS = $$PWD/flatcolor.hlsl
flatcolor_vshader.input = flatcolor_VSPS
flatcolor_vshader.header = vs_flatcolor.hlslh
flatcolor_vshader.entry = VS_FlatColor
flatcolor_vshader.type = vs_5_0
flatcolor_pshader.input = flatcolor_VSPS
flatcolor_pshader.header = ps_flatcolor.hlslh
flatcolor_pshader.entry = PS_FlatColor
flatcolor_pshader.type = ps_5_0
stencilclip_VSPS = $$PWD/stencilclip.hlsl
stencilclip_vshader.input = stencilclip_VSPS
stencilclip_vshader.header = vs_stencilclip.hlslh
@ -106,6 +116,7 @@ tdr_cshader.type = cs_5_0
HLSL_SHADERS = \
vertexcolor_vshader vertexcolor_pshader \
flatcolor_vshader flatcolor_pshader \
stencilclip_vshader stencilclip_pshader \
smoothcolor_vshader smoothcolor_pshader \
texture_vshader texture_pshader \

View File

@ -70,7 +70,7 @@ QQuickGraphicsInfo::QQuickGraphicsInfo(QQuickItem *item)
, m_shaderSourceType(ShaderSourceType(0))
, m_majorVersion(2)
, m_minorVersion(0)
, m_profile(NoProfile)
, m_profile(OpenGLNoProfile)
, m_renderableType(SurfaceFormatUnspecified)
{
connect(item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(setWindow(QQuickWindow*)));
@ -211,9 +211,9 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
The possible values are:
\list
\li GraphicsInfo.NoProfile (default) - OpenGL version is lower than 3.2 or OpenGL is not in use.
\li GraphicsInfo.CoreProfile - Functionality deprecated in OpenGL version 3.0 is not available.
\li GraphicsInfo.CompatibilityProfile - Functionality from earlier OpenGL versions is available.
\li GraphicsInfo.OpenGLNoProfile (default) - OpenGL version is lower than 3.2 or OpenGL is not in use.
\li GraphicsInfo.OpenGLCoreProfile - Functionality deprecated in OpenGL version 3.0 is not available.
\li GraphicsInfo.OpenGLCompatibilityProfile - Functionality from earlier OpenGL versions is available.
\endlist
Reusable QML components will typically use this property in bindings in order to
@ -275,7 +275,7 @@ void QQuickGraphicsInfo::updateInfo()
m_minorVersion = format.minorVersion();
emit minorVersionChanged();
}
ContextProfile profile = static_cast<ContextProfile>(format.profile());
OpenGLContextProfile profile = static_cast<OpenGLContextProfile>(format.profile());
if (m_profile != profile) {
m_profile = profile;
emit profileChanged();

View File

@ -72,7 +72,7 @@ class QQuickGraphicsInfo : public QObject
Q_PROPERTY(int majorVersion READ majorVersion NOTIFY majorVersionChanged FINAL)
Q_PROPERTY(int minorVersion READ minorVersion NOTIFY minorVersionChanged FINAL)
Q_PROPERTY(ContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(OpenGLContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
public:
@ -104,12 +104,12 @@ public:
};
Q_ENUM(ShaderSourceType)
enum ContextProfile {
NoProfile = QSurfaceFormat::NoProfile,
CoreProfile = QSurfaceFormat::CoreProfile,
CompatibilityProfile = QSurfaceFormat::CompatibilityProfile
enum OpenGLContextProfile {
OpenGLNoProfile = QSurfaceFormat::NoProfile,
OpenGLCoreProfile = QSurfaceFormat::CoreProfile,
OpenGLCompatibilityProfile = QSurfaceFormat::CompatibilityProfile
};
Q_ENUM(ContextProfile)
Q_ENUM(OpenGLContextProfile)
enum RenderableType {
SurfaceFormatUnspecified = QSurfaceFormat::DefaultRenderableType,
@ -129,7 +129,7 @@ public:
int majorVersion() const { return m_majorVersion; }
int minorVersion() const { return m_minorVersion; }
ContextProfile profile() const { return m_profile; }
OpenGLContextProfile profile() const { return m_profile; }
RenderableType renderableType() const { return m_renderableType; }
Q_SIGNALS:
@ -155,7 +155,7 @@ private:
ShaderSourceType m_shaderSourceType;
int m_majorVersion;
int m_minorVersion;
ContextProfile m_profile;
OpenGLContextProfile m_profile;
RenderableType m_renderableType;
};

View File

@ -93,19 +93,12 @@ public:
Repeat
};
Q_ENUM(WrapMode)
#ifndef QT_NO_OPENGL
enum Format {
Alpha = GL_ALPHA,
RGB = GL_RGB,
RGBA = GL_RGBA
};
#else
// Equivalents to GL_ALPHA and similar type constants.
enum Format {
Alpha = 0x1906,
RGB,
RGBA
RGB = 0x1907,
RGBA = 0x1908
};
#endif
Q_ENUM(Format)
enum TextureMirroring {

View File

@ -153,8 +153,7 @@ void QSGSoftwareRenderContext::invalidate()
QSGTexture *QSGSoftwareRenderContext::createTexture(const QImage &image, uint flags) const
{
Q_UNUSED(flags)
return new QSGSoftwarePixmapTexture(image);
return new QSGSoftwarePixmapTexture(image, flags);
}
QSGRenderer *QSGSoftwareRenderContext::createRenderer()

View File

@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
class QSGSoftwareNinePatchNode : public QSGNinePatchNode
{
public:
public:
QSGSoftwareNinePatchNode();
void setTexture(QSGTexture *texture) override;

View File

@ -41,11 +41,17 @@
QT_BEGIN_NAMESPACE
QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image)
QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image, uint flags)
{
// Prevent pixmap format conversion to reduce memory consumption
// and surprises in calling code. (See QTBUG-47328)
: m_pixmap(QPixmap::fromImage(image, Qt::NoFormatConversion))
{
if (flags & QSGRenderContext::CreateTexture_Alpha) {
//If texture should have an alpha
m_pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion);
} else {
//Force opaque texture
m_pixmap = QPixmap::fromImage(image.convertToFormat(QImage::Format_RGB32), Qt::NoFormatConversion);
}
}
QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QPixmap &pixmap)

View File

@ -59,7 +59,7 @@ class QSGSoftwarePixmapTexture : public QSGTexture
{
Q_OBJECT
public:
QSGSoftwarePixmapTexture(const QImage &image);
QSGSoftwarePixmapTexture(const QImage &image, uint flags);
QSGSoftwarePixmapTexture(const QPixmap &pixmap);
int textureId() const override;

View File

@ -229,6 +229,7 @@ QImage QSGSoftwareRenderLoop::grab(QQuickWindow *window)
renderWindow(window);
QImage grabbed = grabContent;
grabbed.detach();
grabContent = QImage();
return grabbed;
}

View File

@ -125,6 +125,9 @@ void FlatColorMaterialShader::initialize()
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
\warning This utility class is only functional when running with the OpenGL
backend of the Qt Quick scenegraph.
The flat color material will fill every pixel in a geometry using
a solid color. The color can contain transparency.

View File

@ -41,11 +41,14 @@
\class QSGSimpleMaterialShader
\brief The QSGSimpleMaterialShader class provides a convenient way of
building custom materials for the scene graph.
building custom OpenGL-based materials for the scene graph.
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
\warning This utility class is only functional when running with the OpenGL
backend of the Qt Quick scenegraph.
Where the QSGMaterial and QSGMaterialShader API requires a bit of
boilerplate code to create a functioning material, the
QSGSimpleMaterialShader tries to hide some of this through the use

View File

@ -127,6 +127,9 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
\warning This utility class is only functional when running with the OpenGL
backend of the Qt Quick scenegraph.
The opaque textured material will fill every pixel in a geometry with
the supplied texture. The material does not respect the opacity of the
QSGMaterialShader::RenderState, so opacity nodes in the parent chain
@ -321,6 +324,9 @@ int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
\warning This utility class is only functional when running with the OpenGL
backend of the Qt Quick scenegraph.
The textured material will fill every pixel in a geometry with
the supplied texture.

View File

@ -107,6 +107,9 @@ void QSGVertexColorMaterialShader::initialize()
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
\warning This utility class is only functional when running with the OpenGL
backend of the Qt Quick scenegraph.
The vertex color material will give each vertex in a geometry a color. Pixels between
vertices will be linearly interpolated. The colors can contain transparency.

View File

@ -179,7 +179,11 @@ void tst_qquickanimatedimage::mirror_running()
QImage frame0_expected = frame0.transformed(transform);
QImage frame1_expected = frame1.transformed(transform);
if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
QSKIP("QTBUG-53823");
QCOMPARE(frame0_flipped, frame0_expected);
if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
QSKIP("QTBUG-53823");
QCOMPARE(frame1_flipped, frame1_expected);
delete anim;
@ -212,6 +216,8 @@ void tst_qquickanimatedimage::mirror_notRunning()
screenshot = window.grabWindow();
screenshot.save("screen.png");
if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
QSKIP("QTBUG-53823");
QCOMPARE(screenshot, expected);
// mirroring should not change the current frame or playing status

View File

@ -246,6 +246,11 @@ void tst_qquickborderimage::mirror()
image->setProperty("mirror", true);
screenshot = window->grabWindow();
window->show();
QTest::qWaitForWindowExposed(window);
if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software)
QSKIP("QTBUG-53823");
QCOMPARE(screenshot, srcPixmap);
delete window;

View File

@ -30,6 +30,7 @@
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QtQuick/qsgrendererinterface.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
@ -91,19 +92,21 @@ private:
bool m_isMesaSoftwareRasterizer;
int m_mesaVersion;
bool m_isOpenGLRenderer;
};
tst_QQuickItemLayer::tst_QQuickItemLayer()
: m_isMesaSoftwareRasterizer(false)
, m_mesaVersion(0)
, m_isOpenGLRenderer(true)
{
}
void tst_QQuickItemLayer::initTestCase()
{
QQmlDataTest::initTestCase();
QWindow window;
#ifndef QT_NO_OPENGL
QWindow window;
QOpenGLContext context;
window.setSurfaceType(QWindow::OpenGLSurface);
window.create();
@ -131,9 +134,13 @@ void tst_QQuickItemLayer::initTestCase()
m_mesaVersion = QT_VERSION_CHECK(major, minor, patch);
}
}
#else
window.create();
#endif
QQuickView view;
view.showNormal();
QTest::qWaitForWindowExposed(&view);
if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
m_isOpenGLRenderer = false;
}
// The test draws a red and a blue box next to each other and tests that the
@ -206,6 +213,9 @@ void tst_QQuickItemLayer::layerSourceRect()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QImage fb = runTest("SourceRect.qml");
// Check that the edges are converted to blue
@ -226,6 +236,10 @@ void tst_QQuickItemLayer::layerIsTextureProvider()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QImage fb = runTest("TextureProvider.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0));
@ -259,6 +273,9 @@ void tst_QQuickItemLayer::layerVisibility()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QFETCH(bool, visible);
QFETCH(bool, effect);
QFETCH(qreal, opacity);
@ -307,6 +324,9 @@ void tst_QQuickItemLayer::layerZOrder()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QFETCH(bool, effect);
QQuickView view;
@ -341,6 +361,9 @@ void tst_QQuickItemLayer::changeZOrder()
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QFETCH(bool, layered);
QFETCH(bool, effect);
@ -408,6 +431,10 @@ void tst_QQuickItemLayer::changeSamplerName()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QImage fb = runTest("SamplerNameChange.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff));
}
@ -416,6 +443,9 @@ void tst_QQuickItemLayer::itemEffect()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QImage fb = runTest("ItemEffect.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(199, 0), qRgb(0xff, 0, 0));
@ -451,6 +481,9 @@ void tst_QQuickItemLayer::textureMirroring()
{
QFETCH(int, mirroring);
if (!m_isOpenGLRenderer)
QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects");
QQuickView view;
view.setSource(testFileUrl("TextureMirroring.qml"));

View File

@ -75,7 +75,9 @@ void tst_compilation::boomblock()
QQmlComponent c(&engine);
c.setData(data, QUrl());
}
#ifdef QT_NO_OPENGL
QSKIP("boomblock imports Particles which requires OpenGL Support");
#endif
QBENCHMARK {
QQmlComponent c(&engine);
c.setData(data, QUrl());