Home | History | Annotate | Download | only in hwuicompare
      1 /*
      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 
     17 package com.android.test.hwuicompare;
     18 
     19 import com.android.test.hwuicompare.R;
     20 import com.android.test.hwuicompare.ScriptC_errorCalculator;
     21 
     22 import android.content.Context;
     23 import android.content.res.Resources;
     24 import android.graphics.Bitmap;
     25 import android.graphics.Color;
     26 import android.renderscript.Allocation;
     27 import android.renderscript.Element;
     28 import android.renderscript.RenderScript;
     29 import android.util.Log;
     30 
     31 public 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 }
    191