/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2016 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
** Copyright (C) 2016 Robin Burchell <robin.burchell@viroteck.net>
** 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 "qsgrhivisualizer_p.h"
#include <qmath.h>
#include <QQuickWindow>
#include <private/qsgmaterialrhishader_p.h>
#include <private/qsgshadersourcebuilder_p.h>

QT_BEGIN_NAMESPACE

namespace QSGBatchRenderer
{

#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded \
                              | QSGNode::DirtyOpacity \
                              | QSGNode::DirtyMatrix \
                              | QSGNode::DirtyNodeRemoved)

QMatrix4x4 qsg_matrixForRoot(Node *node);
QRhiVertexInputAttribute::Format qsg_vertexInputFormat(const QSGGeometry::Attribute &a);
QRhiCommandBuffer::IndexFormat qsg_indexFormat(const QSGGeometry *geometry);
QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode);

RhiVisualizer::RhiVisualizer(Renderer *renderer)
    : Visualizer(renderer)
{
}

RhiVisualizer::~RhiVisualizer()
{
    releaseResources();
}

void RhiVisualizer::releaseResources()
{
    m_pipelines.releaseResources();

    m_fade.releaseResources();

    m_changeVis.releaseResources();
    m_batchVis.releaseResources();
    m_clipVis.releaseResources();
    m_overdrawVis.releaseResources();
}

void RhiVisualizer::prepareVisualize()
{
    // Called before the render pass has begun (but after preparing the
    // batches). Now is the time to put resource updates to the renderer's
    // current m_resourceUpdates instance.

    if (m_visualizeMode == VisualizeNothing)
        return;

    if (!m_vs.isValid()) {
        m_vs = QSGMaterialRhiShaderPrivate::loadShader(
                    QLatin1String(":/qt-project.org/scenegraph/shaders_ng/visualization.vert.qsb"));
        m_fs = QSGMaterialRhiShaderPrivate::loadShader(
                    QLatin1String(":/qt-project.org/scenegraph/shaders_ng/visualization.frag.qsb"));
    }

    m_fade.prepare(this, m_renderer->m_rhi, m_renderer->m_resourceUpdates, m_renderer->renderPassDescriptor());

    const bool forceUintIndex = m_renderer->m_uint32IndexForRhi;

    switch (m_visualizeMode) {
    case VisualizeBatches:
        m_batchVis.prepare(m_renderer->m_opaqueBatches, m_renderer->m_alphaBatches,
                           this,
                           m_renderer->m_rhi, m_renderer->m_resourceUpdates,
                           forceUintIndex);
        break;
    case VisualizeClipping:
        m_clipVis.prepare(m_renderer->rootNode(), this,
                          m_renderer->m_rhi, m_renderer->m_resourceUpdates);
        break;
    case VisualizeChanges:
        m_changeVis.prepare(m_renderer->m_nodes.value(m_renderer->rootNode()),
                            this,
                            m_renderer->m_rhi, m_renderer->m_resourceUpdates);
        m_visualizeChangeSet.clear();
        break;
    case VisualizeOverdraw:
        m_overdrawVis.prepare(m_renderer->m_nodes.value(m_renderer->rootNode()),
                              this,
                              m_renderer->m_rhi, m_renderer->m_resourceUpdates);
        break;
    default:
        Q_UNREACHABLE();
        break;
    }
}

void RhiVisualizer::visualize()
{
    if (m_visualizeMode == VisualizeNothing)
        return;

    QRhiCommandBuffer *cb = m_renderer->commandBuffer();
    m_fade.render(cb);

    switch (m_visualizeMode) {
    case VisualizeBatches:
        m_batchVis.render(cb);
        break;
    case VisualizeClipping:
        m_clipVis.render(cb);
        break;
    case VisualizeChanges:
        m_changeVis.render(cb);
        break;
    case VisualizeOverdraw:
        m_overdrawVis.render(cb);
        break;
    default:
        Q_UNREACHABLE();
        break;
    }
}

