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

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

Merge "Early rejection on shadows which are outside of the clip bound."

parents 63f4e55b af6f7ed8
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -3226,11 +3226,13 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
    const int casterVertexCount = casterVertices2d.size();
    Vector3 casterPolygon[casterVertexCount];
    float minZ = FLT_MAX;
    float maxZ = -FLT_MAX;
    for (int i = 0; i < casterVertexCount; i++) {
        const Vertex& point2d = casterVertices2d[i];
        casterPolygon[i] = Vector3(point2d.x, point2d.y, 0);
        mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ);
        minZ = fmin(minZ, casterPolygon[i].z);
        maxZ = fmax(maxZ, casterPolygon[i].z);
    }

    // map the centroid of the caster into 3d
@@ -3248,6 +3250,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
        }
        centroid3d.z += casterLift;
    }

    // Check whether we want to draw the shadow at all by checking the caster's
    // bounds against clip.
    // We only have ortho projection, so we can just ignore the Z in caster for
    // simple rejection calculation.
    Rect localClip = mSnapshot->getLocalClip();
    Rect casterBounds(casterOutline->getBounds());
    casterTransformXY.mapRect(casterBounds);

    bool isCasterOpaque = (casterAlpha == 1.0f);
    // draw caster's shadows
    if (mCaches.propertyAmbientShadowStrength > 0) {
@@ -3255,7 +3266,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
        VertexBuffer ambientShadowVertexBuffer;
        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow(
                isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
                ambientShadowVertexBuffer);
                casterBounds, localClip, maxZ, ambientShadowVertexBuffer);
        drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint);
    }

@@ -3266,7 +3277,8 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
                mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow(
                isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale,
                *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer);
                *currentTransform(), getWidth(), getHeight(), casterBounds, localClip,
                spotShadowVertexBuffer);
        drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint);
    }

+8 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define ANDROID_HWUI_RECT_H

#include <cmath>
#include <SkRect.h>

#include <utils/Log.h>

@@ -68,6 +69,13 @@ public:
            bottom(height) {
    }

    inline Rect(const SkRect& rect):
            left(rect.fLeft),
            top(rect.fTop),
            right(rect.fRight),
            bottom(rect.fBottom) {
    }

    friend int operator==(const Rect& a, const Rect& b) {
        return !memcmp(&a, &b, sizeof(a));
    }
+26 −2
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ static inline T max(T a, T b) {

VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
        const Vector3* casterPolygon, int casterVertexCount,
        const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer) {
        const Vector3& centroid3d, const Rect& casterBounds,
        const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer) {
    ATRACE_CALL();

    // A bunch of parameters to tweak the shadow.
@@ -43,6 +44,16 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
    const float heightFactor = 1.0f / 128;
    const float geomFactor = 64;

    Rect ambientShadowBounds(casterBounds);
    ambientShadowBounds.outset(maxZ * geomFactor * heightFactor);

    if (!localClip.intersects(ambientShadowBounds)) {
#if DEBUG_SHADOW
        ALOGD("Ambient shadow is out of clip rect!");
#endif
        return kVertexBufferMode_OnePolyRingShadow;
    }

    return AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon,
            casterVertexCount, centroid3d, heightFactor, geomFactor,
            shadowVertexBuffer);
@@ -52,7 +63,8 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
        const Vector3* casterPolygon, int casterVertexCount,
        const Vector3& lightPosScale, const mat4& receiverTransform,
        int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) {
        int screenWidth, int screenHeight, const Rect& casterBounds,
        const Rect& localClip, VertexBuffer& shadowVertexBuffer) {
    ATRACE_CALL();

    // A bunch of parameters to tweak the shadow.
@@ -73,6 +85,18 @@ VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
    const float lightSize = maximal / 4;
    const int lightVertexCount = 8;

    // Now light and caster are both in local space, we will check whether
    // the shadow is within the clip area.
    Rect lightRect = Rect(lightCenter.x - lightSize, lightCenter.y - lightSize,
            lightCenter.x + lightSize, lightCenter.y + lightSize);
    lightRect.unionWith(localClip);
    if (!lightRect.intersects(casterBounds)) {
#if DEBUG_SHADOW
        ALOGD("Spot shadow is out of clip rect!");
#endif
        return kVertexBufferMode_OnePolyRingShadow;
    }

    VertexBufferMode mode = SpotShadow::createSpotShadow(isCasterOpaque,
            casterPolygon, casterVertexCount, lightCenter, lightSize,
            lightVertexCount, shadowVertexBuffer);
+4 −2
Original line number Diff line number Diff line
@@ -66,12 +66,14 @@ class ShadowTessellator {
public:
    static VertexBufferMode tessellateAmbientShadow(bool isCasterOpaque,
            const Vector3* casterPolygon, int casterVertexCount,
            const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer);
            const Vector3& centroid3d,  const Rect& casterBounds,
            const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer);

    static VertexBufferMode tessellateSpotShadow(bool isCasterOpaque,
            const Vector3* casterPolygon, int casterVertexCount,
            const Vector3& lightPosScale, const mat4& receiverTransform,
            int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer);
            int screenWidth, int screenHeight, const Rect& casterBounds,
            const Rect& localClip, VertexBuffer& shadowVertexBuffer);

    static void generateShadowIndices(uint16_t*  shadowIndices);