1/*
2 * Copyright (C) 2016 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 */
16package android.uirendering.cts.testclasses;
17
18import android.graphics.Bitmap;
19import android.graphics.Canvas;
20import android.graphics.Color;
21import android.graphics.Paint;
22import android.graphics.Point;
23import android.graphics.PorterDuff;
24import android.graphics.PorterDuffColorFilter;
25import android.graphics.PorterDuffXfermode;
26import android.graphics.drawable.ColorDrawable;
27import android.support.test.filters.LargeTest;
28import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
29import android.uirendering.cts.testinfrastructure.ActivityTestBase;
30import android.uirendering.cts.testinfrastructure.CanvasClient;
31
32import org.junit.Test;
33import org.junit.runner.RunWith;
34import org.junit.runners.Parameterized;
35
36import java.util.List;
37
38@LargeTest // Temporarily hidden from presubmit
39@RunWith(Parameterized.class)
40public class ColorFilterAlphaTest extends ActivityTestBase {
41    // We care about one point in each of the four rectangles of different alpha values, as well as
42    // the area outside the rectangles
43
44    public static final int FILTER_COLOR = 0xFFBB0000;
45
46    private static final Point[] TEST_POINTS = new Point[] {
47            new Point(9, 45),
48            new Point(27, 45),
49            new Point(45, 45),
50            new Point(63, 45),
51            new Point(81, 45)
52    };
53
54    private static Object[][] MODES_AND_EXPECTED_COLORS = new Object[][] {
55        { PorterDuff.Mode.DST, new int[] {
56                0xFFE6E6E6, 0xFFCCCCCC, 0xFFB3B3B3, 0xFF999999, 0xFFFFFFFF } },
57
58        { PorterDuff.Mode.SRC_OVER, new int[] {
59                0xFFBB0000, 0xFFBB0000, 0xFFBB0000, 0xFFBB0000, 0xFFBB0000 } },
60
61        { PorterDuff.Mode.DST_OVER, new int[] {
62                0xFFAF1A1A, 0xFFA33333, 0xFF984D4D, 0xFF8B6666, 0xFFBB0000 } },
63
64        { PorterDuff.Mode.SRC_IN, new int[] {
65                0xFFF1CCCC, 0xFFE49999, 0xFFD66666, 0xFFC83333, 0xFFFFFFFF } },
66
67        { PorterDuff.Mode.DST_IN, new int[] {
68                0xFFE6E6E6, 0xFFCCCCCC, 0xFFB3B3B3, 0xFF999999, 0xFFFFFFFF } },
69
70        { PorterDuff.Mode.SRC_OUT, new int[] {
71                0xFFC83333, 0xFFD66666, 0xFFE49999, 0xFFF1CCCC, 0xFFBB0000 } },
72
73        { PorterDuff.Mode.DST_OUT, new int[] {
74                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } },
75
76        { PorterDuff.Mode.SRC_ATOP, new int[] {
77                0xFFF1CCCC, 0xFFE49999, 0xFFD66666, 0xFFC93333, 0xFFFFFFFF } },
78
79        { PorterDuff.Mode.DST_ATOP, new int[] {
80                0xFFB01A1A, 0xFFA33333, 0xFF984D4D, 0xFF8B6666, 0xFFBB0000 } },
81
82        { PorterDuff.Mode.XOR, new int[] {
83                0xFFC93333, 0xFFD66666, 0xFFE49999, 0xFFF1CCCC, 0xFFBB0000 } },
84
85        { PorterDuff.Mode.MULTIPLY, new int[] {
86                0xFFDFCCCC, 0xFFBE9999, 0xFF9E6666, 0xFF7E3333, 0xFFFFFFFF } },
87
88        { PorterDuff.Mode.SCREEN, new int[] {
89                0xFFC21A1A, 0xFFC93333, 0xFFD04D4D, 0xFFD66666, 0xFFBB0000 } },
90    };
91
92    @Parameterized.Parameters(name = "{0}")
93    public static List<XfermodeTest.Config> configs() {
94        return XfermodeTest.configs(MODES_AND_EXPECTED_COLORS);
95    }
96
97    private final XfermodeTest.Config mConfig;
98
99    public ColorFilterAlphaTest(XfermodeTest.Config config) {
100        mConfig = config;
101    }
102
103    private static final int[] BLOCK_COLORS = new int[] {
104            0x33808080,
105            0x66808080,
106            0x99808080,
107            0xCC808080,
108            0x00000000
109    };
110
111    private static Bitmap createMultiRectBitmap() {
112        Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
113        Canvas canvas = new Canvas(bitmap);
114        Paint paint = new Paint();
115        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
116        final int blockCount = BLOCK_COLORS.length;
117        final int blockWidth = TEST_WIDTH / blockCount;
118        for (int i = 0 ; i < blockCount; i++) {
119            paint.setColor(BLOCK_COLORS[i]);
120            canvas.drawRect(i * blockWidth, 0, (i + 1) * blockWidth, TEST_HEIGHT, paint);
121        }
122        return bitmap;
123    }
124
125
126    @Override
127    public void setUp() {
128        super.setUp();
129
130        // temporary - ensure test isn't capturing window bg only
131        getInstrumentation().runOnMainSync(() -> getActivity().getWindow().setBackgroundDrawable(
132                        new ColorDrawable(Color.GREEN)));
133
134    }
135
136    private CanvasClient mCanvasClient = new CanvasClient() {
137        final Paint mPaint = new Paint();
138        private final Bitmap mBitmap = createMultiRectBitmap();
139
140        @Override
141        public void draw(Canvas canvas, int width, int height) {
142            canvas.drawColor(Color.WHITE); // temporary - ensure test isn't capturing window bg only
143
144            mPaint.setColorFilter(new PorterDuffColorFilter(FILTER_COLOR, mConfig.mode));
145            canvas.drawBitmap(mBitmap, 0, 0, mPaint);
146        }
147    };
148
149    @Test
150    public void test() {
151        createTest()
152                .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
153                .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
154    }
155}
156
157
158