void RhiVisualizer::recordDrawCalls(const QVector<DrawCall> &drawCalls,
                                    QRhiCommandBuffer *cb,
                                    QRhiShaderResourceBindings *srb,
                                    bool blendOneOne)
{
    for (const DrawCall &dc : drawCalls) {
        QRhiGraphicsPipeline *ps = m_pipelines.pipeline(this, m_renderer->m_rhi, srb, m_renderer->renderPassDescriptor(),
                                                        dc.vertex.topology, dc.vertex.format, dc.vertex.stride,
                                                        blendOneOne);
        if (!ps)
            continue;
        cb->setGraphicsPipeline(ps); // no-op if same as the last one
        QRhiCommandBuffer::DynamicOffset dynofs(0, dc.buf.ubufOffset);
        cb->setShaderResources(srb, 1, &dynofs);
        QRhiCommandBuffer::VertexInput vb(dc.buf.vbuf, dc.buf.vbufOffset);
        if (dc.index.count) {
            cb->setVertexInput(0, 1, &vb, dc.buf.ibuf, dc.buf.ibufOffset, dc.index.format);
            cb->drawIndexed(dc.index.count);
        } else {
            cb->setVertexInput(0, 1, &vb);
            cb->draw(dc.vertex.count);
        }
    }
}

const QRhiShaderResourceBinding::StageFlags ubufVisibility =
        QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage;

void RhiVisualizer::Fade::prepare(RhiVisualizer *visualizer,
                                  QRhi *rhi, QRhiResourceUpdateBatch *u, QRhiRenderPassDescriptor *rpDesc)
{
    this->visualizer = visualizer;

    if (!vbuf) {
        float v[] = { -1, 1,   1, 1,   -1, -1,   1, -1 };
        vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(v));
        if (!vbuf->build())
            return;
        u->uploadStaticBuffer(vbuf, v);
    }

    if (!ubuf) {
        ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, DrawCall::UBUF_SIZE);
        if (!ubuf->build())
            return;
        float bgOpacity = 0.8f;
        if (visualizer->m_visualizeMode == Visualizer::VisualizeBatches)
            bgOpacity = 1.0;
        QMatrix4x4 ident;
        u->updateDynamicBuffer(ubuf, 0, 64, ident.constData()); // matrix
        u->updateDynamicBuffer(ubuf, 64, 64, ident.constData()); // rotation
        float color[4] = { 0.0f, 0.0f, 0.0f, bgOpacity };
        u->updateDynamicBuffer(ubuf, 128, 16, color);
        float pattern = 0.0f;
        u->updateDynamicBuffer(ubuf, 144, 4, &pattern);
        qint32 projection = 0;
        u->updateDynamicBuffer(ubuf, 148, 4, &projection);
    }

    if (!srb) {
        srb = rhi->newShaderResourceBindings();
        srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, ubufVisibility, ubuf) });
        if (!srb->build())
            return;
    }

    if (!ps) {
        ps = rhi->newGraphicsPipeline();
        ps->setTopology(QRhiGraphicsPipeline::TriangleStrip);
        QRhiGraphicsPipeline::TargetBlend blend; // defaults to premul alpha, just what we need
        blend.enable = true;
        ps->setTargetBlends({ blend });
        ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
                              { QRhiShaderStage::Fragment, visualizer->m_fs } });
        QRhiVertexInputLayout inputLayout;
        inputLayout.setBindings({ { 2 * sizeof(float) } });
        inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float2, 0 } });
        ps->setVertexInputLayout(inputLayout);
        ps->setShaderResourceBindings(srb);
        ps->setRenderPassDescriptor(rpDesc);
        if (!ps->build())
            return;
    }
}

void RhiVisualizer::Fade::releaseResources()
{
    delete ps;
    ps = nullptr;

    delete srb;
    srb = nullptr;

    delete ubuf;
    ubuf = nullptr;

    delete vbuf;
    vbuf = nullptr;
}

void RhiVisualizer::Fade::render(QRhiCommandBuffer *cb)
{
    cb->setGraphicsPipeline(ps);
    cb->setViewport(visualizer->m_renderer->m_pstate.viewport);
    cb->setShaderResources();
    QRhiCommandBuffer::VertexInput vb(vbuf, 0);
    cb->setVertexInput(0, 1, &vb);
    cb->draw(4);
}

