blob: 8af9d3bca647280cb25e4ed3fba8d37aaddb2797 [file] [log] [blame]
Dake Gu5e6f4382017-07-18 16:12:43 -07001/*
2 * Copyright (C) 2017 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 com.android.test.uibench.leanback;
17
18import android.content.Context;
19import android.graphics.Bitmap;
20import android.graphics.Canvas;
21import android.graphics.Color;
22import android.graphics.Paint;
23import android.os.AsyncTask;
24import android.support.v4.util.LruCache;
25import android.util.DisplayMetrics;
26import android.widget.ImageView;
27
28/**
29 * This class simulates a typical Bitmap memory cache with up to 1.5 times of screen pixels.
30 * The sample bitmap is generated in worker threads in AsyncTask.THREAD_POOL_EXECUTOR.
31 * The class does not involve decoding, disk cache i/o, network i/o, as the test is mostly focusing
32 * on the graphics side.
33 * There will be two general use cases for cards in leanback test:
34 * 1. As a typical app, each card has its own id and load its own Bitmap, the test result will
35 * include impact of texture upload.
36 * 2. All cards share same id/Bitmap and there wont be texture upload.
37 */
38public class BitmapLoader {
39
40 /**
41 * Caches bitmaps with bytes adds up to 1.5 x screen
42 * DO NOT CHANGE this defines baseline of test result.
43 */
44 static final float CACHE_SIZE_TO_SCREEN = 1.5f;
45 /**
46 * 4 bytes per pixel for RGBA_8888
47 */
48 static final int BYTES_PER_PIXEL = 4;
49
50 static LruCache<Long, Bitmap> sLruCache;
51 static Paint sTextPaint = new Paint();
52
53 static {
54 sTextPaint.setColor(Color.BLACK);
55 }
56
57 /**
58 * get or initialize LruCache, the max is set to full screen pixels.
59 */
60 static LruCache<Long, Bitmap> getLruCache(Context context) {
61 if (sLruCache == null) {
62 DisplayMetrics metrics = context.getResources().getDisplayMetrics();
63 int width = metrics.widthPixels;
64 int height = metrics.heightPixels;
65 int maxBytes = (int) (width * height * BYTES_PER_PIXEL * CACHE_SIZE_TO_SCREEN);
66 sLruCache = new LruCache<Long, Bitmap>(maxBytes) {
67 @Override
68 protected int sizeOf(Long key, Bitmap value) {
69 return value.getByteCount();
70 }
71 };
72 }
73 return sLruCache;
74 }
75
76 static class BitmapAsyncTask extends AsyncTask<Void, Void, Bitmap> {
77
78 ImageView mImageView;
79 long mId;
80 int mWidth;
81 int mHeight;
82
83 BitmapAsyncTask(ImageView view, long id, int width, int height) {
84 mImageView = view;
85 mId = id;
86 mImageView.setTag(this);
87 mWidth = width;
88 mHeight = height;
89 }
90
91 @Override
92 protected Bitmap doInBackground(Void... voids) {
93 // generate a sample bitmap: white background and text showing id
94 Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
95 Canvas canvas = new Canvas(bitmap);
96 canvas.drawARGB(0xff, 0xff, 0xff, 0xff);
97 canvas.drawText(Long.toString(mId), 0f, mHeight / 2, sTextPaint);
98 canvas.setBitmap(null);
99 bitmap.prepareToDraw();
100 return bitmap;
101 }
102
103 @Override
104 protected void onCancelled() {
105 if (mImageView.getTag() == this) {
106 mImageView.setTag(null);
107 }
108 }
109
110 @Override
111 protected void onPostExecute(Bitmap bitmap) {
112 if (mImageView.getTag() == this) {
113 mImageView.setTag(null);
114 sLruCache.put(mId, bitmap);
115 mImageView.setImageBitmap(bitmap);
116 }
117 }
118 }
119
120 public static void loadBitmap(ImageView view, long id, int width, int height) {
121 Context context = view.getContext();
122 Bitmap bitmap = getLruCache(context).get(id);
123 if (bitmap != null) {
124 view.setImageBitmap(bitmap);
125 return;
126 }
127 new BitmapAsyncTask(view, id, width, height)
128 .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
129 }
130
131 public static void cancel(ImageView view) {
132 BitmapAsyncTask task = (BitmapAsyncTask) view.getTag();
133 if (task != null && task.mImageView == view) {
134 task.mImageView.setTag(null);
135 task.cancel(false);
136 }
137 }
138
139 public static void clear() {
140 if (sLruCache != null) {
141 sLruCache.evictAll();
142 }
143 }
144}