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