static void fillVertexIndex(RhiVisualizer::DrawCall *dc, QSGGeometry *g, bool withData, bool forceUintIndex)
{
    dc->vertex.topology = qsg_topology(g->drawingMode());
    dc->vertex.format = qsg_vertexInputFormat(g->attributes()[0]);
    dc->vertex.count = g->vertexCount();
    dc->vertex.stride = g->sizeOfVertex();
    if (withData)
        dc->vertex.data = g->vertexData();

    dc->index.format = forceUintIndex ? QRhiCommandBuffer::IndexUInt32 : qsg_indexFormat(g);
    dc->index.count = g->indexCount();
    dc->index.stride = forceUintIndex ? sizeof(quint32) : g->sizeOfIndex();
    if (withData && g->indexCount())
        dc->index.data = g->indexData();
}

static inline uint aligned(uint v, uint byteAlign)
{
    return (v + byteAlign - 1) & ~(byteAlign - 1);
}

static bool ensureBuffer(QRhi *rhi, QRhiBuffer **buf, QRhiBuffer::UsageFlags usage, int newSize)
{
    if (!*buf) {
        *buf = rhi->newBuffer(QRhiBuffer::Dynamic, usage, newSize);
        if (!(*buf)->build())
            return false;
    } else if ((*buf)->size() < newSize) {
        (*buf)->setSize(newSize);
        if (!(*buf)->build())
            return false;
    }
    return true;
}

QRhiGraphicsPipeline *RhiVisualizer::PipelineCache::pipeline(RhiVisualizer *visualizer,
                                                             QRhi *rhi,
                                                             QRhiShaderResourceBindings *srb,
                                                             QRhiRenderPassDescriptor *rpDesc,
                                                             QRhiGraphicsPipeline::Topology topology,
                                                             QRhiVertexInputAttribute::Format vertexFormat,
                                                             quint32 vertexStride,
                                                             bool blendOneOne)
{
    for (int i = 0, ie = pipelines.count(); i != ie; ++i) {
        const Pipeline &p(pipelines.at(i));
        if (p.topology == topology && p.format == vertexFormat && p.stride == vertexStride)
            return p.ps;
    }

    QRhiGraphicsPipeline *ps = rhi->newGraphicsPipeline();
    ps->setTopology(topology);
    QRhiGraphicsPipeline::TargetBlend blend; // premul alpha
    blend.enable = true;
    if (blendOneOne) {
        // only for visualizing overdraw, other modes use premul alpha
        blend.srcColor = QRhiGraphicsPipeline::One;
        blend.dstColor = QRhiGraphicsPipeline::One;
        blend.srcAlpha = QRhiGraphicsPipeline::One;
        blend.dstAlpha = QRhiGraphicsPipeline::One;
    }
    ps->setTargetBlends({ blend });
    ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
                          { QRhiShaderStage::Fragment, visualizer->m_fs } });
    QRhiVertexInputLayout inputLayout;
    inputLayout.setBindings({ { vertexStride } });
    inputLayout.setAttributes({ { 0, 0, vertexFormat, 0 } });
    ps->setVertexInputLayout(inputLayout);
    ps->setShaderResourceBindings(srb);
    ps->setRenderPassDescriptor(rpDesc);
    if (!ps->build())
        return nullptr;

    Pipeline p;
    p.topology = topology;
    p.format = vertexFormat;
    p.stride = vertexStride;
    p.ps = ps;
    pipelines.append(p);

    return ps;
}

void RhiVisualizer::PipelineCache::releaseResources()
{
    for (int i = 0, ie = pipelines.count(); i != ie; ++i)
        delete pipelines.at(i).ps;

    pipelines.clear();
}

