Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75e3ef04 authored by Chet Haase's avatar Chet Haase Committed by Android (Google) Code Review
Browse files

Merge "Fix various hw-accelerated line/point bugs"

parents 2ef1ce49 8a5cc92a
Loading
Loading
Loading
Loading
+63 −89
Original line number Diff line number Diff line
@@ -979,8 +979,8 @@ void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float ri
    }
}

void OpenGLRenderer::setupDrawModelViewIdentity() {
    mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform);
void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) {
    mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform, offset);
}

void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom,
@@ -1389,13 +1389,46 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
    }
}

void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool isHairline,
        float strokeWidth) {
void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
    if (mSnapshot->isIgnored()) return;

    const bool isAA = paint->isAntiAlias();
    float strokeWidth = paint->getStrokeWidth() * 0.5f;
    // A stroke width of 0 has a special meaning in Skia:
    // it draws a line 1 px wide regardless of current transform
    bool isHairLine = paint->getStrokeWidth() == 0.0f;
    int alpha;
    SkXfermode::Mode mode;
    int generatedVerticesCount = 0;
    int verticesCount = count;
    if (count > 4) {
        // Polyline: account for extra vertices needed for continous tri-strip
        verticesCount += (count -4);
    }

    getAlphaAndMode(paint, &alpha, &mode);
    setupDraw();
    if (isAA) {
        setupDrawAALine();
    }
    setupDrawColor(paint->getColor(), alpha);
    setupDrawColorFilter();
    setupDrawShader();
    if (isAA) {
        setupDrawBlending(true, mode);
    } else {
        setupDrawBlending(mode);
    }
    setupDrawProgram();
    setupDrawModelViewIdentity(true);
    setupDrawColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderIdentityUniforms();

    if (isHairLine) {
        // Set a real stroke width to be used in quad construction
        strokeWidth = .5;
    }
    if (isAA) {
        // Expand boundary to enable AA calculations on the quad border
        strokeWidth += .5f;
@@ -1407,25 +1440,22 @@ void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool
    if (!isAA) {
        setupDrawVertices(vertices);
    } else {
        AlphaVertex* alphaCoords = aaVertices + gVertexAlphaOffset;
        void* alphaCoords = ((GLbyte*) aaVertices) + gVertexAlphaOffset;
        // innerProportion is the ratio of the inner (non-AA) port of the line to the total
        // AA stroke width (the base stroke width expanded by a half pixel on either side).
        // This value is used in the fragment shader to determine how to fill fragments.
        float innerProportion = fmax(strokeWidth - 1.0f, 0) / (strokeWidth + .5f);
        setupDrawAALine((void*) aaVertices, (void*) alphaCoords, innerProportion);
        setupDrawAALine((void*) aaVertices, alphaCoords, innerProportion);
    }

    int generatedVerticesCount = 0;
    AlphaVertex *prevAAVertex = NULL;
    Vertex *prevVertex = NULL;
    float inverseScaleX = 1.0f;
    float inverseScaleY = 1.0f;

    if (isHairline) {
    if (isHairLine) {
        // The quad that we use for AA hairlines needs to account for scaling because the line
        // should always be one pixel wide regardless of scale.
        inverseScaleX = 1.0f;
        inverseScaleY = 1.0f;
        if (!mSnapshot->transform->isPureTranslate()) {
            Matrix4 *mat = mSnapshot->transform;
            float m00 = mat->data[Matrix4::kScaleX];
@@ -1446,23 +1476,20 @@ void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool
        vec2 a(points[i], points[i + 1]);
        vec2 b(points[i + 2], points[i + 3]);

        // Bias to snap to the same pixels as Skia
        a += 0.375;
        b += 0.375;

        // Find the normal to the line
        vec2 n = (b - a).copyNormalized() * strokeWidth;
        if (isHairline) {
        if (isHairLine) {
            n *= inverseScaleX;
            if (isAA) {
                float wideningFactor;
                if (fabs(n.x) >= fabs(n.y)) {
                    wideningFactor = fabs(1.0f / n.x);
                } else {
                    wideningFactor = fabs(1.0f / n.y);
                }
            n.x *= inverseScaleX;
            n.y *= inverseScaleY;
                n *= wideningFactor;
            }
        }
        float x = n.x;
        n.x = -n.y;
        n.y = x;
@@ -1525,69 +1552,6 @@ void OpenGLRenderer::drawLinesAsQuads(float *points, int count, bool isAA, bool
    }
}

void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
    if (mSnapshot->isIgnored()) return;

    const bool isAA = paint->isAntiAlias();
    const float strokeWidth = paint->getStrokeWidth() * 0.5f;
    // A stroke width of 0 has a special meaning in Skia:
    // it draws a line 1 px wide regardless of current transform
    bool isHairLine = paint->getStrokeWidth() == 0.0f;

    int alpha;
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);
    int generatedVerticesCount = 0;

    setupDraw();
    if (isAA) {
        setupDrawAALine();
    }
    setupDrawColor(paint->getColor(), alpha);
    setupDrawColorFilter();
    setupDrawShader();
    if (isAA) {
        setupDrawBlending(true, mode);
    } else {
        setupDrawBlending(mode);
    }
    setupDrawProgram();
    setupDrawModelViewIdentity();
    setupDrawColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderIdentityUniforms();

    if (!isHairLine) {
        drawLinesAsQuads(points, count, isAA, isHairLine, strokeWidth);
    } else {
        if (isAA) {
            drawLinesAsQuads(points, count, isAA, isHairLine, .5f);
        } else {
            int verticesCount = count >> 1;
            Vertex lines[verticesCount];
            Vertex* vertices = &lines[0];
            setupDrawVertices(vertices);
            for (int i = 0; i < count; i += 4) {

                const float left = fmin(points[i], points[i + 2]);
                const float right = fmax(points[i], points[i + 2]);
                const float top = fmin(points[i + 1], points[i + 3]);
                const float bottom = fmax(points[i + 1], points[i + 3]);

                Vertex::set(vertices++, points[i], points[i + 1]);
                Vertex::set(vertices++, points[i + 2], points[i + 3]);
                generatedVerticesCount += 2;
                dirtyLayer(left, top,
                        right == left ? left + 1 : right, bottom == top ? top + 1 : bottom,
                        *mSnapshot->transform);
            }

            glLineWidth(1.0f);
            glDrawArrays(GL_LINES, 0, generatedVerticesCount);
        }
    }
}

void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
    if (mSnapshot->isIgnored()) return;

@@ -1596,8 +1560,13 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {

    // A stroke width of 0 has a special meaning in Skia:
    // it draws an unscaled 1px point
    float strokeWidth = paint->getStrokeWidth();
    const bool isHairLine = paint->getStrokeWidth() == 0.0f;

    if (isHairLine) {
        // Now that we know it's hairline, we can set the effective width, to be used later
        strokeWidth = 1.0f;
    }
    const float halfWidth = strokeWidth / 2;
    int alpha;
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);
@@ -1609,13 +1578,13 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
    TextureVertex* vertex = &pointsData[0];

    setupDraw();
    setupDrawPoint(isHairLine ? 1.0f : paint->getStrokeWidth());
    setupDrawPoint(strokeWidth);
    setupDrawColor(paint->getColor(), alpha);
    setupDrawColorFilter();
    setupDrawShader();
    setupDrawBlending(mode);
    setupDrawProgram();
    setupDrawModelViewIdentity();
    setupDrawModelViewIdentity(true);
    setupDrawColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawPointUniforms();
@@ -1625,6 +1594,11 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
    for (int i = 0; i < count; i += 2) {
        TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
        generatedVerticesCount++;
        float left = points[i] - halfWidth;
        float right = points[i] + halfWidth;
        float top = points[i + 1] - halfWidth;
        float bottom = points [i + 1] + halfWidth;
        dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
    }

    glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
+1 −14
Original line number Diff line number Diff line
@@ -282,19 +282,6 @@ private:

    void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);

    /**
     * Draws a line as a quad. Called by drawLines() for all cases except hairline without AA.
     *
     * @param points The vertices of the lines. Every four entries specifies the x/y points
     * of a single line segment.
     * @param count The number of entries in the points array.
     * @param isAA Whether the line is anti-aliased
     * @param isHairline Whether the line has strokeWidth==0, which results in the line being
     * one pixel wide on the display regardless of scale.
     */
    void drawLinesAsQuads(float *points, int count, bool isAA, bool isHairline,
            float strokeWidth);

    /**
     * Draws a textured rectangle with the specified texture. The specified coordinates
     * are transformed by the current snapshot's transform matrix.
@@ -453,7 +440,7 @@ private:
            bool swapSrcDst = false);
    void setupDrawProgram();
    void setupDrawDirtyRegionsDisabled();
    void setupDrawModelViewIdentity();
    void setupDrawModelViewIdentity(bool offset = false);
    void setupDrawModelView(float left, float top, float right, float bottom,
            bool ignoreTransform = false, bool ignoreModelView = false);
    void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
+8 −1
Original line number Diff line number Diff line
@@ -124,8 +124,15 @@ GLuint Program::buildShader(const char* source, GLenum type) {
}

void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
        const mat4& transformMatrix) {
        const mat4& transformMatrix, bool offset) {
    mat4 t(projectionMatrix);
    if (offset) {
        // offset screenspace xy by an amount that compensates for typical precision issues
        // in GPU hardware that tends to paint hor/vert lines in pixels shifted up and to the left.
        // This offset value is based on an assumption that some hardware may use as little
        // as 12.4 precision, so we offset by slightly more than 1/16.
        t.translate(.375, .375, 0);
    }
    t.multiply(transformMatrix);
    t.multiply(modelViewMatrix);

+1 −1
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ public:
     * transform matrices.
     */
    void set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
             const mat4& transformMatrix);
             const mat4& transformMatrix, bool offset = false);

    /**
     * Sets the color associated with this shader.
+9 −0
Original line number Diff line number Diff line
@@ -405,6 +405,15 @@
            </intent-filter>
        </activity>

        <activity
                android:name="PointsActivity"
                android:label="_Points">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
                android:name="Transform3dActivity"
                android:label="_3d">
Loading