-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Fix crash when hiding waveforms in Deere #14170
Changes from 4 commits
6fc3426
ac9ac48
5f693d0
5f82622
8ae7d2f
4c368f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,17 +97,17 @@ void allshader::WaveformRenderMark::initializeGL() { | |
} | ||
|
||
void allshader::WaveformRenderMark::drawTexture( | ||
const QMatrix4x4& matrix, float x, float y, QOpenGLTexture* texture) { | ||
const QMatrix4x4& matrix, float x, float y, QOpenGLTexture* pTexture) { | ||
const float devicePixelRatio = m_waveformRenderer->getDevicePixelRatio(); | ||
const float texx1 = 0.f; | ||
const float texy1 = 0.f; | ||
const float texx2 = 1.f; | ||
const float texy2 = 1.f; | ||
|
||
const float posx1 = x; | ||
const float posx2 = x + static_cast<float>(texture->width() / devicePixelRatio); | ||
const float posx2 = x + static_cast<float>(pTexture->width() / devicePixelRatio); | ||
const float posy1 = y; | ||
const float posy2 = y + static_cast<float>(texture->height() / devicePixelRatio); | ||
const float posy2 = y + static_cast<float>(pTexture->height() / devicePixelRatio); | ||
|
||
const float posarray[] = {posx1, posy1, posx2, posy1, posx1, posy2, posx2, posy2}; | ||
const float texarray[] = {texx1, texy1, texx2, texy1, texx1, texy2, texx2, texy2}; | ||
|
@@ -130,11 +130,11 @@ void allshader::WaveformRenderMark::drawTexture( | |
|
||
m_textureShader.setUniformValue(textureLocation, 0); | ||
|
||
texture->bind(); | ||
pTexture->bind(); | ||
|
||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||
|
||
texture->release(); | ||
pTexture->release(); | ||
|
||
m_textureShader.disableAttributeArray(positionLocation); | ||
m_textureShader.disableAttributeArray(texcoordLocation); | ||
|
@@ -231,6 +231,11 @@ void allshader::WaveformRenderMark::paintGL() { | |
static_cast<TextureGraphics*>(pMark->m_pGraphics.get()) | ||
->texture(); | ||
|
||
if (!pTexture->isCreated()) { | ||
// This happens if the height is zero | ||
continue; | ||
} | ||
|
||
const float currentMarkPoint = | ||
std::round( | ||
static_cast<float>( | ||
|
@@ -383,20 +388,22 @@ void allshader::WaveformRenderMark::drawUntilMark(const QMatrix4x4& matrix, floa | |
// Note that in the legacy waveform widgets this is drawn directly | ||
// in the WaveformWidgetRenderer itself. Doing it here is cleaner. | ||
void allshader::WaveformRenderMark::updatePlayPosMarkTexture() { | ||
float imgwidth; | ||
float imgheight; | ||
const float imgheight = m_waveformRenderer->getBreadth(); | ||
const float imgwidth = 11.f; | ||
|
||
const float height = m_waveformRenderer->getBreadth(); | ||
const float devicePixelRatio = m_waveformRenderer->getDevicePixelRatio(); | ||
if (imgheight == 0.0f) { | ||
return; | ||
} | ||
|
||
const float devicePixelRatio = m_waveformRenderer->getDevicePixelRatio(); | ||
const float lineX = 5.5f; | ||
|
||
imgwidth = 11.f; | ||
imgheight = height; | ||
|
||
QImage image(static_cast<int>(imgwidth * devicePixelRatio), | ||
static_cast<int>(imgheight * devicePixelRatio), | ||
QImage::Format_ARGB32_Premultiplied); | ||
if (image.isNull()) { | ||
return; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imgWidth is < 0 and there is already a check for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When looking at the Qt source, there are other reasons like out of memory or such. All can't probably not happen but this saves Mixxx from crash if it happen anyway. I think a |
||
image.setDevicePixelRatio(devicePixelRatio); | ||
image.fill(QColor(0, 0, 0, 0).rgba()); | ||
|
||
|
@@ -417,8 +424,8 @@ void allshader::WaveformRenderMark::updatePlayPosMarkTexture() { | |
// lines next to playpos | ||
// Note: don't draw lines where they would overlap the triangles, | ||
// otherwise both translucent strokes add up to a darker tone. | ||
painter.drawLine(QLineF(lineX + 1.f, 4.f, lineX + 1.f, height)); | ||
painter.drawLine(QLineF(lineX - 1.f, 4.f, lineX - 1.f, height)); | ||
painter.drawLine(QLineF(lineX + 1.f, 4.f, lineX + 1.f, imgheight)); | ||
painter.drawLine(QLineF(lineX - 1.f, 4.f, lineX - 1.f, imgheight)); | ||
|
||
// triangle at top edge | ||
// Increase line/waveform contrast | ||
|
@@ -433,7 +440,7 @@ void allshader::WaveformRenderMark::updatePlayPosMarkTexture() { | |
painter.setPen(fgColor); | ||
painter.setOpacity(1.0); | ||
// play position line | ||
painter.drawLine(QLineF(lineX, 0.f, lineX, height)); | ||
painter.drawLine(QLineF(lineX, 0.f, lineX, imgheight)); | ||
// triangle at top edge | ||
{ | ||
QPointF baseL = QPointF(lineX - 4.f, 0.f); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,13 +204,8 @@ bool WaveformMark::contains(QPoint point, Qt::Orientation orientation) const { | |
|
||
// Helper struct to calculate the geometry and fontsize needed by generateImage | ||
// to draw the label and text | ||
struct MarkerGeometry { | ||
bool m_isSymbol; // is the label normal text or a single symbol (e.g. open circle arrow) | ||
QFont m_font; | ||
QRectF m_contentRect; | ||
QRectF m_labelRect; | ||
QSizeF m_imageSize; | ||
|
||
class MarkerGeometry { | ||
public: | ||
MarkerGeometry(const QString& label, | ||
bool useIcon, | ||
Qt::Alignment align, | ||
|
@@ -314,10 +309,37 @@ struct MarkerGeometry { | |
return QSize{static_cast<int>(m_imageSize.width() * devicePixelRatio), | ||
static_cast<int>(m_imageSize.height() * devicePixelRatio)}; | ||
} | ||
|
||
const QFont font() const { | ||
return m_font; | ||
} | ||
|
||
const QRectF& contentRect() const { | ||
return m_contentRect; | ||
} | ||
|
||
const QRectF& labelRect() const { | ||
return m_labelRect; | ||
} | ||
|
||
const QSizeF& imageSize() const { | ||
return m_imageSize; | ||
} | ||
|
||
private: | ||
bool m_isSymbol; // is the label normal text or a single symbol (e.g. open circle arrow) | ||
QFont m_font; | ||
QRectF m_contentRect; | ||
QRectF m_labelRect; | ||
QSizeF m_imageSize; | ||
}; | ||
|
||
QImage WaveformMark::generateImage(float devicePixelRatio) { | ||
assert(needsImageUpdate()); | ||
DEBUG_ASSERT(needsImageUpdate()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VERIFY_OR_DEBUG_ASSERT ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but we assert that it never happens and when it happens, it does no harm. |
||
|
||
if (m_breadth == 0.0f) { | ||
return {}; | ||
} | ||
|
||
// Load the pixmap from file. | ||
// If that succeeds loading the text and stroke is skipped. | ||
|
@@ -355,11 +377,14 @@ QImage WaveformMark::generateImage(float devicePixelRatio) { | |
// Determine drawing geometries | ||
const MarkerGeometry markerGeometry{label, useIcon, m_align, m_breadth, m_level}; | ||
|
||
m_label.setAreaRect(markerGeometry.m_labelRect); | ||
m_label.setAreaRect(markerGeometry.labelRect()); | ||
|
||
// Create the image | ||
QImage image{markerGeometry.getImageSize(devicePixelRatio), | ||
QImage::Format_ARGB32_Premultiplied}; | ||
if (image.isNull()) { | ||
return image; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how can that happen? |
||
image.setDevicePixelRatio(devicePixelRatio); | ||
|
||
// Fill with transparent pixels | ||
|
@@ -374,53 +399,53 @@ QImage WaveformMark::generateImage(float devicePixelRatio) { | |
painter.setWorldMatrixEnabled(false); | ||
|
||
// Draw marker lines | ||
const auto hcenter = markerGeometry.m_imageSize.width() / 2.f; | ||
const auto hcenter = markerGeometry.imageSize().width() / 2.f; | ||
m_linePosition = static_cast<float>(hcenter); | ||
|
||
// Draw the center line | ||
painter.setPen(fillColor()); | ||
painter.drawLine(QLineF(hcenter, 0.f, hcenter, markerGeometry.m_imageSize.height())); | ||
painter.drawLine(QLineF(hcenter, 0.f, hcenter, markerGeometry.imageSize().height())); | ||
|
||
painter.setPen(borderColor()); | ||
painter.drawLine(QLineF(hcenter - 1.f, | ||
0.f, | ||
hcenter - 1.f, | ||
markerGeometry.m_imageSize.height())); | ||
markerGeometry.imageSize().height())); | ||
painter.drawLine(QLineF(hcenter + 1.f, | ||
0.f, | ||
hcenter + 1.f, | ||
markerGeometry.m_imageSize.height())); | ||
markerGeometry.imageSize().height())); | ||
|
||
if (useIcon || label.length() != 0) { | ||
painter.setPen(borderColor()); | ||
|
||
// Draw the label rounded rect with border | ||
QPainterPath path; | ||
path.addRoundedRect(markerGeometry.m_labelRect, 2.f, 2.f); | ||
path.addRoundedRect(markerGeometry.labelRect(), 2.f, 2.f); | ||
painter.fillPath(path, fillColor()); | ||
painter.drawPath(path); | ||
|
||
// Center m_contentRect.width() and m_contentRect.height() inside m_labelRect | ||
// and apply the offset x,y so the text ends up in the centered width,height. | ||
QPointF pos(markerGeometry.m_labelRect.x() + | ||
(markerGeometry.m_labelRect.width() - | ||
markerGeometry.m_contentRect.width()) / | ||
QPointF pos(markerGeometry.labelRect().x() + | ||
(markerGeometry.labelRect().width() - | ||
markerGeometry.contentRect().width()) / | ||
2.f - | ||
markerGeometry.m_contentRect.x(), | ||
markerGeometry.m_labelRect.y() + | ||
(markerGeometry.m_labelRect.height() - | ||
markerGeometry.m_contentRect.height()) / | ||
markerGeometry.contentRect().x(), | ||
markerGeometry.labelRect().y() + | ||
(markerGeometry.labelRect().height() - | ||
markerGeometry.contentRect().height()) / | ||
2.f - | ||
markerGeometry.m_contentRect.y()); | ||
markerGeometry.contentRect().y()); | ||
|
||
if (useIcon) { | ||
QSvgRenderer svgRenderer(m_iconPath); | ||
svgRenderer.render(&painter, QRectF(pos, markerGeometry.m_contentRect.size())); | ||
svgRenderer.render(&painter, QRectF(pos, markerGeometry.contentRect().size())); | ||
} else { | ||
// Draw the text | ||
painter.setBrush(Qt::transparent); | ||
painter.setPen(labelColor()); | ||
painter.setFont(markerGeometry.m_font); | ||
painter.setFont(markerGeometry.font()); | ||
|
||
painter.drawText(pos, label); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and where used, of course.