void RhiVisualizer::ChangeVis::gather(Node *n)
{
    if (n->type() == QSGNode::GeometryNodeType && n->element()->batch && visualizer->m_visualizeChangeSet.contains(n)) {
        const uint dirty = visualizer->m_visualizeChangeSet.value(n);
        const bool tinted = (dirty & QSGNODE_DIRTY_PARENT) != 0;
        const QColor color = QColor::fromHsvF((rand() & 1023) / 1023.0f, 0.3f, 1.0f);
        const float alpha = 0.5f;

        QMatrix4x4 matrix = visualizer->m_renderer->m_current_projection_matrix;
        if (n->element()->batch->root)
            matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);

        QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(n->sgNode);
        matrix = matrix * *gn->matrix();

        QSGGeometry *g = gn->geometry();
        if (g->attributeCount() >= 1) {
            DrawCall dc;
            memcpy(dc.uniforms.data, matrix.constData(), 64);
            QMatrix4x4 rotation;
            memcpy(dc.uniforms.data + 64, rotation.constData(), 64);
            float c[4] = {
                float(color.redF()) * alpha,
                float(color.greenF()) * alpha,
                float(color.blueF()) * alpha,
                alpha
            };
            memcpy(dc.uniforms.data + 128, c, 16);
            float pattern = tinted ? 0.5f : 0.0f;
            memcpy(dc.uniforms.data + 144, &pattern, 4);
            qint32 projection = 0;
            memcpy(dc.uniforms.data + 148, &projection, 4);

            fillVertexIndex(&dc, g, true, false);
            drawCalls.append(dc);
        }

        // This is because many changes don't propegate their dirty state to the
        // parent so the node updater will not unset these states. They are
        // not used for anything so, unsetting it should have no side effects.
        n->dirtyState = nullptr;
    }

    SHADOWNODE_TRAVERSE(n) {
        gather(child);
    }
}

void RhiVisualizer::ChangeVis::prepare(Node *n, RhiVisualizer *visualizer,
                                       QRhi *rhi, QRhiResourceUpdateBatch *u)
{
    this->visualizer = visualizer;

    drawCalls.clear();
    gather(n);

    if (drawCalls.isEmpty())
        return;

    const int ubufAlign = rhi->ubufAlignment();
    int vbufOffset = 0;
    int ibufOffset = 0;
    int ubufOffset = 0;
    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        dc.buf.vbufOffset = aligned(vbufOffset, 4);
        vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;

        dc.buf.ibufOffset = aligned(ibufOffset, 4);
        ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;

        dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
        ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
    }

    ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
    if (ibufOffset)
        ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
    const int ubufSize = ubufOffset;
    ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);

    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
        dc.buf.vbuf = vbuf;
        if (dc.index.count) {
            u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
            dc.buf.ibuf = ibuf;
        }
        u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
    }

    if (!srb) {
        srb = rhi->newShaderResourceBindings();
        srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
        if (!srb->build())
            return;
    }
}

void RhiVisualizer::ChangeVis::releaseResources()
{
    delete srb;
    srb = nullptr;

    delete ubuf;
    ubuf = nullptr;

    delete ibuf;
    ibuf = nullptr;

    delete vbuf;
    vbuf = nullptr;
}

void RhiVisualizer::ChangeVis::render(QRhiCommandBuffer *cb)
{
    visualizer->recordDrawCalls(drawCalls, cb, srb);
}

void RhiVisualizer::BatchVis::gather(Batch *b)
{
    if (b->positionAttribute != 0)
        return;

    QMatrix4x4 matrix(visualizer->m_renderer->m_current_projection_matrix);
    if (b->root)
        matrix = matrix * qsg_matrixForRoot(b->root);

    DrawCall dc;

    QMatrix4x4 rotation;
    memcpy(dc.uniforms.data + 64, rotation.constData(), 64);

    QColor color = QColor::fromHsvF((rand() & 1023) / 1023.0, 1.0, 1.0);

    float c[4] = {
        float(color.redF()),
        float(color.greenF()),
        float(color.blueF()),
        1.0f
    };
    memcpy(dc.uniforms.data + 128, c, 16);

    float pattern = b->merged ? 0.0f : 1.0f;
    memcpy(dc.uniforms.data + 144, &pattern, 4);

    qint32 projection = 0;
    memcpy(dc.uniforms.data + 148, &projection, 4);

    if (b->merged) {
        memcpy(dc.uniforms.data, matrix.constData(), 64);

        QSGGeometryNode *gn = b->first->node;
        QSGGeometry *g = gn->geometry();

        fillVertexIndex(&dc, g, false, forceUintIndex);

        for (int ds = 0; ds < b->drawSets.size(); ++ds) {
            const DrawSet &set = b->drawSets.at(ds);
            dc.buf.vbuf = b->vbo.buf;
            dc.buf.vbufOffset = set.vertices;
            dc.buf.ibuf = b->ibo.buf;
            dc.buf.ibufOffset = set.indices;
            dc.index.count = set.indexCount;
            drawCalls.append(dc);
        }
    } else {
        Element *e = b->first;
        int vOffset = 0;
        int iOffset = 0;

        while (e) {
            QSGGeometryNode *gn = e->node;
            QSGGeometry *g = gn->geometry();

            QMatrix4x4 m = matrix * *gn->matrix();
            memcpy(dc.uniforms.data, m.constData(), 64);

            fillVertexIndex(&dc, g, false, forceUintIndex);

            dc.buf.vbuf = b->vbo.buf;
            dc.buf.vbufOffset = vOffset;
            if (g->indexCount()) {
                dc.buf.ibuf = b->ibo.buf;
                dc.buf.ibufOffset = iOffset;
            }

            drawCalls.append(dc);

            vOffset += dc.vertex.count * dc.vertex.stride;
            iOffset += dc.index.count * dc.index.stride;

            e = e->nextInBatch;
        }
    }
}

