Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mark waveformrenderer using rendergraph #14188

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 65 additions & 61 deletions src/waveform/renderers/allshader/digitsrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
#include <QGraphicsBlurEffect>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QOpenGLTexture>
#include <QPainter>
#include <QPainterPath>
#include <cmath>

#include "rendergraph/context.h"
#include "rendergraph/geometry.h"
#include "rendergraph/material/texturematerial.h"
#include "rendergraph/vertexupdaters/texturedvertexupdater.h"
Comment on lines +12 to +15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be before the util includes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

#include "util/assert.h"
#include "util/roundtopixel.h"
#include "waveform/renderers/allshader/matrixforwidgetgeometry.h"
#include "waveform/renderers/allshader/vertexdata.h"

// Render digits using a texture (generated) with digits with blurred dark outline

using namespace rendergraph;

namespace {

// The texture will contain 12 characters: 10 digits, colon and dot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The texture will contain 12 characters: 10 digits, colon and dot
/// The texture will contain 12 characters: 10 digits, colon and dot

And elsewhere, so that it gets picked up by doxygen and IDEs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a clear policy on this? IMO this is just a comment to help understand the code, not really API doc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean we don't really do API docs because we don't give any stability guarantees.

We don't really have a policy but some time ago we said that we try to use triple slash where it makes sense (i.e. if we add comments to classes, functions or constants). That makes the comment accessible to IDEs/LSP and people can see it when hovering over a method/constant, so that they have the explanation at hand instead of having to scroll to the definition.

Just to clarify: we said that we don't want the full-blown @param syntax (also hard to maintain), just that we add an additional slash so that we get IDE support for free.

Expand Down Expand Up @@ -57,23 +60,22 @@ static_assert(checkCharToIndex());

} // namespace

allshader::DigitsRenderer::~DigitsRenderer() = default;

