android renderscript

32
Android RenderScript SK 플플플 / 플플플 플플 2 플 플플플 [email protected]

Upload: jungsoo-nam

Post on 27-Jan-2015

478 views

Category:

Technology


2 download

DESCRIPTION

Android RenderScript and FilterScript

TRANSCRIPT

Page 1: Android RenderScript

Android RenderScript

SK 플래닛 / 모바일 개발 2 팀남정수

[email protected]

Page 2: Android RenderScript

About RenderScript

• RenderScript computation– high performance computation API at the native level that you write

in C (C99 standard)– your apps the ability to run operations with automatic parallelization

across all available processor cores• different types of processors such as the CPU, GPU or DSP

– useful for apps that do image processing, mathematical modeling, or any operations that require lots of mathematical computation

– access to all of these features without having to write code to support different architectures or a different amount of processing cores

– do not need to recompile your application for different processor types, because Renderscript code is compiled on the device at runtime.

Page 3: Android RenderScript

RenderScript system overview

Page 4: Android RenderScript

RenderScript on Android 4.1

• Deprecation Notice– Earlier versions of Renderscript included an

experimental graphics engine component• most of the APIs in rs_graphics.rsh and the corresponding

APIs in android.renderscript

– If you have apps that render graphics with Renderscript, we highly recommend you convert your code to another Android graphics rendering option.• http://docs.huihoo.com/android/4.2/guide/topics/render

script/compute.html#overview

Page 5: Android RenderScript

RenderScript basic 1/21. rs 작성 2. clean 을 수행하면 ScriptC_scriptname.java 생성

3. ScriptC_mono.java

Page 6: Android RenderScript

RenderScript basic 2/24. RenderScript 코드 작성 5. RenderScript 결과 스크린샷

Page 7: Android RenderScript

RenderScript entry points

Function(in .rs) Commentvoid root(const uchar4* v_in, uchar4* v_out) [Default]

forEach_root(in, out)

void root(const uchar4 *v_in, uchar4 *v_out, const uchar4* data, uint32_t x, uint32_t y) forEach_root(in, out)Data 는 이름 변경 가능x,y 는 순선 변경 및 이름 변경 불가능

void root(const uchar4 *v_in, uchar4 *v_out, uint32_t x, uint32_t y) forEach_root(in, out)

void root(const uchar4 *v_in, uchar4 *v_out, const uchar4* data) forEach_root(in, out)

void root(uchar4* v_out) forEach_root(out)

uchar4 __attribute__((kernel)) functionname(uchar4 in, uint32_t x, uint32_t y) forEach_functionname(in, out)

int root() For graphics(deprecated)Called by RenderScriptGL

void functionname() invoke_functionname()

Page 8: Android RenderScript

FilterScript• FilterScript

– Introduced in Android 4.2 (API Level 17), Filterscript defines a subset of Renderscript that focuses on image processing operations, such as those that you would typically write with an OpenGL ES fragment shader.

– 현재 android developer 의 renderscript 항목에는 기본적으로 filterscript 를 사용하기를 설명하고 있다 .• http://developer.android.com/guide/topics/renderscript/compute.html

• Usage– Inputs and return values of root functions cannot contain pointers. The default root

function signature contains pointers, so you must use the __attribute__((kernel)) attribute to declare a custom root function when using Filterscript.

– Built-in types cannot exceed 32-bits.– Filterscript must always use relaxed floating point precision by using the rs_fp_relaxed

pragma.• Most applications can use rs_fp_relaxed without any side effects. This may be very beneficial on some architectures

due to additional optimizations only available with relaxed precision (such as SIMD CPU instructions).

– Filterscript files must end with an .fs extension, instead of an .rs extension• Android-18 에서는 fs 대신에 rs 를 써도 된다 .

Page 9: Android RenderScript

FilterScript example

Page 10: Android RenderScript

ScriptNested Classesclass Script.Builder Only intended for use by generated reflected code. class Script.FieldBase Only intended for use by generated reflected code. class Script.FieldID FieldID is an identifier for a Script + exported field pair. class Script.KernelID KernelID is an identifier for a Script + root function pair. class Script.LaunchOptions Class used to specify clipping for a kernel launch.

Protected MethodsScript.FieldID createFieldID(int slot, Element e) Only to be used by generated reflected classes.Script.KernelID createKernelID(int slot, int sig, Element ein, Element eout) Only to be used by generated reflected classes.void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, Script.LaunchOptions sc) Only intended for use by generated reflected code.void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) Only intended for use by generated reflected code.void invoke(int slot) Only intended for use by generated reflected code.void invoke(int slot, FieldPacker v) Only intended for use by generated reflected code.

Public MethodsInt getXEnd() Returns the current X end Int getXStart() Returns the current X start Int getYEnd() Returns the current Y end Int getYStart() Returns the current Y startInt getZEnd() Returns the current Z end Int getZStart() Returns the current Z start Script.LaunchOptions setX(int xstartArg, int xendArg) Set the X range. Script.LaunchOptions setY(int ystartArg, int yendArg) Set the Y range. Script.LaunchOptions setZ(int zstartArg, int zendArg) Set the Z range.