void RhiVisualizer::BatchVis::prepare(const QDataBuffer<Batch *> &opaqueBatches, const QDataBuffer<Batch *> &alphaBatches,
                                      RhiVisualizer *visualizer,
                                      QRhi *rhi, QRhiResourceUpdateBatch *u,
                                      bool forceUintIndex)
{
    this->visualizer = visualizer;
    this->forceUintIndex = forceUintIndex;

    drawCalls.clear();

    srand(0); // To force random colors to be roughly the same every time..
    for (int i = 0; i < opaqueBatches.size(); ++i)
        gather(opaqueBatches.at(i));
    for (int i = 0; i < alphaBatches.size(); ++i)
        gather(alphaBatches.at(i));

    if (drawCalls.isEmpty())
        return;

    const int ubufAlign = rhi->ubufAlignment();
    int ubufOffset = 0;
    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
        ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
    }

    const int ubufSize = ubufOffset;
    ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);

    for (RhiVisualizer::DrawCall &dc : drawCalls)
        u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);

    if (!srb) {
        srb = rhi->newShaderResourceBindings();
        srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
        if (!srb->build())
            return;
    }
}

void RhiVisualizer::BatchVis::releaseResources()
{
    delete srb;
    srb = nullptr;

    delete ubuf;
    ubuf = nullptr;
}

void RhiVisualizer::BatchVis::render(QRhiCommandBuffer *cb)
{
    visualizer->recordDrawCalls(drawCalls, cb, srb);
}

void RhiVisualizer::ClipVis::gather(QSGNode *node)
{
    if (node->type() == QSGNode::ClipNodeType) {
        QSGClipNode *clipNode = static_cast<QSGClipNode *>(node);
        QMatrix4x4 matrix = visualizer->m_renderer->m_current_projection_matrix;
        if (clipNode->matrix())
            matrix = matrix * *clipNode->matrix();

        QSGGeometry *g = clipNode->geometry();
        if (g->attributeCount() >= 1) {
            DrawCall dc;
            memcpy(dc.uniforms.data, matrix.constData(), 64);
            QMatrix4x4 rotation;
            memcpy(dc.uniforms.data + 64, rotation.constData(), 64);
            float c[4] = { 0.2f, 0.0f, 0.0f, 0.2f };
            memcpy(dc.uniforms.data + 128, c, 16);
            float pattern = 0.5f;
            memcpy(dc.uniforms.data + 144, &pattern, 4);
            qint32 projection = 0;
            memcpy(dc.uniforms.data + 148, &projection, 4);
            fillVertexIndex(&dc, g, true, false);
            drawCalls.append(dc);
        }
    }

    QSGNODE_TRAVERSE(node) {
        gather(child);
    }
}

