• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.uirendering.cts.testclasses;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 
25 import android.content.res.Resources;
26 import android.graphics.Bitmap;
27 import android.graphics.BitmapFactory;
28 import android.graphics.BitmapRegionDecoder;
29 import android.graphics.Canvas;
30 import android.graphics.Color;
31 import android.graphics.Matrix;
32 import android.graphics.Paint;
33 import android.graphics.Picture;
34 import android.graphics.Rect;
35 import android.graphics.drawable.Drawable;
36 import android.graphics.drawable.NinePatchDrawable;
37 import android.uirendering.cts.R;
38 import android.uirendering.cts.bitmapcomparers.ExactComparer;
39 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
40 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
41 import android.uirendering.cts.bitmapverifiers.RectVerifier;
42 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
43 import android.util.DisplayMetrics;
44 
45 import androidx.test.filters.MediumTest;
46 import androidx.test.runner.AndroidJUnit4;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 
52 import java.io.ByteArrayInputStream;
53 import java.io.ByteArrayOutputStream;
54 import java.io.IOException;
55 import java.io.InputStream;
56 
57 @MediumTest
58 @RunWith(AndroidJUnit4.class)
59 public class HardwareBitmapTests extends ActivityTestBase {
60 
61     private Resources mRes;
62 
63     private static final BitmapFactory.Options HARDWARE_OPTIONS = createHardwareOptions();
64 
createHardwareOptions()65     private static BitmapFactory.Options createHardwareOptions() {
66         BitmapFactory.Options options = new BitmapFactory.Options();
67         options.inPreferredConfig = Bitmap.Config.HARDWARE;
68         return options;
69     }
70 
71     @Before
setup()72     public void setup() {
73         mRes = getActivity().getResources();
74     }
75 
76     @Test
testDecodeResource()77     public void testDecodeResource() {
78         createTest().addCanvasClient((canvas, width, height) -> {
79             Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
80                     HARDWARE_OPTIONS);
81             canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint());
82         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
83                 R.drawable.golden_robot, new MSSIMComparer(0.95)));
84     }
85 
86     @Test
testCreateFromPicture()87     public void testCreateFromPicture() {
88         final Rect rect = new Rect(10, 10, 80, 80);
89         Picture picture = new Picture();
90         {
91             Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
92             Paint p = new Paint();
93             p.setAntiAlias(false);
94             p.setColor(Color.BLUE);
95             canvas.drawRect(rect, p);
96             picture.endRecording();
97         }
98         Bitmap hardwareBitmap = Bitmap.createBitmap(picture);
99         assertEquals(TEST_WIDTH, hardwareBitmap.getWidth());
100         assertEquals(TEST_HEIGHT, hardwareBitmap.getHeight());
101         assertEquals(Bitmap.Config.HARDWARE, hardwareBitmap.getConfig());
102         createTest().addCanvasClient((canvas, width, height) -> {
103             canvas.drawBitmap(hardwareBitmap, 0, 0, null);
104         }, true).runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, rect));
105     }
106 
107     @Test
testReadbackThroughPicture()108     public void testReadbackThroughPicture() {
109         Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
110                 HARDWARE_OPTIONS);
111         assertEquals(Bitmap.Config.HARDWARE, hardwareBitmap.getConfig());
112         Picture picture = new Picture();
113         {
114             Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
115             canvas.drawColor(Color.WHITE);
116             canvas.drawBitmap(hardwareBitmap, 0, 0, null);
117             picture.endRecording();
118         }
119         assertTrue(picture.requiresHardwareAcceleration());
120         Bitmap result = Bitmap.createBitmap(picture, picture.getWidth(), picture.getHeight(),
121                 Bitmap.Config.ARGB_8888);
122         assertTrue(new GoldenImageVerifier(getActivity(),
123                 R.drawable.golden_robot, new MSSIMComparer(0.95)).verify(result));
124     }
125 
126     @Test
testReadbackThroughPictureNoEndRecording()127     public void testReadbackThroughPictureNoEndRecording() {
128         // Exact same test as #testReadbackThroughPicture but with an omitted endRecording
129         Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
130                 HARDWARE_OPTIONS);
131         assertEquals(Bitmap.Config.HARDWARE, hardwareBitmap.getConfig());
132         Picture picture = new Picture();
133         {
134             Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
135             canvas.drawColor(Color.WHITE);
136             canvas.drawBitmap(hardwareBitmap, 0, 0, null);
137         }
138         // It will be true, but as endRecording hasn't been called yet it's still in the
139         // "false" state from beginRecording()
140         assertFalse(picture.requiresHardwareAcceleration());
141         Bitmap result = Bitmap.createBitmap(picture, picture.getWidth(), picture.getHeight(),
142                 Bitmap.Config.ARGB_8888);
143         assertTrue(new GoldenImageVerifier(getActivity(),
144                 R.drawable.golden_robot, new MSSIMComparer(0.95)).verify(result));
145     }
146 
147     @Test
testCreateScaledBitmapFromPicture()148     public void testCreateScaledBitmapFromPicture() {
149         Picture picture = new Picture();
150         {
151             Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, HARDWARE_OPTIONS);
152             Canvas canvas = picture.beginRecording(bitmap.getWidth(), bitmap.getHeight());
153             Paint paint = new Paint();
154             paint.setFilterBitmap(true);
155             paint.setAntiAlias(true);
156             canvas.drawBitmap(bitmap, 0, 0, paint);
157             picture.endRecording();
158         }
159         assertTrue(picture.requiresHardwareAcceleration());
160         Bitmap scaled = Bitmap.createBitmap(picture, 24, 24, Bitmap.Config.HARDWARE);
161         createTest().addCanvasClient((canvas, width, height) -> {
162             assertEquals(Bitmap.Config.HARDWARE, scaled.getConfig());
163             canvas.drawBitmap(scaled, 0, 0, null);
164         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
165                 R.drawable.golden_hardwaretest_create_scaled, new MSSIMComparer(0.9)));
166     }
167 
168     @Test
testBitmapRegionDecode()169     public void testBitmapRegionDecode() throws IOException {
170         InputStream inputStream = mRes.openRawResource(R.drawable.robot);
171         BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(inputStream, false);
172         createTest().addCanvasClient((canvas, width, height) -> {
173             Bitmap hardwareBitmap = decoder.decodeRegion(new Rect(10, 15, 34, 39),
174                     HARDWARE_OPTIONS);
175             canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint());
176         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
177                 R.drawable.golden_headless_robot, new MSSIMComparer(0.95)));
178     }
179 
180     @Test
testBitmapConfigFromRGB565()181     public void testBitmapConfigFromRGB565() {
182         testBitmapCopy(R.drawable.robot, Bitmap.Config.RGB_565, Bitmap.Config.HARDWARE);
183     }
184 
185     @Test
testBitmapConfigFromARGB8888()186     public void testBitmapConfigFromARGB8888() {
187         testBitmapCopy(R.drawable.robot, Bitmap.Config.ARGB_8888, Bitmap.Config.HARDWARE);
188     }
189 
190     @Test
testBitmapConfigFromHardwareToHardware()191     public void testBitmapConfigFromHardwareToHardware() {
192         testBitmapCopy(R.drawable.robot, Bitmap.Config.HARDWARE, Bitmap.Config.HARDWARE);
193     }
194 
195     @Test
testBitmapConfigFromHardwareToARGB8888()196     public void testBitmapConfigFromHardwareToARGB8888() {
197         testBitmapCopy(R.drawable.robot, Bitmap.Config.HARDWARE, Bitmap.Config.ARGB_8888);
198     }
199 
200     @Test
testSetDensity()201     public void testSetDensity() {
202         createTest().addCanvasClient((canvas, width, height) -> {
203             Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot);
204             bitmap.setDensity(DisplayMetrics.DENSITY_LOW);
205             canvas.drawBitmap(bitmap, 0, 0, null);
206         }, true).addCanvasClient((canvas, width, height) -> {
207             Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
208                     HARDWARE_OPTIONS);
209             hardwareBitmap.setDensity(DisplayMetrics.DENSITY_LOW);
210             canvas.drawBitmap(hardwareBitmap, 0, 0, null);
211         }, true).runWithComparer(new ExactComparer());
212     }
213 
214     @Test
testNinePatch()215     public void testNinePatch() {
216         createTest().addCanvasClient((canvas, width, height) -> {
217             InputStream is = mRes.openRawResource(R.drawable.blue_padded_square);
218             NinePatchDrawable ninePatch = (NinePatchDrawable) Drawable.createFromResourceStream(
219                     mRes, null, is, null, HARDWARE_OPTIONS);
220             ninePatch.setBounds(0, 0, width, height);
221             ninePatch.setFilterBitmap(false);
222             ninePatch.draw(canvas);
223         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
224                 R.drawable.golden_hardwaretest_ninepatch, new MSSIMComparer(0.95)));
225     }
226 
227     @Test
testCreateIdentityBitmap()228     public void testCreateIdentityBitmap() {
229         Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
230                 HARDWARE_OPTIONS);
231         Bitmap newBitmap = Bitmap.createBitmap(hardwareBitmap);
232         assertEquals(hardwareBitmap, newBitmap);
233     }
234 
235     @Test
testCreateScaledBitmap()236     public void testCreateScaledBitmap() {
237         createTest().addCanvasClient((canvas, width, height) -> {
238             Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
239                     HARDWARE_OPTIONS);
240             Bitmap scaled = Bitmap.createScaledBitmap(hardwareBitmap, 24, 24, true);
241             assertEquals(Bitmap.Config.HARDWARE, scaled.getConfig());
242             canvas.drawBitmap(scaled, 0, 0, null);
243         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
244                 R.drawable.golden_hardwaretest_create_scaled, new MSSIMComparer(0.9)));
245     }
246 
247     @Test
testCreateSubsetBitmap()248     public void testCreateSubsetBitmap() {
249         createTest().addCanvasClient((canvas, width, height) -> {
250             Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
251                     HARDWARE_OPTIONS);
252             Matrix matrix = new Matrix();
253             matrix.setRotate(90);
254             Bitmap cropped = Bitmap.createBitmap(hardwareBitmap, 7, 7, 30, 30);
255             assertEquals(Bitmap.Config.HARDWARE, cropped.getConfig());
256             canvas.drawBitmap(cropped, 0, 0, null);
257         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
258                 R.drawable.golden_hardwaretest_create_subset, new MSSIMComparer(0.9)));
259     }
260 
261     @Test
testCreateTransformedBitmap()262     public void testCreateTransformedBitmap() {
263         createTest().addCanvasClient((canvas, width, height) -> {
264             Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
265                     HARDWARE_OPTIONS);
266             Matrix matrix = new Matrix();
267             matrix.setRotate(90);
268             Bitmap transformed = Bitmap.createBitmap(hardwareBitmap, 7, 7, 30, 30, matrix, false);
269             assertEquals(Bitmap.Config.HARDWARE, transformed.getConfig());
270             canvas.drawBitmap(transformed, 0, 0, null);
271         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
272                 R.drawable.golden_hardwaretest_create_transformed, new MSSIMComparer(0.9)));
273     }
274 
275     @Test
testCompressHardware()276     public void testCompressHardware() {
277         Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
278                 HARDWARE_OPTIONS);
279         ByteArrayOutputStream stream = new ByteArrayOutputStream();
280         assertTrue(hardwareBitmap.compress(Bitmap.CompressFormat.PNG, 50, stream));
281         Bitmap decoded = BitmapFactory.decodeStream(
282                 new ByteArrayInputStream(stream.toByteArray()));
283         createTest().addCanvasClient((canvas, width, height) -> {
284             canvas.drawColor(Color.CYAN);
285             canvas.drawBitmap(hardwareBitmap, 0, 0, null);
286         }, true).addCanvasClient((canvas, width, height) -> {
287             canvas.drawColor(Color.CYAN);
288             canvas.drawBitmap(decoded, 0, 0, null);
289         }, true).runWithComparer(new MSSIMComparer(0.99));
290 
291     }
292 
293     @Test
testHardwareExtractAlpha()294     public void testHardwareExtractAlpha() {
295         Bitmap bitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
296         bitmap.eraseColor(Color.argb(127, 250, 0, 0));
297         bitmap.setPixel(25, 25, Color.BLUE);
298 
299         Bitmap hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
300         Bitmap alphaBitmap = hwBitmap.extractAlpha();
301         assertEquals(Bitmap.Config.ALPHA_8, alphaBitmap.getConfig());
302         assertTrue(Color.alpha(alphaBitmap.getPixel(25, 25)) >= 254);
303         assertEquals(127, Color.alpha(alphaBitmap.getPixel(40, 40)));
304     }
305 
testBitmapCopy(int id, Bitmap.Config from, Bitmap.Config to)306     private void testBitmapCopy(int id, Bitmap.Config from, Bitmap.Config to) {
307         BitmapFactory.Options options = new BitmapFactory.Options();
308         options.inScaled = false;
309         options.inPreferredConfig = from;
310         Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), id, options);
311         assertEquals(from, bitmap.getConfig());
312 
313         createTest().addCanvasClient((canvas, width, height) -> {
314             canvas.drawColor(Color.CYAN);
315             canvas.drawBitmap(bitmap, 0, 0, null);
316         }, true).addCanvasClient((canvas, width, height) -> {
317             canvas.drawColor(Color.CYAN);
318             Bitmap copy = bitmap.copy(to, false);
319             assertNotNull(copy);
320             assertEquals(to, copy.getConfig());
321             canvas.drawBitmap(copy, 0, 0, null);
322         }, true).runWithComparer(new MSSIMComparer(0.99));
323     }
324 }
325