/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsgd3d12builtinmaterials_p.h"
#include "qsgd3d12rendercontext_p.h"
#include <QQuickWindow>
#include <QtCore/qmath.h>
#include <QtGui/private/qfixed_p.h>

#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"
#include "ps_texture.hlslh"
#include "vs_smoothtexture.hlslh"
#include "ps_smoothtexture.hlslh"
#include "vs_textmask.hlslh"
#include "ps_textmask24.hlslh"
#include "ps_textmask32.hlslh"
#include "ps_textmask8.hlslh"
#include "vs_styledtext.hlslh"
#include "ps_styledtext.hlslh"
#include "vs_outlinedtext.hlslh"
#include "ps_outlinedtext.hlslh"

QT_BEGIN_NAMESPACE

// NB! In HLSL constant buffer data is packed into 4-byte boundaries and, more
// 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
{
    return &QSGD3D12VertexColorMaterial::mtype;
}

int QSGD3D12VertexColorMaterial::compare(const QSGMaterial *other) const
{
    Q_UNUSED(other);
    Q_ASSERT(other && type() == other->type());
    // As the vertex color material has all its state in the vertex attributes
    // defined by the geometry, all such materials will be equal.
    return 0;
}

static const int VERTEX_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
static const int VERTEX_COLOR_CB_SIZE_1 = sizeof(float); // float
static const int VERTEX_COLOR_CB_SIZE = VERTEX_COLOR_CB_SIZE_0 + VERTEX_COLOR_CB_SIZE_1;

int QSGD3D12VertexColorMaterial::constantBufferSize() const
{
    return QSGD3D12Engine::alignedConstantBufferSize(VERTEX_COLOR_CB_SIZE);
}

void QSGD3D12VertexColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
{
    pipelineState->shaders.vs = g_VS_VertexColor;
    pipelineState->shaders.vsSize = sizeof(g_VS_VertexColor);
    pipelineState->shaders.ps = g_PS_VertexColor;
    pipelineState->shaders.psSize = sizeof(g_PS_VertexColor);
}

QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
                                                                            QSGD3D12PipelineState *,
                                                                            ExtraState *,
                                                                            quint8 *constantBuffer)
{
    QSGD3D12Material::UpdateResults r = 0;
    quint8 *p = constantBuffer;

    if (state.isMatrixDirty()) {
        memcpy(p, state.combinedMatrix().constData(), VERTEX_COLOR_CB_SIZE_0);
        r |= UpdatedConstantBuffer;
    }
    p += VERTEX_COLOR_CB_SIZE_0;

    if (state.isOpacityDirty()) {
        const float opacity = state.opacity();
        memcpy(p, &opacity, VERTEX_COLOR_CB_SIZE_1);
        r |= UpdatedConstantBuffer;
    }

    return r;
}

QSGD3D12FlatColorMaterial::QSGD3D12FlatColorMaterial()
    : m_color(QColor(255, 255, 255))
{
}

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);
    setFlag(Blending, true);
}

QSGMaterialType QSGD3D12SmoothColorMaterial::mtype;

QSGMaterialType *QSGD3D12SmoothColorMaterial::type() const
{
    return &QSGD3D12SmoothColorMaterial::mtype;
}

int QSGD3D12SmoothColorMaterial::compare(const QSGMaterial *other) const
{
    Q_UNUSED(other);
    Q_ASSERT(other && type() == other->type());
    return 0;
}

static const int SMOOTH_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
static const int SMOOTH_COLOR_CB_SIZE_1 = sizeof(float); // float
static const int SMOOTH_COLOR_CB_SIZE_2 = 2 * sizeof(float); // float2
static const int SMOOTH_COLOR_CB_SIZE = SMOOTH_COLOR_CB_SIZE_0 + SMOOTH_COLOR_CB_SIZE_1 + SMOOTH_COLOR_CB_SIZE_2;

int QSGD3D12SmoothColorMaterial::constantBufferSize() const
{
    return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_COLOR_CB_SIZE);
}

void QSGD3D12SmoothColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
{
    pipelineState->shaders.vs = g_VS_SmoothColor;
    pipelineState->shaders.vsSize = sizeof(g_VS_SmoothColor);
    pipelineState->shaders.ps = g_PS_SmoothColor;
    pipelineState->shaders.psSize = sizeof(g_PS_SmoothColor);
}

