aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/SGTest.cpp
blob: b0cad5b8f3b75240e68375ed9af7ebd9c8ce5df2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkRect.h"
#include "SkSGColor.h"
#include "SkSGDraw.h"
#include "SkSGGroup.h"
#include "SkSGInvalidationController.h"
#include "SkSGRect.h"
#include "SkSGTransform.h"

#include "Test.h"

#include <vector>

static void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root,
                        const SkRect& expected_bounds,
                        const SkRect& expected_inval_bounds,
                        const std::vector<SkRect>* expected_damage) {
    sksg::InvalidationController ic;
    const auto bbox = root->revalidate(&ic, SkMatrix::I());

    if (0) {
        printf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n",
               bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom,
               ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom());
    }

    REPORTER_ASSERT(reporter, bbox == expected_bounds);
    REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds);

    if (expected_damage) {
        REPORTER_ASSERT(reporter, expected_damage->size() == SkTo<size_t>(ic.end() - ic.begin()));
        for (size_t i = 0; i < expected_damage->size(); ++i) {
            const auto r1 = (*expected_damage)[i],
                       r2 = ic.begin()[i];
            if (0) {
                printf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n",
                       r1.left(), r1.top(), r1.right(), r1.bottom(),
                       r2.left(), r2.top(), r2.right(), r2.bottom());
            }
            REPORTER_ASSERT(reporter, r1 == r2);
        }
    }
}

DEF_TEST(SGInvalidation, reporter) {
    auto color = sksg::Color::Make(0xff000000);
    auto r1    = sksg::Rect::Make(SkRect::MakeWH(100, 100)),
         r2    = sksg::Rect::Make(SkRect::MakeWH(100, 100));
    auto grp   = sksg::Group::Make();
    auto tr    = sksg::Transform::Make(grp, SkMatrix::I());

    grp->addChild(sksg::Draw::Make(r1, color));
    grp->addChild(sksg::Draw::Make(r2, color));

    {
        // Initial revalidation.
        check_inval(reporter, tr,
                    SkRect::MakeWH(100, 100),
                    SkRect::MakeLargestS32(),
                    nullptr);
    }

    {
        // Move r2 to (200 100).
        r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200);
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
        check_inval(reporter, tr,
                    SkRect::MakeWH(300, 200),
                    SkRect::MakeWH(300, 200),
                    &damage);
    }

    {
        // Update the common color.
        // TODO: this doesn't work ATM as expected; fix and enable.
//        color->setColor(0xffff0000);
//        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
//        check_inval(reporter, tr,
//                    SkRect::MakeWH(300, 200),
//                    SkRect::MakeWH(300, 200),
//                    &damage);
    }

    {
        // Shrink r1.
        r1->setR(50);
        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} };
        check_inval(reporter, tr,
                    SkRect::MakeWH(300, 200),
                    SkRect::MakeWH(100, 100),
                    &damage);
    }

    {
        // Update transform.
        tr->setMatrix(SkMatrix::MakeScale(2, 2));
        std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} };
        check_inval(reporter, tr,
                    SkRect::MakeWH(600, 400),
                    SkRect::MakeWH(600, 400),
                    &damage);
    }

    {
        // Shrink r2 under transform.
        r2->setR(250);
        std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} };
        check_inval(reporter, tr,
                    SkRect::MakeWH(500, 400),
                    SkRect::MakeLTRB(400, 200, 600, 400),
                    &damage);
    }
}