Page 11: Android RenderScript

Variables

//uchar4 *gPixels; private final static int mExportVarIdx_gPixels = 5; private Allocation mExportVar_gPixels; public void bind_gPixels(Allocation v) { mExportVar_gPixels = v; if (v == null) bindAllocation(null, mExportVarIdx_gPixels); else bindAllocation(v, mExportVarIdx_gPixels); }

public Allocation get_gPixels() { return mExportVar_gPixels; }

//rs_allocation gIn; private final static int mExportVarIdx_gIn = 0; private Allocation mExportVar_gIn; public synchronized void set_gIn(Allocation v) { setVar(mExportVarIdx_gIn, v); mExportVar_gIn = v; }

public Allocation get_gIn() { return mExportVar_gIn; }

public Script.FieldID getFieldID_gIn() { return createFieldID(mExportVarIdx_gIn, null); }

//float gFactor = 6; private final static int mExportVarIdx_gFactor = 6; private float mExportVar_gFactor; public synchronized void set_gFactor(float v) { setVar(mExportVarIdx_gFactor, v); mExportVar_gFactor = v; }

public float get_gFactor() { return mExportVar_gFactor; }

public Script.FieldID getFieldID_gFactor() { return createFieldID(mExportVarIdx_gFactor, null); }//void root(…) private final static int mExportForEachIdx_root = 0; public Script.KernelID getKernelID_root() { return createKernelID(mExportForEachIdx_root, 3, null, null); }

public void forEach_root(Allocation ain, Allocation aout) { // check ain if (!ain.getType().getElement().isCompatible(__U8_4)) { throw new RSRuntimeException("Type mismatch with U8_4!"); } // check aout if (!aout.getType().getElement().isCompatible(__U8_4)) { throw new RSRuntimeException("Type mismatch with U8_4!"); } // Verify dimensions Type tIn = ain.getType(); Type tOut = aout.getType(); if ((tIn.getCount() != tOut.getCount()) || (tIn.getX() != tOut.getX()) || (tIn.getY() != tOut.getY()) || (tIn.getZ() != tOut.getZ()) || (tIn.hasFaces() != tOut.hasFaces()) || (tIn.hasMipmaps() != tOut.hasMipmaps())) { throw new RSRuntimeException("Dimension mismatch between input and output parameters!"); } forEach(mExportForEachIdx_root, ain, aout, null); }

Page 12: Android RenderScript

Structs/* typedef struct __attribute__((packed, aligned(4))) Point { float2 delta; float2 position; //uchar4 color;} Point_t;Point_t *point;*/

public class ScriptField_Point extends android.renderscript.Script.FieldBase { static public class Item { public static final int sizeof = 16;

Float2 delta; Float2 position;

Item() { delta = new Float2(); position = new Float2(); }

}

private Item mItemArray[]; private FieldPacker mIOBuffer; private static java.lang.ref.WeakReference<Element> mElementCache = new java.lang.ref.WeakReference<Element>(null); public static Element createElement(RenderScript rs) { Element.Builder eb = new Element.Builder(rs); eb.add(Element.F32_2(rs), "delta"); eb.add(Element.F32_2(rs), "position"); return eb.create(); }

public synchronized void set(Item i, int index, boolean copyNow) { if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; mItemArray[index] = i; if (copyNow) { copyToArray(i, index); FieldPacker fp = new FieldPacker(Item.sizeof); copyToArrayLocal(i, fp); mAllocation.setFromFieldPacker(index, fp); }

}

public synchronized Item get(int index) { if (mItemArray == null) return null; return mItemArray[index]; }

public synchronized void set_delta(int index, Float2 v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].delta = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(8); fp.addF32(v); mAllocation.setFromFieldPacker(index, 0, fp); }

}

public synchronized void set_position(int index, Float2 v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].position = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof + 8); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(8); fp.addF32(v); mAllocation.setFromFieldPacker(index, 1, fp); } }

Page 13: Android RenderScript

Pointers/* typedef struct Point { float2 position; float size;} Point_t;

Point_t *touchPoints;int32_t *intPointer;*/

private ScriptField_Point mExportVar_touchPoints;public void bind_touchPoints(ScriptField_Point v) { mExportVar_touchPoints = v; if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints);}

public ScriptField_Point get_touchPoints() { return mExportVar_touchPoints;}

private Allocation mExportVar_intPointer;public void bind_intPointer(Allocation v) { mExportVar_intPointer = v; if (v == null) bindAllocation(null, mExportVarIdx_intPointer); else bindAllocation(v, mExportVarIdx_intPointer);}

public Allocation get_intPointer() { return mExportVar_intPointer;}

Page 14: Android RenderScript

