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