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

Commit 630c0aba authored by ztenghui's avatar ztenghui Committed by Android (Google) Code Review
Browse files

Merge "Create one hole inside the umbra area to avoid overdraw."

parents db62c232 50ecf849
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ namespace uirenderer {
 * Calculate the shadows as a triangle strips while alpha value as the
 * shadow values.
 *
 * @param isCasterOpaque Whether the caster is opaque.
 * @param vertices The shadow caster's polygon, which is represented in a Vector3
 *                  array.
 * @param vertexCount The length of caster's polygon in terms of number of
@@ -43,17 +44,18 @@ namespace uirenderer {
 * @param shadowVertexBuffer Return an floating point array of (x, y, a)
 *               triangle strips mode.
 */
void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount,
        const Vector3& centroid3d, float heightFactor, float geomFactor,
        VertexBuffer& shadowVertexBuffer) {
VertexBufferMode AmbientShadow::createAmbientShadow(bool isCasterOpaque,
        const Vector3* vertices, int vertexCount, const Vector3& centroid3d,
        float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) {
    const int rays = SHADOW_RAY_COUNT;
    VertexBufferMode mode = kVertexBufferMode_OnePolyRingShadow;
    // Validate the inputs.
    if (vertexCount < 3 || heightFactor <= 0 || rays <= 0
        || geomFactor <= 0) {
#if DEBUG_SHADOW
        ALOGE("Invalid input for createAmbientShadow(), early return!");
        ALOGW("Invalid input for createAmbientShadow(), early return!");
#endif
        return;
        return mode; // vertex buffer is empty, so any mode doesn't matter.
    }

    Vector<Vector2> dir; // TODO: use C++11 unique_ptr
@@ -75,7 +77,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount
        rayDist[i] = rayDistance;
        if (edgeIndex < 0 || edgeIndex >= vertexCount) {
#if DEBUG_SHADOW
            ALOGE("Invalid edgeIndex!");
            ALOGW("Invalid edgeIndex!");
#endif
            edgeIndex = 0;
        }
@@ -86,7 +88,8 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount

    // The output buffer length basically is roughly rays * layers, but since we
    // need triangle strips, so we need to duplicate vertices to accomplish that.
    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
    AlphaVertex* shadowVertices =
            shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);

    // Calculate the vertex of the shadows.
    //
@@ -95,6 +98,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount
    // calculate the normal N, which should be perpendicular to the edge of the
    // polygon (represented by the neighbor intersection points) .
    // Shadow's vertices will be generated as : P + N * scale.
    const Vector2 centroid2d = Vector2(centroid3d.x, centroid3d.y);
    for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
        Vector2 normal(1.0f, 0.0f);
        calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
@@ -102,7 +106,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount
        // The vertex should be start from rayDist[i] then scale the
        // normalizeNormal!
        Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
                Vector2(centroid3d.x, centroid3d.y);
                centroid2d;

        // outer ring of points, expanded based upon height of each ray intersection
        float expansionDist = rayHeight[rayIndex] * heightFactor *
@@ -114,25 +118,31 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount

        // inner ring of points
        float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor);
        AlphaVertex::set(&shadowVertices[rayIndex + rays],
        AlphaVertex::set(&shadowVertices[rays + rayIndex],
                intersection.x,
                intersection.y,
                opacity);
    }

    // If caster isn't opaque, we need to to fill the umbra by storing the umbra's
    // centroid in the innermost ring of vertices.
    if (!isCasterOpaque) {
        mode = kVertexBufferMode_TwoPolyRingShadow;
        float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor);
    AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1],
            centroid3d.x, centroid3d.y, centroidAlpha);
        AlphaVertex centroidXYA;
        AlphaVertex::set(&centroidXYA, centroid2d.x, centroid2d.y, centroidAlpha);
        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
            shadowVertices[2 * rays + rayIndex] = centroidXYA;
        }
    }

