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.PorterDuffXfermode; 25import android.graphics.RectF; 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.ArrayList; 37import java.util.List; 38 39@LargeTest // Temporarily hidden from presubmit 40@RunWith(Parameterized.class) 41public class XfermodeTest extends ActivityTestBase { 42 /** 43 * There are 4 locations we care about in testing each filter: 44 * 45 * 1) Both empty 46 * 2) Only src, dst empty 47 * 3) Both src + dst 48 * 4) Only dst, src empty 49 */ 50 private final static Point[] TEST_POINTS = new Point[] { 51 new Point(1, 80), 52 new Point(25, 25), 53 new Point(35, 35), 54 new Point(70, 70) 55 }; 56 57 public static class Config { 58 final boolean hardwareAccelerated; 59 final PorterDuff.Mode mode; 60 final int[] expectedColors; 61 62 Config(boolean hardwareAccelerated, Object[] modeAndExpectedColors) { 63 this.hardwareAccelerated = hardwareAccelerated; 64 mode = (PorterDuff.Mode) modeAndExpectedColors[0]; 65 expectedColors = (int[]) modeAndExpectedColors[1]; 66 } 67 68 @Override 69 public String toString() { 70 return mode.name() + ", hardwareAccelerated=" + hardwareAccelerated; 71 } 72 }; 73 74 public static List<XfermodeTest.Config> configs(Object[][] modesAndExpectedColors) { 75 List<XfermodeTest.Config> configs = new ArrayList<>(); 76 for (boolean hardwareAccelerated : new boolean[] {false, true}) { 77 for (Object[] modeAndExpectedColors : modesAndExpectedColors) { 78 configs.add(new XfermodeTest.Config(hardwareAccelerated, modeAndExpectedColors)); 79 } 80 } 81 return configs; 82 } 83 84 private static final int BG_COLOR = 0xFFFFFFFF; 85 private static final int DST_COLOR = 0xFFFFCC44; 86 private static final int SRC_COLOR = 0xFF66AAFF; 87 private static final int MULTIPLY_COLOR = 0xFF668844; 88 private static final int SCREEN_COLOR = 0xFFFFEEFF; 89 90 private static Object[][] MODES_AND_EXPECTED_COLORS = new Object[][] { 91 { PorterDuff.Mode.SRC, new int[] { 92 BG_COLOR, BG_COLOR, SRC_COLOR, SRC_COLOR } }, 93 94 { PorterDuff.Mode.DST, new int[] { 95 BG_COLOR, DST_COLOR, DST_COLOR, BG_COLOR } }, 96 97 { PorterDuff.Mode.SRC_OVER, new int[] { 98 BG_COLOR, DST_COLOR, SRC_COLOR, SRC_COLOR } }, 99 100 { PorterDuff.Mode.DST_OVER, new int[] { 101 BG_COLOR, DST_COLOR, DST_COLOR, SRC_COLOR } }, 102 103 { PorterDuff.Mode.SRC_IN, new int[] { 104 BG_COLOR, BG_COLOR, SRC_COLOR, BG_COLOR } }, 105 106 { PorterDuff.Mode.DST_IN, new int[] { 107 BG_COLOR, BG_COLOR, DST_COLOR, BG_COLOR } }, 108 109 { PorterDuff.Mode.SRC_OUT, new int[] { 110 BG_COLOR, BG_COLOR, BG_COLOR, SRC_COLOR } }, 111 112 { PorterDuff.Mode.DST_OUT, new int[] { 113 BG_COLOR, DST_COLOR, BG_COLOR, BG_COLOR } }, 114 115 { PorterDuff.Mode.SRC_ATOP, new int[] { 116 BG_COLOR, DST_COLOR, SRC_COLOR, BG_COLOR } }, 117 118 { PorterDuff.Mode.DST_ATOP, new int[] { 119 BG_COLOR, BG_COLOR, DST_COLOR, SRC_COLOR } }, 120 121 { PorterDuff.Mode.XOR, new int[] { 122 BG_COLOR, DST_COLOR, BG_COLOR, SRC_COLOR } }, 123 124 { PorterDuff.Mode.MULTIPLY, new int[] { 125 BG_COLOR, BG_COLOR, MULTIPLY_COLOR, BG_COLOR } }, 126 127 { PorterDuff.Mode.SCREEN, new int[] { 128 BG_COLOR, DST_COLOR, SCREEN_COLOR, SRC_COLOR } }, 129 }; 130 131 @Parameterized.Parameters(name = "{0}") 132 public static List<Config> configs() { 133 return configs(MODES_AND_EXPECTED_COLORS); 134 } 135 136 private final Config mConfig; 137 138 public XfermodeTest(Config config) { 139 mConfig = config; 140 } 141 142 143 @Override 144 public void setUp() { 145 super.setUp(); 146 147 // temporary - ensure test isn't capturing window bg only 148 getInstrumentation().runOnMainSync(() -> getActivity().getWindow().setBackgroundDrawable( 149 new ColorDrawable(Color.GREEN))); 150 151 } 152 153 private CanvasClient mCanvasClient = new CanvasClient() { 154 final Paint mPaint = new Paint(); 155 private final RectF mSrcRect = new RectF(30, 30, 80, 80); 156 private final RectF mDstRect = new RectF(10, 10, 60, 60); 157 private final Bitmap mSrcBitmap = createSrc(); 158 private final Bitmap mDstBitmap = createDst(); 159 160 @Override 161 public void draw(Canvas canvas, int width, int height) { 162 canvas.drawColor(Color.WHITE); // temporary - ensure test isn't capturing window bg only 163 164 int sc = canvas.saveLayer(0, 0, TEST_WIDTH, TEST_HEIGHT, null); 165 166 canvas.drawBitmap(mDstBitmap, 0, 0, null); 167 mPaint.setXfermode(new PorterDuffXfermode(mConfig.mode)); 168 canvas.drawBitmap(mSrcBitmap, 0, 0, mPaint); 169 170 canvas.restoreToCount(sc); 171 } 172 173 private Bitmap createSrc() { 174 Bitmap srcB = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888); 175 Canvas srcCanvas = new Canvas(srcB); 176 Paint srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 177 srcPaint.setColor(SRC_COLOR); 178 srcCanvas.drawRect(mSrcRect, srcPaint); 179 return srcB; 180 } 181 182 private Bitmap createDst() { 183 Bitmap dstB = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888); 184 Canvas dstCanvas = new Canvas(dstB); 185 Paint dstPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 186 dstPaint.setColor(DST_COLOR); 187 dstCanvas.drawOval(mDstRect, dstPaint); 188 return dstB; 189 } 190 }; 191 192 @Test 193 public void test() { 194 createTest() 195 .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated) 196 .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors)); 197 } 198} 199