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

Commit d5e8ade4 authored by ztenghui's avatar ztenghui
Browse files

Ambient shadow tessellation improvement.

Using the vertices, instead of ray casting for the triangulation.

This request a dynamic index buffer associated with vertex buffer,
so we update the VertexBuffer to support it.

The ambient shadow could be 3x-6x times faster for circle and rect now.

b/16712006
b/14257173

Change-Id: I2f22a8fe19bc59acee5c18e4a3a395acd5042a66
parent c50a03d7
Loading
Loading
Loading
Loading
+289 −258

File changed.

Preview size limit exceeded, changes collapsed.

+0 −15
Original line number Diff line number Diff line
@@ -28,27 +28,12 @@ namespace uirenderer {

/**
 * AmbientShadow is used to calculate the ambient shadow value around a polygon.
 *
 * TODO: calculateIntersection() now is O(N*M), where N is the number of
 * polygon's vertics and M is the number of rays. In fact, by staring tracing
 * the vertex from the previous intersection, the algorithm can be O(N + M);
 */
class AmbientShadow {
public:
    static void createAmbientShadow(bool isCasterOpaque, const Vector3* poly,
            int polyLength, const Vector3& centroid3d, float heightFactor,
            float geomFactor, VertexBuffer& shadowVertexBuffer);

private:
    static void calculateRayDirections(const int rays, const Vector3* vertices,
            const int vertexCount, const Vector3& centroid3d, Vector2* dir);

    static void calculateIntersection(const Vector3* poly, int nbVertices,
            const Vector3& start, const Vector2& dir, int& outEdgeIndex,
            float& outEdgeFraction, float& outRayDist);

    static void calculateNormal(int rays, int currentRayIndex, const Vector2* dir,
            const float* rayDist, Vector2& normal);
}; // AmbientShadow

}; // namespace uirenderer
+4 −0
Original line number Diff line number Diff line
@@ -2417,6 +2417,10 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
    } else if (mode == VertexBuffer::kTwoPolyRingShadow) {
        mCaches.bindShadowIndicesBuffer();
        glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
    } else if (mode == VertexBuffer::kIndices) {
        mCaches.unbindIndicesBuffer();
        glDrawElements(GL_TRIANGLE_STRIP, vertexBuffer.getIndexCount(), GL_UNSIGNED_SHORT,
                vertexBuffer.getIndices());
    }

    if (isAA) {
+17 −0
Original line number Diff line number Diff line
@@ -111,6 +111,23 @@ public:
    float y;
    float z;

    Vector3 operator+(const Vector3& v) const {
        return (Vector3){x + v.x, y + v.y, z + v.z};
    }

    Vector3 operator-(const Vector3& v) const {
        return (Vector3){x - v.x, y - v.y, z - v.z};
    }

    Vector3 operator/(float s) const {
        return (Vector3){x / s, y / s, z / s};
    }

    Vector3 operator*(float s) const {
        return (Vector3){x * s, y * s, z * s};
    }


    void dump() {
        ALOGD("Vector3[%.2f, %.2f, %.2f]", x, y, z);
    }
+38 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_HWUI_VERTEX_BUFFER_H
#define ANDROID_HWUI_VERTEX_BUFFER_H

#include "utils/MathUtils.h"

namespace android {
namespace uirenderer {
@@ -26,19 +27,27 @@ public:
    enum Mode {
        kStandard = 0,
        kOnePolyRingShadow = 1,
        kTwoPolyRingShadow = 2
        kTwoPolyRingShadow = 2,
        kIndices = 3
    };

    VertexBuffer()
            : mBuffer(0)
            , mIndices(0)
            , mVertexCount(0)
            , mIndexCount(0)
            , mAllocatedVertexCount(0)
            , mAllocatedIndexCount(0)
            , mByteCount(0)
            , mMode(kStandard)
            , mReallocBuffer(0)
            , mCleanupMethod(NULL)
            , mCleanupIndexMethod(NULL)
    {}

    ~VertexBuffer() {
        if (mCleanupMethod) mCleanupMethod(mBuffer);
        if (mCleanupIndexMethod) mCleanupIndexMethod(mIndices);
    }

    /**
@@ -59,6 +68,7 @@ public:
            mReallocBuffer = reallocBuffer + vertexCount;
            return reallocBuffer;
        }
        mAllocatedVertexCount = vertexCount;
        mVertexCount = vertexCount;
        mByteCount = mVertexCount * sizeof(TYPE);
        mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
@@ -68,6 +78,17 @@ public:
        return (TYPE*)mBuffer;
    }

    template <class TYPE>
    TYPE* allocIndices(int indexCount) {
        mAllocatedIndexCount = indexCount;
        mIndexCount = indexCount;
        mIndices = (void*)new TYPE[indexCount];

        mCleanupIndexMethod = &(cleanup<TYPE>);

        return (TYPE*)mIndices;
    }

    template <class TYPE>
    void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) {
        int verticesToCopy = srcBuffer.getVertexCount();
@@ -103,9 +124,17 @@ public:
    }

    const void* getBuffer() const { return mBuffer; }
    const void* getIndices() const { return mIndices; }
    const Rect& getBounds() const { return mBounds; }
    unsigned int getVertexCount() const { return mVertexCount; }
    unsigned int getSize() const { return mByteCount; }
    unsigned int getIndexCount() const { return mIndexCount; }
    void updateIndexCount(unsigned int newCount)  {
        mIndexCount = MathUtils::min(newCount, mAllocatedIndexCount);
    }
    void updateVertexCount(unsigned int newCount)  {
        newCount = MathUtils::min(newCount, mAllocatedVertexCount);
    }
    Mode getMode() const { return mMode; }

    void setBounds(Rect bounds) { mBounds = bounds; }
@@ -127,14 +156,22 @@ private:
    }

    Rect mBounds;

    void* mBuffer;
    void* mIndices;

    unsigned int mVertexCount;
    unsigned int mIndexCount;
    unsigned int mAllocatedVertexCount;
    unsigned int mAllocatedIndexCount;
    unsigned int mByteCount;

    Mode mMode;

    void* mReallocBuffer; // used for multi-allocation

    void (*mCleanupMethod)(void*);
    void (*mCleanupIndexMethod)(void*);
};

}; // namespace uirenderer