blob: a08b558fee1ff0b7469794e61a3906048814cf02 [file] [log] [blame]
Chris Craikc3683b52012-10-01 18:22:38 -07001/*
2 * Copyright (C) 2012 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
17package com.android.test.hwuicompare;
18
19import com.android.test.hwuicompare.R;
20import com.android.test.hwuicompare.ScriptC_errorCalculator;
21
22import android.content.Context;
23import android.content.res.Resources;
24import android.graphics.Bitmap;
25import android.graphics.Color;
26import android.renderscript.Allocation;
27import android.renderscript.Element;
28import android.renderscript.RenderScript;
29import android.util.Log;
30
31public class ErrorCalculator {
32 private static final String LOG_TAG = "ErrorCalculator";
33 private static final int REGION_SIZE = 8;
34
35 private static final boolean LOG_TIMING = false;
36 private static final boolean LOG_CALC = false;
37
38 private final RenderScript mRS;
39 private Allocation mIdealPixelsAllocation;
40 private Allocation mGivenPixelsAllocation;
41 private Allocation mOutputPixelsAllocation;
42
43 private final Allocation mInputRowsAllocation;
44 private final Allocation mOutputRegionsAllocation;
45
46 private final ScriptC_errorCalculator mScript;
47
48 private final int[] mOutputRowRegions;
49
50 public ErrorCalculator(Context c, Resources resources) {
51 int width = resources.getDimensionPixelSize(R.dimen.layer_width);
52 int height = resources.getDimensionPixelSize(R.dimen.layer_height);
53 mOutputRowRegions = new int[height / REGION_SIZE];
54
55 mRS = RenderScript.create(c);
56 int[] rowIndices = new int[height / REGION_SIZE];
57 for (int i = 0; i < rowIndices.length; i++)
58 rowIndices[i] = i * REGION_SIZE;
59
60 mScript = new ScriptC_errorCalculator(mRS, resources, R.raw.errorcalculator);
61 mScript.set_HEIGHT(height);
62 mScript.set_WIDTH(width);
63 mScript.set_REGION_SIZE(REGION_SIZE);
64
65 mInputRowsAllocation = Allocation.createSized(mRS, Element.I32(mRS), rowIndices.length,
66 Allocation.USAGE_SCRIPT);
67 mInputRowsAllocation.copyFrom(rowIndices);
68 mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
69 mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
70 }
71
72
73 private static long startMillis, middleMillis;
74
75 public float calcErrorRS(Bitmap ideal, Bitmap given) {
76 if (LOG_TIMING) {
77 startMillis = System.currentTimeMillis();
78 }
79
80 mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
81 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
82 mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
83 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
84
85 mScript.bind_ideal(mIdealPixelsAllocation);
86 mScript.bind_given(mGivenPixelsAllocation);
87
88 mScript.forEach_countInterestingRegions(mInputRowsAllocation, mOutputRegionsAllocation);
89 mOutputRegionsAllocation.copyTo(mOutputRowRegions);
90
91 int regionCount = 0;
92 for (int region : mOutputRowRegions) {
93 regionCount += region;
94 }
95 int interestingPixels = Math.max(1, regionCount) * REGION_SIZE * REGION_SIZE;
96
97 if (LOG_TIMING) {
98 long startMillis2 = System.currentTimeMillis();
99 }
100
101 mScript.forEach_accumulateError(mInputRowsAllocation, mOutputRegionsAllocation);
102 mOutputRegionsAllocation.copyTo(mOutputRowRegions);
103 float totalError = 0;
104 for (int row : mOutputRowRegions) {
105 totalError += row;
106 }
107 totalError /= 1024.0f;
108
109 if (LOG_TIMING) {
110 long finalMillis = System.currentTimeMillis();
111 Log.d(LOG_TAG, "rs: first part took " + (middleMillis - startMillis) + "ms");
112 Log.d(LOG_TAG, "rs: last part took " + (finalMillis - middleMillis) + "ms");
113 }
114 if (LOG_CALC) {
115 Log.d(LOG_TAG, "rs: error " + totalError + ", pixels " + interestingPixels);
116 }
117 return totalError / interestingPixels;
118 }
119
120 public void calcErrorHeatmapRS(Bitmap ideal, Bitmap given, Bitmap output) {
121 mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
122 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
123 mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
124 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
125
126 mScript.bind_ideal(mIdealPixelsAllocation);
127 mScript.bind_given(mGivenPixelsAllocation);
128
129 mOutputPixelsAllocation = Allocation.createFromBitmap(mRS, output,
130 Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
131 mScript.forEach_displayDifference(mOutputPixelsAllocation, mOutputPixelsAllocation);
132 mOutputPixelsAllocation.copyTo(output);
133 }
134
135 public static float calcError(Bitmap ideal, Bitmap given) {
136 if (LOG_TIMING) {
137 startMillis = System.currentTimeMillis();
138 }
139
140 int interestingRegions = 0;
141 for (int x = 0; x < ideal.getWidth(); x += REGION_SIZE) {
142 for (int y = 0; y < ideal.getWidth(); y += REGION_SIZE) {
143 if (inspectRegion(ideal, x, y)) {
144 interestingRegions++;
145 }
146 }
147 }
148
149 int interestingPixels = Math.max(1, interestingRegions) * REGION_SIZE * REGION_SIZE;
150
151 if (LOG_TIMING) {
152 long startMillis2 = System.currentTimeMillis();
153 }
154
155 float totalError = 0;
156 for (int x = 0; x < ideal.getWidth(); x++) {
157 for (int y = 0; y < ideal.getHeight(); y++) {
158 int idealColor = ideal.getPixel(x, y);
159 int givenColor = given.getPixel(x, y);
160 if (idealColor == givenColor)
161 continue;
162 totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
163 totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
164 totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
165 totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
166 }
167 }
168 totalError /= 1024.0f;
169 if (LOG_TIMING) {
170 long finalMillis = System.currentTimeMillis();
171 Log.d(LOG_TAG, "dvk: first part took " + (middleMillis - startMillis) + "ms");
172 Log.d(LOG_TAG, "dvk: last part took " + (finalMillis - middleMillis) + "ms");
173 }
174 if (LOG_CALC) {
175 Log.d(LOG_TAG, "dvk: error " + totalError + ", pixels " + interestingPixels);
176 }
177 return totalError / interestingPixels;
178 }
179
180 private static boolean inspectRegion(Bitmap ideal, int x, int y) {
181 int regionColor = ideal.getPixel(x, y);
182 for (int i = 0; i < REGION_SIZE; i++) {
183 for (int j = 0; j < REGION_SIZE; j++) {
184 if (ideal.getPixel(x + i, y + j) != regionColor)
185 return true;
186 }
187 }
188 return false;
189 }
190}