Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkRect.h"
      9 #include "SkRectPriv.h"
     10 
     11 #if !defined(SK_BUILD_FOR_GOOGLE3)
     12 
     13 #include "SkSGColor.h"
     14 #include "SkSGDraw.h"
     15 #include "SkSGGroup.h"
     16 #include "SkSGInvalidationController.h"
     17 #include "SkSGRect.h"
     18 #include "SkSGTransform.h"
     19 
     20 #include "Test.h"
     21 
     22 #include <vector>
     23 
     24 static void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root,
     25                         const SkRect& expected_bounds,
     26                         const SkRect& expected_inval_bounds,
     27                         const std::vector<SkRect>* expected_damage) {
     28     sksg::InvalidationController ic;
     29     const auto bbox = root->revalidate(&ic, SkMatrix::I());
     30 
     31     if (0) {
     32         SkDebugf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n",
     33                  bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom,
     34                  ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom());
     35     }
     36 
     37     REPORTER_ASSERT(reporter, bbox == expected_bounds);
     38     REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds);
     39 
     40     if (expected_damage) {
     41         const auto damage_count = SkTo<size_t>(ic.end() - ic.begin());
     42         REPORTER_ASSERT(reporter, expected_damage->size() == damage_count);
     43         for (size_t i = 0; i < std::min(expected_damage->size(), damage_count); ++i) {
     44             const auto r1 = (*expected_damage)[i],
     45                        r2 = ic.begin()[i];
     46             if (0) {
     47                 SkDebugf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n",
     48                          r1.left(), r1.top(), r1.right(), r1.bottom(),
     49                          r2.left(), r2.top(), r2.right(), r2.bottom());
     50             }
     51             REPORTER_ASSERT(reporter, r1 == r2);
     52         }
     53     }
     54 }
     55 
     56 static void inval_test1(skiatest::Reporter* reporter) {
     57     auto color  = sksg::Color::Make(0xff000000);
     58     auto r1     = sksg::Rect::Make(SkRect::MakeWH(100, 100)),
     59          r2     = sksg::Rect::Make(SkRect::MakeWH(100, 100));
     60     auto grp    = sksg::Group::Make();
     61     auto matrix = sksg::Matrix::Make(SkMatrix::I());
     62     auto root   = sksg::Transform::Make(grp, matrix);
     63 
     64     grp->addChild(sksg::Draw::Make(r1, color));
     65     grp->addChild(sksg::Draw::Make(r2, color));
     66 
     67     {
     68         // Initial revalidation.
     69         check_inval(reporter, root,
     70                     SkRect::MakeWH(100, 100),
     71                     SkRectPriv::MakeLargeS32(),
     72                     nullptr);
     73     }
     74 
     75     {
     76         // Move r2 to (200 100).
     77         r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200);
     78         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
     79         check_inval(reporter, root,
     80                     SkRect::MakeWH(300, 200),
     81                     SkRect::MakeWH(300, 200),
     82                     &damage);
     83     }
     84 
     85     {
     86         // Update the common color.
     87         color->setColor(0xffff0000);
     88         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
     89         check_inval(reporter, root,
     90                     SkRect::MakeWH(300, 200),
     91                     SkRect::MakeWH(300, 200),
     92                     &damage);
     93     }
     94 
     95     {
     96         // Shrink r1.
     97         r1->setR(50);
     98         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} };
     99         check_inval(reporter, root,
    100                     SkRect::MakeWH(300, 200),
    101                     SkRect::MakeWH(100, 100),
    102                     &damage);
    103     }
    104 
    105     {
    106         // Update transform.
    107         matrix->setMatrix(SkMatrix::MakeScale(2, 2));
    108         std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} };
    109         check_inval(reporter, root,
    110                     SkRect::MakeWH(600, 400),
    111                     SkRect::MakeWH(600, 400),
    112                     &damage);
    113     }
    114 
    115     {
    116         // Shrink r2 under transform.
    117         r2->setR(250);
    118         std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} };
    119         check_inval(reporter, root,
    120                     SkRect::MakeWH(500, 400),
    121                     SkRect::MakeLTRB(400, 200, 600, 400),
    122                     &damage);
    123     }
    124 }
    125 
    126 static void inval_test2(skiatest::Reporter* reporter) {
    127     auto color = sksg::Color::Make(0xff000000);
    128     auto rect  = sksg::Rect::Make(SkRect::MakeWH(100, 100));
    129     auto m1    = sksg::Matrix::Make(SkMatrix::I()),
    130          m2    = sksg::Matrix::Make(SkMatrix::I(), m1);
    131     auto t1    = sksg::Transform::Make(sksg::Draw::Make(rect, color), m2),
    132          t2    = sksg::Transform::Make(sksg::Draw::Make(rect, color), m1);
    133     auto root  = sksg::Group::Make();
    134     root->addChild(t1);
    135     root->addChild(t2);
    136 
    137     {
    138         // Initial revalidation.
    139         check_inval(reporter, root,
    140                     SkRect::MakeWH(100, 100),
    141                     SkRectPriv::MakeLargeS32(),
    142                     nullptr);
    143     }
    144 
    145     {
    146         // Update the shared color.
    147         color->setColor(0xffff0000);
    148         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 100, 100} };
    149         check_inval(reporter, root,
    150                     SkRect::MakeWH(100, 100),
    151                     SkRect::MakeWH(100, 100),
    152                     &damage);
    153     }
    154 
    155     {
    156         // Update m2.
    157         m2->setMatrix(SkMatrix::MakeScale(2, 2));
    158         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 200, 200} };
    159         check_inval(reporter, root,
    160                     SkRect::MakeWH(200, 200),
    161                     SkRect::MakeWH(200, 200),
    162                     &damage);
    163     }
    164 
    165     {
    166         // Update shared m1.
    167         m1->setMatrix(SkMatrix::MakeTrans(100, 100));
    168         std::vector<SkRect> damage = { {   0,   0, 200, 200},   // draw1 prev bounds
    169                                        { 100, 100, 300, 300},   // draw1 new bounds
    170                                        {   0,   0, 100, 100},   // draw2 prev bounds
    171                                        { 100, 100, 200, 200} }; // draw2 new bounds
    172         check_inval(reporter, root,
    173                     SkRect::MakeLTRB(100, 100, 300, 300),
    174                     SkRect::MakeLTRB(  0,   0, 300, 300),
    175                     &damage);
    176     }
    177 
    178     {
    179         // Update shared rect.
    180         rect->setR(50);
    181         std::vector<SkRect> damage = { { 100, 100, 300, 300},   // draw1 prev bounds
    182                                        { 100, 100, 200, 300},   // draw1 new bounds
    183                                        { 100, 100, 200, 200},   // draw2 prev bounds
    184                                        { 100, 100, 150, 200} }; // draw2 new bounds
    185         check_inval(reporter, root,
    186                     SkRect::MakeLTRB(100, 100, 200, 300),
    187                     SkRect::MakeLTRB(100, 100, 300, 300),
    188                     &damage);
    189     }
    190 }
    191 
    192 DEF_TEST(SGInvalidation, reporter) {
    193     inval_test1(reporter);
    194     inval_test2(reporter);
    195 }
    196 
    197 #endif // !defined(SK_BUILD_FOR_GOOGLE3)
    198