Merge "Update imageprocessing to remove generated files. Fix thread launch race condition."
This commit is contained in:
@@ -21,7 +21,8 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
|
||||
$(call all-renderscript-files-under, src)
|
||||
#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
|
||||
|
||||
LOCAL_PACKAGE_NAME := ImageProcessing
|
||||
|
||||
Binary file not shown.
@@ -1,176 +0,0 @@
|
||||
#pragma version(1)
|
||||
|
||||
#include "../../../../scriptc/rs_types.rsh"
|
||||
#include "../../../../scriptc/rs_math.rsh"
|
||||
|
||||
#include "ip.rsh"
|
||||
|
||||
int height;
|
||||
int width;
|
||||
int radius;
|
||||
|
||||
uchar4 * InPixel;
|
||||
uchar4 * OutPixel;
|
||||
uchar4 * ScratchPixel;
|
||||
|
||||
float inBlack;
|
||||
float outBlack;
|
||||
float inWhite;
|
||||
float outWhite;
|
||||
float gamma;
|
||||
|
||||
float saturation;
|
||||
|
||||
static float inWMinInB;
|
||||
static float outWMinOutB;
|
||||
static float overInWMinInB;
|
||||
|
||||
#pragma rs export_var(height, width, radius, InPixel, OutPixel, ScratchPixel, inBlack, outBlack, inWhite, outWhite, gamma, saturation, InPixel, OutPixel, ScratchPixel, vBlurScript, hBlurScript)
|
||||
#pragma rs export_func(filter, filterBenchmark);
|
||||
|
||||
rs_script vBlurScript;
|
||||
rs_script hBlurScript;
|
||||
|
||||
|
||||
// Store our coefficients here
|
||||
static float gaussian[MAX_RADIUS * 2 + 1];
|
||||
static rs_matrix3x3 colorMat;
|
||||
|
||||
static void computeColorMatrix() {
|
||||
// Saturation
|
||||
// Linear weights
|
||||
//float rWeight = 0.3086f;
|
||||
//float gWeight = 0.6094f;
|
||||
//float bWeight = 0.0820f;
|
||||
|
||||
// Gamma 2.2 weights (we haven't converted our image to linear space yet for perf reasons)
|
||||
float rWeight = 0.299f;
|
||||
float gWeight = 0.587f;
|
||||
float bWeight = 0.114f;
|
||||
|
||||
float oneMinusS = 1.0f - saturation;
|
||||
|
||||
rsMatrixSet(&colorMat, 0, 0, oneMinusS * rWeight + saturation);
|
||||
rsMatrixSet(&colorMat, 0, 1, oneMinusS * rWeight);
|
||||
rsMatrixSet(&colorMat, 0, 2, oneMinusS * rWeight);
|
||||
rsMatrixSet(&colorMat, 1, 0, oneMinusS * gWeight);
|
||||
rsMatrixSet(&colorMat, 1, 1, oneMinusS * gWeight + saturation);
|
||||
rsMatrixSet(&colorMat, 1, 2, oneMinusS * gWeight);
|
||||
rsMatrixSet(&colorMat, 2, 0, oneMinusS * bWeight);
|
||||
rsMatrixSet(&colorMat, 2, 1, oneMinusS * bWeight);
|
||||
rsMatrixSet(&colorMat, 2, 2, oneMinusS * bWeight + saturation);
|
||||
|
||||
inWMinInB = inWhite - inBlack;
|
||||
outWMinOutB = outWhite - outBlack;
|
||||
overInWMinInB = 1.f / inWMinInB;
|
||||
}
|
||||
|
||||
static void computeGaussianWeights() {
|
||||
// Compute gaussian weights for the blur
|
||||
// e is the euler's number
|
||||
float e = 2.718281828459045f;
|
||||
float pi = 3.1415926535897932f;
|
||||
// g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
|
||||
// x is of the form [-radius .. 0 .. radius]
|
||||
// and sigma varies with radius.
|
||||
// Based on some experimental radius values and sigma's
|
||||
// we approximately fit sigma = f(radius) as
|
||||
// sigma = radius * 0.4 + 0.6
|
||||
// The larger the radius gets, the more our gaussian blur
|
||||
// will resemble a box blur since with large sigma
|
||||
// the gaussian curve begins to lose its shape
|
||||
float sigma = 0.4f * (float)radius + 0.6f;
|
||||
|
||||
// Now compute the coefficints
|
||||
// We will store some redundant values to save some math during
|
||||
// the blur calculations
|
||||
// precompute some values
|
||||
float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
|
||||
float coeff2 = - 1.0f / (2.0f * sigma * sigma);
|
||||
|
||||
float normalizeFactor = 0.0f;
|
||||
float floatR = 0.0f;
|
||||
int r;
|
||||
for(r = -radius; r <= radius; r ++) {
|
||||
floatR = (float)r;
|
||||
gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
|
||||
normalizeFactor += gaussian[r + radius];
|
||||
}
|
||||
|
||||
//Now we need to normalize the weights because all our coefficients need to add up to one
|
||||
normalizeFactor = 1.0f / normalizeFactor;
|
||||
for(r = -radius; r <= radius; r ++) {
|
||||
floatR = (float)r;
|
||||
gaussian[r + radius] *= normalizeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
static void processNoBlur() {
|
||||
float inWMinInB = inWhite - inBlack;
|
||||
float outWMinOutB = outWhite - outBlack;
|
||||
float4 currentPixel = 0;
|
||||
|
||||
for(int h = 0; h < height; h ++) {
|
||||
uchar4 *input = InPixel + h*width;
|
||||
uchar4 *output = OutPixel + h*width;
|
||||
|
||||
for(int w = 0; w < width; w ++) {
|
||||
//currentPixel.xyz = convert_float3(input.xyz);
|
||||
currentPixel.x = (float)(input->x);
|
||||
currentPixel.y = (float)(input->y);
|
||||
currentPixel.z = (float)(input->z);
|
||||
|
||||
float3 temp = rsMatrixMultiply(&colorMat, currentPixel.xyz);
|
||||
temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB;
|
||||
temp = pow(temp, (float3)gamma);
|
||||
currentPixel.xyz = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f);
|
||||
|
||||
//output.xyz = convert_uchar3(currentPixel.xyz);
|
||||
output->x = (uint8_t)currentPixel.x;
|
||||
output->y = (uint8_t)currentPixel.y;
|
||||
output->z = (uint8_t)currentPixel.z;
|
||||
output->w = input->w;
|
||||
|
||||
input++;
|
||||
output++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void blur() {
|
||||
computeGaussianWeights();
|
||||
|
||||
FilterStruct fs;
|
||||
fs.gaussian = gaussian;
|
||||
fs.width = width;
|
||||
fs.height = height;
|
||||
fs.radius = radius;
|
||||
|
||||
fs.ain = rsGetAllocation(InPixel);
|
||||
rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel), &fs);
|
||||
|
||||
fs.ain = rsGetAllocation(ScratchPixel);
|
||||
rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs);
|
||||
}
|
||||
|
||||
void filter() {
|
||||
RS_DEBUG(radius);
|
||||
|
||||
computeColorMatrix();
|
||||
|
||||
if(radius > 0) {
|
||||
blur();
|
||||
}
|
||||
processNoBlur();
|
||||
|
||||
int count = 0;
|
||||
rsSendToClient(&count, 1, 4, 0);
|
||||
}
|
||||
|
||||
void filterBenchmark() {
|
||||
blur();
|
||||
|
||||
int count = 0;
|
||||
rsSendToClient(&count, 1, 4, 0);
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -44,6 +44,7 @@ public class ImageProcessingActivity extends Activity
|
||||
private ScriptC_Threshold mScript;
|
||||
private ScriptC_Vertical_blur mScriptVBlur;
|
||||
private ScriptC_Horizontal_blur mScriptHBlur;
|
||||
private ScriptC_Levels mScriptLevels;
|
||||
private int mRadius = 0;
|
||||
private SeekBar mRadiusSeekBar;
|
||||
|
||||
@@ -260,29 +261,29 @@ public class ImageProcessingActivity extends Activity
|
||||
}
|
||||
else if(seekBar == mInBlackSeekBar) {
|
||||
mInBlack = (float)progress;
|
||||
mScript.set_inBlack(mInBlack);
|
||||
mScriptLevels.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
|
||||
}
|
||||
else if(seekBar == mOutBlackSeekBar) {
|
||||
mOutBlack = (float)progress;
|
||||
mScript.set_outBlack(mOutBlack);
|
||||
mScriptLevels.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
|
||||
}
|
||||
else if(seekBar == mInWhiteSeekBar) {
|
||||
mInWhite = (float)progress + 127.0f;
|
||||
mScript.set_inWhite(mInWhite);
|
||||
mScriptLevels.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
|
||||
}
|
||||
else if(seekBar == mOutWhiteSeekBar) {
|
||||
mOutWhite = (float)progress + 127.0f;
|
||||
mScript.set_outWhite(mOutWhite);
|
||||
mScriptLevels.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
|
||||
}
|
||||
else if(seekBar == mGammaSeekBar) {
|
||||
mGamma = (float)progress/100.0f;
|
||||
mGamma = Math.max(mGamma, 0.1f);
|
||||
mGamma = 1.0f / mGamma;
|
||||
mScript.set_gamma(mGamma);
|
||||
mScriptLevels.invoke_setGamma(mGamma);
|
||||
}
|
||||
else if(seekBar == mSaturationSeekBar) {
|
||||
mSaturation = (float)progress / 50.0f;
|
||||
mScript.set_saturation(mSaturation);
|
||||
mScriptLevels.invoke_setSaturation(mSaturation);
|
||||
}
|
||||
|
||||
long t = java.lang.System.currentTimeMillis();
|
||||
@@ -375,20 +376,18 @@ public class ImageProcessingActivity extends Activity
|
||||
mOutPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapOut);
|
||||
mScratchPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapScratch);
|
||||
|
||||
mScriptVBlur = new ScriptC_Vertical_blur(mRS, getResources(), R.raw.vertical_blur_bc, false);
|
||||
mScriptHBlur = new ScriptC_Horizontal_blur(mRS, getResources(), R.raw.horizontal_blur_bc, false);
|
||||
mScriptVBlur = new ScriptC_Vertical_blur(mRS, getResources(), R.raw.vertical_blur, false);
|
||||
mScriptHBlur = new ScriptC_Horizontal_blur(mRS, getResources(), R.raw.horizontal_blur, false);
|
||||
mScriptLevels = new ScriptC_Levels(mRS, getResources(), R.raw.levels, false);
|
||||
|
||||
mScript = new ScriptC_Threshold(mRS, getResources(), R.raw.threshold_bc, false);
|
||||
mScript = new ScriptC_Threshold(mRS, getResources(), R.raw.threshold, false);
|
||||
mScript.set_width(mBitmapIn.getWidth());
|
||||
mScript.set_height(mBitmapIn.getHeight());
|
||||
mScript.set_radius(mRadius);
|
||||
|
||||
mScript.set_inBlack(mInBlack);
|
||||
mScript.set_outBlack(mOutBlack);
|
||||
mScript.set_inWhite(mInWhite);
|
||||
mScript.set_outWhite(mOutWhite);
|
||||
mScript.set_gamma(mGamma);
|
||||
mScript.set_saturation(mSaturation);
|
||||
mScriptLevels.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
|
||||
mScriptLevels.invoke_setGamma(mGamma);
|
||||
mScriptLevels.invoke_setSaturation(mSaturation);
|
||||
|
||||
mScript.bind_InPixel(mInPixelsAllocation);
|
||||
mScript.bind_OutPixel(mOutPixelsAllocation);
|
||||
@@ -396,6 +395,7 @@ public class ImageProcessingActivity extends Activity
|
||||
|
||||
mScript.set_vBlurScript(mScriptVBlur);
|
||||
mScript.set_hBlurScript(mScriptHBlur);
|
||||
mScript.set_levelsScript(mScriptLevels);
|
||||
}
|
||||
|
||||
private Bitmap loadBitmap(int resource) {
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.rs.image;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
|
||||
public class ScriptC_Horizontal_blur extends ScriptC {
|
||||
// Constructor
|
||||
public ScriptC_Horizontal_blur(RenderScript rs, Resources resources, int id, boolean isRoot) {
|
||||
super(rs, resources, id, isRoot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.rs.image;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
|
||||
public class ScriptC_Threshold extends ScriptC {
|
||||
// Constructor
|
||||
public ScriptC_Threshold(RenderScript rs, Resources resources, int id, boolean isRoot) {
|
||||
super(rs, resources, id, isRoot);
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_height = 0;
|
||||
private int mExportVar_height;
|
||||
public void set_height(int v) {
|
||||
mExportVar_height = v;
|
||||
setVar(mExportVarIdx_height, v);
|
||||
}
|
||||
|
||||
public int get_height() {
|
||||
return mExportVar_height;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_width = 1;
|
||||
private int mExportVar_width;
|
||||
public void set_width(int v) {
|
||||
mExportVar_width = v;
|
||||
setVar(mExportVarIdx_width, v);
|
||||
}
|
||||
|
||||
public int get_width() {
|
||||
return mExportVar_width;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_radius = 2;
|
||||
private int mExportVar_radius;
|
||||
public void set_radius(int v) {
|
||||
mExportVar_radius = v;
|
||||
setVar(mExportVarIdx_radius, v);
|
||||
}
|
||||
|
||||
public int get_radius() {
|
||||
return mExportVar_radius;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_InPixel = 3;
|
||||
private Allocation mExportVar_InPixel;
|
||||
public void bind_InPixel(Allocation v) {
|
||||
mExportVar_InPixel = v;
|
||||
if(v == null) bindAllocation(null, mExportVarIdx_InPixel);
|
||||
else bindAllocation(v, mExportVarIdx_InPixel);
|
||||
}
|
||||
|
||||
public Allocation get_InPixel() {
|
||||
return mExportVar_InPixel;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_OutPixel = 4;
|
||||
private Allocation mExportVar_OutPixel;
|
||||
public void bind_OutPixel(Allocation v) {
|
||||
mExportVar_OutPixel = v;
|
||||
if(v == null) bindAllocation(null, mExportVarIdx_OutPixel);
|
||||
else bindAllocation(v, mExportVarIdx_OutPixel);
|
||||
}
|
||||
|
||||
public Allocation get_OutPixel() {
|
||||
return mExportVar_OutPixel;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_ScratchPixel = 5;
|
||||
private Allocation mExportVar_ScratchPixel;
|
||||
public void bind_ScratchPixel(Allocation v) {
|
||||
mExportVar_ScratchPixel = v;
|
||||
if(v == null) bindAllocation(null, mExportVarIdx_ScratchPixel);
|
||||
else bindAllocation(v, mExportVarIdx_ScratchPixel);
|
||||
}
|
||||
|
||||
public Allocation get_ScratchPixel() {
|
||||
return mExportVar_ScratchPixel;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_inBlack = 6;
|
||||
private float mExportVar_inBlack;
|
||||
public void set_inBlack(float v) {
|
||||
mExportVar_inBlack = v;
|
||||
setVar(mExportVarIdx_inBlack, v);
|
||||
}
|
||||
|
||||
public float get_inBlack() {
|
||||
return mExportVar_inBlack;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_outBlack = 7;
|
||||
private float mExportVar_outBlack;
|
||||
public void set_outBlack(float v) {
|
||||
mExportVar_outBlack = v;
|
||||
setVar(mExportVarIdx_outBlack, v);
|
||||
}
|
||||
|
||||
public float get_outBlack() {
|
||||
return mExportVar_outBlack;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_inWhite = 8;
|
||||
private float mExportVar_inWhite;
|
||||
public void set_inWhite(float v) {
|
||||
mExportVar_inWhite = v;
|
||||
setVar(mExportVarIdx_inWhite, v);
|
||||
}
|
||||
|
||||
public float get_inWhite() {
|
||||
return mExportVar_inWhite;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_outWhite = 9;
|
||||
private float mExportVar_outWhite;
|
||||
public void set_outWhite(float v) {
|
||||
mExportVar_outWhite = v;
|
||||
setVar(mExportVarIdx_outWhite, v);
|
||||
}
|
||||
|
||||
public float get_outWhite() {
|
||||
return mExportVar_outWhite;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_gamma = 10;
|
||||
private float mExportVar_gamma;
|
||||
public void set_gamma(float v) {
|
||||
mExportVar_gamma = v;
|
||||
setVar(mExportVarIdx_gamma, v);
|
||||
}
|
||||
|
||||
public float get_gamma() {
|
||||
return mExportVar_gamma;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_saturation = 11;
|
||||
private float mExportVar_saturation;
|
||||
public void set_saturation(float v) {
|
||||
mExportVar_saturation = v;
|
||||
setVar(mExportVarIdx_saturation, v);
|
||||
}
|
||||
|
||||
public float get_saturation() {
|
||||
return mExportVar_saturation;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_vBlurScript = 12;
|
||||
private Script mExportVar_vBlurScript;
|
||||
public void set_vBlurScript(Script v) {
|
||||
mExportVar_vBlurScript = v;
|
||||
setVar(mExportVarIdx_vBlurScript, (v == null) ? 0 : v.getID());
|
||||
}
|
||||
|
||||
public Script get_vBlurScript() {
|
||||
return mExportVar_vBlurScript;
|
||||
}
|
||||
|
||||
private final static int mExportVarIdx_hBlurScript = 13;
|
||||
private Script mExportVar_hBlurScript;
|
||||
public void set_hBlurScript(Script v) {
|
||||
mExportVar_hBlurScript = v;
|
||||
setVar(mExportVarIdx_hBlurScript, (v == null) ? 0 : v.getID());
|
||||
}
|
||||
|
||||
public Script get_hBlurScript() {
|
||||
return mExportVar_hBlurScript;
|
||||
}
|
||||
|
||||
private final static int mExportFuncIdx_filter = 0;
|
||||
public void invoke_filter() {
|
||||
invoke(mExportFuncIdx_filter);
|
||||
}
|
||||
|
||||
private final static int mExportFuncIdx_filterBenchmark = 1;
|
||||
public void invoke_filterBenchmark() {
|
||||
invoke(mExportFuncIdx_filterBenchmark);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.rs.image;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
|
||||
public class ScriptC_Vertical_blur extends ScriptC {
|
||||
// Constructor
|
||||
public ScriptC_Vertical_blur(RenderScript rs, Resources resources, int id, boolean isRoot) {
|
||||
super(rs, resources, id, isRoot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma version(1)
|
||||
|
||||
#include "../../../../scriptc/rs_types.rsh"
|
||||
#include "../../../../scriptc/rs_math.rsh"
|
||||
#include <rs_types.rsh>
|
||||
#include <rs_math.rsh>
|
||||
|
||||
#include "ip.rsh"
|
||||
|
||||
@@ -6,8 +6,6 @@ typedef struct {
|
||||
rs_allocation ain;
|
||||
|
||||
float *gaussian; //[MAX_RADIUS * 2 + 1];
|
||||
rs_matrix3x3 colorMat;
|
||||
|
||||
int height;
|
||||
int width;
|
||||
int radius;
|
||||
@@ -0,0 +1,88 @@
|
||||
#pragma version(1)
|
||||
|
||||
#include <rs_types.rsh>
|
||||
#include <rs_math.rsh>
|
||||
|
||||
#include "ip.rsh"
|
||||
|
||||
|
||||
static float inBlack;
|
||||
static float outBlack;
|
||||
static float inWhite;
|
||||
static float outWhite;
|
||||
static float3 gamma;
|
||||
static float saturation;
|
||||
|
||||
static float inWMinInB;
|
||||
static float outWMinOutB;
|
||||
static float overInWMinInB;
|
||||
static rs_matrix3x3 colorMat;
|
||||
|
||||
//#pragma rs export_var(height, width, radius, InPixel, OutPixel, ScratchPixel, inBlack, outBlack, inWhite, outWhite, gamma, saturation, InPixel, OutPixel, ScratchPixel, vBlurScript, hBlurScript)
|
||||
#pragma rs export_func(setLevels, setSaturation, setGamma);
|
||||
|
||||
void setLevels(float iBlk, float oBlk, float iWht, float oWht) {
|
||||
inBlack = iBlk;
|
||||
outBlack = oBlk;
|
||||
inWhite = iWht;
|
||||
outWhite = oWht;
|
||||
|
||||
inWMinInB = inWhite - inBlack;
|
||||
outWMinOutB = outWhite - outBlack;
|
||||
overInWMinInB = 1.f / inWMinInB;
|
||||
}
|
||||
|
||||
void setSaturation(float sat) {
|
||||
saturation = sat;
|
||||
|
||||
// Saturation
|
||||
// Linear weights
|
||||
//float rWeight = 0.3086f;
|
||||
//float gWeight = 0.6094f;
|
||||
//float bWeight = 0.0820f;
|
||||
|
||||
// Gamma 2.2 weights (we haven't converted our image to linear space yet for perf reasons)
|
||||
float rWeight = 0.299f;
|
||||
float gWeight = 0.587f;
|
||||
float bWeight = 0.114f;
|
||||
|
||||
float oneMinusS = 1.0f - saturation;
|
||||
rsMatrixSet(&colorMat, 0, 0, oneMinusS * rWeight + saturation);
|
||||
rsMatrixSet(&colorMat, 0, 1, oneMinusS * rWeight);
|
||||
rsMatrixSet(&colorMat, 0, 2, oneMinusS * rWeight);
|
||||
rsMatrixSet(&colorMat, 1, 0, oneMinusS * gWeight);
|
||||
rsMatrixSet(&colorMat, 1, 1, oneMinusS * gWeight + saturation);
|
||||
rsMatrixSet(&colorMat, 1, 2, oneMinusS * gWeight);
|
||||
rsMatrixSet(&colorMat, 2, 0, oneMinusS * bWeight);
|
||||
rsMatrixSet(&colorMat, 2, 1, oneMinusS * bWeight);
|
||||
rsMatrixSet(&colorMat, 2, 2, oneMinusS * bWeight + saturation);
|
||||
}
|
||||
|
||||
void setGamma(float g) {
|
||||
gamma = (float3)g;
|
||||
}
|
||||
|
||||
|
||||
void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
|
||||
const uchar4 *input = v_in;
|
||||
uchar4 *output = v_out;
|
||||
|
||||
float4 currentPixel = 0;
|
||||
|
||||
//currentPixel.xyz = convert_float3(input.xyz);
|
||||
currentPixel.x = (float)(input->x);
|
||||
currentPixel.y = (float)(input->y);
|
||||
currentPixel.z = (float)(input->z);
|
||||
|
||||
float3 temp = rsMatrixMultiply(&colorMat, currentPixel.xyz);
|
||||
temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB;
|
||||
temp = pow(temp, (float3)gamma);
|
||||
currentPixel.xyz = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f);
|
||||
|
||||
//output.xyz = convert_uchar3(currentPixel.xyz);
|
||||
output->x = (uint8_t)currentPixel.x;
|
||||
output->y = (uint8_t)currentPixel.y;
|
||||
output->z = (uint8_t)currentPixel.z;
|
||||
output->w = input->w;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#pragma version(1)
|
||||
|
||||
#include <rs_types.rsh>
|
||||
#include <rs_math.rsh>
|
||||
|
||||
#include "ip.rsh"
|
||||
|
||||
int height;
|
||||
int width;
|
||||
int radius;
|
||||
|
||||
uchar4 * InPixel;
|
||||
uchar4 * OutPixel;
|
||||
uchar4 * ScratchPixel;
|
||||
|
||||
#pragma rs export_var(height, width, radius, InPixel, OutPixel, ScratchPixel, vBlurScript, hBlurScript, levelsScript)
|
||||
#pragma rs export_func(filter, filterBenchmark);
|
||||
|
||||
rs_script vBlurScript;
|
||||
rs_script hBlurScript;
|
||||
rs_script levelsScript;
|
||||
|
||||
|
||||
// Store our coefficients here
|
||||
static float gaussian[MAX_RADIUS * 2 + 1];
|
||||
|
||||
|
||||
static void computeGaussianWeights() {
|
||||
// Compute gaussian weights for the blur
|
||||
// e is the euler's number
|
||||
float e = 2.718281828459045f;
|
||||
float pi = 3.1415926535897932f;
|
||||
// g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
|
||||
// x is of the form [-radius .. 0 .. radius]
|
||||
// and sigma varies with radius.
|
||||
// Based on some experimental radius values and sigma's
|
||||
// we approximately fit sigma = f(radius) as
|
||||
// sigma = radius * 0.4 + 0.6
|
||||
// The larger the radius gets, the more our gaussian blur
|
||||
// will resemble a box blur since with large sigma
|
||||
// the gaussian curve begins to lose its shape
|
||||
float sigma = 0.4f * (float)radius + 0.6f;
|
||||
|
||||
// Now compute the coefficints
|
||||
// We will store some redundant values to save some math during
|
||||
// the blur calculations
|
||||
// precompute some values
|
||||
float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
|
||||
float coeff2 = - 1.0f / (2.0f * sigma * sigma);
|
||||
|
||||
float normalizeFactor = 0.0f;
|
||||
float floatR = 0.0f;
|
||||
int r;
|
||||
for(r = -radius; r <= radius; r ++) {
|
||||
floatR = (float)r;
|
||||
gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
|
||||
normalizeFactor += gaussian[r + radius];
|
||||
}
|
||||
|
||||
//Now we need to normalize the weights because all our coefficients need to add up to one
|
||||
normalizeFactor = 1.0f / normalizeFactor;
|
||||
for(r = -radius; r <= radius; r ++) {
|
||||
floatR = (float)r;
|
||||
gaussian[r + radius] *= normalizeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void blur() {
|
||||
computeGaussianWeights();
|
||||
|
||||
FilterStruct fs;
|
||||
fs.gaussian = gaussian;
|
||||
fs.width = width;
|
||||
fs.height = height;
|
||||
fs.radius = radius;
|
||||
|
||||
fs.ain = rsGetAllocation(InPixel);
|
||||
rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel), &fs);
|
||||
|
||||
fs.ain = rsGetAllocation(ScratchPixel);
|
||||
rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs);
|
||||
}
|
||||
|
||||
void filter() {
|
||||
//RS_DEBUG(radius);
|
||||
|
||||
if(radius > 0) {
|
||||
blur();
|
||||
rsForEach(levelsScript, rsGetAllocation(OutPixel), rsGetAllocation(OutPixel), 0);
|
||||
} else {
|
||||
rsForEach(levelsScript, rsGetAllocation(InPixel), rsGetAllocation(OutPixel), 0);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
rsSendToClient(&count, 1, 4, 0);
|
||||
}
|
||||
|
||||
void filterBenchmark() {
|
||||
blur();
|
||||
|
||||
int count = 0;
|
||||
rsSendToClient(&count, 1, 4, 0);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma version(1)
|
||||
|
||||
#include "../../../../scriptc/rs_types.rsh"
|
||||
#include "../../../../scriptc/rs_math.rsh"
|
||||
#include <rs_types.rsh>
|
||||
#include <rs_math.rsh>
|
||||
|
||||
#include "ip.rsh"
|
||||
|
||||
@@ -361,7 +361,7 @@ void * Context::helperThreadProc(void *vrsc)
|
||||
Context *rsc = static_cast<Context *>(vrsc);
|
||||
uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount);
|
||||
|
||||
LOGE("helperThreadProc 1 %p idx=%i", rsc, idx);
|
||||
LOGV("RS helperThread starting %p idx=%i", rsc, idx);
|
||||
|
||||
rsc->mWorkers.mLaunchSignals[idx].init();
|
||||
rsc->mWorkers.mNativeThreadId[idx] = gettid();
|
||||
@@ -376,13 +376,13 @@ void * Context::helperThreadProc(void *vrsc)
|
||||
while(rsc->mRunning) {
|
||||
rsc->mWorkers.mLaunchSignals[idx].wait();
|
||||
if (rsc->mWorkers.mLaunchCallback) {
|
||||
LOGE("helperThreadProc 4");
|
||||
rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx);
|
||||
}
|
||||
LOGE("helperThreadProc 5");
|
||||
android_atomic_dec(&rsc->mWorkers.mRunningCount);
|
||||
rsc->mWorkers.mCompleteSignal.set();
|
||||
}
|
||||
|
||||
LOGV("RS helperThread exiting %p idx=%i", rsc, idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -479,6 +479,10 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth)
|
||||
LOGE("Failed to start rs context thread.");
|
||||
return;
|
||||
}
|
||||
while(!mRunning) {
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
mWorkers.mRunningCount = 0;
|
||||
mWorkers.mLaunchCount = 0;
|
||||
for (uint32_t ct=0; ct < mWorkers.mCount; ct++) {
|
||||
@@ -490,9 +494,6 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth)
|
||||
}
|
||||
}
|
||||
|
||||
while(!mRunning) {
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&threadAttr);
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ public:
|
||||
bool ext_OES_texture_npot() const {return mGL.OES_texture_npot;}
|
||||
|
||||
void launchThreads(WorkerCallback_t cbk, void *data);
|
||||
uint32_t getWorkerPoolSize() const {return (uint32_t)mWorkers.mRunningCount;}
|
||||
|
||||
protected:
|
||||
Device *mDev;
|
||||
|
||||
@@ -171,7 +171,6 @@ typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint
|
||||
static void wc_xy(void *usr, uint32_t idx)
|
||||
{
|
||||
MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
|
||||
LOGE("usr %p, idx %i", usr, idx);
|
||||
|
||||
while (1) {
|
||||
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
|
||||
@@ -279,32 +278,32 @@ void ScriptC::runForEach(Context *rsc,
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
LOGE("launch 1");
|
||||
if ((rsc->getWorkerPoolSize() > 1) &&
|
||||
((mtls.dimY * mtls.dimZ * mtls.dimArray) > 1)) {
|
||||
|
||||
//LOGE("launch 1");
|
||||
rsc->launchThreads(wc_xy, &mtls);
|
||||
LOGE("launch 2");
|
||||
}
|
||||
//LOGE("launch 2");
|
||||
} else {
|
||||
for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) {
|
||||
for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) {
|
||||
for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) {
|
||||
uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar +
|
||||
mtls.dimX * mtls.dimY * z +
|
||||
mtls.dimX * y;
|
||||
uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
|
||||
const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
|
||||
|
||||
/*
|
||||
for (uint32_t ar = arrayStart; ar < arrayEnd; ar++) {
|
||||
for (uint32_t z = zStart; z < zEnd; z++) {
|
||||
for (uint32_t y = yStart; y < yEnd; y++) {
|
||||
uint32_t offset = dimX * dimY * dimZ * ar +
|
||||
dimX * dimY * z +
|
||||
dimX * y;
|
||||
uint8_t *xPtrOut = ptrOut + (eStrideOut * offset);
|
||||
const uint8_t *xPtrIn = ptrIn + (eStrideIn * offset);
|
||||
|
||||
for (uint32_t x = xStart; x < xEnd; x++) {
|
||||
((rs_t)mProgram.mRoot) (xPtrIn, xPtrOut, usr, x, y, z, ar);
|
||||
xPtrIn += eStrideIn;
|
||||
xPtrOut += eStrideOut;
|
||||
for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) {
|
||||
((rs_t)mProgram.mRoot) (xPtrIn, xPtrOut, usr, x, y, z, ar);
|
||||
xPtrIn += mtls.eStrideIn;
|
||||
xPtrOut += mtls.eStrideOut;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
setTLS(oldTLS);
|
||||
}
|
||||
|
||||
@@ -394,6 +393,9 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s)
|
||||
s->mEnviroment.mFieldAddress = (void **)calloc(100, sizeof(void *));
|
||||
bccGetExportVars(s->mBccScript, (BCCsizei *)&s->mEnviroment.mFieldCount,
|
||||
100, s->mEnviroment.mFieldAddress);
|
||||
//for (int ct2=0; ct2 < s->mEnviroment.mFieldCount; ct2++ ) {
|
||||
//LOGE("Script field %i = %p", ct2, s->mEnviroment.mFieldAddress[ct2]);
|
||||
//}
|
||||
|
||||
s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
|
||||
s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
|
||||
|
||||
Reference in New Issue
Block a user