• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <compositionengine/ProjectionSpace.h>
17 #include <gtest/gtest.h>
18 
19 namespace android::compositionengine {
20 namespace {
21 
22 // Returns a rectangular strip along the side of the given rect pointed by
23 // rotation. E.g. if rotation is ROTATION_0, the srip will be along the top
24 // side, if it is ROTATION_90 the stip will be along the right wall.
25 // One of the dimensions of the strip will be 0 and the other one will match
26 // the length of the corresponding side.
27 // The strip will be contained inside the given rect.
getSideStrip(const Rect & rect,ui::Rotation rotation)28 Rect getSideStrip(const Rect& rect, ui::Rotation rotation) {
29     int width, height;
30     if (rotation == ui::ROTATION_90 || rotation == ui::ROTATION_270) {
31         width = 0;
32         height = rect.height();
33     } else {
34         width = rect.width();
35         height = 0;
36     }
37 
38     if (rotation == ui::ROTATION_0 || rotation == ui::ROTATION_270) {
39         return Rect(rect.left, rect.top, rect.left + width, rect.top + height);
40     }
41 
42     if (rotation == ui::ROTATION_90) {
43         return Rect(rect.right, rect.top, rect.right + width, rect.top + height);
44     }
45 
46     if (rotation == ui::ROTATION_180) {
47         return Rect(rect.left, rect.bottom, rect.left + width, rect.bottom + height);
48     }
49 
50     return Rect::INVALID_RECT;
51 }
52 } // namespace
53 
TEST(ProjectionSpaceTest,getTransformToSelfIsIdentity)54 TEST(ProjectionSpaceTest, getTransformToSelfIsIdentity) {
55     ProjectionSpace space;
56     space.content = Rect(100, 200);
57     space.bounds = Rect(100, 200);
58 
59     const ui::Transform identity;
60     for (int rotation = 0; rotation <= 3; rotation++) {
61         space.orientation = ui::Rotation(rotation);
62         EXPECT_EQ(space.getTransform(space), identity);
63     }
64 }
65 
TEST(ProjectionSpaceTest,getTransformWhenTranslationIsNeeded)66 TEST(ProjectionSpaceTest, getTransformWhenTranslationIsNeeded) {
67     ProjectionSpace source;
68     source.content = Rect(10, 10, 20, 20);
69     source.bounds = Rect(100, 200);
70 
71     ProjectionSpace dest;
72     dest.content = Rect(10, 20, 30, 20);
73     dest.bounds = source.bounds;
74 
75     const auto transform = source.getTransform(dest);
76     EXPECT_EQ(transform.transform(source.content), dest.content);
77 }
78 
TEST(ProjectionSpaceTest,getTransformWhenScaleIsNeeded)79 TEST(ProjectionSpaceTest, getTransformWhenScaleIsNeeded) {
80     ProjectionSpace source;
81     source.content = Rect(0, 0, 20, 20);
82     source.bounds = Rect(100, 200);
83 
84     ProjectionSpace dest;
85     dest.content = Rect(0, 0, 40, 30);
86     dest.bounds = source.bounds;
87 
88     const auto transform = source.getTransform(dest);
89     EXPECT_EQ(transform.transform(source.content), dest.content);
90 }
91 
TEST(ProjectionSpaceTest,getSideStripTest)92 TEST(ProjectionSpaceTest, getSideStripTest) {
93     const Rect rect(10, 20, 40, 100);
94     EXPECT_EQ(getSideStrip(rect, ui::ROTATION_0), Rect(10, 20, 40, 20));
95     EXPECT_EQ(getSideStrip(rect, ui::ROTATION_90), Rect(40, 20, 40, 100));
96     EXPECT_EQ(getSideStrip(rect, ui::ROTATION_180), Rect(10, 100, 40, 100));
97     EXPECT_EQ(getSideStrip(rect, ui::ROTATION_270), Rect(10, 20, 10, 100));
98 }
99 
testTransform(const ProjectionSpace & source,const ProjectionSpace & dest)100 void testTransform(const ProjectionSpace& source, const ProjectionSpace& dest) {
101     const auto transform = source.getTransform(dest);
102     EXPECT_EQ(transform.transform(source.content), dest.content)
103             << "Source content doesn't map to dest content when projecting " << to_string(source)
104             << " onto " << to_string(dest);
105 
106     // We take a strip at the top (according to the orientation) of each
107     // content rect and verify that transform maps between them. This way we
108     // verify that the transform is rotating properly.
109     // In the following example the strip is marked with asterisks:
110     //
111     //      *******                +-------*
112     //      |     |                |       *
113     //      |     |                |       *
114     //      +-----+                +-------*
115     // source(ROTATION_0)      dest (ROTATION_90)
116     const auto sourceStrip = getSideStrip(source.content, source.orientation);
117     const auto destStrip = getSideStrip(dest.content, dest.orientation);
118     ASSERT_NE(sourceStrip, Rect::INVALID_RECT);
119     ASSERT_NE(destStrip, Rect::INVALID_RECT);
120     const auto mappedStrip = transform.transform(sourceStrip);
121     EXPECT_EQ(mappedStrip, destStrip)
122             << to_string(sourceStrip) << " maps to " << to_string(mappedStrip) << " instead of "
123             << to_string(destStrip) << " when projecting " << to_string(source) << " onto "
124             << to_string(dest);
125 }
126 
TEST(ProjectionSpaceTest,getTransformWithOrienations)127 TEST(ProjectionSpaceTest, getTransformWithOrienations) {
128     ProjectionSpace source;
129     source.bounds = Rect(12, 13, 678, 789);
130     source.content = Rect(40, 50, 234, 343);
131     ProjectionSpace dest;
132     dest.bounds = Rect(17, 18, 879, 564);
133     dest.content = Rect(43, 52, 432, 213);
134 
135     for (int sourceRot = 0; sourceRot <= 3; sourceRot++) {
136         source.orientation = ui::Rotation(sourceRot);
137         for (int destRot = 0; destRot <= 3; destRot++) {
138             dest.orientation = ui::Rotation(destRot);
139             testTransform(source, dest);
140         }
141     }
142 }
143 
144 } // namespace android::compositionengine
145