From: Ivailo Monev Date: Tue, 26 Jul 2016 00:47:19 +0000 (+0000) Subject: cleanup the OpenGL painting engine X-Git-Tag: 4.12.0~6942 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=da73e0a79a8609d0ce1661e9ab1dfb47567afc78;p=kde%2FKatie.git cleanup the OpenGL painting engine Signed-off-by: Ivailo Monev --- diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index eb4298264..5d1f077ad 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -99,10 +99,6 @@ static bool DEBUG_TEMP_FLAG; #define DEBUG_ONCE_STR(str) DEBUG_ONCE qDebug() << (str); #endif -#ifdef Q_WS_X11 -static bool qt_nvidiaFboNeedsFinish = false; -#endif - static inline void qt_glColor4ubv(unsigned char *col) { glColor4f(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, col[3]/255.0f); @@ -416,12 +412,6 @@ inline void QGLOffscreen::release() if (!offscreen || !bound) return; -#ifdef Q_WS_X11 - // workaround for bug in nvidia driver versions 9x.xx - if (qt_nvidiaFboNeedsFinish) - glFinish(); -#endif - DEBUG_ONCE_STR("QGLOffscreen: releasing offscreen"); if (drawable_fbo) @@ -650,7 +640,6 @@ public: , composition_mode(QPainter::CompositionMode_SourceOver) , has_pen(false) , has_brush(false) - , has_fast_pen(false) , use_stencil_method(false) , dirty_drawable_texture(false) , has_stencil_face_ext(false) @@ -701,7 +690,6 @@ public: void drawFastRect(const QRectF &rect); void strokePath(const QPainterPath &path, bool use_cache); - void strokePathFastPen(const QPainterPath &path, bool needsResolving); void strokeLines(const QPainterPath &path); void updateDepthClip(); @@ -712,16 +700,6 @@ public: shader_ctx = 0; } - inline void updateFastPen() { - qreal pen_width = cpen.widthF(); - has_fast_pen = - ((pen_width == 0 || (pen_width <= 1 && matrix.type() <= QTransform::TxTranslate)) - || cpen.isCosmetic()) - && cpen.style() == Qt::SolidLine - && cpen.isSolid(); - - } - void disableClipping(); void enableClipping(); void ensureDrawableTexture(); @@ -738,7 +716,6 @@ public: uint has_pen : 1; uint has_brush : 1; - uint has_fast_pen : 1; uint use_stencil_method : 1; uint dirty_drawable_texture : 1; uint has_stencil_face_ext : 1; @@ -1246,7 +1223,6 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev) return false; d->offscreen.setDevice(pdev); - d->has_fast_pen = false; d->inverseScale = 1; d->opacity = 1; d->device->beginPaint(); @@ -1281,22 +1257,6 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev) && (d->use_stencil_method && QGLExtensions::glExtensions() & QGLExtensions::StencilTwoSide)) d->has_stencil_face_ext = qt_resolve_stencil_face_extension(ctx); -#ifdef Q_WS_X11 - static bool nvidia_workaround_needs_init = true; - if (nvidia_workaround_needs_init) { - // nvidia 9x.xx unix drivers contain a bug which requires us to - // call glFinish before releasing an fbo to avoid painting - // artifacts - const QByteArray versionString(reinterpret_cast(glGetString(GL_VERSION))); - const int pos = versionString.indexOf("NVIDIA"); - if (pos >= 0) { - const float nvidiaDriverVersion = versionString.mid(pos + strlen("NVIDIA")).toFloat(); - qt_nvidiaFboNeedsFinish = nvidiaDriverVersion >= 90.0 && nvidiaDriverVersion < 100.0; - } - nvidia_workaround_needs_init = false; - } -#endif - #ifndef QT_OPENGL_ES if (!ctx->d_ptr->internal_context) { glGetDoublev(GL_PROJECTION_MATRIX, &d->projection_matrix[0][0]); @@ -1459,10 +1419,7 @@ void QOpenGLPaintEngine::updateState(const QPaintEngineState &state) Q_D(QOpenGLPaintEngine); QPaintEngine::DirtyFlags flags = state.state(); - bool update_fast_pen = false; - if (flags & DirtyOpacity) { - update_fast_pen = true; d->opacity = state.opacity(); if (d->opacity > 1.0f) d->opacity = 1.0f; @@ -1474,7 +1431,6 @@ void QOpenGLPaintEngine::updateState(const QPaintEngineState &state) } if (flags & DirtyTransform) { - update_fast_pen = true; updateMatrix(state.transform()); // brush setup depends on transform state if (state.brush().style() != Qt::NoBrush) @@ -1482,7 +1438,6 @@ void QOpenGLPaintEngine::updateState(const QPaintEngineState &state) } if (flags & DirtyPen) { - update_fast_pen = true; updatePen(state.pen()); } @@ -1518,16 +1473,6 @@ void QOpenGLPaintEngine::updateState(const QPaintEngineState &state) if (flags & DirtyCompositionMode) { updateCompositionMode(state.compositionMode()); } - - if (update_fast_pen) { - Q_D(QOpenGLPaintEngine); - qreal pen_width = d->cpen.widthF(); - d->has_fast_pen = - ((pen_width == 0 || (pen_width <= 1 && d->txop <= QTransform::TxTranslate)) - || d->cpen.isCosmetic()) - && d->cpen.style() == Qt::SolidLine - && d->cpen.isSolid(); - } } @@ -2151,8 +2096,6 @@ void QOpenGLPaintEngine::updatePen(const QPen &pen) } else { d->setGLPen(pen.color()); } - - d->updateFastPen(); } void QOpenGLPaintEngine::updateBrush(const QBrush &brush, const QPointF &origin) @@ -2204,7 +2147,6 @@ void QOpenGLPaintEngine::updateMatrix(const QTransform &mtx) qreal(0.0001)); d->updateGLMatrix(); - d->updateFastPen(); } void QOpenGLPaintEnginePrivate::updateGLMatrix() const @@ -3428,33 +3370,21 @@ void QOpenGLPaintEnginePrivate::drawFastRect(const QRectF &r) } if (has_pen) { - if (has_fast_pen && !high_quality_antialiasing) { - setGradientOps(cpen.brush(), r); - - vertexArray[8] = vertexArray[0]; - vertexArray[9] = vertexArray[1]; - - glVertexPointer(2, GL_FLOAT, 0, vertexArray); - glEnableClientState(GL_VERTEX_ARRAY); - glDrawArrays(GL_LINE_STRIP, 0, 5); - glDisableClientState(GL_VERTEX_ARRAY); - } else { - QPainterPath path; - path.setFillRule(Qt::WindingFill); + QPainterPath path; + path.setFillRule(Qt::WindingFill); - qreal left = r.left(); - qreal right = r.right(); - qreal top = r.top(); - qreal bottom = r.bottom(); + qreal left = r.left(); + qreal right = r.right(); + qreal top = r.top(); + qreal bottom = r.bottom(); - path.moveTo(left, top); - path.lineTo(right, top); - path.lineTo(right, bottom); - path.lineTo(left, bottom); - path.lineTo(left, top); + path.moveTo(left, top); + path.lineTo(right, top); + path.lineTo(right, bottom); + path.lineTo(left, bottom); + path.lineTo(left, top); - strokePath(path, false); - } + strokePath(path, false); QOpenGLCoordinateOffset::disableOffset(this); } @@ -3532,36 +3462,12 @@ void QOpenGLPaintEngine::drawRects(const QRectF *rects, int rectCount) } if (d->has_pen) { - if (d->has_fast_pen) - d->strokeLines(path); - else - d->strokePath(path, false); + d->strokePath(path, false); } } } } -static void addQuadAsTriangle(GLfloat *quad, GLfloat *triangle) -{ - triangle[0] = quad[0]; - triangle[1] = quad[1]; - - triangle[2] = quad[2]; - triangle[3] = quad[3]; - - triangle[4] = quad[4]; - triangle[5] = quad[5]; - - triangle[6] = quad[4]; - triangle[7] = quad[5]; - - triangle[8] = quad[6]; - triangle[9] = quad[7]; - - triangle[10] = quad[0]; - triangle[11] = quad[1]; -} - void QOpenGLPaintEngine::drawPoints(const QPoint *points, int pointCount) { Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF)); @@ -3601,41 +3507,6 @@ void QOpenGLPaintEngine::drawPoints(const QPointF *points, int pointCount) d->flushDrawQueue(); - if (d->has_fast_pen) { - QVarLengthArray vertexArray(6 * pointCount); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - int j = 0; - for (int i = 0; i < pointCount; ++i) { - QPointF mapped = d->matrix.map(points[i]); - - GLfloat x = GLfloat(qRound(mapped.x())); - GLfloat y = GLfloat(qRound(mapped.y())); - - vertexArray[j++] = x; - vertexArray[j++] = y - 0.5f; - - vertexArray[j++] = x + 1.5f; - vertexArray[j++] = y + 1.0f; - - vertexArray[j++] = x; - vertexArray[j++] = y + 1.0f; - } - - glEnableClientState(GL_VERTEX_ARRAY); - - glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); - glDrawArrays(GL_TRIANGLES, 0, pointCount*3); - - glDisableClientState(GL_VERTEX_ARRAY); - - glPopMatrix(); - return; - } - const qreal *vertexArray = reinterpret_cast(&points[0]); if (sizeof(qreal) == sizeof(double)) { @@ -3690,122 +3561,24 @@ void QOpenGLPaintEngine::drawLines(const QLineF *lines, int lineCount) } if (d->has_pen) { - QOpenGLCoordinateOffset offset(d); - if (d->has_fast_pen && !d->high_quality_antialiasing) { - //### gradient resolving on lines isn't correct - d->setGradientOps(d->cpen.brush(), QRectF()); - - bool useRects = false; - // scale or 90 degree rotation? - if (d->matrix.type() <= QTransform::TxTranslate - || (!d->cpen.isCosmetic() - && (d->matrix.type() <= QTransform::TxScale - || (d->matrix.type() == QTransform::TxRotate - && d->matrix.m11() == 0 && d->matrix.m22() == 0)))) { - useRects = true; - for (int i = 0; i < lineCount; ++i) { - if (lines[i].p1().x() != lines[i].p2().x() - && lines[i].p1().y() != lines[i].p2().y()) { - useRects = false; - break; - } - } - } - - GLfloat endCap = d->cpen.capStyle() == Qt::FlatCap ? 0.0f : 0.5f; - if (useRects) { - QVarLengthArray vertexArray(12 * lineCount); - - GLfloat quad[8]; - for (int i = 0; i < lineCount; ++i) { - GLfloat x1 = lines[i].x1(); - GLfloat x2 = lines[i].x2(); - GLfloat y1 = lines[i].y1(); - GLfloat y2 = lines[i].y2(); - - if (x1 == x2) { - if (y1 > y2) - qSwap(y1, y2); - - quad[0] = x1 - 0.5f; - quad[1] = y1 - endCap; - - quad[2] = x1 + 0.5f; - quad[3] = y1 - endCap; - - quad[4] = x1 + 0.5f; - quad[5] = y2 + endCap; - - quad[6] = x1 - 0.5f; - quad[7] = y2 + endCap; - } else { - if (x1 > x2) - qSwap(x1, x2); - - quad[0] = x1 - endCap; - quad[1] = y1 + 0.5f; - - quad[2] = x1 - endCap; - quad[3] = y1 - 0.5f; - - quad[4] = x2 + endCap; - quad[5] = y1 - 0.5f; - - quad[6] = x2 + endCap; - quad[7] = y1 + 0.5f; - } - - addQuadAsTriangle(quad, &vertexArray[12*i]); - } - - glEnableClientState(GL_VERTEX_ARRAY); - - glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); - glDrawArrays(GL_TRIANGLES, 0, lineCount*6); - - glDisableClientState(GL_VERTEX_ARRAY); - } else { - QVarLengthArray vertexArray(4 * lineCount); - for (int i = 0; i < lineCount; ++i) { - vertexArray[4*i] = lines[i].x1(); - vertexArray[4*i+1] = lines[i].y1(); - vertexArray[4*i+2] = lines[i].x2(); - vertexArray[4*i+3] = lines[i].y2(); - } - - glEnableClientState(GL_VERTEX_ARRAY); - - glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); - glDrawArrays(GL_LINES, 0, lineCount*2); - - glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), vertexArray.constData() + 2); - glDrawArrays(GL_POINTS, 0, lineCount); - - glDisableClientState(GL_VERTEX_ARRAY); - } - } else { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - for (int i=0; icpen.capStyle() != Qt::FlatCap) { - QPointF p = l.p1(); - drawPoints(&p, 1); - } - continue; + QPainterPath path; + path.setFillRule(Qt::WindingFill); + for (int i=0; icpen.capStyle() != Qt::FlatCap) { + QPointF p = l.p1(); + drawPoints(&p, 1); } - - path.moveTo(l.x1(), l.y1()); - path.lineTo(l.x2(), l.y2()); + continue; } - if (d->has_fast_pen && d->high_quality_antialiasing) - d->strokeLines(path); - else - d->strokePath(path, false); + path.moveTo(l.x1(), l.y1()); + path.lineTo(l.x2(), l.y2()); } + + d->strokePath(path, false); } } @@ -3832,8 +3605,7 @@ void QOpenGLPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly } QRectF bounds; - if ((mode == ConvexMode && !d->high_quality_antialiasing && state()->brushNeedsResolving()) || - ((d->has_fast_pen && !d->high_quality_antialiasing) && state()->penNeedsResolving())) { + if (mode == ConvexMode && !d->high_quality_antialiasing && state()->brushNeedsResolving()) { qreal minx = points[0].x(), miny = points[0].y(), maxx = points[0].x(), maxy = points[0].y(); for (int i = 1; i < pointCount; ++i) { @@ -3882,38 +3654,13 @@ void QOpenGLPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly } if (d->has_pen) { - if (d->has_fast_pen && !d->high_quality_antialiasing) { - d->setGradientOps(d->cpen.brush(), bounds); - QVarLengthArray vertexArray(pointCount*2 + 2); - glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); - int i; - for (i=0; ihas_fast_pen) - d->strokeLines(path); - else - d->strokePath(path, true); - } + d->strokePath(path, true); } } @@ -3987,140 +3734,6 @@ void QOpenGLPaintEnginePrivate::strokePath(const QPainterPath &path, bool use_ca cbrush = old_brush; } -void QOpenGLPaintEnginePrivate::strokePathFastPen(const QPainterPath &path, bool needsResolving) -{ -#ifndef QT_OPENGL_ES - QRectF bounds; - if (needsResolving) - bounds = path.controlPointRect(); - setGradientOps(cpen.brush(), bounds); - - QBezier beziers[32]; - for (int i=0; i= beziers) { - // check if we can pop the top bezier curve from the stack - qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1); - qreal d; - if (l > inverseScale) { - d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - - (b->y4 - b->y1)*(b->x1 - b->x2) ) - + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - - (b->y4 - b->y1)*(b->x1 - b->x3) ); - d /= l; - } else { - d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) + - qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3); - } - if (d < inverseScaleHalf || b == beziers + 31) { - // good enough, we pop it off and add the endpoint - glVertex2d(b->x4, b->y4); - --b; - } else { - // split, second half of the polygon goes lower into the stack - b->split(b+1, b); - ++b; - } - } - } // case CurveToElement - default: - break; - } // end of switch - } - glEnd(); // GL_LINE_STRIP -#else - // have to use vertex arrays on embedded - QRectF bounds; - if (needsResolving) - bounds = path.controlPointRect(); - setGradientOps(cpen.brush(), bounds); - - glEnableClientState(GL_VERTEX_ARRAY); - tess_points.reset(); - QBezier beziers[32]; - for (int i=0; i= beziers) { - // check if we can pop the top bezier curve from the stack - qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1); - qreal d; - if (l > inverseScale) { - d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - - (b->y4 - b->y1)*(b->x1 - b->x2) ) - + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - - (b->y4 - b->y1)*(b->x1 - b->x3) ); - d /= l; - } else { - d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) + - qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3); - } - if (d < inverseScaleHalf || b == beziers + 31) { - // good enough, we pop it off and add the endpoint - tess_points.add(QPointF(b->x4, b->y4)); - --b; - } else { - // split, second half of the polygon goes lower into the stack - b->split(b+1, b); - ++b; - } - } - } // case CurveToElement - default: - break; - } // end of switch - } - glVertexPointer(2, GL_FLOAT, 0, tess_points.data()); - glDrawArrays(GL_LINE_STRIP, 0, tess_points.size()); - glDisableClientState(GL_VERTEX_ARRAY); -#endif -} - static bool pathClosed(const QPainterPath &path) { QPointF lastMoveTo = path.elementAt(0); @@ -4198,10 +3811,7 @@ void QOpenGLPaintEngine::drawPath(const QPainterPath &path) } if (d->has_pen) { - if (d->has_fast_pen && !d->high_quality_antialiasing) - d->strokePathFastPen(path, state()->penNeedsResolving()); - else - d->strokePath(path, true); + d->strokePath(path, true); } } @@ -5436,18 +5046,6 @@ void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush) updateBrush(old_brush, state()->brushOrigin); } -template static inline bool isRect(const T *pts, int elementCount) { - return (elementCount == 5 // 5-point polygon, check for closed rect - && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point - && pts[0] == pts[6] && pts[2] == pts[4] // x values equal - && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... - ) || - (elementCount == 4 // 4-point polygon, check for unclosed rect - && pts[0] == pts[6] && pts[2] == pts[4] // x values equal - && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... - ); -} - void QOpenGLPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { const qreal *points = path.points();