diff options
author | Romain Guy <romainguy@android.com> | 2009-10-09 16:05:25 -0700 |
---|---|---|
committer | Romain Guy <romainguy@android.com> | 2009-10-09 16:05:25 -0700 |
commit | d7fa122dfed376cd9c60eac516e2730acf23f3dd (patch) | |
tree | 6648be549b3a01bfaa8dfccb3ae4344ab1b21f65 | |
parent | 98e0b146b80670b52805b4b210ef5582dad6bb68 (diff) | |
download | frameworks_base-d7fa122dfed376cd9c60eac516e2730acf23f3dd.zip frameworks_base-d7fa122dfed376cd9c60eac516e2730acf23f3dd.tar.gz frameworks_base-d7fa122dfed376cd9c60eac516e2730acf23f3dd.tar.bz2 |
Add new RenderScript sample: ImageProcessing.
Change-Id: I5e482bbc34911c940a3a74258f8f8549b1939bc4
-rw-r--r-- | libs/rs/java/ImageProcessing/Android.mk | 25 | ||||
-rw-r--r-- | libs/rs/java/ImageProcessing/AndroidManifest.xml | 16 | ||||
-rw-r--r-- | libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg | bin | 0 -> 76367 bytes | |||
-rw-r--r-- | libs/rs/java/ImageProcessing/res/layout/main.xml | 38 | ||||
-rw-r--r-- | libs/rs/java/ImageProcessing/res/raw/threshold.rs | 44 | ||||
-rw-r--r-- | libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java | 195 | ||||
-rw-r--r-- | libs/rs/rsScriptC_Lib.cpp | 75 |
7 files changed, 393 insertions, 0 deletions
diff --git a/libs/rs/java/ImageProcessing/Android.mk b/libs/rs/java/ImageProcessing/Android.mk new file mode 100644 index 0000000..5a844d5 --- /dev/null +++ b/libs/rs/java/ImageProcessing/Android.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2009 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. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under, src) +#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript + +LOCAL_PACKAGE_NAME := ImageProcessing + +include $(BUILD_PACKAGE) diff --git a/libs/rs/java/ImageProcessing/AndroidManifest.xml b/libs/rs/java/ImageProcessing/AndroidManifest.xml new file mode 100644 index 0000000..b48d208 --- /dev/null +++ b/libs/rs/java/ImageProcessing/AndroidManifest.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.rs.image"> + + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + + <application android:label="Image Processing"> + <activity android:name="ImageProcessingActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg b/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg Binary files differnew file mode 100644 index 0000000..81a87b1 --- /dev/null +++ b/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg diff --git a/libs/rs/java/ImageProcessing/res/layout/main.xml b/libs/rs/java/ImageProcessing/res/layout/main.xml new file mode 100644 index 0000000..0872cf2a --- /dev/null +++ b/libs/rs/java/ImageProcessing/res/layout/main.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<merge xmlns:android="http://schemas.android.com/apk/res/android"> + + <SurfaceView + android:id="@+id/surface" + android:layout_width="1dip" + android:layout_height="1dip" /> + + <ImageView + android:id="@+id/display" + android:layout_width="320dip" + android:layout_height="266dip" /> + + <SeekBar + android:id="@+id/threshold" + android:layout_marginBottom="10dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + +</merge>
\ No newline at end of file diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs new file mode 100644 index 0000000..dec5587 --- /dev/null +++ b/libs/rs/java/ImageProcessing/res/raw/threshold.rs @@ -0,0 +1,44 @@ +struct color_s { + char b; + char g; + char r; + char a; +}; + +void filter(struct color_s *in, struct color_s *out, struct vec3_s *luminanceVector) { + struct vec3_s pixel; + pixel.x = (in->r & 0xFF) / 255.0f; + pixel.y = (in->g & 0xFF) / 255.0f; + pixel.z = (in->b & 0xFF) / 255.0f; + + float luminance = vec3Dot(luminanceVector, &pixel); + luminance = maxf(0.0f, luminance - Params->threshold); + vec3Scale(&pixel, signf(luminance)); + + out->a = in->a; + out->r = pixel.x * 255.0f; + out->g = pixel.y * 255.0f; + out->b = pixel.z * 255.0f; +} + +void main() { + struct color_s *in = (struct color_s *) InPixel; + struct color_s *out = (struct color_s *) OutPixel; + + struct vec3_s luminanceVector; + luminanceVector.x = 0.2125f; + luminanceVector.y = 0.7154f; + luminanceVector.z = 0.0721f; + + int count = Params->inWidth * Params->inHeight; + int i; + + for (i = 0; i < count; i++) { + filter(in, out, &luminanceVector); + + in++; + out++; + } + + sendToClient(&count, 1, 4, 0); +} diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java new file mode 100644 index 0000000..b1facfc --- /dev/null +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009 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.app.Activity; +import android.os.Bundle; +import android.graphics.BitmapFactory; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.renderscript.ScriptC; +import android.renderscript.RenderScript; +import android.renderscript.Type; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Script; +import android.view.SurfaceView; +import android.view.SurfaceHolder; +import android.widget.ImageView; +import android.widget.SeekBar; + +public class ImageProcessingActivity extends Activity implements SurfaceHolder.Callback { + private Bitmap mBitmap; + private Params mParams; + private Script.Invokable mInvokable; + private int[] mOutData; + + @SuppressWarnings({"FieldCanBeLocal"}) + private RenderScript mRS; + @SuppressWarnings({"FieldCanBeLocal"}) + private Type mParamsType; + @SuppressWarnings({"FieldCanBeLocal"}) + private Allocation mParamsAllocation; + @SuppressWarnings({"FieldCanBeLocal"}) + private Type mPixelType; + @SuppressWarnings({"FieldCanBeLocal"}) + private Allocation mInPixelsAllocation; + @SuppressWarnings({"FieldCanBeLocal"}) + private Allocation mOutPixelsAllocation; + + private SurfaceView mSurfaceView; + private ImageView mDisplayView; + + static class Params { + public int inWidth; + public int outWidth; + public int inHeight; + public int outHeight; + + public float threshold; + } + + static class Pixel { + public byte a; + public byte r; + public byte g; + public byte b; + } + + class FilterCallback extends RenderScript.RSMessage { + private Runnable mAction = new Runnable() { + public void run() { + mOutPixelsAllocation.readData(mOutData); + mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0, + mParams.outWidth, mParams.outHeight); + mDisplayView.invalidate(); + } + }; + + @Override + public void run() { + mSurfaceView.removeCallbacks(mAction); + mSurfaceView.post(mAction); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mBitmap = loadBitmap(R.drawable.data); + + mSurfaceView = (SurfaceView) findViewById(R.id.surface); + mSurfaceView.getHolder().addCallback(this); + + mDisplayView = (ImageView) findViewById(R.id.display); + mDisplayView.setImageBitmap(mBitmap); + + ((SeekBar) findViewById(R.id.threshold)).setOnSeekBarChangeListener( + new SeekBar.OnSeekBarChangeListener() { + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser) { + mParams.threshold = progress / 100.0f; + mParamsAllocation.data(mParams); + mInvokable.execute(); + } + } + + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + } + + public void surfaceCreated(SurfaceHolder holder) { + mParams = createParams(); + mInvokable = createScript(); + + mInvokable.execute(); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + } + + public void surfaceDestroyed(SurfaceHolder holder) { + } + + private Script.Invokable createScript() { + mRS = new RenderScript(mSurfaceView.getHolder().getSurface(), false, false); + mRS.mMessageCallback = new FilterCallback(); + + mParamsType = Type.createFromClass(mRS, Params.class, 1, "Parameters"); + mParamsAllocation = Allocation.createTyped(mRS, mParamsType); + mParamsAllocation.data(mParams); + + final int pixelCount = mParams.inWidth * mParams.inHeight; + + mPixelType = Type.createFromClass(mRS, Pixel.class, 1, "Pixel"); + mInPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS), + pixelCount); + mOutPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS), + pixelCount); + + final int[] data = new int[pixelCount]; + mBitmap.getPixels(data, 0, mParams.inWidth, 0, 0, mParams.inWidth, mParams.inHeight); + mInPixelsAllocation.data(data); + + mOutData = new int[pixelCount]; + mOutPixelsAllocation.data(mOutData); + + ScriptC.Builder sb = new ScriptC.Builder(mRS); + sb.setType(mParamsType, "Params", 0); + sb.setType(mPixelType, "InPixel", 1); + sb.setType(mPixelType, "OutPixel", 2); + sb.setType(true, 2); + Script.Invokable invokable = sb.addInvokable("main"); + sb.setScript(getResources(), R.raw.threshold); + sb.setRoot(true); + + ScriptC script = sb.create(); + script.bindAllocation(mParamsAllocation, 0); + script.bindAllocation(mInPixelsAllocation, 1); + script.bindAllocation(mOutPixelsAllocation, 2); + + return invokable; + } + + private Params createParams() { + final Params params = new Params(); + params.inWidth = params.outWidth = mBitmap.getWidth(); + params.inHeight = params.outHeight = mBitmap.getHeight(); + params.threshold = 0.5f; + return params; + } + + private Bitmap loadBitmap(int resource) { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options)); + } + + private static Bitmap copyBitmap(Bitmap source) { + Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig()); + Canvas c = new Canvas(b); + c.drawBitmap(source, 0, 0, null); + source.recycle(); + return b; + } +} diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 436f48b..5aef56d 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -227,6 +227,53 @@ static void SC_vec3Scale(vec3_t *lhs, float scale) lhs->z *= scale; } +////////////////////////////////////////////////////////////////////////////// +// Vec4 routines +////////////////////////////////////////////////////////////////////////////// + +static void SC_vec4Norm(vec4_t *v) +{ + float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w); + len = 1 / len; + v->x *= len; + v->y *= len; + v->z *= len; + v->w *= len; +} + +static float SC_vec4Length(const vec4_t *v) +{ + return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w); +} + +static void SC_vec4Add(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs) +{ + dest->x = lhs->x + rhs->x; + dest->y = lhs->y + rhs->y; + dest->z = lhs->z + rhs->z; + dest->w = lhs->w + rhs->w; +} + +static void SC_vec4Sub(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs) +{ + dest->x = lhs->x - rhs->x; + dest->y = lhs->y - rhs->y; + dest->z = lhs->z - rhs->z; + dest->w = lhs->w - rhs->w; +} + +static float SC_vec4Dot(const vec4_t *lhs, const vec4_t *rhs) +{ + return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z + lhs->w * rhs->w; +} + +static void SC_vec4Scale(vec4_t *lhs, float scale) +{ + lhs->x *= scale; + lhs->y *= scale; + lhs->z *= scale; + lhs->w *= scale; +} ////////////////////////////////////////////////////////////////////////////// // Math routines @@ -286,6 +333,16 @@ static float SC_randf2(float min, float max) return r / RAND_MAX * (max - min) + min; } +static int SC_sign(int value) +{ + return (value > 0) - (value < 0); +} + +static float SC_signf(float value) +{ + return (value > 0) - (value < 0); +} + static float SC_clampf(float amount, float low, float high) { return amount < low ? low : (amount > high ? high : amount); @@ -1103,6 +1160,10 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { "int", "(int)" }, { "sqrf", (void *)&SC_sqrf, "float", "(float)" }, + { "sign", (void *)&SC_sign, + "int", "(int)" }, + { "signf", (void *)&SC_signf, + "float", "(float)" }, { "clamp", (void *)&SC_clamp, "int", "(int, int, int)" }, { "clampf", (void *)&SC_clampf, @@ -1200,6 +1261,20 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { { "vec3Scale", (void *)&SC_vec3Scale, "void", "(struct vec3_s *lhs, float scale)" }, + // vec4 + { "vec4Norm", (void *)&SC_vec4Norm, + "void", "(struct vec4_s *)" }, + { "vec4Length", (void *)&SC_vec4Length, + "float", "(struct vec4_s *)" }, + { "vec4Add", (void *)&SC_vec4Add, + "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" }, + { "vec4Sub", (void *)&SC_vec4Sub, + "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" }, + { "vec4Dot", (void *)&SC_vec4Dot, + "float", "(struct vec4_s *lhs, struct vec4_s *rhs)" }, + { "vec4Scale", (void *)&SC_vec4Scale, + "void", "(struct vec4_s *lhs, float scale)" }, + // context { "bindProgramFragment", (void *)&SC_bindProgramFragment, "void", "(int)" }, |