Merge "Remove CanvasCompare." am: 688256e5d7
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2399535 Change-Id: I4fa7e96439055bfc186a199b88403a326e649472 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1,63 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (C) 2012 The Android Open Source Project
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
package {
|
|
||||||
// See: http://go/android-license-faq
|
|
||||||
default_applicable_licenses: [
|
|
||||||
"frameworks_base_license",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
android_test {
|
|
||||||
name: "CanvasCompare",
|
|
||||||
srcs: [
|
|
||||||
"src/**/*.java",
|
|
||||||
":CanvasCompare-rscript{CanvasCompare.srcjar}",
|
|
||||||
],
|
|
||||||
resource_zips: [
|
|
||||||
":CanvasCompare-rscript{CanvasCompare.res.zip}",
|
|
||||||
],
|
|
||||||
platform_apis: true,
|
|
||||||
libs: [
|
|
||||||
"android.test.runner",
|
|
||||||
"android.test.base",
|
|
||||||
],
|
|
||||||
static_libs: ["junit"],
|
|
||||||
}
|
|
||||||
|
|
||||||
genrule {
|
|
||||||
name: "CanvasCompare-rscript",
|
|
||||||
srcs: [
|
|
||||||
"src/**/*.rscript",
|
|
||||||
":rs_script_api",
|
|
||||||
":rs_clang_headers",
|
|
||||||
],
|
|
||||||
tools: [
|
|
||||||
"llvm-rs-cc",
|
|
||||||
"soong_zip",
|
|
||||||
],
|
|
||||||
out: [
|
|
||||||
"CanvasCompare.srcjar",
|
|
||||||
"CanvasCompare.res.zip",
|
|
||||||
],
|
|
||||||
cmd: "for f in $(locations src/**/*.rscript); do " +
|
|
||||||
" $(location llvm-rs-cc) -o $(genDir)/res/raw -p $(genDir)/src " +
|
|
||||||
" -I $$(dirname $$(echo $(locations :rs_script_api) | awk '{ print $$1 }')) " +
|
|
||||||
" -I $$(dirname $$(echo $(locations :rs_clang_headers) | awk '{ print $$1 }')) $${f}; " +
|
|
||||||
"done && " +
|
|
||||||
"$(location soong_zip) -srcjar -o $(location CanvasCompare.srcjar) -C $(genDir)/src -D $(genDir)/src &&" +
|
|
||||||
"$(location soong_zip) -o $(location CanvasCompare.res.zip) -C $(genDir)/res -D $(genDir)/res",
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="com.android.test.hwuicompare">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
|
|
||||||
<application android:label="@string/app_name"
|
|
||||||
android:theme="@android:style/Theme.Holo.Light.NoActionBar">
|
|
||||||
<activity android:name="AutomaticActivity"
|
|
||||||
android:label="CanvasAutoCompare"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name="ManualActivity"
|
|
||||||
android:label="CanvasManualCompare"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<uses-library android:name="android.test.runner"/>
|
|
||||||
</application>
|
|
||||||
<instrumentation android:name="android.test.InstrumentationTestRunner"
|
|
||||||
android:targetPackage="com.android.test.hwuicompare"
|
|
||||||
android:label="HW/SW Canvas comparison tool."/>
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
include /libs/hwui/OWNERS
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
@@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" >
|
|
||||||
|
|
||||||
<com.android.test.hwuicompare.MainView
|
|
||||||
android:id="@+id/hardware_view"
|
|
||||||
android:layout_width="@dimen/layer_width"
|
|
||||||
android:layout_height="@dimen/layer_width" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/software_image_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentRight="true" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/hardware_image_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentRight="true" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<HorizontalScrollView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" >
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/spinner_layout"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal" />
|
|
||||||
</HorizontalScrollView>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dip"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:baselineAligned="true"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<com.android.test.hwuicompare.MainView
|
|
||||||
android:id="@+id/hardware_view"
|
|
||||||
android:layout_width="@dimen/layer_width"
|
|
||||||
android:layout_height="@dimen/layer_width" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<com.android.test.hwuicompare.MainView
|
|
||||||
android:id="@+id/software_view"
|
|
||||||
android:layout_width="@dimen/layer_width"
|
|
||||||
android:layout_height="@dimen/layer_width" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/compare_image_view"
|
|
||||||
android:layout_width="@dimen/layer_width_double"
|
|
||||||
android:layout_height="@dimen/layer_height_double"
|
|
||||||
android:filter="false" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/previous"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:contentDescription="@string/previous_combination"
|
|
||||||
android:src="@android:drawable/ic_media_previous" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/next"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:contentDescription="@string/next_combination"
|
|
||||||
android:src="@android:drawable/ic_media_next" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/current_error"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/show_hardware_version"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/show_hardware_version" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/show_software_version"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/show_software_version" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/show_error_heatmap"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/show_error_heatmap" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">Canvas Compare Test</string>
|
|
||||||
|
|
||||||
<!-- show hardware rendered version of the layer -->
|
|
||||||
<string name="show_hardware_version">Hardware</string>
|
|
||||||
<!-- show software rendered version of the layer -->
|
|
||||||
<string name="show_software_version">Software</string>
|
|
||||||
<!-- show layer error -->
|
|
||||||
<string name="show_error_values">Error</string>
|
|
||||||
<!-- show layer error heatmap -->
|
|
||||||
<string name="show_error_heatmap">Heatmap</string>
|
|
||||||
<!-- select and display the next combination of painting options-->
|
|
||||||
<string name="next_combination">Next Combination</string>
|
|
||||||
<!-- select and display the previous combination of painting options-->
|
|
||||||
<string name="previous_combination">Previous Combination</string>
|
|
||||||
</resources>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<resources>
|
|
||||||
|
|
||||||
<!-- NOTE: the below MUST be multiples of 64 -->
|
|
||||||
<dimen name="layer_height">320px</dimen>
|
|
||||||
<dimen name="layer_width">320px</dimen>
|
|
||||||
|
|
||||||
<dimen name="layer_height_double">640px</dimen>
|
|
||||||
<dimen name="layer_width_double">640px</dimen>
|
|
||||||
|
|
||||||
</resources>
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.Trace;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
public class AutomaticActivity extends CompareActivity {
|
|
||||||
private static final String LOG_TAG = "AutomaticActivity";
|
|
||||||
private static final float ERROR_DISPLAY_THRESHOLD = 0.01f;
|
|
||||||
protected static final boolean DRAW_BITMAPS = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Threshold of error change required to consider a test regressed/improved
|
|
||||||
*/
|
|
||||||
private static final float ERROR_CHANGE_THRESHOLD = 0.001f;
|
|
||||||
|
|
||||||
private static final float[] ERROR_CUTOFFS = {
|
|
||||||
0, 0.005f, 0.01f, 0.02f, 0.05f, 0.1f, 0.25f, 0.5f, 1f, 2f
|
|
||||||
};
|
|
||||||
|
|
||||||
private final float[] mErrorRates = new float[ERROR_CUTOFFS.length];
|
|
||||||
private float mTotalTests = 0;
|
|
||||||
private float mTotalError = 0;
|
|
||||||
private int mTestsRegressed = 0;
|
|
||||||
private int mTestsImproved = 0;
|
|
||||||
|
|
||||||
private ImageView mSoftwareImageView = null;
|
|
||||||
private ImageView mHardwareImageView = null;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract static class FinalCallback {
|
|
||||||
abstract void report(String name, float value);
|
|
||||||
void complete() {};
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ArrayList<FinalCallback> mFinalCallbacks = new ArrayList<FinalCallback>();
|
|
||||||
|
|
||||||
Runnable mRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
loadBitmaps();
|
|
||||||
if (mSoftwareBitmap == null || mHardwareBitmap == null) {
|
|
||||||
Log.e(LOG_TAG, "bitmap is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DRAW_BITMAPS) {
|
|
||||||
mSoftwareImageView.setImageBitmap(mSoftwareBitmap);
|
|
||||||
mHardwareImageView.setImageBitmap(mHardwareBitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "calculateError");
|
|
||||||
float error = mErrorCalculator.calcErrorRS(mSoftwareBitmap, mHardwareBitmap);
|
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
|
|
||||||
|
|
||||||
final String[] modifierNames = DisplayModifier.getLastAppliedModifications();
|
|
||||||
handleError(modifierNames, error);
|
|
||||||
|
|
||||||
if (DisplayModifier.step()) {
|
|
||||||
finishTest();
|
|
||||||
} else {
|
|
||||||
mHardwareView.invalidate();
|
|
||||||
if (DRAW_BITMAPS) {
|
|
||||||
mSoftwareImageView.invalidate();
|
|
||||||
mHardwareImageView.invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mHandler.removeCallbacks(mRunnable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
mHandler.removeCallbacks(mRunnable);
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.automatic_layout);
|
|
||||||
|
|
||||||
mSoftwareImageView = findViewById(R.id.software_image_view);
|
|
||||||
mHardwareImageView = findViewById(R.id.hardware_image_view);
|
|
||||||
|
|
||||||
onCreateCommon(mRunnable);
|
|
||||||
beginTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TestResult {
|
|
||||||
TestResult(String label, float error) {
|
|
||||||
mLabel = label;
|
|
||||||
mTotalError = error;
|
|
||||||
mCount = 1;
|
|
||||||
}
|
|
||||||
public void addInto(float error) {
|
|
||||||
mTotalError += error;
|
|
||||||
mCount++;
|
|
||||||
}
|
|
||||||
public float getAverage() {
|
|
||||||
return mTotalError / mCount;
|
|
||||||
}
|
|
||||||
final String mLabel;
|
|
||||||
float mTotalError;
|
|
||||||
int mCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSONObject mOutputJson = null;
|
|
||||||
JSONObject mInputJson = null;
|
|
||||||
final HashMap<String, TestResult> mModifierResults = new HashMap<String, TestResult>();
|
|
||||||
final HashMap<String, TestResult> mIndividualResults = new HashMap<String, TestResult>();
|
|
||||||
final HashMap<String, TestResult> mModifierDiffResults = new HashMap<String, TestResult>();
|
|
||||||
final HashMap<String, TestResult> mIndividualDiffResults = new HashMap<String, TestResult>();
|
|
||||||
private void beginTest() {
|
|
||||||
mFinalCallbacks.add(new FinalCallback() {
|
|
||||||
@Override
|
|
||||||
void report(String name, float value) {
|
|
||||||
Log.d(LOG_TAG, name + " " + value);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
File inputFile = new File(Environment.getExternalStorageDirectory(),
|
|
||||||
"CanvasCompareInput.json");
|
|
||||||
if (inputFile.exists() && inputFile.canRead() && inputFile.length() > 0) {
|
|
||||||
try {
|
|
||||||
FileInputStream inputStream = new FileInputStream(inputFile);
|
|
||||||
Log.d(LOG_TAG, "Parsing input file...");
|
|
||||||
StringBuffer content = new StringBuffer((int)inputFile.length());
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
while (inputStream.read(buffer) != -1) {
|
|
||||||
content.append(new String(buffer));
|
|
||||||
}
|
|
||||||
mInputJson = new JSONObject(content.toString());
|
|
||||||
inputStream.close();
|
|
||||||
Log.d(LOG_TAG, "Parsed input file with " + mInputJson.length() + " entries");
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(LOG_TAG, "error parsing input json", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(LOG_TAG, "error reading input json from sd", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mOutputJson = new JSONObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void logTestResultHash(String label, HashMap<String, TestResult> map) {
|
|
||||||
Log.d(LOG_TAG, "---------------");
|
|
||||||
Log.d(LOG_TAG, label + ":");
|
|
||||||
Log.d(LOG_TAG, "---------------");
|
|
||||||
TreeSet<TestResult> set = new TreeSet<TestResult>(new Comparator<TestResult>() {
|
|
||||||
@Override
|
|
||||||
public int compare(TestResult lhs, TestResult rhs) {
|
|
||||||
if (lhs == rhs) return 0; // don't need to worry about complex equality
|
|
||||||
|
|
||||||
int cmp = Float.compare(lhs.getAverage(), rhs.getAverage());
|
|
||||||
if (cmp != 0) {
|
|
||||||
return cmp;
|
|
||||||
}
|
|
||||||
return lhs.mLabel.compareTo(rhs.mLabel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (TestResult t : map.values()) {
|
|
||||||
set.add(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TestResult t : set.descendingSet()) {
|
|
||||||
if (Math.abs(t.getAverage()) > ERROR_DISPLAY_THRESHOLD) {
|
|
||||||
Log.d(LOG_TAG, String.format("%2.4f : %s", t.getAverage(), t.mLabel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(LOG_TAG, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void finishTest() {
|
|
||||||
for (FinalCallback c : mFinalCallbacks) {
|
|
||||||
c.report("averageError", (mTotalError / mTotalTests));
|
|
||||||
for (int i = 1; i < ERROR_CUTOFFS.length; i++) {
|
|
||||||
c.report(String.format("tests with error over %1.3f", ERROR_CUTOFFS[i]),
|
|
||||||
mErrorRates[i]);
|
|
||||||
}
|
|
||||||
if (mInputJson != null) {
|
|
||||||
c.report("tests regressed", mTestsRegressed);
|
|
||||||
c.report("tests improved", mTestsImproved);
|
|
||||||
}
|
|
||||||
c.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (mOutputJson != null) {
|
|
||||||
String outputString = mOutputJson.toString(4);
|
|
||||||
File outputFile = new File(Environment.getExternalStorageDirectory(),
|
|
||||||
"CanvasCompareOutput.json");
|
|
||||||
FileOutputStream outputStream = new FileOutputStream(outputFile);
|
|
||||||
outputStream.write(outputString.getBytes());
|
|
||||||
outputStream.close();
|
|
||||||
Log.d(LOG_TAG, "Saved output file with " + mOutputJson.length() + " entries");
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(LOG_TAG, "error during JSON stringify", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(LOG_TAG, "error storing JSON output on sd", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
logTestResultHash("Modifier change vs previous", mModifierDiffResults);
|
|
||||||
logTestResultHash("Invidual test change vs previous", mIndividualDiffResults);
|
|
||||||
logTestResultHash("Modifier average test results", mModifierResults);
|
|
||||||
logTestResultHash("Individual test results", mIndividualResults);
|
|
||||||
|
|
||||||
Toast.makeText(getApplicationContext(), "done!", Toast.LENGTH_SHORT).show();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts the error value into all TestResult objects, associated with each of its modifiers
|
|
||||||
*/
|
|
||||||
private static void addForAllModifiers(String fullName, float error, String[] modifierNames,
|
|
||||||
HashMap<String, TestResult> modifierResults) {
|
|
||||||
for (String modifierName : modifierNames) {
|
|
||||||
TestResult r = modifierResults.get(fullName);
|
|
||||||
if (r == null) {
|
|
||||||
modifierResults.put(modifierName, new TestResult(modifierName, error));
|
|
||||||
} else {
|
|
||||||
r.addInto(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleError(final String[] modifierNames, final float error) {
|
|
||||||
String fullName = "";
|
|
||||||
for (String s : modifierNames) {
|
|
||||||
fullName = fullName.concat("." + s);
|
|
||||||
}
|
|
||||||
fullName = fullName.substring(1);
|
|
||||||
|
|
||||||
float deltaError = 0;
|
|
||||||
if (mInputJson != null) {
|
|
||||||
try {
|
|
||||||
deltaError = error - (float)mInputJson.getDouble(fullName);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.w(LOG_TAG, "Warning: unable to read from input json", e);
|
|
||||||
}
|
|
||||||
if (deltaError > ERROR_CHANGE_THRESHOLD) mTestsRegressed++;
|
|
||||||
if (deltaError < -ERROR_CHANGE_THRESHOLD) mTestsImproved++;
|
|
||||||
mIndividualDiffResults.put(fullName, new TestResult(fullName, deltaError));
|
|
||||||
addForAllModifiers(fullName, deltaError, modifierNames, mModifierDiffResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
mIndividualResults.put(fullName, new TestResult(fullName, error));
|
|
||||||
addForAllModifiers(fullName, error, modifierNames, mModifierResults);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (mOutputJson != null) {
|
|
||||||
mOutputJson.put(fullName, error);
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(LOG_TAG, "exception during JSON recording", e);
|
|
||||||
mOutputJson = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < ERROR_CUTOFFS.length; i++) {
|
|
||||||
if (error <= ERROR_CUTOFFS[i]) break;
|
|
||||||
mErrorRates[i]++;
|
|
||||||
}
|
|
||||||
mTotalError += error;
|
|
||||||
mTotalTests++;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean forceRecreateBitmaps() {
|
|
||||||
// disable, unless needed for drawing into imageviews
|
|
||||||
return DRAW_BITMAPS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FOR TESTING
|
|
||||||
public void setFinalCallback(FinalCallback c) {
|
|
||||||
mFinalCallbacks.add(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import com.android.test.hwuicompare.R;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Trace;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
abstract public class CompareActivity extends Activity {
|
|
||||||
private static final String LOG_TAG = "CompareActivity";
|
|
||||||
|
|
||||||
protected MainView mHardwareView = null;
|
|
||||||
|
|
||||||
protected Bitmap mSoftwareBitmap;
|
|
||||||
protected Bitmap mHardwareBitmap;
|
|
||||||
|
|
||||||
protected ErrorCalculator mErrorCalculator;
|
|
||||||
|
|
||||||
protected Handler mHandler;
|
|
||||||
|
|
||||||
Runnable mDrawCallback = null;
|
|
||||||
protected boolean mRedrewFlag = true;
|
|
||||||
|
|
||||||
protected void onCreateCommon(final Runnable postDrawCallback) {
|
|
||||||
mDrawCallback = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mRedrewFlag = true;
|
|
||||||
mHandler.post(postDrawCallback);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
getWindow().setBackgroundDrawable(new ColorDrawable(0xffefefef));
|
|
||||||
ResourceModifiers.init(getResources());
|
|
||||||
|
|
||||||
mHardwareView = findViewById(R.id.hardware_view);
|
|
||||||
mHardwareView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
|
||||||
mHardwareView.setBackgroundColor(Color.WHITE);
|
|
||||||
mHardwareView.addDrawCallback(mDrawCallback);
|
|
||||||
|
|
||||||
int width = getResources().getDimensionPixelSize(R.dimen.layer_width);
|
|
||||||
int height = getResources().getDimensionPixelSize(R.dimen.layer_height);
|
|
||||||
mSoftwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
mHardwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
|
|
||||||
mErrorCalculator = new ErrorCalculator(getApplicationContext(), getResources());
|
|
||||||
|
|
||||||
mHandler = new Handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean forceRecreateBitmaps();
|
|
||||||
|
|
||||||
protected void loadBitmaps() {
|
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "loadBitmaps");
|
|
||||||
if (forceRecreateBitmaps()) {
|
|
||||||
int width = mSoftwareBitmap.getWidth();
|
|
||||||
int height = mSoftwareBitmap.getHeight();
|
|
||||||
|
|
||||||
mSoftwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
mHardwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "softwareDraw");
|
|
||||||
mHardwareView.draw(new Canvas(mSoftwareBitmap));
|
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Method getHardwareLayer = View.class.getDeclaredMethod("getHardwareLayer");
|
|
||||||
if (!getHardwareLayer.isAccessible())
|
|
||||||
getHardwareLayer.setAccessible(true);
|
|
||||||
Object hardwareLayer = getHardwareLayer.invoke(mHardwareView);
|
|
||||||
if (hardwareLayer == null) {
|
|
||||||
Log.d(LOG_TAG, "failure to access hardware layer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Method copyInto = hardwareLayer.getClass()
|
|
||||||
.getDeclaredMethod("copyInto", Bitmap.class);
|
|
||||||
if (!copyInto.isAccessible())
|
|
||||||
copyInto.setAccessible(true);
|
|
||||||
|
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "copyInto");
|
|
||||||
boolean success = (Boolean) copyInto.invoke(hardwareLayer, mHardwareBitmap);
|
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
|
|
||||||
if (!success) {
|
|
||||||
Log.d(LOG_TAG, "failure to copy hardware layer into bitmap");
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,503 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
public abstract class DisplayModifier {
|
|
||||||
|
|
||||||
// automated tests ignore any combination of operations that don't together return TOTAL_MASK
|
|
||||||
protected final static int TOTAL_MASK = 0x1F;
|
|
||||||
|
|
||||||
// if we're filling, ensure we're not also sweeping over stroke parameters
|
|
||||||
protected final static int SWEEP_STROKE_WIDTH_BIT = 0x1 << 0;
|
|
||||||
protected final static int SWEEP_STROKE_CAP_BIT = 0x1 << 1;
|
|
||||||
protected final static int SWEEP_STROKE_JOIN_BIT = 0x1 << 2;
|
|
||||||
|
|
||||||
protected final static int SWEEP_SHADER_BIT = 0x1 << 3; // only allow non-simple shaders to use rectangle drawing
|
|
||||||
protected final static int SWEEP_TRANSFORM_BIT = 0x1 << 4; // only sweep over specified transforms
|
|
||||||
|
|
||||||
abstract public void modifyDrawing(Paint paint, Canvas canvas);
|
|
||||||
protected int mask() { return 0x0; };
|
|
||||||
|
|
||||||
private static final RectF gRect = new RectF(0, 0, 200, 175);
|
|
||||||
private static final float[] gPts = new float[] {
|
|
||||||
0, 100, 100, 0, 100, 200, 200, 100
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int NUM_PARALLEL_LINES = 24;
|
|
||||||
private static final float[] gTriPts = new float[] {
|
|
||||||
75, 0, 130, 130, 130, 130, 0, 130, 0, 130, 75, 0
|
|
||||||
};
|
|
||||||
private static final float[] gLinePts = new float[NUM_PARALLEL_LINES * 8 + gTriPts.length];
|
|
||||||
static {
|
|
||||||
int index;
|
|
||||||
for (index = 0; index < gTriPts.length; index++) {
|
|
||||||
gLinePts[index] = gTriPts[index];
|
|
||||||
}
|
|
||||||
float val = 0;
|
|
||||||
for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
|
|
||||||
gLinePts[index + 0] = 150;
|
|
||||||
gLinePts[index + 1] = val;
|
|
||||||
gLinePts[index + 2] = 300;
|
|
||||||
gLinePts[index + 3] = val;
|
|
||||||
index += 4;
|
|
||||||
val += 8 + (2.0f/NUM_PARALLEL_LINES);
|
|
||||||
}
|
|
||||||
val = 0;
|
|
||||||
for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
|
|
||||||
gLinePts[index + 0] = val;
|
|
||||||
gLinePts[index + 1] = 150;
|
|
||||||
gLinePts[index + 2] = val;
|
|
||||||
gLinePts[index + 3] = 300;
|
|
||||||
index += 4;
|
|
||||||
val += 8 + (2.0f/NUM_PARALLEL_LINES);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static final Map<String, Map<String, DisplayModifier>> gMaps = Map.of(
|
|
||||||
"aa", Map.of(
|
|
||||||
"true", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"false", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setAntiAlias(false);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
"style", Map.of(
|
|
||||||
"fill", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"stroke", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
|
|
||||||
},
|
|
||||||
"fillAndStroke", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
|
|
||||||
}),
|
|
||||||
"strokeWidth", Map.of(
|
|
||||||
"hair", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeWidth(0);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
|
|
||||||
},
|
|
||||||
"0.3", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeWidth(0.3f);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"1", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeWidth(1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"5", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeWidth(5);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"30", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeWidth(30);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
"strokeCap", Map.of(
|
|
||||||
"butt", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeCap(Paint.Cap.BUTT);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_CAP_BIT; }
|
|
||||||
},
|
|
||||||
"round", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeCap(Paint.Cap.ROUND);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"square", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeCap(Paint.Cap.SQUARE);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
"strokeJoin", Map.of(
|
|
||||||
"bevel", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeJoin(Paint.Join.BEVEL);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_JOIN_BIT; }
|
|
||||||
},
|
|
||||||
"round", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeJoin(Paint.Join.ROUND);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"miter", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setStrokeJoin(Paint.Join.MITER);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
// TODO: add miter0, miter1 etc to test miter distances
|
|
||||||
"transform", Map.of(
|
|
||||||
"noTransform", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_TRANSFORM_BIT; };
|
|
||||||
},
|
|
||||||
"rotate5", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.rotate(5);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rotate45", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.rotate(45);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rotate90", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.rotate(90);
|
|
||||||
canvas.translate(0, -200);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scale2x2", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.scale(2, 2);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_TRANSFORM_BIT; };
|
|
||||||
},
|
|
||||||
"rot20scl1x4", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.rotate(20);
|
|
||||||
canvas.scale(1, 4);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_TRANSFORM_BIT; };
|
|
||||||
}),
|
|
||||||
"shader", Map.ofEntries(
|
|
||||||
entry("noShader", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_SHADER_BIT; };
|
|
||||||
}),
|
|
||||||
entry("repeatShader", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mRepeatShader);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_SHADER_BIT; };
|
|
||||||
}),
|
|
||||||
entry("translatedShader", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mTranslatedShader);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("scaledShader", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mScaledShader);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("horGradient", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mHorGradient);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("diagGradient", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mDiagGradient);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_SHADER_BIT; };
|
|
||||||
}),
|
|
||||||
entry("vertGradient", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mVertGradient);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("radGradient", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mRadGradient);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("sweepGradient", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mSweepGradient);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("composeShader", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mComposeShader);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("bad composeShader", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mBadComposeShader);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("bad composeShader 2", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setShader(ResourceModifiers.instance().mAnotherBadComposeShader);
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
"drawing", Map.ofEntries(
|
|
||||||
entry("roundRect", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawRoundRect(gRect, 20, 20, paint);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("rect", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawRect(gRect, paint);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_SHADER_BIT | SWEEP_STROKE_CAP_BIT; };
|
|
||||||
}),
|
|
||||||
entry("circle", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawCircle(100, 100, 75, paint);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("oval", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawOval(gRect, paint);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("lines", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawLines(gLinePts, paint);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_CAP_BIT; };
|
|
||||||
}),
|
|
||||||
entry("plusPoints", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawPoints(gPts, paint);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("text", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setTextSize(36);
|
|
||||||
canvas.drawText("TEXTTEST", 0, 50, paint);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("shadowtext", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
paint.setTextSize(36);
|
|
||||||
paint.setShadowLayer(3.0f, 0.0f, 3.0f, 0xffff00ff);
|
|
||||||
canvas.drawText("TEXTTEST", 0, 50, paint);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("bitmapMesh", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawBitmapMesh(ResourceModifiers.instance().mBitmap, 3, 3,
|
|
||||||
ResourceModifiers.instance().mBitmapVertices, 0, null, 0, null);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
entry("arc", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawArc(gRect, 260, 285, false, paint);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_CAP_BIT; };
|
|
||||||
}),
|
|
||||||
entry("arcFromCenter", new DisplayModifier() {
|
|
||||||
@Override
|
|
||||||
public void modifyDrawing(Paint paint, Canvas canvas) {
|
|
||||||
canvas.drawArc(gRect, 260, 285, true, paint);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int mask() { return SWEEP_STROKE_JOIN_BIT; };
|
|
||||||
})));
|
|
||||||
// WARNING: DON'T PUT MORE MAPS BELOW THIS
|
|
||||||
|
|
||||||
private static Map<String, DisplayModifier> getMapAtIndex(int index) {
|
|
||||||
for (Map<String, DisplayModifier> map : gMaps.values()) {
|
|
||||||
if (index == 0) {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// indices instead of iterators for easier bidirectional traversal
|
|
||||||
private static final int mIndices[] = new int[gMaps.size()];
|
|
||||||
private static final String[] mLastAppliedModifications = new String[gMaps.size()];
|
|
||||||
|
|
||||||
private static boolean stepInternal(boolean forward) {
|
|
||||||
int modifierMapIndex = gMaps.size() - 1;
|
|
||||||
while (modifierMapIndex >= 0) {
|
|
||||||
Map<String, DisplayModifier> map = getMapAtIndex(modifierMapIndex);
|
|
||||||
mIndices[modifierMapIndex] += (forward ? 1 : -1);
|
|
||||||
|
|
||||||
if (mIndices[modifierMapIndex] >= 0 && mIndices[modifierMapIndex] < map.size()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIndices[modifierMapIndex] = (forward ? 0 : map.size() - 1);
|
|
||||||
modifierMapIndex--;
|
|
||||||
}
|
|
||||||
return modifierMapIndex < 0; // true if resetting
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean step() {
|
|
||||||
boolean ret = false;
|
|
||||||
do {
|
|
||||||
ret |= stepInternal(true);
|
|
||||||
} while (!checkModificationStateMask());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean stepBack() {
|
|
||||||
boolean ret = false;
|
|
||||||
do {
|
|
||||||
ret |= stepInternal(false);
|
|
||||||
} while (!checkModificationStateMask());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean checkModificationStateMask() {
|
|
||||||
int operatorMask = 0x0;
|
|
||||||
int mapIndex = 0;
|
|
||||||
for (Map<String, DisplayModifier> map : gMaps.values()) {
|
|
||||||
int displayModifierIndex = mIndices[mapIndex];
|
|
||||||
for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
|
|
||||||
if (displayModifierIndex == 0) {
|
|
||||||
mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
|
|
||||||
operatorMask |= modifierEntry.getValue().mask();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
displayModifierIndex--;
|
|
||||||
}
|
|
||||||
mapIndex++;
|
|
||||||
}
|
|
||||||
return operatorMask == TOTAL_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void apply(Paint paint, Canvas canvas) {
|
|
||||||
int mapIndex = 0;
|
|
||||||
for (Map<String, DisplayModifier> map : gMaps.values()) {
|
|
||||||
int displayModifierIndex = mIndices[mapIndex];
|
|
||||||
for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
|
|
||||||
if (displayModifierIndex == 0) {
|
|
||||||
mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
|
|
||||||
modifierEntry.getValue().modifyDrawing(paint, canvas);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
displayModifierIndex--;
|
|
||||||
}
|
|
||||||
mapIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] getLastAppliedModifications() {
|
|
||||||
return mLastAppliedModifications.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[][] getStrings() {
|
|
||||||
String[][] keys = new String[gMaps.size()][];
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (Map<String, DisplayModifier> map : gMaps.values()) {
|
|
||||||
keys[i] = new String[map.size()];
|
|
||||||
int j = 0;
|
|
||||||
for (String key : map.keySet()) {
|
|
||||||
keys[i][j++] = key;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setIndex(int mapIndex, int newIndexValue) {
|
|
||||||
mIndices[mapIndex] = newIndexValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] getIndices() {
|
|
||||||
return mIndices;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.renderscript.Allocation;
|
|
||||||
import android.renderscript.Element;
|
|
||||||
import android.renderscript.RenderScript;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class ErrorCalculator {
|
|
||||||
private static final String LOG_TAG = "ErrorCalculator";
|
|
||||||
private static final int REGION_SIZE = 8;
|
|
||||||
|
|
||||||
private static final boolean LOG_TIMING = false;
|
|
||||||
private static final boolean LOG_CALC = false;
|
|
||||||
|
|
||||||
private RenderScript mRS;
|
|
||||||
private Allocation mIdealPixelsAllocation;
|
|
||||||
private Allocation mGivenPixelsAllocation;
|
|
||||||
private Allocation mOutputPixelsAllocation;
|
|
||||||
|
|
||||||
private Allocation mInputRowsAllocation;
|
|
||||||
private Allocation mOutputRegionsAllocation;
|
|
||||||
|
|
||||||
private ScriptC_errorCalculator mScript;
|
|
||||||
|
|
||||||
private int[] mOutputRowRegions;
|
|
||||||
|
|
||||||
public ErrorCalculator(Context c, Resources resources) {
|
|
||||||
int width = resources.getDimensionPixelSize(R.dimen.layer_width);
|
|
||||||
int height = resources.getDimensionPixelSize(R.dimen.layer_height);
|
|
||||||
mOutputRowRegions = new int[height / REGION_SIZE];
|
|
||||||
|
|
||||||
mRS = RenderScript.create(c);
|
|
||||||
int[] rowIndices = new int[height / REGION_SIZE];
|
|
||||||
for (int i = 0; i < rowIndices.length; i++)
|
|
||||||
rowIndices[i] = i * REGION_SIZE;
|
|
||||||
|
|
||||||
mScript = new ScriptC_errorCalculator(mRS);
|
|
||||||
mScript.set_HEIGHT(height);
|
|
||||||
mScript.set_WIDTH(width);
|
|
||||||
mScript.set_REGION_SIZE(REGION_SIZE);
|
|
||||||
|
|
||||||
mInputRowsAllocation = Allocation.createSized(mRS, Element.I32(mRS), rowIndices.length,
|
|
||||||
Allocation.USAGE_SCRIPT);
|
|
||||||
mInputRowsAllocation.copyFrom(rowIndices);
|
|
||||||
mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
|
|
||||||
mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static long startMillis, middleMillis;
|
|
||||||
|
|
||||||
public float calcErrorRS(Bitmap ideal, Bitmap given) {
|
|
||||||
if (LOG_TIMING) {
|
|
||||||
startMillis = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
|
|
||||||
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
|
||||||
mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
|
|
||||||
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
|
||||||
|
|
||||||
mScript.set_ideal(mIdealPixelsAllocation);
|
|
||||||
mScript.set_given(mGivenPixelsAllocation);
|
|
||||||
|
|
||||||
mScript.forEach_countInterestingRegions(mInputRowsAllocation, mOutputRegionsAllocation);
|
|
||||||
mOutputRegionsAllocation.copyTo(mOutputRowRegions);
|
|
||||||
|
|
||||||
int regionCount = 0;
|
|
||||||
for (int region : mOutputRowRegions) {
|
|
||||||
regionCount += region;
|
|
||||||
}
|
|
||||||
int interestingPixels = Math.max(1, regionCount) * REGION_SIZE * REGION_SIZE;
|
|
||||||
|
|
||||||
if (LOG_TIMING) {
|
|
||||||
long startMillis2 = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
mScript.forEach_accumulateError(mInputRowsAllocation, mOutputRegionsAllocation);
|
|
||||||
mOutputRegionsAllocation.copyTo(mOutputRowRegions);
|
|
||||||
float totalError = 0;
|
|
||||||
for (int row : mOutputRowRegions) {
|
|
||||||
totalError += row;
|
|
||||||
}
|
|
||||||
totalError /= 1024.0f;
|
|
||||||
|
|
||||||
if (LOG_TIMING) {
|
|
||||||
long finalMillis = System.currentTimeMillis();
|
|
||||||
Log.d(LOG_TAG, "rs: first part took " + (middleMillis - startMillis) + "ms");
|
|
||||||
Log.d(LOG_TAG, "rs: last part took " + (finalMillis - middleMillis) + "ms");
|
|
||||||
}
|
|
||||||
if (LOG_CALC) {
|
|
||||||
Log.d(LOG_TAG, "rs: error " + totalError + ", pixels " + interestingPixels);
|
|
||||||
}
|
|
||||||
return totalError / interestingPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void calcErrorHeatmapRS(Bitmap ideal, Bitmap given, Bitmap output) {
|
|
||||||
mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
|
|
||||||
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
|
||||||
mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
|
|
||||||
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
|
||||||
|
|
||||||
mScript.set_ideal(mIdealPixelsAllocation);
|
|
||||||
mScript.set_given(mGivenPixelsAllocation);
|
|
||||||
|
|
||||||
mOutputPixelsAllocation = Allocation.createFromBitmap(mRS, output,
|
|
||||||
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
|
||||||
mScript.forEach_displayDifference(mOutputPixelsAllocation, mOutputPixelsAllocation);
|
|
||||||
mOutputPixelsAllocation.copyTo(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float calcError(Bitmap ideal, Bitmap given) {
|
|
||||||
if (LOG_TIMING) {
|
|
||||||
startMillis = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
int interestingRegions = 0;
|
|
||||||
for (int x = 0; x < ideal.getWidth(); x += REGION_SIZE) {
|
|
||||||
for (int y = 0; y < ideal.getWidth(); y += REGION_SIZE) {
|
|
||||||
if (inspectRegion(ideal, x, y)) {
|
|
||||||
interestingRegions++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int interestingPixels = Math.max(1, interestingRegions) * REGION_SIZE * REGION_SIZE;
|
|
||||||
|
|
||||||
if (LOG_TIMING) {
|
|
||||||
long startMillis2 = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
float totalError = 0;
|
|
||||||
for (int x = 0; x < ideal.getWidth(); x++) {
|
|
||||||
for (int y = 0; y < ideal.getHeight(); y++) {
|
|
||||||
int idealColor = ideal.getPixel(x, y);
|
|
||||||
int givenColor = given.getPixel(x, y);
|
|
||||||
if (idealColor == givenColor)
|
|
||||||
continue;
|
|
||||||
totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
|
|
||||||
totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
|
|
||||||
totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
|
|
||||||
totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
totalError /= 1024.0f;
|
|
||||||
if (LOG_TIMING) {
|
|
||||||
long finalMillis = System.currentTimeMillis();
|
|
||||||
Log.d(LOG_TAG, "dvk: first part took " + (middleMillis - startMillis) + "ms");
|
|
||||||
Log.d(LOG_TAG, "dvk: last part took " + (finalMillis - middleMillis) + "ms");
|
|
||||||
}
|
|
||||||
if (LOG_CALC) {
|
|
||||||
Log.d(LOG_TAG, "dvk: error " + totalError + ", pixels " + interestingPixels);
|
|
||||||
}
|
|
||||||
return totalError / interestingPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean inspectRegion(Bitmap ideal, int x, int y) {
|
|
||||||
int regionColor = ideal.getPixel(x, y);
|
|
||||||
for (int i = 0; i < REGION_SIZE; i++) {
|
|
||||||
for (int j = 0; j < REGION_SIZE; j++) {
|
|
||||||
if (ideal.getPixel(x + i, y + j) != regionColor)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
public class MainView extends View {
|
|
||||||
Paint mPaint = new Paint();
|
|
||||||
|
|
||||||
public MainView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MainView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MainView(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
mPaint.reset();
|
|
||||||
DisplayModifier.apply(mPaint, canvas);
|
|
||||||
|
|
||||||
if (mDrawCallback != null) {
|
|
||||||
mDrawCallback.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable mDrawCallback;
|
|
||||||
public void addDrawCallback(Runnable drawCallback) {
|
|
||||||
mDrawCallback = drawCallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import com.android.test.hwuicompare.R;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
public class ManualActivity extends CompareActivity {
|
|
||||||
private static final String LOG_TAG = "ManualActivity";
|
|
||||||
private ImageView mCompareImageView;
|
|
||||||
private Bitmap mCompareBitmap;
|
|
||||||
private TextView mErrorTextView;
|
|
||||||
private MainView mSoftwareView;
|
|
||||||
|
|
||||||
private static final int COMPARE_VIEW_UNINITIALIZED = -1;
|
|
||||||
private static final int COMPARE_VIEW_HARDWARE = 0;
|
|
||||||
private static final int COMPARE_VIEW_SOFTWARE = 1;
|
|
||||||
private static final int COMPARE_VIEW_HEATMAP = 2; // TODO: add more like this? any ideas?
|
|
||||||
|
|
||||||
private int mCompareImageViewState = COMPARE_VIEW_UNINITIALIZED;
|
|
||||||
private int mLastCompareImageViewState = COMPARE_VIEW_UNINITIALIZED;
|
|
||||||
|
|
||||||
Runnable mRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Log.d(LOG_TAG, "mRunnable running, mRedrewFlag = " + mRedrewFlag);
|
|
||||||
|
|
||||||
if (mRedrewFlag) {
|
|
||||||
loadBitmaps();
|
|
||||||
// recalculate error
|
|
||||||
float error = mErrorCalculator.calcErrorRS(mSoftwareBitmap, mHardwareBitmap);
|
|
||||||
String modname = "";
|
|
||||||
for (String s : DisplayModifier.getLastAppliedModifications()) {
|
|
||||||
modname = modname.concat(s + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(LOG_TAG, "error for " + modname + " is " + error);
|
|
||||||
mErrorTextView.setText(String.format("%.4f", error));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCompareImageViewState != mLastCompareImageViewState || mRedrewFlag) {
|
|
||||||
switch (mCompareImageViewState) {
|
|
||||||
case COMPARE_VIEW_UNINITIALIZED:
|
|
||||||
// set to hardware
|
|
||||||
case COMPARE_VIEW_HARDWARE:
|
|
||||||
mCompareImageView.setImageBitmap(mHardwareBitmap);
|
|
||||||
break;
|
|
||||||
case COMPARE_VIEW_SOFTWARE:
|
|
||||||
mCompareImageView.setImageBitmap(mSoftwareBitmap);
|
|
||||||
break;
|
|
||||||
case COMPARE_VIEW_HEATMAP:
|
|
||||||
mErrorCalculator.calcErrorHeatmapRS(mSoftwareBitmap, mHardwareBitmap,
|
|
||||||
mCompareBitmap);
|
|
||||||
mCompareImageView.setImageBitmap(mCompareBitmap);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mCompareImageView.getDrawable().setFilterBitmap(false);
|
|
||||||
mCompareImageView.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
mLastCompareImageViewState = mCompareImageViewState;
|
|
||||||
mRedrewFlag = false;
|
|
||||||
mHandler.removeCallbacks(mRunnable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void redrawViews() {
|
|
||||||
mHardwareView.invalidate();
|
|
||||||
mSoftwareView.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.manual_layout);
|
|
||||||
onCreateCommon(mRunnable);
|
|
||||||
|
|
||||||
mSoftwareView = (MainView) findViewById(R.id.software_view);
|
|
||||||
mSoftwareView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
|
||||||
mSoftwareView.setBackgroundColor(Color.WHITE);
|
|
||||||
mSoftwareView.addDrawCallback(mDrawCallback);
|
|
||||||
|
|
||||||
mCompareImageView = (ImageView) findViewById(R.id.compare_image_view);
|
|
||||||
|
|
||||||
int width = getResources().getDimensionPixelSize(R.dimen.layer_width);
|
|
||||||
int height = getResources().getDimensionPixelSize(R.dimen.layer_height);
|
|
||||||
mCompareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
|
|
||||||
mErrorTextView = (TextView) findViewById(R.id.current_error);
|
|
||||||
((ImageButton) findViewById(R.id.next)).setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
DisplayModifier.step();
|
|
||||||
updateSpinners();
|
|
||||||
redrawViews();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
((ImageButton) findViewById(R.id.previous)).setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
DisplayModifier.stepBack();
|
|
||||||
updateSpinners();
|
|
||||||
redrawViews();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
((Button) findViewById(R.id.show_hardware_version))
|
|
||||||
.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
mCompareImageViewState = COMPARE_VIEW_HARDWARE;
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
((Button) findViewById(R.id.show_software_version))
|
|
||||||
.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
mCompareImageViewState = COMPARE_VIEW_SOFTWARE;
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
((Button) findViewById(R.id.show_error_heatmap)).setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
mCompareImageViewState = COMPARE_VIEW_HEATMAP;
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
buildSpinnerLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DisplayModifierSpinner extends Spinner {
|
|
||||||
private final int mIndex;
|
|
||||||
|
|
||||||
public DisplayModifierSpinner(int index) {
|
|
||||||
super(ManualActivity.this);
|
|
||||||
mIndex = index;
|
|
||||||
setOnItemSelectedListener(new OnItemSelectedListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(AdapterView<?> parentView, View selectedItem,
|
|
||||||
int position, long id) {
|
|
||||||
DisplayModifier.setIndex(mIndex, position);
|
|
||||||
redrawViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(AdapterView<?> parentView) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Spinner[] mSpinners;
|
|
||||||
|
|
||||||
private void buildSpinnerLayout() {
|
|
||||||
LinearLayout layout = (LinearLayout) findViewById(R.id.spinner_layout);
|
|
||||||
String[][] mapsStrings = DisplayModifier.getStrings();
|
|
||||||
mSpinners = new Spinner[mapsStrings.length];
|
|
||||||
int index = 0;
|
|
||||||
for (String[] spinnerValues : mapsStrings) {
|
|
||||||
mSpinners[index] = new DisplayModifierSpinner(index);
|
|
||||||
mSpinners[index].setAdapter(new ArrayAdapter<String>(this,
|
|
||||||
android.R.layout.simple_spinner_dropdown_item, spinnerValues));
|
|
||||||
layout.addView(mSpinners[index]);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
Log.d(LOG_TAG, "created " + index + " spinners");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSpinners() {
|
|
||||||
int[] indices = DisplayModifier.getIndices();
|
|
||||||
for (int i = 0; i < mSpinners.length; i++) {
|
|
||||||
mSpinners[i].setSelection(indices[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean forceRecreateBitmaps() {
|
|
||||||
// continually recreate bitmaps to avoid modifying bitmaps currently being drawn
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import com.android.test.hwuicompare.R;
|
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.BitmapShader;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.ComposeShader;
|
|
||||||
import android.graphics.LinearGradient;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.graphics.RadialGradient;
|
|
||||||
import android.graphics.SweepGradient;
|
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.graphics.Shader;
|
|
||||||
|
|
||||||
public class ResourceModifiers {
|
|
||||||
public final BitmapShader mRepeatShader;
|
|
||||||
public final BitmapShader mTranslatedShader;
|
|
||||||
public final BitmapShader mScaledShader;
|
|
||||||
private final int mTexWidth;
|
|
||||||
private final int mTexHeight;
|
|
||||||
private final float mDrawWidth;
|
|
||||||
private final float mDrawHeight;
|
|
||||||
public final LinearGradient mHorGradient;
|
|
||||||
public final LinearGradient mDiagGradient;
|
|
||||||
public final LinearGradient mVertGradient;
|
|
||||||
public final RadialGradient mRadGradient;
|
|
||||||
public final SweepGradient mSweepGradient;
|
|
||||||
public final ComposeShader mComposeShader;
|
|
||||||
public final ComposeShader mBadComposeShader;
|
|
||||||
public final ComposeShader mAnotherBadComposeShader;
|
|
||||||
public final Bitmap mBitmap;
|
|
||||||
private final Matrix mMtx1;
|
|
||||||
private final Matrix mMtx2;
|
|
||||||
private final Matrix mMtx3;
|
|
||||||
|
|
||||||
public final float[] mBitmapVertices;
|
|
||||||
public final int[] mBitmapColors;
|
|
||||||
|
|
||||||
private static ResourceModifiers sInstance = null;
|
|
||||||
public static ResourceModifiers instance() { return sInstance; }
|
|
||||||
public static void init(Resources resources) {
|
|
||||||
sInstance = new ResourceModifiers(resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceModifiers(Resources resources) {
|
|
||||||
mBitmap = BitmapFactory.decodeResource(resources, R.drawable.sunset1);
|
|
||||||
mTexWidth = mBitmap.getWidth();
|
|
||||||
mTexHeight = mBitmap.getHeight();
|
|
||||||
|
|
||||||
mDrawWidth = resources.getDimensionPixelSize(R.dimen.layer_width);
|
|
||||||
mDrawHeight = resources.getDimensionPixelSize(R.dimen.layer_height);
|
|
||||||
|
|
||||||
mRepeatShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
|
|
||||||
Shader.TileMode.REPEAT);
|
|
||||||
|
|
||||||
mTranslatedShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
|
|
||||||
Shader.TileMode.REPEAT);
|
|
||||||
mMtx1 = new Matrix();
|
|
||||||
mMtx1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
|
|
||||||
mMtx1.postRotate(45, 0, 0);
|
|
||||||
mTranslatedShader.setLocalMatrix(mMtx1);
|
|
||||||
|
|
||||||
mScaledShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR,
|
|
||||||
Shader.TileMode.MIRROR);
|
|
||||||
mMtx2 = new Matrix();
|
|
||||||
mMtx2.setScale(0.5f, 0.5f);
|
|
||||||
mScaledShader.setLocalMatrix(mMtx2);
|
|
||||||
|
|
||||||
mHorGradient = new LinearGradient(0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
Color.RED, Color.GREEN, Shader.TileMode.CLAMP);
|
|
||||||
mMtx3 = new Matrix();
|
|
||||||
mMtx3.setScale(mDrawHeight, 1.0f);
|
|
||||||
mMtx3.postRotate(-90.0f);
|
|
||||||
mMtx3.postTranslate(0.0f, mDrawHeight);
|
|
||||||
mHorGradient.setLocalMatrix(mMtx3);
|
|
||||||
|
|
||||||
mDiagGradient = new LinearGradient(0.0f, 0.0f, mDrawWidth / 2.0f, mDrawHeight / 2.0f,
|
|
||||||
Color.BLUE, Color.RED, Shader.TileMode.CLAMP);
|
|
||||||
|
|
||||||
mVertGradient = new LinearGradient(0.0f, 0.0f, 0.0f, mDrawHeight / 2.0f,
|
|
||||||
Color.YELLOW, Color.MAGENTA, Shader.TileMode.MIRROR);
|
|
||||||
|
|
||||||
mSweepGradient = new SweepGradient(mDrawWidth / 2.0f, mDrawHeight / 2.0f,
|
|
||||||
Color.YELLOW, Color.MAGENTA);
|
|
||||||
|
|
||||||
mComposeShader = new ComposeShader(mRepeatShader, mHorGradient,
|
|
||||||
PorterDuff.Mode.MULTIPLY);
|
|
||||||
|
|
||||||
final float width = mBitmap.getWidth() / 8.0f;
|
|
||||||
final float height = mBitmap.getHeight() / 8.0f;
|
|
||||||
|
|
||||||
mBitmapVertices = new float[] {
|
|
||||||
0.0f, 0.0f, width, 0.0f, width * 2, 0.0f, width * 3, 0.0f,
|
|
||||||
0.0f, height, width, height, width * 2, height, width * 4, height,
|
|
||||||
0.0f, height * 2, width, height * 2, width * 2, height * 2, width * 3, height * 2,
|
|
||||||
0.0f, height * 4, width, height * 4, width * 2, height * 4, width * 4, height * 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
mBitmapColors = new int[] {
|
|
||||||
0xffff0000, 0xff00ff00, 0xff0000ff, 0xffff0000,
|
|
||||||
0xff0000ff, 0xffff0000, 0xff00ff00, 0xff00ff00,
|
|
||||||
0xff00ff00, 0xff0000ff, 0xffff0000, 0xff00ff00,
|
|
||||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ff0000,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use a repeating gradient with many colors to test the non simple case.
|
|
||||||
mRadGradient = new RadialGradient(mDrawWidth / 4.0f, mDrawHeight / 4.0f, 4.0f,
|
|
||||||
mBitmapColors, null, Shader.TileMode.REPEAT);
|
|
||||||
|
|
||||||
mBadComposeShader = new ComposeShader(mRadGradient, mComposeShader,
|
|
||||||
PorterDuff.Mode.MULTIPLY);
|
|
||||||
|
|
||||||
mAnotherBadComposeShader = new ComposeShader(mRadGradient, mVertGradient,
|
|
||||||
PorterDuff.Mode.MULTIPLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package com.android.test.hwuicompare;
|
|
||||||
|
|
||||||
import com.android.test.hwuicompare.AutomaticActivity.FinalCallback;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
|
||||||
|
|
||||||
public class Test extends ActivityInstrumentationTestCase2<AutomaticActivity> {
|
|
||||||
AutomaticActivity mActivity;
|
|
||||||
private Bundle mBundle;
|
|
||||||
|
|
||||||
public Test() {
|
|
||||||
super(AutomaticActivity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
mBundle = new Bundle();
|
|
||||||
mActivity = getActivity();
|
|
||||||
mActivity.setFinalCallback(new FinalCallback() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void report(String key, float value) {
|
|
||||||
mBundle.putFloat(key, value);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
void complete() {
|
|
||||||
synchronized(mBundle) {
|
|
||||||
mBundle.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCanvas() {
|
|
||||||
synchronized(mBundle) {
|
|
||||||
try {
|
|
||||||
mBundle.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getInstrumentation().sendStatus(0, mBundle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#pragma version(1)
|
|
||||||
#pragma rs java_package_name(com.android.test.hwuicompare)
|
|
||||||
|
|
||||||
int REGION_SIZE;
|
|
||||||
int WIDTH;
|
|
||||||
int HEIGHT;
|
|
||||||
|
|
||||||
rs_allocation ideal;
|
|
||||||
rs_allocation given;
|
|
||||||
|
|
||||||
void countInterestingRegions(const int32_t *v_in, int32_t *v_out) {
|
|
||||||
int y = v_in[0];
|
|
||||||
v_out[0] = 0;
|
|
||||||
|
|
||||||
for (int x = 0; x < HEIGHT; x += REGION_SIZE) {
|
|
||||||
bool interestingRegion = false;
|
|
||||||
uchar4 regionColor = rsGetElementAt_uchar4(ideal, x, y);
|
|
||||||
for (int i = 0; i < REGION_SIZE && !interestingRegion; i++) {
|
|
||||||
for (int j = 0; j < REGION_SIZE && !interestingRegion; j++) {
|
|
||||||
uchar4 testVal = rsGetElementAt_uchar4(ideal, x + j, y + i);
|
|
||||||
interestingRegion |= (testVal.r != regionColor.r);
|
|
||||||
interestingRegion |= (testVal.g != regionColor.g);
|
|
||||||
interestingRegion |= (testVal.b != regionColor.b);
|
|
||||||
interestingRegion |= (testVal.a != regionColor.a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (interestingRegion) {
|
|
||||||
v_out[0]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void accumulateError(const int32_t *v_in, int32_t *v_out) {
|
|
||||||
int startY = v_in[0];
|
|
||||||
int error = 0;
|
|
||||||
for (int y = startY; y < startY + REGION_SIZE; y++) {
|
|
||||||
for (int x = 0; x < HEIGHT; x++) {
|
|
||||||
uchar4 idealPixel = rsGetElementAt_uchar4(ideal, x, y);
|
|
||||||
uchar4 givenPixel = rsGetElementAt_uchar4(given, x, y);
|
|
||||||
|
|
||||||
error += abs(idealPixel.x - givenPixel.x);
|
|
||||||
error += abs(idealPixel.y - givenPixel.y);
|
|
||||||
error += abs(idealPixel.z - givenPixel.z);
|
|
||||||
error += abs(idealPixel.w - givenPixel.w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v_out[0] = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void displayDifference(const uchar4 *v_in, uchar4 *v_out, uint32_t x, uint32_t y) {
|
|
||||||
float4 idealPixel = rsGetElementAt_float4(ideal, x, y);
|
|
||||||
float4 givenPixel = rsGetElementAt_float4(given, x, y);
|
|
||||||
|
|
||||||
float4 diff = idealPixel - givenPixel;
|
|
||||||
float totalDiff = diff.x + diff.y + diff.z + diff.w;
|
|
||||||
if (totalDiff < 0) {
|
|
||||||
v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2.f, 0.f, 1.f));
|
|
||||||
} else {
|
|
||||||
v_out[0] = rsPackColorTo8888(clamp(totalDiff/2.f, 0.f, 1.f), 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user