#if DEBUG_SHADOW
    if (currentVertexIndex != SHADOW_VERTEX_COUNT) {
        ALOGE("number of vertex generated for ambient shadow is wrong! "
              "current: %d , expected: %d", currentVertexIndex, SHADOW_VERTEX_COUNT);
    }
    for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) {
        ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
                shadowVertices[i].y, shadowVertices[i].alpha);
    }
#endif
    return mode;
}

/**
+4 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#define ANDROID_HWUI_AMBIENT_SHADOW_H

#include "Debug.h"
#include "OpenGLRenderer.h"
#include "Vector.h"
#include "VertexBuffer.h"

@@ -34,9 +35,9 @@ namespace uirenderer {
 */
class AmbientShadow {
public:
    static void createAmbientShadow(const Vector3* poly, int polyLength,
            const Vector3& centroid3d, float heightFactor, float geomFactor,
            VertexBuffer& shadowVertexBuffer);
    static VertexBufferMode createAmbientShadow(bool isCasterOpaque, const Vector3* poly,
            int polyLength, const Vector3& centroid3d, float heightFactor,
            float geomFactor, VertexBuffer& shadowVertexBuffer);

private:
    static void calculateRayDirections(int rays, Vector2* dir);
+2 −2
Original line number Diff line number Diff line
@@ -445,11 +445,11 @@ bool Caches::bindQuadIndicesBuffer() {

bool Caches::bindShadowIndicesBuffer() {
    if (!mShadowStripsIndices) {
        uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT];
        uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT];
        ShadowTessellator::generateShadowIndices(shadowIndices);
        glGenBuffers(1, &mShadowStripsIndices);
        bool force = bindIndicesBufferInternal(mShadowStripsIndices);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t),
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t),
            shadowIndices, GL_STATIC_DRAW);

        delete[] shadowIndices;
+14 −10
Original line number Diff line number Diff line
@@ -2414,9 +2414,12 @@ status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode,
    if (mode == kVertexBufferMode_Standard) {
        mCaches.unbindIndicesBuffer();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
    } else {
    } else if (mode == kVertexBufferMode_OnePolyRingShadow) {
        mCaches.bindShadowIndicesBuffer();
        glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
    } else if (mode == kVertexBufferMode_TwoPolyRingShadow) {
        mCaches.bindShadowIndicesBuffer();
        glDrawElements(GL_TRIANGLE_STRIP, SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
        glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
    }

    if (isAA) {
@@ -3245,14 +3248,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
        }
        centroid3d.z += casterLift;
    }

    bool isCasterOpaque = (casterAlpha == 1.0f);
    // draw caster's shadows
    if (mCaches.propertyAmbientShadowStrength > 0) {
        paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0);
        VertexBuffer ambientShadowVertexBuffer;
        ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
                centroid3d, ambientShadowVertexBuffer);
        drawVertexBuffer(kVertexBufferMode_Shadow, ambientShadowVertexBuffer, &paint);
        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow(
                isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
                ambientShadowVertexBuffer);
        drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint);
    }

    if (mCaches.propertySpotShadowStrength > 0) {
@@ -3260,10 +3264,10 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
        VertexBuffer spotShadowVertexBuffer;
        Vector3 lightPosScale(mCaches.propertyLightPosXScale,
                mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
        ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount,
                lightPosScale, *currentTransform(), getWidth(), getHeight(),
                spotShadowVertexBuffer);
        drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint);
        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow(
                isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale,
                *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer);
        drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint);
    }

    return DrawGlInfo::kStatusDrew;
+2 −1
Original line number Diff line number Diff line
@@ -119,7 +119,8 @@ enum ModelViewMode {

enum VertexBufferMode {
    kVertexBufferMode_Standard = 0,
    kVertexBufferMode_Shadow = 1
    kVertexBufferMode_OnePolyRingShadow = 1,
    kVertexBufferMode_TwoPolyRingShadow = 2
};

///////////////////////////////////////////////////////////////////////////////
Loading