MemoryAndroid Object Type

Description

Element An element describes one cell of a memory allocation and can have two forms: basic or complex.Basic:• Single float value• 4 element float vector• single RGB-565 color• single unsigned int 16Complex:• Structs

Type A type is a memory allocation template and consists of an element and one or more dimensions. It describes the layout of the memory (basically an array of Elements) but does not allocate the memory for the data that it describes.

Allocation An allocation provides the memory for applications based on a description of the memory that is represented by a Type. Allocated memory can exist in many memory spaces concurrently. If memory is modified in one space, you must explicitly synchronize the memory, so that it is updated in all the other spaces in which it exists.

Page 15: Android RenderScript

Allocation• Lifecycle

– Immutable– Once created– The replacement is to create a new allocation and copy contents

• Memory usages– USAGE_SCRIPT: Allocates in the script memory space. This is the default memory space if you do not specify a

memory space.– USAGE_GRAPHICS_TEXTURE: Allocates in the texture memory space of the GPU.

• This was deprecated in API level 16.

– USAGE_GRAPHICS_VERTEX: Allocates in the vertex memory space of the GPU.• This was deprecated in API level 16.

– USAGE_GRAPHICS_CONSTANTS: Allocates in the constants memory space of the GPU that is used by the various program objects.• This was deprecated in API level 16.

– USAGE_SHARED

• Memory management– synchronized void destory()

• Frees any native resources associated with this object. The primary use is to force immediate cleanup of resources when it is believed the GC will not respond quickly enough.

– synchronized void resize(int dimX)• This method was deprecated in API level 18. RenderScript objects should be immutable once created. The replacement is to create a new

allocation and copy the contents.

Page 16: Android RenderScript

RenderScript vs OpenGL ES• Cons

– ARGB -> BGRA 로 swizzling 할 필요없음 ( 성능 저하 요소 )– Android Bitmap 기준으로 연산하므로 Y Flip 필요없음 ( 성능 저하 요소 )– Texture 좌표 대신에 bitmap 의 실제 pixel array index 를 사용하므로 정확한 연산이 가능

• GLSL 은 texture 와 texture 좌표 (float) 기반이므로 정확한 픽셀 값을 sampling(texture 에서 pixel 을 얻어오는 과정 ) 얻어오기 힘듬

– Android 표준으로 지원– Lifecycle 관리 불필요– 일반 View 와 조화로운 drawing 가능 (drawing routine 자체가 없음 )– CPU/GPU 조화로운 병렬처리 가능 (GPU 가 병렬처리가 불가할때는 CPU 로 병렬처리 )

• Pros– Vertex shader 부재

• Vertex shader 가 해야할일을 모든 pixel 단위로 연산하므로 오버헤드 증가• RSSurfaceView 를 사용하면 해당 기능을 사용가능 ( 그런데 현재는 deprecated 됨 )

– RenderScript 개발자 부족• 문서 , 자료 부족

– GLSL 보다 높은 수준의 C like 언어로 되어 있음

Page 17: Android RenderScript

RenderScript Flow chart

Page 18: Android RenderScript

RenderScript samplesingle image sampling

• Single-image sampling(default)– *v_in, *v_out 은 현재 이미지의 in, out 포인터– forEach_root() 를 사용– rsUnpackColor8888 은 uchar4 -> float4 로 unpacking– rsPackColorTo8888 은 float4 를 uchar4 로 packing

Page 19: Android RenderScript

RenderScript sample multi image sampling

• Multi-image sampling– 주어진 하나의 image pixel pointer 인 *v_in, *v_out 만 sampling 하지 않고– 추가로 bind 된 uchar4* 를 통해 다수 image 의 pixel 을 sampling 하는 작업– 주로 인접 pixel 을 얻어서 filter 처리할때 사용– forEach_root() 대신에 invoke_filter() 를 사용한다 .

Page 20: Android RenderScript

RenderScript sample multi pass effect

• Multi-pass– RenderScript 의 root 함수를 n 회 수행한 후에 allocation 에서 getBitmap 하는 형태의 effect– n-1 회와 n 회 사이에서는 bitmap 으로 copy 하지 않고 allocation 상에서 data 를 전달

Page 21: Android RenderScript

Histogram sample(1/12)

Page 22: Android RenderScript

Histogram sample(2/12)

Page 23: Android RenderScript

Histogram sample(3/12)

Page 24: Android RenderScript

Histogram sample(4/12)

Page 25: Android RenderScript

Histogram sample(5/12)

Page 26: Android RenderScript

Histogram sample(6/12)

Page 27: Android RenderScript

Histogram sample(7/12)

Page 28: Android RenderScript

Histogram sample(8/12)

Page 29: Android RenderScript

Histogram sample(9/12)

Page 30: Android RenderScript

Histogram sample(10/12)

Page 31: Android RenderScript

Histogram sample(11/12)

Page 32: Android RenderScript

Histogram sample(12/12)