xref: /aosp_15_r20/external/skia/modules/skottie/tests/Image.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/include/Skottie.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
13*c8dee2aaSAndroid Build Coastguard Worker 
14*c8dee2aaSAndroid Build Coastguard Worker using namespace skottie;
15*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Skottie_Image_CustomTransform,r)16*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Skottie_Image_CustomTransform, r) {
17*c8dee2aaSAndroid Build Coastguard Worker     static constexpr char json[] =
18*c8dee2aaSAndroid Build Coastguard Worker         R"({
19*c8dee2aaSAndroid Build Coastguard Worker              "v": "5.2.1",
20*c8dee2aaSAndroid Build Coastguard Worker              "w": 100,
21*c8dee2aaSAndroid Build Coastguard Worker              "h": 100,
22*c8dee2aaSAndroid Build Coastguard Worker              "fr": 10,
23*c8dee2aaSAndroid Build Coastguard Worker              "ip": 0,
24*c8dee2aaSAndroid Build Coastguard Worker              "op": 100,
25*c8dee2aaSAndroid Build Coastguard Worker              "assets": [{
26*c8dee2aaSAndroid Build Coastguard Worker                "id": "img_0",
27*c8dee2aaSAndroid Build Coastguard Worker                "p" : "img_0.png",
28*c8dee2aaSAndroid Build Coastguard Worker                "u" : "images/",
29*c8dee2aaSAndroid Build Coastguard Worker                "w" : 100,
30*c8dee2aaSAndroid Build Coastguard Worker                "h" :  50
31*c8dee2aaSAndroid Build Coastguard Worker              }],
32*c8dee2aaSAndroid Build Coastguard Worker              "layers": [
33*c8dee2aaSAndroid Build Coastguard Worker                {
34*c8dee2aaSAndroid Build Coastguard Worker                  "ip": 0,
35*c8dee2aaSAndroid Build Coastguard Worker                  "op": 100,
36*c8dee2aaSAndroid Build Coastguard Worker                  "ty": 2,
37*c8dee2aaSAndroid Build Coastguard Worker                  "refId": "img_0",
38*c8dee2aaSAndroid Build Coastguard Worker                  "ks": {
39*c8dee2aaSAndroid Build Coastguard Worker                    "p": { "a": 0, "k": [0,25] }
40*c8dee2aaSAndroid Build Coastguard Worker                  }
41*c8dee2aaSAndroid Build Coastguard Worker                }
42*c8dee2aaSAndroid Build Coastguard Worker              ]
43*c8dee2aaSAndroid Build Coastguard Worker            })";
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker     SkMemoryStream stream(json, strlen(json));
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker     static const struct TestData {
48*c8dee2aaSAndroid Build Coastguard Worker         float    t;
49*c8dee2aaSAndroid Build Coastguard Worker         SkMatrix m;
50*c8dee2aaSAndroid Build Coastguard Worker         SkColor  c[5]; // expected color samples at center/L/T/R/B
51*c8dee2aaSAndroid Build Coastguard Worker     } tests[] {
52*c8dee2aaSAndroid Build Coastguard Worker         { 0, SkMatrix::I(),
53*c8dee2aaSAndroid Build Coastguard Worker             {0xffff0000, 0xffff0000, 0xff00ff00, 0xffff0000, 0xff00ff00}},
54*c8dee2aaSAndroid Build Coastguard Worker         { 1, SkMatrix::Translate(50,25) * SkMatrix::Scale(.5f,.5f) * SkMatrix::Translate(-50,-25),
55*c8dee2aaSAndroid Build Coastguard Worker             {0xffff0000, 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00}},
56*c8dee2aaSAndroid Build Coastguard Worker         { 2, SkMatrix::Translate(-50, 0),
57*c8dee2aaSAndroid Build Coastguard Worker             {0xff00ff00, 0xffff0000, 0xff00ff00, 0xff00ff00, 0xff00ff00}},
58*c8dee2aaSAndroid Build Coastguard Worker         { 3, SkMatrix::Translate(0, -25),
59*c8dee2aaSAndroid Build Coastguard Worker             {0xff00ff00, 0xff00ff00, 0xffff0000, 0xff00ff00, 0xff00ff00}},
60*c8dee2aaSAndroid Build Coastguard Worker         { 4, SkMatrix::Translate(50, 0),
61*c8dee2aaSAndroid Build Coastguard Worker             {0xffff0000, 0xff00ff00, 0xff00ff00, 0xffff0000, 0xff00ff00}},
62*c8dee2aaSAndroid Build Coastguard Worker         { 5, SkMatrix::Translate(0, 25),
63*c8dee2aaSAndroid Build Coastguard Worker             {0xffff0000, 0xffff0000, 0xff00ff00, 0xffff0000, 0xffff0000}},
64*c8dee2aaSAndroid Build Coastguard Worker     };
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     class TestImageAsset final : public ImageAsset {
67*c8dee2aaSAndroid Build Coastguard Worker     public:
68*c8dee2aaSAndroid Build Coastguard Worker         TestImageAsset(const TestData* tst, skiatest::Reporter* r)
69*c8dee2aaSAndroid Build Coastguard Worker             : fTest(tst)
70*c8dee2aaSAndroid Build Coastguard Worker             , fReporter(r) {
71*c8dee2aaSAndroid Build Coastguard Worker             auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(200, 100));
72*c8dee2aaSAndroid Build Coastguard Worker             surf->getCanvas()->drawColor(0xffff0000);
73*c8dee2aaSAndroid Build Coastguard Worker             fImage = surf->makeImageSnapshot();
74*c8dee2aaSAndroid Build Coastguard Worker         }
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker     private:
77*c8dee2aaSAndroid Build Coastguard Worker         bool isMultiFrame() override { return true; }
78*c8dee2aaSAndroid Build Coastguard Worker 
79*c8dee2aaSAndroid Build Coastguard Worker         FrameData getFrameData(float t) override {
80*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(fReporter, t == fTest->t);
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker             return { fImage, SkSamplingOptions(), fTest++->m };
83*c8dee2aaSAndroid Build Coastguard Worker         }
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkImage>      fImage;
86*c8dee2aaSAndroid Build Coastguard Worker         const TestData*     fTest;
87*c8dee2aaSAndroid Build Coastguard Worker         skiatest::Reporter* fReporter;
88*c8dee2aaSAndroid Build Coastguard Worker     };
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker     class TestResourceProvider final : public ResourceProvider {
91*c8dee2aaSAndroid Build Coastguard Worker     public:
92*c8dee2aaSAndroid Build Coastguard Worker         TestResourceProvider(const TestData* tst, skiatest::Reporter* r)
93*c8dee2aaSAndroid Build Coastguard Worker             : fTest(tst)
94*c8dee2aaSAndroid Build Coastguard Worker             , fReporter(r) {}
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker     private:
97*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override {
98*c8dee2aaSAndroid Build Coastguard Worker             return sk_make_sp<TestImageAsset>(fTest, fReporter);
99*c8dee2aaSAndroid Build Coastguard Worker         }
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker         const TestData*      fTest;
102*c8dee2aaSAndroid Build Coastguard Worker         skiatest::Reporter*  fReporter;
103*c8dee2aaSAndroid Build Coastguard Worker     };
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker     auto anim = Animation::Builder()
106*c8dee2aaSAndroid Build Coastguard Worker                     .setResourceProvider(sk_make_sp<TestResourceProvider>(tests, r))
107*c8dee2aaSAndroid Build Coastguard Worker                     .make(&stream);
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, anim);
110*c8dee2aaSAndroid Build Coastguard Worker 
111*c8dee2aaSAndroid Build Coastguard Worker     static constexpr SkSize render_size{100, 100};
112*c8dee2aaSAndroid Build Coastguard Worker     auto surf = SkSurfaces::Raster(
113*c8dee2aaSAndroid Build Coastguard Worker             SkImageInfo::MakeN32Premul(render_size.width(), render_size.height()));
114*c8dee2aaSAndroid Build Coastguard Worker     auto rect = SkRect::MakeSize(render_size);
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker     SkPixmap pmap;
117*c8dee2aaSAndroid Build Coastguard Worker     surf->peekPixels(&pmap);
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker     for (const auto& tst : tests) {
120*c8dee2aaSAndroid Build Coastguard Worker         surf->getCanvas()->clear(0xff00ff00);
121*c8dee2aaSAndroid Build Coastguard Worker         anim->seekFrameTime(tst.t);
122*c8dee2aaSAndroid Build Coastguard Worker         anim->render(surf->getCanvas(), &rect);
123*c8dee2aaSAndroid Build Coastguard Worker 
124*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r,
125*c8dee2aaSAndroid Build Coastguard Worker             tst.c[0] == pmap.getColor(render_size.width() / 2, render_size.height() / 2));
126*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r,
127*c8dee2aaSAndroid Build Coastguard Worker             tst.c[1] == pmap.getColor(1                      , render_size.height() / 2));
128*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r,
129*c8dee2aaSAndroid Build Coastguard Worker             tst.c[2] == pmap.getColor(render_size.width() / 2, 1));
130*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r,
131*c8dee2aaSAndroid Build Coastguard Worker             tst.c[3] == pmap.getColor(render_size.width() - 1, render_size.height() / 2));
132*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r,
133*c8dee2aaSAndroid Build Coastguard Worker             tst.c[4] == pmap.getColor(render_size.width() /2 , render_size.height() - 1));
134*c8dee2aaSAndroid Build Coastguard Worker     }
135*c8dee2aaSAndroid Build Coastguard Worker }
136