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

Commit 10645211 authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Fix bug in calculating perspective damage"

parents 00cdbce6 c1288239
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -121,7 +121,14 @@ void DamageAccumulator::popTransform() {
static inline void mapRect(const Matrix4* matrix, const SkRect& in, SkRect* out) {
    if (in.isEmpty()) return;
    Rect temp(in);
    if (CC_LIKELY(!matrix->isPerspective())) {
        matrix->mapRect(temp);
    } else {
        // Don't attempt to calculate damage for a perspective transform
        // as the numbers this works with can break the perspective
        // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX
        temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
    }
    out->join(RECT_ARGS(temp));
}

@@ -134,7 +141,14 @@ static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRe
    const SkMatrix* transform = props.getTransformMatrix();
    SkRect temp(in);
    if (transform && !transform->isIdentity()) {
        if (CC_LIKELY(!transform->hasPerspective())) {
            transform->mapRect(&temp);
        } else {
            // Don't attempt to calculate damage for a perspective transform
            // as the numbers this works with can break the perspective
            // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX
            temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
        }
    }
    temp.offset(props.getLeft(), props.getTop());
    out->join(temp);
+5 −0
Original line number Diff line number Diff line
@@ -24,6 +24,11 @@

#include "utils/Macros.h"

// Smaller than INT_MIN/INT_MAX because we offset these values
// and thus don't want to be adding offsets to INT_MAX, that's bad
#define DIRTY_MIN (-0x7ffffff-1)
#define DIRTY_MAX (0x7ffffff)

namespace android {
namespace uirenderer {

+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ void RenderNode::damageSelf(TreeInfo& info) {
        } else {
            // Hope this is big enough?
            // TODO: Get this from the display list ops or something
            info.damageAccumulator->dirty(INT_MIN, INT_MIN, INT_MAX, INT_MAX);
            info.damageAccumulator->dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
        }
    }
}
+62 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <DamageAccumulator.h>
#include <Matrix.h>
#include <RenderNode.h>
#include <utils/LinearAllocator.h>

#include <SkRect.h>
@@ -35,10 +36,12 @@ TEST(DamageAccumulator, identity) {
    identity.loadIdentity();
    da.pushTransform(&identity);
    da.dirty(50, 50, 100, 100);
    {
        da.pushTransform(&identity);
        da.peekAtDirty(&curDirty);
        ASSERT_EQ(SkRect(), curDirty);
        da.popTransform();
    }
    da.peekAtDirty(&curDirty);
    ASSERT_EQ(SkRect::MakeLTRB(50, 50, 100, 100), curDirty);
    da.popTransform();
@@ -69,13 +72,62 @@ TEST(DamageAccumulator, union) {
    SkRect curDirty;
    identity.loadIdentity();
    da.pushTransform(&identity);
    {
        da.pushTransform(&identity);
        da.dirty(50, 50, 100, 100);
        da.popTransform();
        da.pushTransform(&identity);
        da.dirty(150, 50, 200, 125);
        da.popTransform();
    }
    da.popTransform();
    da.finish(&curDirty);
    ASSERT_EQ(SkRect::MakeLTRB(50, 50, 200, 125), curDirty);
}

TEST(DamageAccumulator, basicRenderNode) {
    DamageAccumulator da;
    RenderNode node1;
    node1.animatorProperties().setLeftTopRightBottom(50, 50, 500, 500);
    node1.animatorProperties().updateMatrix();
    da.pushTransform(&node1);
    {
        RenderNode node2;
        node2.animatorProperties().setLeftTopRightBottom(50, 50, 100, 100);
        node2.animatorProperties().updateMatrix();
        da.pushTransform(&node2);
        da.dirty(0, 0, 25, 25);
        da.popTransform();
    }
    da.popTransform();
    SkRect dirty;
    da.finish(&dirty);
    ASSERT_EQ(SkRect::MakeLTRB(100, 100, 125, 125), dirty);
}

TEST(DamageAccumulator, perspectiveTransform) {
    DamageAccumulator da;
    RenderNode node1;
    node1.animatorProperties().setLeftTopRightBottom(50, 50, 500, 500);
    node1.animatorProperties().setClipToBounds(true);
    node1.animatorProperties().updateMatrix();
    da.pushTransform(&node1);
    {
        RenderNode node2;
        node2.animatorProperties().setLeftTopRightBottom(50, 50, 100, 100);
        node2.animatorProperties().setClipToBounds(false);
        node2.animatorProperties().setRotationX(1.0f);
        node2.animatorProperties().setRotationY(1.0f);
        node2.animatorProperties().setRotation(20.0f);
        node2.animatorProperties().setCameraDistance(500.0f);
        node2.animatorProperties().setTranslationZ(30.0f);
        node2.animatorProperties().updateMatrix();
        da.pushTransform(&node2);
        da.dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
        da.popTransform();
    }
    da.popTransform();
    SkRect dirty;
    da.finish(&dirty);
    ASSERT_EQ(SkRect::MakeLTRB(50, 50, 500, 500), dirty);
}