QSGD3D12Material::UpdateResults QSGD3D12SmoothColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
                                                                            QSGD3D12PipelineState *,
                                                                            ExtraState *,
                                                                            quint8 *constantBuffer)
{
    QSGD3D12Material::UpdateResults r = 0;
    quint8 *p = constantBuffer;

    if (state.isMatrixDirty()) {
        memcpy(p, state.combinedMatrix().constData(), SMOOTH_COLOR_CB_SIZE_0);
        r |= UpdatedConstantBuffer;
    }
    p += SMOOTH_COLOR_CB_SIZE_0;

    if (state.isOpacityDirty()) {
        const float opacity = state.opacity();
        memcpy(p, &opacity, SMOOTH_COLOR_CB_SIZE_1);
        r |= UpdatedConstantBuffer;
    }
    p += SMOOTH_COLOR_CB_SIZE_1;

    if (state.isMatrixDirty()) {
        const QRect viewport = state.viewportRect();
        const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() };
        memcpy(p, v, SMOOTH_COLOR_CB_SIZE_2);
        r |= UpdatedConstantBuffer;
    }

    return r;
}

QSGMaterialType QSGD3D12TextureMaterial::mtype;

QSGMaterialType *QSGD3D12TextureMaterial::type() const
{
    return &QSGD3D12TextureMaterial::mtype;
}

int QSGD3D12TextureMaterial::compare(const QSGMaterial *other) const
{
    Q_ASSERT(other && type() == other->type());
    const QSGD3D12TextureMaterial *o = static_cast<const QSGD3D12TextureMaterial *>(other);
    if (int diff = m_texture->textureId() - o->texture()->textureId())
        return diff;
    return int(m_filtering) - int(o->m_filtering);
}

static const int TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
static const int TEXTURE_CB_SIZE_1 = sizeof(float); // float
static const int TEXTURE_CB_SIZE = TEXTURE_CB_SIZE_0 + TEXTURE_CB_SIZE_1;

int QSGD3D12TextureMaterial::constantBufferSize() const
{
    return QSGD3D12Engine::alignedConstantBufferSize(TEXTURE_CB_SIZE);
}

void QSGD3D12TextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
{
    pipelineState->shaders.vs = g_VS_Texture;
    pipelineState->shaders.vsSize = sizeof(g_VS_Texture);
    pipelineState->shaders.ps = g_PS_Texture;
    pipelineState->shaders.psSize = sizeof(g_PS_Texture);

    pipelineState->shaders.rootSig.textureViewCount = 1;
}

QSGD3D12Material::UpdateResults QSGD3D12TextureMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
                                                                        QSGD3D12PipelineState *pipelineState,
                                                                        ExtraState *,
                                                                        quint8 *constantBuffer)
{
    QSGD3D12Material::UpdateResults r = 0;
    quint8 *p = constantBuffer;

    if (state.isMatrixDirty()) {
        memcpy(p, state.combinedMatrix().constData(), TEXTURE_CB_SIZE_0);
        r |= UpdatedConstantBuffer;
    }
    p += TEXTURE_CB_SIZE_0;

    if (state.isOpacityDirty()) {
        const float opacity = state.opacity();
        memcpy(p, &opacity, TEXTURE_CB_SIZE_1);
        r |= UpdatedConstantBuffer;
    }

    Q_ASSERT(m_texture);
    m_texture->setFiltering(m_filtering);
    m_texture->setMipmapFiltering(m_mipmap_filtering);
    m_texture->setHorizontalWrapMode(m_horizontal_wrap);
    m_texture->setVerticalWrapMode(m_vertical_wrap);

    QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
    if (m_filtering == QSGTexture::Linear)
        tv.filter = m_mipmap_filtering == QSGTexture::Linear
                ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest;
    else
        tv.filter = m_mipmap_filtering == QSGTexture::Linear
                ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest;
    tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
    tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;

    m_texture->bind();

    return r;
}

void QSGD3D12TextureMaterial::setTexture(QSGTexture *texture)
{
    m_texture = texture;
    setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false);
}

QSGD3D12SmoothTextureMaterial::QSGD3D12SmoothTextureMaterial()
{
    setFlag(RequiresFullMatrixExceptTranslate, true);
    setFlag(Blending, true);
}

QSGMaterialType QSGD3D12SmoothTextureMaterial::mtype;

QSGMaterialType *QSGD3D12SmoothTextureMaterial::type() const
{
    return &QSGD3D12SmoothTextureMaterial::mtype;
}