void allshader::DigitsRenderer::init() {
initializeOpenGLFunctions();
m_shader.init();
allshader::DigitsRenderNode::DigitsRenderNode() {
setGeometry(std::make_unique<Geometry>(TextureMaterial::attributes(), 0));
setMaterial(std::make_unique<TextureMaterial>());
geometry().setDrawingMode(Geometry::DrawingMode::Triangles);
}

float allshader::DigitsRenderer::height() const {
allshader::DigitsRenderNode::~DigitsRenderNode() = default;

float allshader::DigitsRenderNode::height() const {
return m_height;
}

void allshader::DigitsRenderer::updateTexture(
float fontPointSize, float maxHeight, float devicePixelRatio) {
if (std::lround(maxHeight * devicePixelRatio) <= 0) {
return;
}

void allshader::DigitsRenderNode::updateTexture(rendergraph::Context* pContext,
float fontPointSize,
float maxHeight,
float devicePixelRatio) {
if (fontPointSize == m_fontPointSize && maxHeight == m_maxHeight) {
return;
}
Expand Down Expand Up @@ -184,12 +186,12 @@ void allshader::DigitsRenderer::updateTexture(
blur->setBlurRadius(static_cast<float>(m_penWidth) / 3);

QGraphicsScene scene;
auto item = std::make_unique<QGraphicsPixmapItem>();
item->setPixmap(QPixmap::fromImage(image));
item->setGraphicsEffect(blur.release());
QGraphicsPixmapItem item;
item.setPixmap(QPixmap::fromImage(image));
item.setGraphicsEffect(blur.release());
image.fill(Qt::transparent);
QPainter painter(&image);
scene.addItem(item.release());
scene.addItem(&item);
scene.render(&painter, QRectF(), QRectF(0, 0, image.width(), image.height()));
}

Expand All @@ -210,64 +212,66 @@ void allshader::DigitsRenderer::updateTexture(
painter.drawPath(path);
}

m_texture.setData(image);
dynamic_cast<TextureMaterial&>(material())
.setTexture(std::make_unique<Texture>(pContext, image));
}

float allshader::DigitsRenderer::draw(const QMatrix4x4& matrix,
void allshader::DigitsRenderNode::update(
float x,
float y,
bool multiLine,
const QString& s1,
const QString& s2) {
const int numVerticesPerRectangle = 6;
const int reserved = (s1.length() + s2.length()) * numVerticesPerRectangle;
geometry().allocate(reserved);
TexturedVertexUpdater vertexUpdater{geometry().vertexDataAs<Geometry::TexturedPoint2D>()};

const float ch = height();
if (!s1.isEmpty()) {
const auto w = addVertices(vertexUpdater,
x,
y,
s1);
if (multiLine) {
y += ch;
} else {
x += w + ch * 0.75f;
}
}
if (!s2.isEmpty()) {
addVertices(vertexUpdater,
x,
y,
s2);
}

DEBUG_ASSERT(reserved == vertexUpdater.index());
}

void allshader::DigitsRenderNode::clear() {
geometry().allocate(0);
}

float allshader::DigitsRenderNode::addVertices(TexturedVertexUpdater& vertexUpdater,
float x,
float y,
const QString& s) {
const int n = s.length();
const float x0 = x;
const float space = static_cast<float>(m_penWidth) / 2;

VertexData posVertices;
VertexData texVertices;

posVertices.reserve(n * 6); // two triangles per character
texVertices.reserve(n * 6);

for (QChar c : s) {
if (x != x0) {
x -= space;
}
int index = charToIndex(c);

texVertices.addRectangle(m_offset[index], 0.f, m_offset[index + 1], 1.f);
posVertices.addRectangle(x,
y,
x + m_width[index],
y + height());
vertexUpdater.addRectangle({x, y},
{x + m_width[index], y + height()},
{m_offset[index], 0.f},
{m_offset[index + 1], 1.f});
x += m_width[index];
}

m_shader.bind();

const int matrixLocation = m_shader.uniformLocation("matrix");
const int textureLocation = m_shader.uniformLocation("texture");
const int positionLocation = m_shader.attributeLocation("position");
const int texcoordLocation = m_shader.attributeLocation("texcoord");

m_shader.setUniformValue(matrixLocation, matrix);

m_shader.enableAttributeArray(positionLocation);
m_shader.setAttributeArray(
positionLocation, GL_FLOAT, posVertices.constData(), 2);
m_shader.enableAttributeArray(texcoordLocation);
m_shader.setAttributeArray(
texcoordLocation, GL_FLOAT, texVertices.constData(), 2);

m_shader.setUniformValue(textureLocation, 0);

m_texture.bind();

glDrawArrays(GL_TRIANGLES, 0, posVertices.size());

m_texture.release();

m_shader.disableAttributeArray(positionLocation);
m_shader.disableAttributeArray(texcoordLocation);
m_shader.release();

return x - x0;
}
44 changes: 29 additions & 15 deletions src/waveform/renderers/allshader/digitsrenderer.h
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
#pragma once

#include <QOpenGLFunctions>
#include "rendergraph/context.h"
#include "rendergraph/geometrynode.h"
#include "util/class.h"

#include "shaders/textureshader.h"
#include "util/opengltexture2d.h"
namespace rendergraph {
class TexturedVertexUpdater;
} // namespace rendergraph

namespace allshader {
class DigitsRenderer;
}
class DigitsRenderNode;
} // namespace allshader

class allshader::DigitsRenderer : public QOpenGLFunctions {
class allshader::DigitsRenderNode : public rendergraph::GeometryNode {
public:
DigitsRenderer() = default;
~DigitsRenderer();
DigitsRenderNode();
~DigitsRenderNode();

void init();
void updateTexture(float fontPointSize, float maxHeight, float devicePixelRatio);
float draw(const QMatrix4x4& matrix,
void updateTexture(rendergraph::Context* pContext,
float fontPointSize,
float maxHeight,
float devicePixelRatio);

void update(
float x,
float y,
const QString& s);
bool multiLine,
const QString& s1,
const QString& s2);

void clear();

float height() const;

private:
mixxx::TextureShader m_shader;
OpenGLTexture2D m_texture;
float addVertices(rendergraph::TexturedVertexUpdater& vertexUpdater,
float x,
float y,
const QString& s);

int m_penWidth;
float m_offset[13];
float m_width[12];
float m_fontPointSize{};
float m_height{};
float m_maxHeight{};
float m_adjustedFontPointSize{};
DISALLOW_COPY_AND_ASSIGN(DigitsRenderer);
DISALLOW_COPY_AND_ASSIGN(DigitsRenderNode);
};
Loading
Loading