void RhiVisualizer::ClipVis::prepare(QSGNode *node, RhiVisualizer *visualizer,
                                     QRhi *rhi, QRhiResourceUpdateBatch *u)
{
    this->visualizer = visualizer;

    drawCalls.clear();
    gather(node);

    if (drawCalls.isEmpty())
        return;

    const int ubufAlign = rhi->ubufAlignment();
    int vbufOffset = 0;
    int ibufOffset = 0;
    int ubufOffset = 0;
    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        dc.buf.vbufOffset = aligned(vbufOffset, 4);
        vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;

        dc.buf.ibufOffset = aligned(ibufOffset, 4);
        ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;

        dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
        ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
    }

    ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
    if (ibufOffset)
        ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
    const int ubufSize = ubufOffset;
    ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);

    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
        dc.buf.vbuf = vbuf;
        if (dc.index.count) {
            u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
            dc.buf.ibuf = ibuf;
        }
        u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
    }

    if (!srb) {
        srb = rhi->newShaderResourceBindings();
        srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
        if (!srb->build())
            return;
    }
}

void RhiVisualizer::ClipVis::releaseResources()
{
    delete srb;
    srb = nullptr;

    delete ubuf;
    ubuf = nullptr;

    delete ibuf;
    ibuf = nullptr;

    delete vbuf;
    vbuf = nullptr;
}

void RhiVisualizer::ClipVis::render(QRhiCommandBuffer *cb)
{
    visualizer->recordDrawCalls(drawCalls, cb, srb);
}

void RhiVisualizer::OverdrawVis::gather(Node *n)
{
    if (n->type() == QSGNode::GeometryNodeType && n->element()->batch) {
        QMatrix4x4 matrix = visualizer->m_renderer->m_current_projection_matrix;
        matrix(2, 2) = visualizer->m_renderer->m_zRange;
        matrix(2, 3) = 1.0f - n->element()->order * visualizer->m_renderer->m_zRange;

        if (n->element()->batch->root)
            matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);

        QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(n->sgNode);
        matrix = matrix * *gn->matrix();

        QSGGeometry *g = gn->geometry();
        if (g->attributeCount() >= 1) {
            DrawCall dc;
            memcpy(dc.uniforms.data, matrix.constData(), 64);
            memcpy(dc.uniforms.data + 64, rotation.constData(), 64);

            float c[4];
            const float ca = 0.33f;
            if (n->element()->batch->isOpaque) {
                c[0] = ca * 0.3f; c[1] = ca * 1.0f; c[2] = ca * 0.3f; c[3] = ca;
            } else {
                c[0] = ca * 1.0f; c[1] = ca * 0.3f; c[2] = ca * 0.3f; c[3] = ca;
            }
            memcpy(dc.uniforms.data + 128, c, 16);
            float pattern = 0.0f;
            memcpy(dc.uniforms.data + 144, &pattern, 4);
            qint32 projection = 1;
            memcpy(dc.uniforms.data + 148, &projection, 4);

            fillVertexIndex(&dc, g, true, false);
            drawCalls.append(dc);
        }
    }

    SHADOWNODE_TRAVERSE(n) {
        gather(child);
    }
}