int QSGD3D12SmoothTextureMaterial::compare(const QSGMaterial *other) const
{
    Q_ASSERT(other && type() == other->type());
    const QSGD3D12SmoothTextureMaterial *o = static_cast<const QSGD3D12SmoothTextureMaterial *>(other);
    if (int diff = m_texture->textureId() - o->texture()->textureId())
        return diff;
    return int(m_filtering) - int(o->m_filtering);
}

static const int SMOOTH_TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
static const int SMOOTH_TEXTURE_CB_SIZE_1 = sizeof(float); // float
static const int SMOOTH_TEXTURE_CB_SIZE_2 = 2 * sizeof(float); // float2
static const int SMOOTH_TEXTURE_CB_SIZE = SMOOTH_TEXTURE_CB_SIZE_0 + SMOOTH_TEXTURE_CB_SIZE_1 + SMOOTH_TEXTURE_CB_SIZE_2;

int QSGD3D12SmoothTextureMaterial::constantBufferSize() const
{
    return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_TEXTURE_CB_SIZE);
}

void QSGD3D12SmoothTextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
{
    pipelineState->shaders.vs = g_VS_SmoothTexture;
    pipelineState->shaders.vsSize = sizeof(g_VS_SmoothTexture);
    pipelineState->shaders.ps = g_PS_SmoothTexture;
    pipelineState->shaders.psSize = sizeof(g_PS_SmoothTexture);

    pipelineState->shaders.rootSig.textureViewCount = 1;
}

QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
                                                                              QSGD3D12PipelineState *pipelineState,
                                                                              ExtraState *,
                                                                              quint8 *constantBuffer)
{
    QSGD3D12Material::UpdateResults r = 0;
    quint8 *p = constantBuffer;

    if (state.isMatrixDirty()) {
        memcpy(p, state.combinedMatrix().constData(), SMOOTH_TEXTURE_CB_SIZE_0);
        r |= UpdatedConstantBuffer;
    }
    p += SMOOTH_TEXTURE_CB_SIZE_0;

    if (state.isOpacityDirty()) {
        const float opacity = state.opacity();
        memcpy(p, &opacity, SMOOTH_TEXTURE_CB_SIZE_1);
        r |= UpdatedConstantBuffer;
    }
    p += SMOOTH_TEXTURE_CB_SIZE_1;

    if (state.isMatrixDirty()) {
        const QRect viewport = state.viewportRect();
        const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() };
        memcpy(p, v, SMOOTH_TEXTURE_CB_SIZE_2);
        r |= UpdatedConstantBuffer;
    }

    Q_ASSERT(m_texture);
    m_texture->setFiltering(m_filtering);
    m_texture->setMipmapFiltering(m_mipmap_filtering);
    m_texture->setHorizontalWrapMode(m_horizontal_wrap);
    m_texture->setVerticalWrapMode(m_vertical_wrap);

    QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
    if (m_filtering == QSGTexture::Linear)
        tv.filter = m_mipmap_filtering == QSGTexture::Linear
                ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest;
    else
        tv.filter = m_mipmap_filtering == QSGTexture::Linear
                ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest;
    tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
    tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;

    m_texture->bind();

    return r;
}

QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc,
                                           const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
    : m_styleType(styleType),
      m_rc(rc),
      m_font(font)
{
    setFlag(Blending, true);

    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
    if (QFontEngine *fontEngine = fontD->fontEngine) {
        if (glyphFormat == QFontEngine::Format_None)
            glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None
                    ? fontEngine->glyphFormat : QFontEngine::Format_A32;

        QSGD3D12Engine *d3dengine = rc->engine();
        const float devicePixelRatio = d3dengine->windowDevicePixelRatio();
        QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio);
        if (!fontEngine->supportsTransformation(glyphCacheTransform))
            glyphCacheTransform = QTransform();

        m_glyphCache = fontEngine->glyphCache(d3dengine, glyphFormat, glyphCacheTransform);
        if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) {
            m_glyphCache = new QSGD3D12GlyphCache(d3dengine, glyphFormat, glyphCacheTransform);
            fontEngine->setGlyphCache(d3dengine, m_glyphCache.data());
            rc->registerFontengineForCleanup(fontEngine);
        }
    }
}

QSGMaterialType QSGD3D12TextMaterial::mtype[QSGD3D12TextMaterial::NTextMaterialTypes];

