1/*
2* Copyright (C) 2014 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/LICENSE2.0
9*
10* Unless required by applicable law or agreed to in riting, 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*/
16package android.uirendering.cts.testclasses;
17
18import android.graphics.Bitmap;
19import android.graphics.Canvas;
20import android.graphics.Color;
21import android.graphics.LinearGradient;
22import android.graphics.Paint;
23import android.graphics.Rect;
24import android.graphics.Shader;
25import android.support.test.filters.LargeTest;
26import android.support.test.filters.MediumTest;
27import android.support.test.runner.AndroidJUnit4;
28import android.uirendering.cts.bitmapcomparers.BitmapComparer;
29import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
30import android.uirendering.cts.testinfrastructure.ActivityTestBase;
31import android.uirendering.cts.testinfrastructure.CanvasClient;
32import android.uirendering.cts.testinfrastructure.DisplayModifier;
33import android.uirendering.cts.testinfrastructure.ResourceModifier;
34
35import org.junit.Test;
36import org.junit.runner.RunWith;
37
38/**
39 * Test cases of all combination of resource modifications.
40 */
41@LargeTest
42@RunWith(AndroidJUnit4.class)
43public class SweepTests extends ActivityTestBase {
44    private final static DisplayModifier COLOR_FILTER_GRADIENT_MODIFIER = new DisplayModifier() {
45        private final Rect mBounds = new Rect(30, 30, 150, 150);
46        private final int[] mColors = new int[] {
47                Color.RED, Color.GREEN, Color.BLUE
48        };
49
50        private final Bitmap mBitmap = createGradient();
51
52        @Override
53        public void modifyDrawing(Paint paint, Canvas canvas) {
54            canvas.drawBitmap(mBitmap, 0, 0, paint);
55        }
56
57        private Bitmap createGradient() {
58            LinearGradient gradient = new LinearGradient(15, 45, 75, 45, mColors, null,
59                    Shader.TileMode.REPEAT);
60            Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
61            Paint p = new Paint();
62            p.setShader(gradient);
63            Canvas c = new Canvas(bitmap);
64            c.drawRect(mBounds, p);
65            return bitmap;
66        }
67    };
68
69    public static final DisplayModifier mCircleDrawModifier = new DisplayModifier() {
70        @Override
71        public void modifyDrawing(Paint paint, Canvas canvas) {
72            canvas.drawCircle(TEST_WIDTH / 2, TEST_HEIGHT / 2, TEST_HEIGHT / 2, paint);
73        }
74    };
75
76    /**
77     * 0.5 defines minimum similarity as 50%
78     */
79    private static final float HIGH_THRESHOLD = 0.5f;
80
81    private static final BitmapComparer[] DEFAULT_MSSIM_COMPARER = new BitmapComparer[] {
82            new MSSIMComparer(HIGH_THRESHOLD)
83    };
84
85    @Test
86    public void testBasicDraws() {
87        sweepModifiersForMask(DisplayModifier.Accessor.SHAPES_MASK, null, DEFAULT_MSSIM_COMPARER);
88    }
89
90    @Test
91    public void testBasicShaders() {
92        sweepModifiersForMask(DisplayModifier.Accessor.SHADER_MASK, mCircleDrawModifier,
93                DEFAULT_MSSIM_COMPARER);
94    }
95
96    @Test
97    public void testColorFilterUsingGradient() {
98        sweepModifiersForMask(DisplayModifier.Accessor.COLOR_FILTER_MASK,
99                COLOR_FILTER_GRADIENT_MODIFIER, DEFAULT_MSSIM_COMPARER);
100    }
101
102    protected void sweepModifiersForMask(int mask, final DisplayModifier drawOp,
103                BitmapComparer[] bitmapComparers) {
104        if ((mask & DisplayModifier.Accessor.ALL_OPTIONS_MASK) == 0) {
105            throw new IllegalArgumentException("Attempt to test with a mask that is invalid");
106        }
107        // Get the accessor of all the different modifications possible
108        final DisplayModifier.Accessor modifierAccessor = new DisplayModifier.Accessor(mask);
109        // Initialize the resources that we will need to access
110        ResourceModifier.init(getActivity().getResources());
111        // For each modification combination, we will get the CanvasClient associated with it and
112        // from there execute a normal canvas test with that.
113        CanvasClient canvasClient = (canvas, width, height) -> {
114            Paint paint = new Paint();
115            modifierAccessor.modifyDrawing(canvas, paint);
116            if (drawOp != null) {
117                drawOp.modifyDrawing(paint, canvas);
118            }
119        };
120
121        int index = 0;
122        // Create the test cases with each combination
123        do {
124            int arrIndex = Math.min(index, bitmapComparers.length - 1);
125            TestCaseBuilder builder = createTest();
126            String debugString = modifierAccessor.getDebugString();
127            if (debugString.contains("bitmapMesh")) {
128                // picture mode is disabled due to bug:34871089
129                builder.addCanvasClientWithoutUsingPicture(debugString, canvasClient);
130            } else {
131                builder.addCanvasClient(debugString, canvasClient);
132            }
133            builder.runWithComparer(bitmapComparers[arrIndex]);
134            index++;
135        } while (modifierAccessor.step());
136    }
137}
138