void RhiVisualizer::OverdrawVis::prepare(Node *n, RhiVisualizer *visualizer,
                                         QRhi *rhi, QRhiResourceUpdateBatch *u)
{
    this->visualizer = visualizer;

    step += float(M_PI * 2 / 1000.0);
    if (step > float(M_PI * 2))
        step = 0.0f;

    const float yfix = rhi->isYUpInNDC() ? 1.0f : -1.0f;
    rotation.setToIdentity();
    rotation.translate(0.0f, 0.5f * yfix, 4.0f);
    rotation.scale(2.0f, 2.0f, 1.0f);
    rotation.rotate(-30.0f * yfix, 1.0f, 0.0f, 0.0f);
    rotation.rotate(80.0f * std::sin(step), 0.0f, 1.0f, 0.0f);
    rotation.translate(0.0f, 0.0f, -1.0f);

    drawCalls.clear();
    gather(n);

    if (!box.vbuf) {
        const float v[] = {
            // lower
            -1, 1, 0,   1, 1, 0,
            -1, 1, 0,   -1, -1, 0,
            1, 1, 0,    1, -1, 0,
            -1, -1, 0,  1, -1, 0,

            // upper
            -1, 1, 1,   1, 1, 1,
            -1, 1, 1,   -1, -1, 1,
            1, 1, 1,    1, -1, 1,
            -1, -1, 1,  1, -1, 1,

            // sides
            -1, -1, 0,  -1, -1, 1,
            1, -1, 0,   1, -1, 1,
            -1, 1, 0,   -1, 1, 1,
            1, 1, 0,    1, 1, 1
        };
        box.vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(v));
        if (!box.vbuf->build())
            return;
        u->uploadStaticBuffer(box.vbuf, v);
    }

    if (!box.ubuf) {
        box.ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, DrawCall::UBUF_SIZE);
        if (!box.ubuf->build())
            return;
        QMatrix4x4 ident;
        u->updateDynamicBuffer(box.ubuf, 0, 64, ident.constData());
        float color[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
        u->updateDynamicBuffer(box.ubuf, 128, 16, color);
        float pattern = 0.0f;
        u->updateDynamicBuffer(box.ubuf, 144, 4, &pattern);
        qint32 projection = 1;
        u->updateDynamicBuffer(box.ubuf, 148, 4, &projection);
    }

    u->updateDynamicBuffer(box.ubuf, 64, 64, rotation.constData());

    if (!box.srb) {
        box.srb = rhi->newShaderResourceBindings();
        box.srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, ubufVisibility, box.ubuf) });
        if (!box.srb->build())
            return;
    }

    if (!box.ps) {
        box.ps = rhi->newGraphicsPipeline();
        box.ps->setTopology(QRhiGraphicsPipeline::Lines);
        box.ps->setLineWidth(2); // may be be ignored (D3D, Metal), but may be used on GL and Vulkan
        QRhiGraphicsPipeline::TargetBlend blend;
        blend.enable = true;
        blend.srcColor = QRhiGraphicsPipeline::One;
        blend.dstColor = QRhiGraphicsPipeline::One;
        blend.srcAlpha = QRhiGraphicsPipeline::One;
        blend.dstAlpha = QRhiGraphicsPipeline::One;
        box.ps->setTargetBlends({ blend });
        box.ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
                                  { QRhiShaderStage::Fragment, visualizer->m_fs } });
        QRhiVertexInputLayout inputLayout;
        inputLayout.setBindings({ { 3 * sizeof(float) } });
        inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float3, 0 } });
        box.ps->setVertexInputLayout(inputLayout);
        box.ps->setShaderResourceBindings(box.srb);
        box.ps->setRenderPassDescriptor(visualizer->m_renderer->renderPassDescriptor());
        if (!box.ps->build())
            return;
    }

    if (drawCalls.isEmpty())
        return;

    const int ubufAlign = rhi->ubufAlignment();
    int vbufOffset = 0;
    int ibufOffset = 0;
    int ubufOffset = 0;
    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        dc.buf.vbufOffset = aligned(vbufOffset, 4);
        vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;

        dc.buf.ibufOffset = aligned(ibufOffset, 4);
        ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;

        dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
        ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
    }

    ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
    if (ibufOffset)
        ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
    const int ubufSize = ubufOffset;
    ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);

    for (RhiVisualizer::DrawCall &dc : drawCalls) {
        u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
        dc.buf.vbuf = vbuf;
        if (dc.index.count) {
            u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
            dc.buf.ibuf = ibuf;
        }
        u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
    }

    if (!srb) {
        srb = rhi->newShaderResourceBindings();
        srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
        if (!srb->build())
            return;
    }
}

void RhiVisualizer::OverdrawVis::releaseResources()
{
    delete srb;
    srb = nullptr;

    delete ubuf;
    ubuf = nullptr;

    delete ibuf;
    ibuf = nullptr;

    delete vbuf;
    vbuf = nullptr;

    delete box.ps;
    box.ps = nullptr;

    delete box.srb;
    box.srb = nullptr;

    delete box.ubuf;
    box.ubuf = nullptr;

    delete box.vbuf;
    box.vbuf = nullptr;
}

void RhiVisualizer::OverdrawVis::render(QRhiCommandBuffer *cb)
{
    cb->setGraphicsPipeline(box.ps);
    cb->setShaderResources();
    QRhiCommandBuffer::VertexInput vb(box.vbuf, 0);
    cb->setVertexInput(0, 1, &vb);
    cb->draw(24);

    visualizer->recordDrawCalls(drawCalls, cb, srb, true);
}

}

QT_END_NAMESPACE