QSGMaterialType *QSGD3D12TextMaterial::type() const
{
    // Format_A32 has special blend settings and therefore two materials with
    // the same style but different formats where one is A32 are treated as
    // different. This way the renderer can manage the pipeline state properly.
    const int matStyle = m_styleType * 2;
    const int matFormat = glyphCache()->glyphFormat() != QFontEngine::Format_A32 ? 0 : 1;
    return &QSGD3D12TextMaterial::mtype[matStyle + matFormat];
}

int QSGD3D12TextMaterial::compare(const QSGMaterial *other) const
{
    Q_ASSERT(other && type() == other->type());
    const QSGD3D12TextMaterial *o = static_cast<const QSGD3D12TextMaterial *>(other);
    if (m_styleType != o->m_styleType)
        return m_styleType - o->m_styleType;
    if (m_glyphCache != o->m_glyphCache)
        return m_glyphCache.data() < o->m_glyphCache.data() ? -1 : 1;
    if (m_styleShift != o->m_styleShift)
        return m_styleShift.y() - o->m_styleShift.y();
    int styleColorDiff = qsg_colorDiff(m_styleColor, o->m_styleColor);
    if (styleColorDiff)
        return styleColorDiff;
    return qsg_colorDiff(m_color, o->m_color);
}

static const int TEXT_CB_SIZE_0 = 16 * sizeof(float); // float4x4 mvp
static const int TEXT_CB_SIZE_1 = 2 * sizeof(float); // float2 textureScale
static const int TEXT_CB_SIZE_2 = sizeof(float); // float dpr
static const int TEXT_CB_SIZE_3 = sizeof(float); // float color
static const int TEXT_CB_SIZE_4 = 4 * sizeof(float); // float4 colorVec
static const int TEXT_CB_SIZE_5 = 2 * sizeof(float); // float2 shift
static const int TEXT_CB_SIZE_5_PADDING = 2 * sizeof(float); // float2 padding (the next float4 would cross the 16-byte boundary)
static const int TEXT_CB_SIZE_6 = 4 * sizeof(float); // float4 styleColor
static const int TEXT_CB_SIZE = TEXT_CB_SIZE_0 + TEXT_CB_SIZE_1 + TEXT_CB_SIZE_2 + TEXT_CB_SIZE_3
        + TEXT_CB_SIZE_4 + TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING + TEXT_CB_SIZE_6;

int QSGD3D12TextMaterial::constantBufferSize() const
{
    return QSGD3D12Engine::alignedConstantBufferSize(TEXT_CB_SIZE);
}

void QSGD3D12TextMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
{
    if (m_styleType == Normal) {
        pipelineState->shaders.vs = g_VS_TextMask;
        pipelineState->shaders.vsSize = sizeof(g_VS_TextMask);
        switch (glyphCache()->glyphFormat()) {
        case QFontEngine::Format_A32:
            pipelineState->shaders.ps = g_PS_TextMask24;
            pipelineState->shaders.psSize = sizeof(g_PS_TextMask24);
            break;
        case QFontEngine::Format_ARGB:
            pipelineState->shaders.ps = g_PS_TextMask32;
            pipelineState->shaders.psSize = sizeof(g_PS_TextMask32);
            break;
        default:
            pipelineState->shaders.ps = g_PS_TextMask8;
            pipelineState->shaders.psSize = sizeof(g_PS_TextMask8);
            break;
        }
    } else if (m_styleType == Outlined) {
        pipelineState->shaders.vs = g_VS_OutlinedText;
        pipelineState->shaders.vsSize = sizeof(g_VS_OutlinedText);
        pipelineState->shaders.ps = g_PS_OutlinedText;
        pipelineState->shaders.psSize = sizeof(g_PS_OutlinedText);
    } else {
        pipelineState->shaders.vs = g_VS_StyledText;
        pipelineState->shaders.vsSize = sizeof(g_VS_StyledText);
        pipelineState->shaders.ps = g_PS_StyledText;
        pipelineState->shaders.psSize = sizeof(g_PS_StyledText);
    }

    pipelineState->shaders.rootSig.textureViewCount = 1;
}

QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
                                                                     QSGD3D12PipelineState *pipelineState,
                                                                     ExtraState *extraState,
                                                                     quint8 *constantBuffer)
{
    QSGD3D12Material::UpdateResults r = 0;
    quint8 *p = constantBuffer;

    if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
        // can freely change the state due to the way type() works
        pipelineState->blend = QSGD3D12PipelineState::BlendColor;
        extraState->blendFactor = m_color;
        r |= UpdatedBlendFactor; // must be set always as this affects the command list
    }

    if (state.isMatrixDirty()) {
        memcpy(p, state.combinedMatrix().constData(), TEXT_CB_SIZE_0);
        r |= UpdatedConstantBuffer;
    }
    p += TEXT_CB_SIZE_0;

    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() || memcmp(p, &dpr, TEXT_CB_SIZE_2)) {
        memcpy(p, &dpr, TEXT_CB_SIZE_2);
        r |= UpdatedConstantBuffer;
    }
    p += TEXT_CB_SIZE_2;

    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);
            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;
        }
    }
    p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4;

    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) {
        const QVector4D color = qsg_premultiply(m_styleColor, state.opacity());
        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]);
    tv.filter = QSGD3D12TextureView::FilterNearest;
    tv.addressModeHoriz = QSGD3D12TextureView::AddressClamp;
    tv.addressModeVert = QSGD3D12TextureView::AddressClamp;

    glyphCache()->useTexture();

    return r;
}

void QSGD3D12TextMaterial::populate(const QPointF &p,
                                    const QVector<quint32> &glyphIndexes,
                                    const QVector<QPointF> &glyphPositions,
                                    QSGGeometry *geometry,
                                    QRectF *boundingRect,
                                    QPointF *baseLine,
                                    const QMargins &margins)
{
    Q_ASSERT(m_font.isValid());
    QVector<QFixedPoint> fixedPointPositions;
    const int glyphPositionsSize = glyphPositions.size();
    fixedPointPositions.reserve(glyphPositionsSize);
    for (int i=0; i < glyphPositionsSize; ++i)
        fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));

    QSGD3D12GlyphCache *cache = glyphCache();
    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
    cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(),
                    fixedPointPositions.data());
    cache->fillInPendingGlyphs();

    int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat());

    float glyphCacheScaleX = cache->transform().m11();
    float glyphCacheScaleY = cache->transform().m22();
    float glyphCacheInverseScaleX = 1.0 / glyphCacheScaleX;
    float glyphCacheInverseScaleY = 1.0 / glyphCacheScaleY;

    Q_ASSERT(geometry->indexType() == QSGGeometry::UnsignedShortType);
    geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6);
    QVector4D *vp = reinterpret_cast<QVector4D *>(geometry->vertexDataAsTexturedPoint2D());
    Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D));
    ushort *ip = geometry->indexDataAsUShort();

    QPointF position(p.x(), p.y() - m_font.ascent());
    bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
    for (int i = 0; i < glyphIndexes.size(); ++i) {
         QFixed subPixelPosition;
         if (supportsSubPixelPositions)
             subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x()));

         QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
         const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);

         QPointF glyphPosition = glyphPositions.at(i) + position;
         float x = (qFloor(glyphPosition.x() * glyphCacheScaleX) * glyphCacheInverseScaleX)
                 + (c.baseLineX * glyphCacheInverseScaleX) - margin;
         float y = (qRound(glyphPosition.y() * glyphCacheScaleY) * glyphCacheInverseScaleY)
                 - (c.baseLineY * glyphCacheInverseScaleY) - margin;

         float w = c.w * glyphCacheInverseScaleX;
         float h = c.h * glyphCacheInverseScaleY;

         *boundingRect |= QRectF(x + margin, y + margin, w, h);

         float cx1 = x - margins.left();
         float cx2 = x + w + margins.right();
         float cy1 = y - margins.top();
         float cy2 = y + h + margins.bottom();

         float tx1 = c.x - margins.left();
         float tx2 = c.x + c.w + margins.right();
         float ty1 = c.y - margins.top();
         float ty2 = c.y + c.h + margins.bottom();

         if (baseLine->isNull())
             *baseLine = glyphPosition;

         vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1);
         vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1);
         vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2);
         vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2);

         int o = i * 4;
         ip[6 * i + 0] = o + 0;
         ip[6 * i + 1] = o + 2;
         ip[6 * i + 2] = o + 3;
         ip[6 * i + 3] = o + 3;
         ip[6 * i + 4] = o + 1;
         ip[6 * i + 5] = o + 0;
    }
}

QT_END_NAMESPACE
