diff options
Diffstat (limited to 'libs/rs')
85 files changed, 10606 insertions, 0 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk new file mode 100644 index 0000000..6b11a25 --- /dev/null +++ b/libs/rs/Android.mk @@ -0,0 +1,117 @@ +ifeq ($(BUILD_RENDERSCRIPT),true) + +LOCAL_PATH:=$(call my-dir) + + +# Build rsg-generator ==================== +include $(CLEAR_VARS) + +LOCAL_MODULE := rsg-generator + +# These symbols are normally defined by BUILD_XXX, but we need to define them +# here so that local-intermediates-dir works. + +LOCAL_IS_HOST_MODULE := true +LOCAL_MODULE_CLASS := EXECUTABLES +intermediates := $(local-intermediates-dir) + +GEN := $(addprefix $(intermediates)/, \ + lex.yy.c \ + ) +$(GEN): PRIVATE_CUSTOM_TOOL = flex -o $@ $< + +$(intermediates)/lex.yy.c : $(LOCAL_PATH)/spec.lex + $(transform-generated-source) + +$(LOCAL_PATH)/rsg_generator.c : $(intermediates)/lex.yy.c + +LOCAL_SRC_FILES:= \ + rsg_generator.c + +include $(BUILD_HOST_EXECUTABLE) + +# TODO: This should go into build/core/config.mk +RSG_GENERATOR:=$(LOCAL_BUILT_MODULE) + + + +# Build render script lib ==================== +include $(CLEAR_VARS) +LOCAL_MODULE := libRS + +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +intermediates:= $(local-intermediates-dir) + +# Generate custom headers + +GEN := $(addprefix $(intermediates)/, \ + rsgApiStructs.h \ + rsgApiFuncDecl.h \ + ) + +$(GEN) : PRIVATE_PATH := $(LOCAL_PATH) +$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(PRIVATE_PATH)/rs.spec +$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec +$(GEN): $(intermediates)/%.h : $(LOCAL_PATH)/%.h.rsg + $(transform-generated-source) + +# used in jni/Android.mk +rs_generated_source += $(GEN) +LOCAL_GENERATED_SOURCES += $(GEN) + +# Generate custom source files + +GEN := $(addprefix $(intermediates)/, \ + rsgApi.cpp \ + rsgApiReplay.cpp \ + ) + +$(GEN) : PRIVATE_PATH := $(LOCAL_PATH) +$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(PRIVATE_PATH)/rs.spec +$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec +$(GEN): $(intermediates)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg + $(transform-generated-source) + +# used in jni/Android.mk +rs_generated_source += $(GEN) + +LOCAL_GENERATED_SOURCES += $(GEN) + +LOCAL_SRC_FILES:= \ + rsAdapter.cpp \ + rsAllocation.cpp \ + rsComponent.cpp \ + rsContext.cpp \ + rsDevice.cpp \ + rsElement.cpp \ + rsFileA3D.cpp \ + rsLight.cpp \ + rsLocklessFifo.cpp \ + rsObjectBase.cpp \ + rsMatrix.cpp \ + rsMesh.cpp \ + rsProgram.cpp \ + rsProgramFragment.cpp \ + rsProgramFragmentStore.cpp \ + rsProgramVertex.cpp \ + rsSampler.cpp \ + rsScript.cpp \ + rsScriptC.cpp \ + rsScriptC_Lib.cpp \ + rsThreadIO.cpp \ + rsType.cpp \ + rsTriangleMesh.cpp + +LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libui libacc +LOCAL_LDLIBS := -lpthread -ldl +LOCAL_MODULE:= libRS +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + +# Include the subdirectories ==================== +include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk,\ + java \ + )) + +endif
\ No newline at end of file diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h new file mode 100644 index 0000000..855ea63 --- /dev/null +++ b/libs/rs/RenderScript.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2007 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. + */ + +#ifndef RENDER_SCRIPT_H +#define RENDER_SCRIPT_H + +#include <stdint.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////// +// + +typedef void * RsAdapter1D; +typedef void * RsAdapter2D; +typedef void * RsAllocation; +typedef void * RsContext; +typedef void * RsDevice; +typedef void * RsElement; +typedef void * RsFile; +typedef void * RsSampler; +typedef void * RsScript; +typedef void * RsScriptBasicTemp; +typedef void * RsTriangleMesh; +typedef void * RsType; +typedef void * RsLight; + +typedef void * RsProgramVertex; +typedef void * RsProgramFragment; +typedef void * RsProgramFragmentStore; + +RsDevice rsDeviceCreate(); +void rsDeviceDestroy(RsDevice); + +RsContext rsContextCreate(RsDevice, void *, uint32_t version); +void rsContextDestroy(RsContext); + +enum RsDataType { + RS_TYPE_FLOAT, + RS_TYPE_UNSIGNED, + RS_TYPE_SIGNED +}; + +enum RsDataKind { + RS_KIND_USER, + RS_KIND_RED, + RS_KIND_GREEN, + RS_KIND_BLUE, + RS_KIND_ALPHA, + RS_KIND_LUMINANCE, + RS_KIND_INTENSITY, + RS_KIND_X, + RS_KIND_Y, + RS_KIND_Z, + RS_KIND_W, + RS_KIND_S, + RS_KIND_T, + RS_KIND_Q, + RS_KIND_R, + RS_KIND_NX, + RS_KIND_NY, + RS_KIND_NZ, + RS_KIND_INDEX +}; + +enum RsElementPredefined { + RS_ELEMENT_USER_U8, + RS_ELEMENT_USER_I8, + RS_ELEMENT_USER_U16, + RS_ELEMENT_USER_I16, + RS_ELEMENT_USER_U32, + RS_ELEMENT_USER_I32, + RS_ELEMENT_USER_FLOAT, + + RS_ELEMENT_A_8, // 7 + RS_ELEMENT_RGB_565, // 8 + RS_ELEMENT_RGBA_5551, // 9 + RS_ELEMENT_RGBA_4444, // 10 + RS_ELEMENT_RGB_888, // 11 + RS_ELEMENT_RGBA_8888, // 12 + + RS_ELEMENT_INDEX_16, //13 + RS_ELEMENT_INDEX_32, + RS_ELEMENT_XY_F32, + RS_ELEMENT_XYZ_F32, + RS_ELEMENT_ST_XY_F32, + RS_ELEMENT_ST_XYZ_F32, + RS_ELEMENT_NORM_XYZ_F32, + RS_ELEMENT_NORM_ST_XYZ_F32, +}; + +enum RsSamplerParam { + RS_SAMPLER_MIN_FILTER, + RS_SAMPLER_MAG_FILTER, + RS_SAMPLER_WRAP_S, + RS_SAMPLER_WRAP_T, + RS_SAMPLER_WRAP_R +}; + +enum RsSamplerValue { + RS_SAMPLER_NEAREST, + RS_SAMPLER_LINEAR, + RS_SAMPLER_LINEAR_MIP_LINEAR, + RS_SAMPLER_WRAP, + RS_SAMPLER_CLAMP +}; + +enum RsDimension { + RS_DIMENSION_X, + RS_DIMENSION_Y, + RS_DIMENSION_Z, + RS_DIMENSION_LOD, + RS_DIMENSION_FACE, + + RS_DIMENSION_ARRAY_0 = 100, + RS_DIMENSION_ARRAY_1, + RS_DIMENSION_ARRAY_2, + RS_DIMENSION_ARRAY_3, + RS_DIMENSION_MAX = RS_DIMENSION_ARRAY_3 +}; + +enum RsDepthFunc { + RS_DEPTH_FUNC_ALWAYS, + RS_DEPTH_FUNC_LESS, + RS_DEPTH_FUNC_LEQUAL, + RS_DEPTH_FUNC_GREATER, + RS_DEPTH_FUNC_GEQUAL, + RS_DEPTH_FUNC_EQUAL, + RS_DEPTH_FUNC_NOTEQUAL +}; + +enum RsBlendSrcFunc { + RS_BLEND_SRC_ZERO, + RS_BLEND_SRC_ONE, + RS_BLEND_SRC_DST_COLOR, + RS_BLEND_SRC_ONE_MINUS_DST_COLOR, + RS_BLEND_SRC_SRC_ALPHA, + RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, + RS_BLEND_SRC_DST_ALPHA, + RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, + RS_BLEND_SRC_SRC_ALPHA_SATURATE +}; + +enum RsBlendDstFunc { + RS_BLEND_DST_ZERO, + RS_BLEND_DST_ONE, + RS_BLEND_DST_SRC_COLOR, + RS_BLEND_DST_ONE_MINUS_SRC_COLOR, + RS_BLEND_DST_SRC_ALPHA, + RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, + RS_BLEND_DST_DST_ALPHA, + RS_BLEND_DST_ONE_MINUS_DST_ALPHA +}; + +enum RsTexEnvMode { + RS_TEX_ENV_MODE_REPLACE, + RS_TEX_ENV_MODE_MODULATE, + RS_TEX_ENV_MODE_DECAL +}; + +enum RsPrimitive { + RS_PRIMITIVE_POINT, + RS_PRIMITIVE_LINE, + RS_PRIMITIVE_LINE_STRIP, + RS_PRIMITIVE_TRIANGLE, + RS_PRIMITIVE_TRIANGLE_STRIP, + RS_PRIMITIVE_TRIANGLE_FAN +}; + + +#include "rsgApiFuncDecl.h" + +#ifdef __cplusplus +}; +#endif + +#endif // RENDER_SCRIPT_H + + + diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/RenderScriptEnv.h new file mode 100644 index 0000000..0789301 --- /dev/null +++ b/libs/rs/RenderScriptEnv.h @@ -0,0 +1,40 @@ +#include <stdint.h> + + +typedef void * RsAdapter1D; +typedef void * RsAdapter2D; +typedef void * RsAllocation; +typedef void * RsContext; +typedef void * RsDevice; +typedef void * RsElement; +typedef void * RsSampler; +typedef void * RsScript; +typedef void * RsScriptBasicTemp; +typedef void * RsTriangleMesh; +typedef void * RsType; +typedef void * RsProgramFragment; +typedef void * RsProgramFragmentStore; +typedef void * RsLight; + + +typedef struct { + float m[16]; +} rsc_Matrix; + + +typedef struct { + float v[4]; +} rsc_Vector4; + +#define RS_PROGRAM_VERTEX_MODELVIEW_OFFSET 0 +#define RS_PROGRAM_VERTEX_PROJECTION_OFFSET 16 +#define RS_PROGRAM_VERTEX_TEXTURE_OFFSET 32 + +//typedef int (*rsc_RunScript)(uint32_t launchIndex, const rsc_FunctionTable *); + + +/* EnableCap */ +#define GL_LIGHTING 0x0B50 + +/* LightName */ +#define GL_LIGHT0 0x4000 diff --git a/libs/rs/java/Android.mk b/libs/rs/java/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/libs/rs/java/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/libs/rs/java/Film/Android.mk b/libs/rs/java/Film/Android.mk new file mode 100644 index 0000000..b7f98fc --- /dev/null +++ b/libs/rs/java/Film/Android.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2008 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 := Film + +include $(BUILD_PACKAGE) diff --git a/libs/rs/java/Film/AndroidManifest.xml b/libs/rs/java/Film/AndroidManifest.xml new file mode 100644 index 0000000..a5ce8a1 --- /dev/null +++ b/libs/rs/java/Film/AndroidManifest.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.film"> + <application android:label="Film"> + <activity android:name="Film" + android:screenOrientation="portrait" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <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/Film/res/raw/filmimage.c b/libs/rs/java/Film/res/raw/filmimage.c new file mode 100644 index 0000000..3bd9496 --- /dev/null +++ b/libs/rs/java/Film/res/raw/filmimage.c @@ -0,0 +1,110 @@ +// Fountain test script + +#pragma version(1) +#pragma stateVertex(orthoWindow) +#pragma stateRaster(flat) +#pragma stateFragment(PgmFragBackground) +#pragma stateFragmentStore(MyBlend) + + +int main(void* con, int ft, int launchID) { + int count, touch, x, y, rate, maxLife, lifeShift; + int life; + int ct, ct2; + int newPart; + int drawCount; + int dx, dy, idx; + int posx,posy; + int c; + int srcIdx; + int dstIdx; + + count = loadI32(con, 0, 1); + touch = loadI32(con, 0, 2); + x = loadI32(con, 0, 3); + y = loadI32(con, 0, 4); + + rate = 4; + maxLife = (count / rate) - 1; + lifeShift = 0; + { + life = maxLife; + while (life > 255) { + life = life >> 1; + lifeShift ++; + } + } + + drawRect(con, 0, 256, 0, 512); + contextBindProgramFragment(con, NAMED_PgmFragParts); + + if (touch) { + newPart = loadI32(con, 2, 0); + for (ct2=0; ct2<rate; ct2++) { + dx = scriptRand(con, 0x10000) - 0x8000; + dy = scriptRand(con, 0x10000) - 0x8000; + + idx = newPart * 5 + 1; + storeI32(con, 2, idx, dx); + storeI32(con, 2, idx + 1, dy); + storeI32(con, 2, idx + 2, maxLife); + storeI32(con, 2, idx + 3, x << 16); + storeI32(con, 2, idx + 4, y << 16); + + newPart++; + if (newPart >= count) { + newPart = 0; + } + } + storeI32(con, 2, 0, newPart); + } + + drawCount = 0; + for (ct=0; ct < count; ct++) { + srcIdx = ct * 5 + 1; + + dx = loadI32(con, 2, srcIdx); + dy = loadI32(con, 2, srcIdx + 1); + life = loadI32(con, 2, srcIdx + 2); + posx = loadI32(con, 2, srcIdx + 3); + posy = loadI32(con, 2, srcIdx + 4); + + if (life) { + if (posy < (480 << 16)) { + dstIdx = drawCount * 9; + c = 0xffafcf | ((life >> lifeShift) << 24); + + storeU32(con, 1, dstIdx, c); + storeI32(con, 1, dstIdx + 1, posx); + storeI32(con, 1, dstIdx + 2, posy); + + storeU32(con, 1, dstIdx + 3, c); + storeI32(con, 1, dstIdx + 4, posx + 0x10000); + storeI32(con, 1, dstIdx + 5, posy + dy * 4); + + storeU32(con, 1, dstIdx + 6, c); + storeI32(con, 1, dstIdx + 7, posx - 0x10000); + storeI32(con, 1, dstIdx + 8, posy + dy * 4); + drawCount ++; + } else { + if (dy > 0) { + dy = (-dy) >> 1; + } + } + + posx = posx + dx; + posy = posy + dy; + dy = dy + 0x400; + life --; + + //storeI32(con, 2, srcIdx, dx); + storeI32(con, 2, srcIdx + 1, dy); + storeI32(con, 2, srcIdx + 2, life); + storeI32(con, 2, srcIdx + 3, posx); + storeI32(con, 2, srcIdx + 4, posy); + } + } + + drawTriangleArray(con, NAMED_PartBuffer, drawCount); + return 1; +} diff --git a/libs/rs/java/Film/res/raw/filmstrip.c b/libs/rs/java/Film/res/raw/filmstrip.c new file mode 100644 index 0000000..6885251 --- /dev/null +++ b/libs/rs/java/Film/res/raw/filmstrip.c @@ -0,0 +1,114 @@ +// Fountain test script + +#pragma version(1) +#pragma stateVertex(PVBackground) +#pragma stateFragment(PFBackground) +#pragma stateFragmentStore(PFSBackground) + +/* +typedef struct FilmScriptUserEnvRec { + RsAllocation tex[13]; + int32_t triangleOffsets[64]; + float triangleOffsetsTex[64]; + int32_t triangleOffsetsCount; +} FilmScriptUserEnv; +*/ + +// The script enviroment has 3 env allocations. +// bank0: (r) The enviroment structure +// bank1: (r) The position information +// bank2: (rw) The temporary texture state + +int main(int index) +{ + int f1,f2,f3,f4, f5,f6,f7,f8, f9,f10,f11,f12, f13,f14,f15,f16; + int g1,g2,g3,g4, g5,g6,g7,g8, g9,g10,g11,g12, g13,g14,g15,g16; + float trans; + float rot; + int x; + float focusPos; // float + int focusID; + int lastFocusID; + int imgCount; + + trans = loadF(1, 0); + rot = loadF(1, 1); + + matrixLoadScale(&f16, 2.f, 2.f, 2.f); + matrixTranslate(&f16, 0.f, 0.f, trans); + matrixRotate(&f16, 90.f, 0.f, 0.f, 1.f); + matrixRotate(&f16, rot, 1.f, 0.f, 0.f); + storeMatrix(3, 0, &f16); + + //materialDiffuse(con, 0.0f, 0.0f, 0.0f, 1.0f); + //materialSpecular(con, 0.5f, 0.5f, 0.5f, 0.5f); + //materialShininess(intToFloat(20)); + drawTriangleMesh(NAMED_mesh); + + + + //int imgId = 0; + + bindProgramFragmentStore(NAMED_PFImages); + bindProgramFragment(NAMED_PFSImages); + bindProgramVertex(NAMED_PVImages); + + //focusPos = loadF(1, 2); + //focusID = 0; + //lastFocusID = loadI32(2, 0); + //imgCount = 13; + + /* + disable(GL_LIGHTING); + + + if (trans > (-.3)) { + focusID = -1.0 - focusPos; + if (focusID >= imgCount) { + focusID = -1; + } + } else { + focusID = -1; + } + + if (focusID != lastFocusID) { + if (lastFocusID >= 0) { + uploadToTexture(con, env->tex[lastFocusID], 1); + } + if (focusID >= 0) { + uploadToTexture(con, env->tex[focusID], 0); + } + } + storeEnvI32(con, 2, 0, focusID); + + + for (imgId=1; imgId <= imgCount; imgId++) { + float pos = focusPos + imgId + .4f; + int offset = (int)floor(pos*2); + pos -= 0.75; + + offset += env->triangleOffsetsCount / 2; + + if ((offset < 0) || (offset >= env->triangleOffsetsCount)) { + continue; + } + + int start = offset -2; + int end = offset + 2; + + if (start < 0) { + start = 0; + } + if (end > env->triangleOffsetsCount) { + end = env->triangleOffsetsCount; + } + + programFragmentBindTexture(con, env->fpImages, 0, env->tex[imgId - 1]); + matrixLoadTranslate(con, &m, -pos - env->triangleOffsetsTex[env->triangleOffsetsCount / 2], 0, 0); + storeEnvMatrix(con, 3, RS_PROGRAM_VERTEX_TEXTURE_OFFSET, &m); + renderTriangleMeshRange(con, env->mesh, env->triangleOffsets[start], env->triangleOffsets[end] - env->triangleOffsets[start]); + } +*/ + return 0; +} + diff --git a/libs/rs/java/Film/src/com/android/film/Film.java b/libs/rs/java/Film/src/com/android/film/Film.java new file mode 100644 index 0000000..6e99816 --- /dev/null +++ b/libs/rs/java/Film/src/com/android/film/Film.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008 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.film; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class Film extends Activity { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + private FilmView mView; + + // get the current looper (from your Activity UI thread for instance + + + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new FilmView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + + Runtime.getRuntime().exit(0); + } + + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} + diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java new file mode 100644 index 0000000..fca0818 --- /dev/null +++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2008 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.film; + +import java.io.Writer; + +import android.renderscript.RenderScript; +import android.renderscript.ProgramVertexAlloc; +import android.renderscript.Matrix; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class FilmRS { + + public FilmRS() { + } + + public void init(RenderScript rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + initRS(); + } + + public void setFilmStripPosition(int x, int y) + { + if (x < 50) { + x = 50; + } + if (x > 270) { + x = 270; + } + + float anim = ((float)x-50) / 270.f; + mBufferPos[0] = 2f * anim + 0.5f; // translation + mBufferPos[1] = (anim * 40); // rotation + mBufferPos[2] = ((float)y) / 16.f - 8; // focusPos + mAllocPos.data(mBufferPos); + } + + + private Resources mRes; + private RenderScript mRS; + private RenderScript.Script mScriptStrip; + private RenderScript.Script mScriptImage; + private RenderScript.Element mElementVertex; + private RenderScript.Element mElementIndex; + private RenderScript.Sampler mSampler; + private RenderScript.ProgramFragmentStore mPFSBackground; + private RenderScript.ProgramFragmentStore mPFSImages; + private RenderScript.ProgramFragment mPFBackground; + private RenderScript.ProgramFragment mPFImages; + private RenderScript.ProgramVertex mPVBackground; + private RenderScript.ProgramVertex mPVImages; + private ProgramVertexAlloc mPVA; + + private RenderScript.Allocation mAllocEnv; + private RenderScript.Allocation mAllocPos; + private RenderScript.Allocation mAllocState; + private RenderScript.Allocation mAllocPV; + private RenderScript.TriangleMesh mMesh; + private RenderScript.Light mLight; + + private float[] mBufferPos; + private float[] mBufferPV; + + private void initSamplers() { + mRS.samplerBegin(); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, + RenderScript.SamplerValue.LINEAR_MIP_LINEAR); + mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_S, + RenderScript.SamplerValue.CLAMP); + mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_T, + RenderScript.SamplerValue.CLAMP); + mSampler = mRS.samplerCreate(); + } + + private void initPFS() { + mRS.programFragmentStoreBegin(null, null); + mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.LESS); + mRS.programFragmentStoreDitherEnable(true); + mPFSBackground = mRS.programFragmentStoreCreate(); + mPFSBackground.setName("PFSBackground"); + + mRS.programFragmentStoreBegin(null, null); + mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.EQUAL); + mRS.programFragmentStoreDitherEnable(false); + mRS.programFragmentStoreDepthMask(false); + mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE, + RenderScript.BlendDstFunc.ONE); + mPFSImages = mRS.programFragmentStoreCreate(); + mPFSImages.setName("PFSImages"); + } + + private void initPF() { + mRS.programFragmentBegin(null, null); + mPFBackground = mRS.programFragmentCreate(); + mPFBackground.setName("PFBackground"); + + mRS.programFragmentBegin(null, null); + mRS.programFragmentSetTexEnable(0, true); + //mRS.programFragmentSetEnvMode(0, RS_TEX_ENV_MODE_REPLACE); + //rsProgramFragmentSetType(0, gEnv.tex[0]->getType()); + mPFImages = mRS.programFragmentCreate(); + mPFImages.setName("PFImages"); + } + + private void initPV() { + mRS.lightBegin(); + mLight = mRS.lightCreate(); + mLight.setPosition(0, -0.5f, -1.0f); + + mRS.programVertexBegin(null, null); + mRS.programVertexSetTextureMatrixEnable(true); + mRS.programVertexAddLight(mLight); + mPVBackground = mRS.programVertexCreate(); + mPVBackground.setName("PVBackground"); + + mRS.programVertexBegin(null, null); + mPVImages = mRS.programVertexCreate(); + mPVImages.setName("PVImages"); + } + + + int mParams[] = new int[10]; + + private void initRS() { + mElementVertex = mRS.elementGetPredefined( + RenderScript.ElementPredefined.NORM_ST_XYZ_F32); + mElementIndex = mRS.elementGetPredefined( + RenderScript.ElementPredefined.INDEX_16); + + mRS.triangleMeshBegin(mElementVertex, mElementIndex); + FilmStripMesh fsm = new FilmStripMesh(); + fsm.init(mRS); + mMesh = mRS.triangleMeshCreate(); + mMesh.setName("mesh"); + + initPFS(); + initSamplers(); + initPF(); + initPV(); + mPFImages.bindSampler(mSampler, 0); + + Log.e("rs", "Done loading named"); + + mRS.scriptCBegin(); + mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f); + mRS.scriptCSetScript(mRes, R.raw.filmstrip); + mRS.scriptCSetRoot(true); + mScriptStrip = mRS.scriptCCreate(); + + mBufferPos = new float[3]; + mAllocPos = mRS.allocationCreatePredefSized( + RenderScript.ElementPredefined.USER_FLOAT, + mBufferPos.length); + + mPVA = new ProgramVertexAlloc(mRS); + mPVBackground.bindAllocation(0, mPVA.mAlloc); + mPVImages.bindAllocation(0, mPVA.mAlloc); + mPVA.setupProjectionNormalized(320, 480); + + + mScriptStrip.bindAllocation(mAllocPos, 1); + //mScriptStrip.bindAllocation(gStateAlloc, 2); + mScriptStrip.bindAllocation(mPVA.mAlloc, 3); + + +/* + { + Resources res = getResources(); + Drawable d = res.getDrawable(R.drawable.gadgets_clock_mp3); + BitmapDrawable bd = (BitmapDrawable)d; + Bitmap b = bd.getBitmap(); + mTexture = mRS.allocationCreateFromBitmap(b, + RenderScript.ElementPredefined.RGB_565, + true); + mTexture.uploadToTexture(0); + } + + mRS.programFragmentStoreBegin(null, null); + mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.SRC_ALPHA, RenderScript.BlendDstFunc.ONE); + mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS); + mPFS = mRS.programFragmentStoreCreate(); + mPFS.setName("MyBlend"); + mRS.contextBindProgramFragmentStore(mPFS); + */ + + setFilmStripPosition(0, 0); + + mRS.contextBindRootScript(mScriptStrip); + } +} + + + diff --git a/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java b/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java new file mode 100644 index 0000000..02bffd8 --- /dev/null +++ b/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java @@ -0,0 +1,255 @@ +/* + * 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.film; + +import java.io.Writer; +import java.lang.Math; +import android.util.Log; + +import android.renderscript.RenderScript; + + +class FilmStripMesh { + + class Vertex { + float nx; + float ny; + float nz; + float s; + float t; + float x; + float y; + float z; + + Vertex() { + nx = 0; + ny = 0; + nz = 0; + s = 0; + t = 0; + x = 0; + y = 0; + z = 0; + } + + void xyz(float _x, float _y, float _z) { + x = _x; + y = _y; + z = _z; + } + + void nxyz(float _x, float _y, float _z) { + nx = _x; + ny = _y; + nz = _z; + } + + void st(float _s, float _t) { + s = _s; + t = _t; + } + + void computeNorm(Vertex v1, Vertex v2) { + float dx = v1.x - v2.x; + float dy = v1.y - v2.y; + float dz = v1.z - v2.z; + float len = (float)java.lang.Math.sqrt(dx*dx + dy*dy + dz*dz); + dx /= len; + dy /= len; + dz /= len; + + nx = dx * dz; + ny = dy * dz; + nz = (float)java.lang.Math.sqrt(dx*dx + dy*dy); + + len = (float)java.lang.Math.sqrt(nx*nx + ny*ny + nz*nz); + nx /= len; + ny /= len; + nz /= len; + } + + void addToRS(RenderScript rs) { + rs.triangleMeshAddVertex_XYZ_ST_NORM(x, y, z, s, t, nx, ny, nz); + } + } + + int[] mTriangleOffsets; + float[] mTriangleOffsetsTex; + int mTriangleOffsetsCount; + + void init(RenderScript rs) + { + float vtx[] = new float[] { + 60.431003f, 124.482050f, + 60.862074f, 120.872604f, + 61.705303f, 117.336662f, + 62.949505f, 113.921127f, + 64.578177f, 110.671304f, + 66.569716f, 107.630302f, + 68.897703f, 104.838457f, + 71.531259f, 102.332803f, + 74.435452f, 100.146577f, + 77.571757f, 98.308777f, + 80.898574f, 96.843781f, + 84.371773f, 95.771023f, + 87.945283f, 95.104731f, + 98.958994f, 95.267098f, + 109.489523f, 98.497596f, + 118.699582f, 104.539366f, + 125.856872f, 112.912022f, + 130.392311f, 122.949849f, + 131.945283f, 133.854731f, + 130.392311f, 144.759613f, + 125.856872f, 154.797439f, + 118.699582f, 163.170096f, + 109.489523f, 169.211866f, + 98.958994f, 172.442364f, + 87.945283f, 172.604731f, + 72.507313f, 172.672927f, + 57.678920f, 168.377071f, + 44.668135f, 160.067134f, + 34.534908f, 148.420104f, + 28.104767f, 134.384831f, + 25.901557f, 119.104731f, + 28.104767f, 103.824631f, + 34.534908f, 89.789358f, + 44.668135f, 78.142327f, + 57.678920f, 69.832390f, + 72.507313f, 65.536534f, + 87.945283f, 65.604731f, + 106.918117f, 65.688542f, + 125.141795f, 60.409056f, + 141.131686f, 50.196376f, + 153.585137f, 35.882502f, + 161.487600f, 18.633545f, + 164.195283f, -0.145269f, + 161.487600f, -18.924084f, + 153.585137f, -36.173040f, + 141.131686f, -50.486914f, + 125.141795f, -60.699594f, + 106.918117f, -65.979081f, + 87.945283f, -65.895269f, + 80f, -65.895269f, + 60f, -65.895269f, + 40f, -65.895269f, + 20f, -65.895269f, + 0f, -65.895269f, + -20f, -65.895269f, + -40f, -65.895269f, + -60f, -65.895269f, + -80f, -65.895269f, + -87.945283f, -65.895269f, + -106.918117f, -65.979081f, + -125.141795f, -60.699594f, + -141.131686f, -50.486914f, + -153.585137f, -36.173040f, + -161.487600f, -18.924084f, + -164.195283f, -0.145269f, + -161.487600f, 18.633545f, + -153.585137f, 35.882502f, + -141.131686f, 50.196376f, + -125.141795f, 60.409056f, + -106.918117f, 65.688542f, + -87.945283f, 65.604731f, + -72.507313f, 65.536534f, + -57.678920f, 69.832390f, + -44.668135f, 78.142327f, + -34.534908f, 89.789358f, + -28.104767f, 103.824631f, + -25.901557f, 119.104731f, + -28.104767f, 134.384831f, + -34.534908f, 148.420104f, + -44.668135f, 160.067134f, + -57.678920f, 168.377071f, + -72.507313f, 172.672927f, + -87.945283f, 172.604731f, + -98.958994f, 172.442364f, + -109.489523f, 169.211866f, + -118.699582f, 163.170096f, + -125.856872f, 154.797439f, + -130.392311f, 144.759613f, + -131.945283f, 133.854731f, + -130.392311f, 122.949849f, + -125.856872f, 112.912022f, + -118.699582f, 104.539366f, + -109.489523f, 98.497596f, + -98.958994f, 95.267098f, + -87.945283f, 95.104731f, + -84.371773f, 95.771023f, + -80.898574f, 96.843781f, + -77.571757f, 98.308777f, + -74.435452f, 100.146577f, + -71.531259f, 102.332803f, + -68.897703f, 104.838457f, + -66.569716f, 107.630302f, + -64.578177f, 110.671304f, + -62.949505f, 113.921127f, + -61.705303f, 117.336662f, + -60.862074f, 120.872604f, + -60.431003f, 124.482050f + }; + + + mTriangleOffsets = new int[64]; + mTriangleOffsetsTex = new float[64]; + + mTriangleOffsets[0] = 0; + mTriangleOffsetsCount = 1; + + Vertex t = new Vertex(); + t.nxyz(1, 0, 0); + int count = vtx.length / 2; + + float runningS = 0; + for (int ct=0; ct < (count-1); ct++) { + t.x = -vtx[ct*2] / 100.f; + t.z = vtx[ct*2+1] / 100.f; + t.s = runningS; + t.nx = (vtx[ct*2+3] - vtx[ct*2 +1]); + t.ny = (vtx[ct*2+2] - vtx[ct*2 ]); + float len = (float)java.lang.Math.sqrt(t.nx * t.nx + t.ny * t.ny); + runningS += len / 100; + t.nx /= len; + t.ny /= len; + t.y = -0.5f; + t.t = 0; + //Log.e("xx", "vtx " + t.x + " " + t.y + " " + t.z); + t.addToRS(rs); + t.y = .5f; + t.t = 1; + t.addToRS(rs); + + //LOGE(" %f", runningS); + if((runningS*2) > mTriangleOffsetsCount) { + //LOGE("**** img %i %i", gTriangleOffsetsCount, ct*2); + mTriangleOffsets[mTriangleOffsetsCount] = ct*2; + mTriangleOffsetsTex[mTriangleOffsetsCount] = t.s; + mTriangleOffsetsCount ++; + } + } + + count = (count * 2 - 2); + for (int ct=0; ct < (count-2); ct+= 2) { + rs.triangleMeshAddTriangle(ct, ct+1, ct+2); + rs.triangleMeshAddTriangle(ct+1, ct+3, ct+2); + } + } + + +} + diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java new file mode 100644 index 0000000..a743b1b --- /dev/null +++ b/libs/rs/java/Film/src/com/android/film/FilmView.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008 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.film; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class FilmView extends RSSurfaceView { + + public FilmView(Context context) { + super(context); + + //setFocusable(true); + } + + private RenderScript mRS; + private FilmRS mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + + mRS = createRenderScript(); + mRender = new FilmRS(); + mRender.init(mRS, getResources(), w, h); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = true; + int act = ev.getAction(); + if (act == ev.ACTION_UP) { + ret = false; + } + mRender.setFilmStripPosition((int)ev.getX(), (int)ev.getY()); + return ret; + } +} + + diff --git a/libs/rs/java/Fountain/Android.mk b/libs/rs/java/Fountain/Android.mk new file mode 100644 index 0000000..b6a9f10 --- /dev/null +++ b/libs/rs/java/Fountain/Android.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2008 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 := Fountain + +include $(BUILD_PACKAGE) diff --git a/libs/rs/java/Fountain/AndroidManifest.xml b/libs/rs/java/Fountain/AndroidManifest.xml new file mode 100644 index 0000000..dd0e428 --- /dev/null +++ b/libs/rs/java/Fountain/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.fountain"> + <application android:label="Fountain"> + <activity android:name="Fountain" + android:theme="@android:style/Theme.Translucent"> + <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/Fountain/res/drawable/gadgets_clock_mp3.png b/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png Binary files differnew file mode 100755 index 0000000..e91bfb4 --- /dev/null +++ b/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c new file mode 100644 index 0000000..99551fc --- /dev/null +++ b/libs/rs/java/Fountain/res/raw/fountain.c @@ -0,0 +1,106 @@ +// Fountain test script + +#pragma version(1) +#pragma stateVertex(default) +#pragma stateFragment(PgmFragParts) +#pragma stateFragmentStore(PFSBlend) + + +int main(int launchID) { + int count, touch, x, y, rate, maxLife, lifeShift; + int life; + int ct, ct2; + int newPart; + int drawCount; + int dx, dy, idx; + int posx,posy; + int c; + int srcIdx; + int dstIdx; + + count = loadI32(0, 1); + touch = loadI32(0, 2); + x = loadI32(0, 3); + y = loadI32(0, 4); + + rate = 4; + maxLife = (count / rate) - 1; + lifeShift = 0; + { + life = maxLife; + while (life > 255) { + life = life >> 1; + lifeShift ++; + } + } + + if (touch) { + newPart = loadI32(2, 0); + for (ct2=0; ct2<rate; ct2++) { + dx = (int)((randf(1.f) - 0.5f) * 0x10000); + dy = (int)((randf(1.f) - 0.5f) * 0x10000); + + idx = newPart * 5 + 1; + storeI32(2, idx, dx); + storeI32(2, idx + 1, dy); + storeI32(2, idx + 2, maxLife); + storeI32(2, idx + 3, x << 16); + storeI32(2, idx + 4, y << 16); + + newPart++; + if (newPart >= count) { + newPart = 0; + } + } + storeI32(2, 0, newPart); + } + + drawCount = 0; + for (ct=0; ct < count; ct++) { + srcIdx = ct * 5 + 1; + + dx = loadI32(2, srcIdx); + dy = loadI32(2, srcIdx + 1); + life = loadI32(2, srcIdx + 2); + posx = loadI32(2, srcIdx + 3); + posy = loadI32(2, srcIdx + 4); + + if (life) { + if (posy < (480 << 16)) { + dstIdx = drawCount * 9; + c = 0xffafcf | ((life >> lifeShift) << 24); + + storeI32(1, dstIdx, c); + storeI32(1, dstIdx + 1, posx); + storeI32(1, dstIdx + 2, posy); + + storeI32(1, dstIdx + 3, c); + storeI32(1, dstIdx + 4, posx + 0x10000); + storeI32(1, dstIdx + 5, posy + dy * 4); + + storeI32(1, dstIdx + 6, c); + storeI32(1, dstIdx + 7, posx - 0x10000); + storeI32(1, dstIdx + 8, posy + dy * 4); + drawCount ++; + } else { + if (dy > 0) { + dy = (-dy) >> 1; + } + } + + posx = posx + dx; + posy = posy + dy; + dy = dy + 0x400; + life --; + + //storeI32(2, srcIdx, dx); + storeI32(2, srcIdx + 1, dy); + storeI32(2, srcIdx + 2, life); + storeI32(2, srcIdx + 3, posx); + storeI32(2, srcIdx + 4, posy); + } + } + + drawTriangleArray(NAMED_PartBuffer, drawCount); + return 1; +} diff --git a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java new file mode 100644 index 0000000..58c78fa --- /dev/null +++ b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008 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.fountain; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class Fountain extends Activity { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + private FountainView mView; + + // get the current looper (from your Activity UI thread for instance + + + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new FountainView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + + Runtime.getRuntime().exit(0); + } + + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} + diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java new file mode 100644 index 0000000..c8e9a1e --- /dev/null +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008 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.fountain; + +import java.io.Writer; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.renderscript.RenderScript; +import android.renderscript.ProgramVertexAlloc; +import android.util.Log; + +public class FountainRS { + + public FountainRS() { + } + + public void init(RenderScript rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + initRS(); + } + + public void newTouchPosition(int x, int y) { + mParams[0] = 1; + mParams[1] = x; + mParams[2] = y; + mIntAlloc.subData1D(2, 3, mParams); + } + + + ///////////////////////////////////////// + + private Resources mRes; + + private RenderScript mRS; + private RenderScript.Allocation mIntAlloc; + private RenderScript.Allocation mPartAlloc; + private RenderScript.Allocation mVertAlloc; + private RenderScript.Script mScript; + private RenderScript.ProgramFragmentStore mPFS; + private RenderScript.ProgramFragment mPF; + + private Bitmap mBackground; + + int mParams[] = new int[10]; + + private void initRS() { + int partCount = 1024; + + mIntAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, 10); + mPartAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, partCount * 3 * 3); + mPartAlloc.setName("PartBuffer"); + mVertAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, partCount * 5 + 1); + + mRS.programFragmentStoreBegin(null, null); + mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.SRC_ALPHA, RenderScript.BlendDstFunc.ONE); + mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS); + mRS.programFragmentStoreDepthMask(false); + mRS.programFragmentStoreDitherEnable(false); + mPFS = mRS.programFragmentStoreCreate(); + mPFS.setName("PFSBlend"); + + mRS.programFragmentBegin(null, null); + mPF = mRS.programFragmentCreate(); + mPF.setName("PgmFragParts"); + + mParams[0] = 0; + mParams[1] = partCount; + mParams[2] = 0; + mParams[3] = 0; + mParams[4] = 0; + mIntAlloc.data(mParams); + + int t2[] = new int[partCount * 4*3]; + for (int ct=0; ct < t2.length; ct++) { + t2[ct] = 0; + } + mPartAlloc.data(t2); + + mRS.scriptCBegin(); + mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f); + mRS.scriptCSetScript(mRes, R.raw.fountain); + mRS.scriptCSetRoot(true); + mScript = mRS.scriptCCreate(); + + mScript.bindAllocation(mIntAlloc, 0); + mScript.bindAllocation(mPartAlloc, 1); + mScript.bindAllocation(mVertAlloc, 2); + mRS.contextBindRootScript(mScript); + } + +} + + diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java new file mode 100644 index 0000000..be8b24e --- /dev/null +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008 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.fountain; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class FountainView extends RSSurfaceView { + + public FountainView(Context context) { + super(context); + + //setFocusable(true); + } + + private RenderScript mRS; + private FountainRS mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + + mRS = createRenderScript(); + mRender = new FountainRS(); + mRender.init(mRS, getResources(), w, h); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = true; + int act = ev.getAction(); + if (act == ev.ACTION_UP) { + ret = false; + } + mRender.newTouchPosition((int)ev.getX(), (int)ev.getY()); + return ret; + } +} + + diff --git a/libs/rs/java/Rollo/Android.mk b/libs/rs/java/Rollo/Android.mk new file mode 100644 index 0000000..5a4957c --- /dev/null +++ b/libs/rs/java/Rollo/Android.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2008 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 := Rollo + +include $(BUILD_PACKAGE) diff --git a/libs/rs/java/Rollo/AndroidManifest.xml b/libs/rs/java/Rollo/AndroidManifest.xml new file mode 100644 index 0000000..127a140 --- /dev/null +++ b/libs/rs/java/Rollo/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.rollo"> + <application android:label="Rollo"> + <activity android:name="Rollo" + android:theme="@android:style/Theme.Translucent"> + <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/Rollo/res/raw/browser.png b/libs/rs/java/Rollo/res/raw/browser.png Binary files differnew file mode 100644 index 0000000..513f0be --- /dev/null +++ b/libs/rs/java/Rollo/res/raw/browser.png diff --git a/libs/rs/java/Rollo/res/raw/market.png b/libs/rs/java/Rollo/res/raw/market.png Binary files differnew file mode 100644 index 0000000..83b6910 --- /dev/null +++ b/libs/rs/java/Rollo/res/raw/market.png diff --git a/libs/rs/java/Rollo/res/raw/photos.png b/libs/rs/java/Rollo/res/raw/photos.png Binary files differnew file mode 100644 index 0000000..1ed8f1e --- /dev/null +++ b/libs/rs/java/Rollo/res/raw/photos.png diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c new file mode 100644 index 0000000..d338d0d --- /dev/null +++ b/libs/rs/java/Rollo/res/raw/rollo.c @@ -0,0 +1,105 @@ +#pragma version(1) +#pragma stateVertex(PV) +#pragma stateFragment(PF) +#pragma stateFragmentStore(PFS) + +// Scratch buffer layout +#define SCRATCH_FADE 0 +#define SCRATCH_ZOOM 1 +#define SCRATCH_ROT 2 + +//#define STATE_POS_X 0 +#define STATE_DONE 1 +//#define STATE_PRESSURE 2 +#define STATE_ZOOM 3 +//#define STATE_WARP 4 +#define STATE_ORIENTATION 5 +#define STATE_SELECTION 6 +#define STATE_FIRST_VISIBLE 7 +#define STATE_COUNT 8 +#define STATE_TOUCH 9 + +float filter(float val, float target, float str) +{ + float delta = (target - val); + return val + delta * str; +} + +int main(void* con, int ft, int launchID) +{ + int rowCount; + int row; + int col; + int imageID; + int done = loadI32(0, STATE_DONE); + int selectedID = loadI32(0, STATE_SELECTION); + + float f = loadF(2, 0); + + pfClearColor(0.0f, 0.0f, 0.0f, f); + if (done) { + if (f > 0.02f) { + //f = f - 0.02f; + //storeF(2, 0, f); + } + } else { + if (f < 0.8f) { + f = f + 0.02f; + storeF(2, 0, f); + } + } + + float touchCut = 1.f; + if (loadI32(0, STATE_TOUCH)) { + touchCut = 5.f; + } + + + float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f; + float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut); + storeF(2, SCRATCH_ZOOM, zoom); + + float targetRot = loadI32(0, STATE_FIRST_VISIBLE) / 180.0f * 3.14f; + float rot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut); + storeF(2, SCRATCH_ROT, rot); + + float diam = 8.f;// + curve * 2.f; + float scale = 1.0f / zoom; + + rot = rot * scale; + float rotStep = 20.0f / 180.0f * 3.14f * scale; + rowCount = 4; + int index = 0; + int iconCount = loadI32(0, STATE_COUNT); + while (iconCount) { + float tmpSin = sinf(rot); + float tmpCos = cosf(rot); + + float tx1 = tmpSin * diam - (tmpCos * scale); + float tx2 = tx1 + (tmpCos * scale * 2.f); + float tz1 = tmpCos * diam + (tmpSin * scale); + float tz2 = tz1 - (tmpSin * scale * 2.f); + + int y; + for (y = rowCount -1; (y >= 0) && iconCount; y--) { + float ty1 = ((y * 3.0f) - 4.5f) * scale; + float ty2 = ty1 + scale * 2.f; + bindTexture(NAMED_PF, 0, loadI32(1, y)); + color(1.0f, 1.0f, 1.0f, 1.0f); + if (done && (index != selectedID)) { + color(0.4f, 0.4f, 0.4f, 1.0f); + } + drawQuad(tx1, ty1, tz1, + tx2, ty1, tz2, + tx2, ty2, tz2, + tx1, ty2, tz1); + iconCount--; + index++; + } + rot = rot + rotStep; + } + + return 0; +} + + diff --git a/libs/rs/java/Rollo/res/raw/rollo2.c b/libs/rs/java/Rollo/res/raw/rollo2.c new file mode 100644 index 0000000..b04ea73 --- /dev/null +++ b/libs/rs/java/Rollo/res/raw/rollo2.c @@ -0,0 +1,67 @@ +#pragma version(1) +#pragma stateVertex(PV) +#pragma stateFragment(PF) +#pragma stateFragmentStore(PFS) + +void drawLoop(int x, int y, int z, int rot) +{ + int ct; + int tx; + int ty; + int tmpSin; + int tmpCos; + int sz; + + for (ct = 0; ct < 10; ct ++) { + tmpSin = sinx((ct * 36 + rot) * 0x10000); + tmpCos = cosx((ct * 36 + rot) * 0x10000); + + ty = y + tmpCos * 4; + tx = x + tmpSin * 4; + pfBindTexture(NAMED_PF, 0, loadI32(1, ct & 3)); + + sz = 0xc000; + drawQuad(tx - sz, ty - sz, z, + tx + sz, ty - sz, z, + tx + sz, ty + sz, z, + tx - sz, ty + sz, z); + } +} + +int main(void* con, int ft, int launchID) +{ + int rowCount; + int x; + int y; + int row; + int col; + int imageID; + int tx1; + int ty1; + int tz1; + int tx2; + int ty2; + int tz2; + int tmpSin; + int tmpCos; + int iconCount; + int pressure; + + int ringCount; + + + + rotStep = 16 * 0x10000; + pressure = loadI32(0, 2); + rowCount = 4; + + iconCount = loadI32(0, 1); + rot = (-20 + loadI32(0, 0)) * 0x10000; + + for (ringCount = 0; ringCount < 5; ringCount++) { + drawLoop(0, 0, 0x90000 + (ringCount * 0x80000)); + } + + return 0; +} + diff --git a/libs/rs/java/Rollo/res/raw/settings.png b/libs/rs/java/Rollo/res/raw/settings.png Binary files differnew file mode 100644 index 0000000..dd2cd95 --- /dev/null +++ b/libs/rs/java/Rollo/res/raw/settings.png diff --git a/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java new file mode 100644 index 0000000..400d801 --- /dev/null +++ b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008 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.rollo; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class Rollo extends Activity { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + private RolloView mView; + + // get the current looper (from your Activity UI thread for instance + + + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new RolloView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + + Runtime.getRuntime().exit(0); + } + + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} + diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java new file mode 100644 index 0000000..d7252fb --- /dev/null +++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java @@ -0,0 +1,90 @@ + /* + * 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.rollo; + +import java.io.Writer; +import java.lang.Math; + +import android.renderscript.RenderScript; + + +class RolloMesh { + static public final float mCardHeight = 1.2f; + static public final float mCardWidth = 1.8f; + static public final float mTabHeight = 0.2f; + static public final float mTabs = 3; + static public final float mTabGap = 0.1f; + + static RenderScript.TriangleMesh createCard(RenderScript rs) { + RenderScript.Element vtx = rs.elementGetPredefined( + RenderScript.ElementPredefined.ST_XYZ_F32); + RenderScript.Element idx = rs.elementGetPredefined( + RenderScript.ElementPredefined.INDEX_16); + + float w = mCardWidth / 2; + float h = mCardHeight; + float z = 0; + + rs.triangleMeshBegin(vtx, idx); + rs.triangleMeshAddVertex_XYZ_ST(-w, 0, z, 0, 0); + rs.triangleMeshAddVertex_XYZ_ST(-w, h, z, 0, 1); + rs.triangleMeshAddVertex_XYZ_ST( w, h, z, 1, 1); + rs.triangleMeshAddVertex_XYZ_ST( w, 0, z, 1, 0); + rs.triangleMeshAddTriangle(0,1,2); + rs.triangleMeshAddTriangle(0,2,3); + return rs.triangleMeshCreate(); + } + + static RenderScript.TriangleMesh createTab(RenderScript rs) { + RenderScript.Element vtx = rs.elementGetPredefined( + RenderScript.ElementPredefined.ST_XYZ_F32); + RenderScript.Element idx = rs.elementGetPredefined( + RenderScript.ElementPredefined.INDEX_16); + + + float tabSlope = 0.1f; + float num = 0; + + float w = (mCardWidth - ((mTabs - 1) * mTabGap)) / mTabs; + float w1 = -(mCardWidth / 2) + ((w + mTabGap) * num); + float w2 = w1 + (w * tabSlope); + float w3 = w1 + w - (w * tabSlope); + float w4 = w1 + w; + float h1 = mCardHeight; + float h2 = h1 + mTabHeight; + float z = 0; + + float stScale = w / mTabHeight / 2; + float stScale2 = stScale * (tabSlope / w); + + + rs.triangleMeshBegin(vtx, idx); + rs.triangleMeshAddVertex_XYZ_ST(w1, h1, z, -stScale, 0); + rs.triangleMeshAddVertex_XYZ_ST(w2, h2, z, -stScale2, 1); + rs.triangleMeshAddVertex_XYZ_ST(w3, h2, z, stScale2, 1); + rs.triangleMeshAddVertex_XYZ_ST(w4, h1, z, stScale, 0); + rs.triangleMeshAddTriangle(0,1,2); + rs.triangleMeshAddTriangle(0,2,3); + return rs.triangleMeshCreate(); + } + + + +} + + diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java new file mode 100644 index 0000000..8f48335 --- /dev/null +++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2008 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.rollo; + +import java.io.Writer; + +import android.renderscript.RenderScript; +import android.renderscript.ProgramVertexAlloc; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RolloRS { + //public static final int STATE_SELECTED_ID = 0; + public static final int STATE_DONE = 1; + //public static final int STATE_PRESSURE = 2; + public static final int STATE_ZOOM = 3; + //public static final int STATE_WARP = 4; + public static final int STATE_ORIENTATION = 5; + public static final int STATE_SELECTION = 6; + public static final int STATE_FIRST_VISIBLE = 7; + public static final int STATE_COUNT = 8; + public static final int STATE_TOUCH = 9; + + + public RolloRS() { + } + + public void init(RenderScript rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + initNamed(); + initRS(); + } + + public void setPosition(float column) { + mAllocStateBuf[STATE_FIRST_VISIBLE] = (int)(column * (-20)); + mAllocState.data(mAllocStateBuf); + } + + public void setTouch(boolean touch) { + mAllocStateBuf[STATE_TOUCH] = touch ? 1 : 0; + mAllocState.data(mAllocStateBuf); + } + + public void setZoom(float z) { + //Log.e("rs", "zoom " + Float.toString(z)); + + mAllocStateBuf[STATE_ZOOM] = (int)(z * 1000.f); + mAllocState.data(mAllocStateBuf); + } + + public void setSelected(int index) { + Log.e("rs", "setSelected " + Integer.toString(index)); + + mAllocStateBuf[STATE_SELECTION] = index; + mAllocStateBuf[STATE_DONE] = 1; + mAllocState.data(mAllocStateBuf); + } + + + private Resources mRes; + private RenderScript mRS; + private RenderScript.Script mScript; + private RenderScript.Sampler mSampler; + private RenderScript.ProgramFragmentStore mPFSBackground; + private RenderScript.ProgramFragment mPFBackground; + private RenderScript.ProgramFragment mPFImages; + private RenderScript.ProgramVertex mPV; + private ProgramVertexAlloc mPVAlloc; + private RenderScript.Allocation[] mIcons; + private RenderScript.Allocation mIconPlate; + + private int[] mAllocStateBuf; + private RenderScript.Allocation mAllocState; + + private int[] mAllocIconIDBuf; + private RenderScript.Allocation mAllocIconID; + + private int[] mAllocScratchBuf; + private RenderScript.Allocation mAllocScratch; + + private void initNamed() { + mRS.samplerBegin(); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, + RenderScript.SamplerValue.LINEAR);//_MIP_LINEAR); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MAG, + RenderScript.SamplerValue.LINEAR); + mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_S, + RenderScript.SamplerValue.CLAMP); + mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_T, + RenderScript.SamplerValue.CLAMP); + mSampler = mRS.samplerCreate(); + + + mRS.programFragmentBegin(null, null); + mRS.programFragmentSetTexEnable(0, true); + mRS.programFragmentSetTexEnvMode(0, RenderScript.EnvMode.MODULATE); + mPFImages = mRS.programFragmentCreate(); + mPFImages.setName("PF"); + mPFImages.bindSampler(mSampler, 0); + + mRS.programFragmentStoreBegin(null, null); + mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.LESS); + mRS.programFragmentStoreDitherEnable(false); + mRS.programFragmentStoreDepthMask(false); + mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE, + RenderScript.BlendDstFunc.ONE); + mPFSBackground = mRS.programFragmentStoreCreate(); + mPFSBackground.setName("PFS"); + + mPVAlloc = new ProgramVertexAlloc(mRS); + mRS.programVertexBegin(null, null); + mRS.programVertexSetTextureMatrixEnable(true); + mPV = mRS.programVertexCreate(); + mPV.setName("PV"); + mPV.bindAllocation(0, mPVAlloc.mAlloc); + + + + mPVAlloc.setupProjectionNormalized(320, 480); + //mPVAlloc.setupOrthoNormalized(320, 480); + mRS.contextBindProgramVertex(mPV); + + mAllocScratchBuf = new int[32]; + for(int ct=0; ct < mAllocScratchBuf.length; ct++) { + mAllocScratchBuf[ct] = 0; + } + mAllocScratch = mRS.allocationCreatePredefSized( + RenderScript.ElementPredefined.USER_I32, mAllocScratchBuf.length); + mAllocScratch.data(mAllocScratchBuf); + + Log.e("rs", "Done loading named"); + + + + { + mIcons = new RenderScript.Allocation[4]; + mAllocIconIDBuf = new int[mIcons.length]; + mAllocIconID = mRS.allocationCreatePredefSized( + RenderScript.ElementPredefined.USER_I32, mAllocIconIDBuf.length); + + + Bitmap b; + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScaled = false; + + b = BitmapFactory.decodeResource(mRes, R.raw.browser, opts); + mIcons[0] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + + b = BitmapFactory.decodeResource(mRes, R.raw.market, opts); + mIcons[1] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + + b = BitmapFactory.decodeResource(mRes, R.raw.photos, opts); + mIcons[2] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + + b = BitmapFactory.decodeResource(mRes, R.raw.settings, opts); + mIcons[3] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + + for(int ct=0; ct < mIcons.length; ct++) { + mIcons[ct].uploadToTexture(0); + mAllocIconIDBuf[ct] = mIcons[ct].getID(); + } + mAllocIconID.data(mAllocIconIDBuf); + + RenderScript.Element e = mRS.elementGetPredefined(RenderScript.ElementPredefined.RGB_565); + mRS.typeBegin(e); + mRS.typeAdd(RenderScript.Dimension.X, 64); + mRS.typeAdd(RenderScript.Dimension.Y, 64); + RenderScript.Type t = mRS.typeCreate(); + mIconPlate = mRS.allocationCreateTyped(t); + //t.destroy(); + //e.destroy(); + + int tmp[] = new int[64 * 32]; + for(int ct = 0; ct < (64*32); ct++) { + tmp[ct] = 7 | (13 << 5) | (7 << 11); + tmp[ct] = tmp[ct] | (tmp[ct] << 16); + } + for(int ct = 0; ct < 32; ct++) { + tmp[ct] = 0; + tmp[ct + (63*32)] = 0; + } + for(int ct = 0; ct < 64; ct++) { + tmp[ct * 32] = 0; + tmp[ct * 32 + 31] = 0; + } + mIconPlate.data(tmp); + Log.e("xx", "plate"); + mIconPlate.uploadToTexture(0); + mIconPlate.setName("Plate"); + mPFImages.bindTexture(mIconPlate, 0); + } + + } + + + + private void initRS() { + mRS.scriptCBegin(); + mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 0.0f); + mRS.scriptCSetScript(mRes, R.raw.rollo); + //mRS.scriptCSetScript(mRes, R.raw.rollo2); + mRS.scriptCSetRoot(true); + //mRS.scriptCSetClearDepth(0); + mScript = mRS.scriptCCreate(); + + mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, 0, 0, 38, 0, 0}; + mAllocState = mRS.allocationCreatePredefSized( + RenderScript.ElementPredefined.USER_I32, mAllocStateBuf.length); + mScript.bindAllocation(mAllocState, 0); + mScript.bindAllocation(mAllocIconID, 1); + mScript.bindAllocation(mAllocScratch, 2); + setPosition(0); + setZoom(1); + + //RenderScript.File f = mRS.fileOpen("/sdcard/test.a3d"); + + mRS.contextBindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java new file mode 100644 index 0000000..b5e02af --- /dev/null +++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2008 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.rollo; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; +import java.lang.Float; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.graphics.PixelFormat; + + +public class RolloView extends RSSurfaceView { + public RolloView(Context context) { + super(context); + setFocusable(true); + getHolder().setFormat(PixelFormat.TRANSLUCENT); + } + + private RenderScript mRS; + private RolloRS mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + + mRS = createRenderScript(); + mRender = new RolloRS(); + mRender.init(mRS, getResources(), w, h); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + boolean mControlMode = false; + boolean mZoomMode = false; + boolean mFlingMode = false; + float mFlingX = 0; + float mFlingY = 0; + float mColumn = -1; + float mOldColumn; + float mZoom = 1; + + int mIconCount = 38; + int mRows = 4; + int mColumns = (mIconCount + mRows - 1) / mRows; + + float mMaxZoom = ((float)mColumns) / 3.f; + + + void setColumn(boolean clamp) + { + //Log.e("rs", " col = " + Float.toString(mColumn)); + float c = mColumn; + if(c > (mColumns -2)) { + c = (mColumns -2); + } + if(c < 1) { + c = 1; + } + mRender.setPosition(c); + if(clamp) { + mColumn = c; + } + } + + void computeSelection(float x, float y) + { + float col = mColumn + (x - 0.5f) * 3; + int iCol = (int)(col + 0.25f); + + float row = (y / 0.8f) * mRows; + int iRow = (int)(row - 0.25f); + + mRender.setSelected(iCol * mRows + iRow); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = true; + int act = ev.getAction(); + if (act == ev.ACTION_UP) { + ret = false; + } + + float nx = ev.getX() / getWidth(); + float ny = ev.getY() / getHeight(); + + mRender.setTouch(ret); + + if((ny > 0.85f) || mControlMode) { + mFlingMode = false; + + // Projector control + if((nx > 0.2f) && (nx < 0.8f) || mControlMode) { + if(act != ev.ACTION_UP) { + float zoom = mMaxZoom; + if(mControlMode) { + if(!mZoomMode) { + zoom = 1.f; + } + float dx = nx - mFlingX; + + if((ny < 0.9) && mZoomMode) { + zoom = mMaxZoom - ((0.9f - ny) * 10.f); + if(zoom < 1) { + zoom = 1; + mZoomMode = false; + } + mOldColumn = mColumn; + } + mColumn += dx * 4;// * zoom; + if(zoom > 1.01f) { + mColumn += (mZoom - zoom) * (nx - 0.5f) * 4 * zoom; + } + } else { + mOldColumn = mColumn; + mColumn = ((float)mColumns) / 2; + mControlMode = true; + mZoomMode = true; + } + mZoom = zoom; + mFlingX = nx; + mRender.setZoom(zoom); + } else { + if(mControlMode && (mZoom < 1.01f)) { + computeSelection(nx, ny); + } + mControlMode = false; + mColumn = mOldColumn; + mRender.setZoom(1.f); + } + } else { + // Do something with corners here.... + } + setColumn(true); + + } else { + // icon control + if(act != ev.ACTION_UP) { + if(mFlingMode) { + mColumn += (mFlingX - nx) * 4; + setColumn(true); + } + mFlingMode = true; + mFlingX = nx; + mFlingY = ny; + } else { + mFlingMode = false; + } + } + + + return ret; + } + + @Override + public boolean onTrackballEvent(MotionEvent ev) + { + float x = ev.getX(); + float y = ev.getY(); + //Float tx = new Float(x); + //Float ty = new Float(y); + //Log.e("rs", "tbe " + tx.toString() + ", " + ty.toString()); + + + return true; + } + +} + + diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec new file mode 100644 index 0000000..2f99808 --- /dev/null +++ b/libs/rs/rs.spec @@ -0,0 +1,449 @@ + + +ContextBindRootScript { + param RsScript sampler + } + +ContextBindProgramFragmentStore { + param RsProgramFragmentStore pgm + } + +ContextBindProgramFragment { + param RsProgramFragment pgm + } + +ContextBindProgramVertex { + param RsProgramVertex pgm + } + +AssignName { + param void *obj + param const char *name + param size_t len + } + +ElementBegin { +} + +ElementAddPredefined { + param RsElementPredefined predef + } + +ElementAdd { + param RsDataKind dataKind + param RsDataType dataType + param bool isNormalized + param size_t bits + } + +ElementCreate { + ret RsElement + } + +ElementGetPredefined { + param RsElementPredefined predef + ret RsElement + } + +ElementDestroy { + param RsElement ve + } + +TypeBegin { + param RsElement type + } + +TypeAdd { + param RsDimension dim + param size_t value + } + +TypeCreate { + ret RsType + } + +TypeDestroy { + param RsType p + } + +AllocationCreateTyped { + param RsType type + ret RsAllocation + } + +AllocationCreatePredefSized { + param RsElementPredefined predef + param size_t count + ret RsAllocation + } + +AllocationCreateSized { + param RsElement e + param size_t count + ret RsAllocation + } + +AllocationCreateFromFile { + param const char *file + param bool genMips + ret RsAllocation + } + +AllocationCreateFromBitmap { + param uint32_t width + param uint32_t height + param RsElementPredefined dstFmt + param RsElementPredefined srcFmt + param bool genMips + param const void * data + ret RsAllocation + } + + +AllocationUploadToTexture { + param RsAllocation alloc + param uint32_t baseMipLevel + } + +AllocationUploadToBufferObject { + param RsAllocation alloc + } + +AllocationDestroy { + param RsAllocation alloc + } + + +AllocationData { + param RsAllocation va + param const void * data + } + +Allocation1DSubData { + param RsAllocation va + param uint32_t xoff + param uint32_t count + param const void *data + } + +Allocation2DSubData { + param RsAllocation va + param uint32_t xoff + param uint32_t yoff + param uint32_t w + param uint32_t h + param const void *data + } + + +Adapter1DCreate { + ret RsAdapter1D + } + +Adapter1DBindAllocation { + param RsAdapter1D adapt + param RsAllocation alloc + } + +Adapter1DDestroy { + param RsAdapter1D adapter + } + +Adapter1DSetConstraint { + param RsAdapter1D adapter + param RsDimension dim + param uint32_t value + } + +Adapter1DData { + param RsAdapter1D adapter + param const void * data + } + +Adapter1DSubData { + param RsAdapter1D adapter + param uint32_t xoff + param uint32_t count + param const void *data + } + +Adapter2DCreate { + ret RsAdapter2D + } + +Adapter2DBindAllocation { + param RsAdapter2D adapt + param RsAllocation alloc + } + +Adapter2DDestroy { + param RsAdapter2D adapter + } + +Adapter2DSetConstraint { + param RsAdapter2D adapter + param RsDimension dim + param uint32_t value + } + +Adapter2DData { + param RsAdapter2D adapter + param const void *data + } + +Adapter2DSubData { + param RsAdapter2D adapter + param uint32_t xoff + param uint32_t yoff + param uint32_t w + param uint32_t h + param const void *data + } + +SamplerBegin { + } + +SamplerSet { + param RsSamplerParam p + param RsSamplerValue value + } + +SamplerCreate { + ret RsSampler + } + +SamplerDestroy { + param RsSampler s + } + +TriangleMeshBegin { + param RsElement vertex + param RsElement index + } + +TriangleMeshAddVertex { + param const void *vtx + } + +TriangleMeshAddTriangle { + param uint32_t idx1 + param uint32_t idx2 + param uint32_t idx3 + } + +TriangleMeshCreate { + ret RsTriangleMesh + } + +TriangleMeshDestroy { + param RsTriangleMesh mesh + } + +TriangleMeshRender { + param RsTriangleMesh vtm + } + +TriangleMeshRenderRange { + param RsTriangleMesh vtm + param uint32_t start + param uint32_t count + } + +ScriptDestroy { + param RsScript script + } + +ScriptBindAllocation { + param RsScript vtm + param RsAllocation va + param uint32_t slot + } + + +ScriptCBegin { + } + +ScriptCSetClearColor { + param float r + param float g + param float b + param float a + } + +ScriptCSetClearDepth { + param float depth + } + +ScriptCSetClearStencil { + param uint32_t stencil + } + +ScriptCAddType { + param RsType type + } + +ScriptCSetRoot { + param bool isRoot + } + +ScriptCSetScript { + param void * codePtr + } + +ScriptCSetText { + param const char * text + param uint32_t length + } + +ScriptCCreate { + ret RsScript + } + + +ProgramFragmentStoreBegin { + param RsElement in + param RsElement out + } + +ProgramFragmentStoreColorMask { + param bool r + param bool g + param bool b + param bool a + } + +ProgramFragmentStoreBlendFunc { + param RsBlendSrcFunc srcFunc + param RsBlendDstFunc destFunc + } + +ProgramFragmentStoreDepthMask { + param bool enable +} + +ProgramFragmentStoreDither { + param bool enable +} + +ProgramFragmentStoreDepthFunc { + param RsDepthFunc func +} + +ProgramFragmentStoreCreate { + ret RsProgramFragmentStore + } + +ProgramFragmentStoreDestroy { + param RsProgramFragmentStore pfs + } + + +ProgramFragmentBegin { + param RsElement in + param RsElement out + } + +ProgramFragmentBindTexture { + param RsProgramFragment pf + param uint32_t slot + param RsAllocation a + } + +ProgramFragmentBindSampler { + param RsProgramFragment pf + param uint32_t slot + param RsSampler s + } + +ProgramFragmentSetType { + param uint32_t slot + param RsType t + } + +ProgramFragmentSetEnvMode { + param uint32_t slot + param RsTexEnvMode env + } + +ProgramFragmentSetTexEnable { + param uint32_t slot + param bool enable + } + +ProgramFragmentCreate { + ret RsProgramFragment + } + +ProgramFragmentDestroy { + param RsProgramFragment pf + } + + +ProgramVertexBegin { + param RsElement in + param RsElement out + } + +ProgramVertexCreate { + ret RsProgramVertex + } + +ProgramVertexBindAllocation { + param RsProgramVertex vpgm + param uint32_t slot + param RsAllocation constants + } + +ProgramVertexSetType { + param uint32_t slot + param RsType constants + } + +ProgramVertexSetTextureMatrixEnable { + param bool enable + } + +ProgramVertexAddLight { + param RsLight light + } + +LightBegin { + } + +LightSetLocal { + param bool isLocal + } + +LightSetMonochromatic { + param bool isMono + } + +LightCreate { + ret RsLight light + } + +LightDestroy { + param RsLight light + } + +LightSetPosition { + param RsLight light + param float x + param float y + param float z + } + +LightSetColor { + param RsLight light + param float r + param float g + param float b + } + +FileOpen { + ret RsFile + param const char *name + param size_t len + } + + diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp new file mode 100644 index 0000000..7ac2aed --- /dev/null +++ b/libs/rs/rsAdapter.cpp @@ -0,0 +1,245 @@ + +/* + * 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. + */ + +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + + +Adapter1D::Adapter1D() +{ + reset(); +} + +Adapter1D::Adapter1D(Allocation *a) +{ + reset(); + setAllocation(a); +} + +void Adapter1D::reset() +{ + mY = 0; + mZ = 0; + mLOD = 0; + mFace = 0; +} + +void * Adapter1D::getElement(uint32_t x) +{ + rsAssert(mAllocation.get()); + rsAssert(mAllocation->getPtr()); + rsAssert(mAllocation->getType()); + uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr()); + ptr += mAllocation->getType()->getLODOffset(mLOD, x, mY); + return ptr; +} + +void Adapter1D::subData(uint32_t xoff, uint32_t count, const void *data) +{ + if (mAllocation.get() && mAllocation.get()->getType()) { + void *ptr = getElement(xoff); + count *= mAllocation.get()->getType()->getElementSizeBytes(); + memcpy(ptr, data, count); + } +} + +void Adapter1D::data(const void *data) +{ + memcpy(getElement(0), + data, + mAllocation.get()->getType()->getSizeBytes()); +} + +namespace android { +namespace renderscript { + +RsAdapter1D rsi_Adapter1DCreate(Context *rsc) +{ + return new Adapter1D(); +} + +void rsi_Adapter1DDestroy(Context *rsc, RsAdapter1D va) +{ + Adapter1D * a = static_cast<Adapter1D *>(va); + a->decRef(); +} + +void rsi_Adapter1DBindAllocation(Context *rsc, RsAdapter1D va, RsAllocation valloc) +{ + Adapter1D * a = static_cast<Adapter1D *>(va); + Allocation * alloc = static_cast<Allocation *>(valloc); + a->setAllocation(alloc); +} + +void rsi_Adapter1DSetConstraint(Context *rsc, RsAdapter1D va, RsDimension dim, uint32_t value) +{ + Adapter1D * a = static_cast<Adapter1D *>(va); + switch(dim) { + case RS_DIMENSION_X: + rsAssert(!"Cannot contrain X in an 1D adapter"); + return; + case RS_DIMENSION_Y: + a->setY(value); + break; + case RS_DIMENSION_Z: + a->setZ(value); + break; + case RS_DIMENSION_LOD: + a->setLOD(value); + break; + case RS_DIMENSION_FACE: + a->setFace(value); + break; + default: + rsAssert(!"Unimplemented constraint"); + return; + } +} + +void rsi_Adapter1DSubData(Context *rsc, RsAdapter1D va, uint32_t xoff, uint32_t count, const void *data) +{ + Adapter1D * a = static_cast<Adapter1D *>(va); + a->subData(xoff, count, data); +} + +void rsi_Adapter1DData(Context *rsc, RsAdapter1D va, const void *data) +{ + Adapter1D * a = static_cast<Adapter1D *>(va); + a->data(data); +} + +} +} + +////////////////////////// + +Adapter2D::Adapter2D() +{ + reset(); +} + +Adapter2D::Adapter2D(Allocation *a) +{ + reset(); + setAllocation(a); +} + +void Adapter2D::reset() +{ + mZ = 0; + mLOD = 0; + mFace = 0; +} + +void * Adapter2D::getElement(uint32_t x, uint32_t y) const +{ + rsAssert(mAllocation.get()); + rsAssert(mAllocation->getPtr()); + rsAssert(mAllocation->getType()); + uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr()); + ptr += mAllocation->getType()->getLODOffset(mLOD, x, y); + return ptr; +} + +void Adapter2D::subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data) +{ + rsAssert(mAllocation.get()); + rsAssert(mAllocation->getPtr()); + rsAssert(mAllocation->getType()); + + uint32_t eSize = mAllocation.get()->getType()->getElementSizeBytes(); + uint32_t lineSize = eSize * w; + uint32_t destW = getDimX(); + + const uint8_t *src = static_cast<const uint8_t *>(data); + for (uint32_t line=yoff; line < (yoff+h); line++) { + memcpy(getElement(xoff, line), src, lineSize); + src += lineSize; + } +} + +void Adapter2D::data(const void *data) +{ + memcpy(getElement(0,0), + data, + mAllocation.get()->getType()->getSizeBytes()); +} + + + +namespace android { +namespace renderscript { + +RsAdapter2D rsi_Adapter2DCreate(Context *rsc) +{ + return new Adapter2D(); +} + +void rsi_Adapter2DDestroy(Context *rsc, RsAdapter2D va) +{ + Adapter2D * a = static_cast<Adapter2D *>(va); + a->decRef(); +} + +void rsi_Adapter2DBindAllocation(Context *rsc, RsAdapter2D va, RsAllocation valloc) +{ + Adapter2D * a = static_cast<Adapter2D *>(va); + Allocation * alloc = static_cast<Allocation *>(valloc); + a->setAllocation(alloc); +} + +void rsi_Adapter2DSetConstraint(Context *rsc, RsAdapter2D va, RsDimension dim, uint32_t value) +{ + Adapter2D * a = static_cast<Adapter2D *>(va); + switch(dim) { + case RS_DIMENSION_X: + rsAssert(!"Cannot contrain X in an 2D adapter"); + return; + case RS_DIMENSION_Y: + rsAssert(!"Cannot contrain Y in an 2D adapter"); + break; + case RS_DIMENSION_Z: + a->setZ(value); + break; + case RS_DIMENSION_LOD: + a->setLOD(value); + break; + case RS_DIMENSION_FACE: + a->setFace(value); + break; + default: + rsAssert(!"Unimplemented constraint"); + return; + } +} + +void rsi_Adapter2DData(Context *rsc, RsAdapter2D va, const void *data) +{ + Adapter2D * a = static_cast<Adapter2D *>(va); + a->data(data); +} + +void rsi_Adapter2DSubData(Context *rsc, RsAdapter2D va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data) +{ + Adapter2D * a = static_cast<Adapter2D *>(va); + a->subData(xoff, yoff, w, h, data); +} + +} +} diff --git a/libs/rs/rsAdapter.h b/libs/rs/rsAdapter.h new file mode 100644 index 0000000..865535e --- /dev/null +++ b/libs/rs/rsAdapter.h @@ -0,0 +1,96 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_ADAPTER_H +#define ANDROID_RS_ADAPTER_H + +#include "rsAllocation.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +class Adapter1D : public ObjectBase +{ + +public: + // By policy this allocation will hold a pointer to the type + // but will not destroy it on destruction. + Adapter1D(); + Adapter1D(Allocation *); + void reset(); + void * getElement(uint32_t x); + + void setAllocation(Allocation *a) {mAllocation.set(a);} + + uint32_t getDimX() const {return mAllocation->getType()->getLODDimX(mLOD);} + + const Type * getBaseType() const {return mAllocation->getType();} + + inline void setY(uint32_t y) {mY = y;} + inline void setZ(uint32_t z) {mZ = z;} + inline void setLOD(uint32_t lod) {mLOD = lod;} + inline void setFace(uint32_t face) {mFace = face;} + //void setArray(uint32_t num, uint32_t value); + + void subData(uint32_t xoff, uint32_t count, const void *data); + void data(const void *data); + +protected: + ObjectBaseRef<Allocation> mAllocation; + uint32_t mY; + uint32_t mZ; + uint32_t mLOD; + uint32_t mFace; +}; + +class Adapter2D : public ObjectBase +{ + +public: + // By policy this allocation will hold a pointer to the type + // but will not destroy it on destruction. + Adapter2D(); + Adapter2D(Allocation *); + void reset(); + void * getElement(uint32_t x, uint32_t y) const; + + uint32_t getDimX() const {return mAllocation->getType()->getLODDimX(mLOD);} + uint32_t getDimY() const {return mAllocation->getType()->getLODDimY(mLOD);} + const Type * getBaseType() const {return mAllocation->getType();} + + void setAllocation(Allocation *a) {mAllocation.set(a);} + inline void setZ(uint32_t z) {mZ = z;} + inline void setLOD(uint32_t lod) {mLOD = lod;} + inline void setFace(uint32_t face) {mFace = face;} + //void setArray(uint32_t num, uint32_t value); + + void data(const void *data); + void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data); + +protected: + ObjectBaseRef<Allocation> mAllocation; + uint32_t mZ; + uint32_t mLOD; + uint32_t mFace; +}; + + +} +} +#endif + diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp new file mode 100644 index 0000000..c143307 --- /dev/null +++ b/libs/rs/rsAllocation.cpp @@ -0,0 +1,477 @@ +/* + * 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. + */ + +#include "rsContext.h" + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + +Allocation::Allocation(const Type *type) +{ + mPtr = NULL; + + mCpuWrite = false; + mCpuRead = false; + mGpuWrite = false; + mGpuRead = false; + + mReadWriteRatio = 0; + mUpdateSize = 0; + + mIsTexture = false; + mTextureID = 0; + + mIsVertexBuffer = false; + mBufferID = 0; + + mType.set(type); + mPtr = malloc(mType->getSizeBytes()); + if (!mPtr) { + LOGE("Allocation::Allocation, alloc failure"); + } + +} + +Allocation::~Allocation() +{ +} + +void Allocation::setCpuWritable(bool) +{ +} + +void Allocation::setGpuWritable(bool) +{ +} + +void Allocation::setCpuReadable(bool) +{ +} + +void Allocation::setGpuReadable(bool) +{ +} + +bool Allocation::fixAllocation() +{ + return false; +} + +void Allocation::uploadToTexture(uint32_t lodOffset) +{ + //rsAssert(!mTextureId); + rsAssert(lodOffset < mType->getLODCount()); + + GLenum type = mType->getElement()->getGLType(); + GLenum format = mType->getElement()->getGLFormat(); + + if (!type || !format) { + return; + } + + if (!mTextureID) { + glGenTextures(1, &mTextureID); + } + glBindTexture(GL_TEXTURE_2D, mTextureID); + + Adapter2D adapt(this); + for(uint32_t lod = 0; (lod + lodOffset) < mType->getLODCount(); lod++) { + adapt.setLOD(lod+lodOffset); + + uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); + glTexImage2D(GL_TEXTURE_2D, lod, format, + adapt.getDimX(), adapt.getDimY(), + 0, format, type, ptr); + } +} + +void Allocation::uploadToBufferObject() +{ + rsAssert(!mType->getDimY()); + rsAssert(!mType->getDimZ()); + + if (!mBufferID) { + glGenBuffers(1, &mBufferID); + } + glBindBuffer(GL_ARRAY_BUFFER, mBufferID); + glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void Allocation::data(const void *data) +{ + memcpy(mPtr, data, mType->getSizeBytes()); +} + +void Allocation::subData(uint32_t xoff, uint32_t count, const void *data) +{ + uint32_t eSize = mType->getElementSizeBytes(); + uint8_t * ptr = static_cast<uint8_t *>(mPtr); + ptr += eSize * xoff; + memcpy(ptr, data, count * eSize); +} + +void Allocation::subData(uint32_t xoff, uint32_t yoff, + uint32_t w, uint32_t h, const void *data) +{ + uint32_t eSize = mType->getElementSizeBytes(); + uint32_t lineSize = eSize * w; + uint32_t destW = mType->getDimX(); + + const uint8_t *src = static_cast<const uint8_t *>(data); + uint8_t *dst = static_cast<uint8_t *>(mPtr); + dst += eSize * (xoff + yoff * destW); + for (uint32_t line=yoff; line < (yoff+h); line++) { + uint8_t * ptr = static_cast<uint8_t *>(mPtr); + memcpy(dst, src, lineSize); + src += lineSize; + dst += destW * eSize; + } +} + +void Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff, + uint32_t w, uint32_t h, uint32_t d, const void *data) +{ +} + + + +///////////////// +// + + +namespace android { +namespace renderscript { + +RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype) +{ + const Type * type = static_cast<const Type *>(vtype); + + Allocation * alloc = new Allocation(type); + alloc->incRef(); + return alloc; +} + +RsAllocation rsi_AllocationCreatePredefSized(Context *rsc, RsElementPredefined t, size_t count) +{ + RsElement e = rsi_ElementGetPredefined(rsc, t); + return rsi_AllocationCreateSized(rsc, e, count); +} + +RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count) +{ + Type * type = new Type(); + type->setDimX(count); + type->setElement(static_cast<Element *>(e)); + type->compute(); + return rsi_AllocationCreateTyped(rsc, type); +} + +void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, uint32_t baseMipLevel) +{ + Allocation *alloc = static_cast<Allocation *>(va); + alloc->uploadToTexture(baseMipLevel); +} + +void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) +{ + Allocation *alloc = static_cast<Allocation *>(va); + alloc->uploadToBufferObject(); +} + +void rsi_AllocationDestroy(Context *rsc, RsAllocation) +{ +} + +static void mip565(const Adapter2D &out, const Adapter2D &in) +{ + uint32_t w = out.getDimX(); + uint32_t h = out.getDimY(); + + for (uint32_t y=0; y < w; y++) { + uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y)); + const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2)); + const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1)); + + for (uint32_t x=0; x < h; x++) { + *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]); + oPtr ++; + i1 += 2; + i2 += 2; + } + } +} + +static void mip8888(const Adapter2D &out, const Adapter2D &in) +{ + uint32_t w = out.getDimX(); + uint32_t h = out.getDimY(); + + for (uint32_t y=0; y < w; y++) { + uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y)); + const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2)); + const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1)); + + for (uint32_t x=0; x < h; x++) { + *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]); + oPtr ++; + i1 += 2; + i2 += 2; + } + } + +} + + +typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count); + +static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) +{ + memcpy(dst, src, count * 2); +} +static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) +{ + memcpy(dst, src, count); +} +static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) +{ + memcpy(dst, src, count * 4); +} + + +static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) +{ + uint16_t *d = static_cast<uint16_t *>(dst); + const uint8_t *s = static_cast<const uint8_t *>(src); + + while(count--) { + *d = rs888to565(s[0], s[1], s[2]); + d++; + s+= 3; + } +} + +static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) +{ + uint16_t *d = static_cast<uint16_t *>(dst); + const uint8_t *s = static_cast<const uint8_t *>(src); + + while(count--) { + *d = rs888to565(s[0], s[1], s[2]); + d++; + s+= 4; + } +} + +static ElementConverter_t pickConverter(RsElementPredefined dstFmt, RsElementPredefined srcFmt) +{ + if ((dstFmt == RS_ELEMENT_RGB_565) && + (srcFmt == RS_ELEMENT_RGB_565)) { + return elementConverter_cpy_16; + } + + if ((dstFmt == RS_ELEMENT_RGB_565) && + (srcFmt == RS_ELEMENT_RGB_888)) { + return elementConverter_888_to_565; + } + + if ((dstFmt == RS_ELEMENT_RGB_565) && + (srcFmt == RS_ELEMENT_RGBA_8888)) { + return elementConverter_8888_to_565; + } + + if ((dstFmt == RS_ELEMENT_RGBA_8888) && + (srcFmt == RS_ELEMENT_RGBA_8888)) { + return elementConverter_cpy_32; + } + + LOGE("pickConverter, unsuported combo"); + return 0; +} + + +RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElementPredefined dstFmt, RsElementPredefined srcFmt, bool genMips, const void *data) +{ + rsi_TypeBegin(rsc, rsi_ElementGetPredefined(rsc, RS_ELEMENT_RGB_565)); + rsi_TypeAdd(rsc, RS_DIMENSION_X, w); + rsi_TypeAdd(rsc, RS_DIMENSION_Y, h); + if (genMips) { + rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1); + } + RsType type = rsi_TypeCreate(rsc); + + RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type); + Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); + if (texAlloc == NULL) { + LOGE("Memory allocation failure"); + return NULL; + } + texAlloc->incRef(); + + ElementConverter_t cvt = pickConverter(dstFmt, srcFmt); + cvt(texAlloc->getPtr(), data, w * h); + + if (genMips) { + Adapter2D adapt(texAlloc); + Adapter2D adapt2(texAlloc); + for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { + adapt.setLOD(lod); + adapt2.setLOD(lod + 1); + mip565(adapt2, adapt); + } + } + + return texAlloc; +} + +RsAllocation rsi_AllocationCreateFromFile(Context *rsc, const char *file, bool genMips) +{ + bool use32bpp = false; + + typedef struct _Win3xBitmapHeader + { + uint16_t type; + uint32_t totalSize; + uint32_t reserved; + uint32_t offset; + int32_t hdrSize; /* Size of this header in bytes */ + int32_t width; /* Image width in pixels */ + int32_t height; /* Image height in pixels */ + int16_t planes; /* Number of color planes */ + int16_t bpp; /* Number of bits per pixel */ + /* Fields added for Windows 3.x follow this line */ + int32_t compression; /* Compression methods used */ + int32_t sizeOfBitmap; /* Size of bitmap in bytes */ + int32_t horzResolution; /* Horizontal resolution in pixels per meter */ + int32_t vertResolution; /* Vertical resolution in pixels per meter */ + int32_t colorsUsed; /* Number of colors in the image */ + int32_t colorsImportant; /* Minimum number of important colors */ + } __attribute__((__packed__)) WIN3XBITMAPHEADER; + + _Win3xBitmapHeader hdr; + + FILE *f = fopen(file, "rb"); + if (f == NULL) { + LOGE("rsAllocationCreateFromBitmap failed to open file %s", file); + return NULL; + } + memset(&hdr, 0, sizeof(hdr)); + fread(&hdr, sizeof(hdr), 1, f); + + if (hdr.bpp != 24) { + LOGE("Unsuported BMP type"); + fclose(f); + return NULL; + } + + int32_t texWidth = rsHigherPow2(hdr.width); + int32_t texHeight = rsHigherPow2(hdr.height); + + if (use32bpp) { + rsi_TypeBegin(rsc, rsi_ElementGetPredefined(rsc, RS_ELEMENT_RGBA_8888)); + } else { + rsi_TypeBegin(rsc, rsi_ElementGetPredefined(rsc, RS_ELEMENT_RGB_565)); + } + rsi_TypeAdd(rsc, RS_DIMENSION_X, texWidth); + rsi_TypeAdd(rsc, RS_DIMENSION_Y, texHeight); + if (genMips) { + rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1); + } + RsType type = rsi_TypeCreate(rsc); + + RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type); + Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); + texAlloc->incRef(); + if (texAlloc == NULL) { + LOGE("Memory allocation failure"); + fclose(f); + return NULL; + } + + // offset to letterbox if height is not pow2 + Adapter2D adapt(texAlloc); + uint8_t * fileInBuf = new uint8_t[texWidth * 3]; + uint32_t yOffset = (hdr.width - hdr.height) / 2; + + if (use32bpp) { + uint8_t *tmp = static_cast<uint8_t *>(adapt.getElement(0, yOffset)); + for (int y=0; y < hdr.height; y++) { + fseek(f, hdr.offset + (y*hdr.width*3), SEEK_SET); + fread(fileInBuf, 1, hdr.width * 3, f); + for(int x=0; x < hdr.width; x++) { + tmp[0] = fileInBuf[x*3 + 2]; + tmp[1] = fileInBuf[x*3 + 1]; + tmp[2] = fileInBuf[x*3]; + tmp[3] = 0xff; + tmp += 4; + } + } + } else { + uint16_t *tmp = static_cast<uint16_t *>(adapt.getElement(0, yOffset)); + for (int y=0; y < hdr.height; y++) { + fseek(f, hdr.offset + (y*hdr.width*3), SEEK_SET); + fread(fileInBuf, 1, hdr.width * 3, f); + for(int x=0; x < hdr.width; x++) { + *tmp = rs888to565(fileInBuf[x*3 + 2], fileInBuf[x*3 + 1], fileInBuf[x*3]); + tmp++; + } + } + } + + fclose(f); + delete [] fileInBuf; + + if (genMips) { + Adapter2D adapt2(texAlloc); + for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { + adapt.setLOD(lod); + adapt2.setLOD(lod + 1); + if (use32bpp) { + mip8888(adapt2, adapt); + } else { + mip565(adapt2, adapt); + } + } + } + + return texAlloc; +} + + +void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data) +{ + Allocation *a = static_cast<Allocation *>(va); + a->data(data); +} + +void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data) +{ + Allocation *a = static_cast<Allocation *>(va); + a->subData(xoff, count, data); +} + +void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data) +{ + Allocation *a = static_cast<Allocation *>(va); + a->subData(xoff, yoff, w, h, data); +} + + +} +} diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h new file mode 100644 index 0000000..d0b91fd --- /dev/null +++ b/libs/rs/rsAllocation.h @@ -0,0 +1,96 @@ +/* + * 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. + */ + +#ifndef ANDROID_STRUCTURED_ALLOCATION_H +#define ANDROID_STRUCTURED_ALLOCATION_H + +#include "rsType.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + + +class Allocation : public ObjectBase +{ + // The graphics equilivent of malloc. The allocation contains a structure of elements. + + +public: + // By policy this allocation will hold a pointer to the type + // but will not destroy it on destruction. + Allocation(const Type *); + virtual ~Allocation(); + + void setCpuWritable(bool); + void setGpuWritable(bool); + void setCpuReadable(bool); + void setGpuReadable(bool); + + bool fixAllocation(); + + void * getPtr() const {return mPtr;} + const Type * getType() const {return mType.get();} + + void uploadToTexture(uint32_t lodOffset = 0); + uint32_t getTextureID() const {return mTextureID;} + + void uploadToBufferObject(); + uint32_t getBufferObjectID() const {return mBufferID;} + + + void data(const void *data); + void subData(uint32_t xoff, uint32_t count, const void *data); + void subData(uint32_t xoff, uint32_t yoff, + uint32_t w, uint32_t h, const void *data); + void subData(uint32_t xoff, uint32_t yoff, uint32_t zoff, + uint32_t w, uint32_t h, uint32_t d, const void *data); + +protected: + ObjectBaseRef<const Type> mType; + void * mPtr; + + // Usage restrictions + bool mCpuWrite; + bool mCpuRead; + bool mGpuWrite; + bool mGpuRead; + + // more usage hint data from the application + // which can be used by a driver to pick the best memory type. + // Likely ignored for now + float mReadWriteRatio; + float mUpdateSize; + + + // Is this a legal structure to be used as a texture source. + // Initially this will require 1D or 2D and color data + bool mIsTexture; + uint32_t mTextureID; + + // Is this a legal structure to be used as a vertex source. + // Initially this will require 1D and x(yzw). Additional per element data + // is allowed. + bool mIsVertexBuffer; + uint32_t mBufferID; + +}; + +} +} +#endif + diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp new file mode 100644 index 0000000..a931811 --- /dev/null +++ b/libs/rs/rsComponent.cpp @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#include "rsComponent.h" + +using namespace android; +using namespace android::renderscript; + + +Component::Component() +{ + mType = FLOAT; + mKind = NONE; + mIsNormalized = false; + mBits = 0; +} + +Component::Component( + DataKind dk, DataType dt, + bool isNormalized, uint32_t bits) +{ + mType = dt; + mKind = dk; + mIsNormalized = isNormalized; + mBits = bits; +} + +Component::~Component() +{ +} diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h new file mode 100644 index 0000000..e1b0585 --- /dev/null +++ b/libs/rs/rsComponent.h @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_STRUCTURED_COMPONENT_H +#define ANDROID_RS_STRUCTURED_COMPONENT_H + +#include "rsUtils.h" +#include "rsObjectBase.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class Component : public ObjectBase +{ +public: + enum DataType { + FLOAT, + UNSIGNED, + SIGNED + }; + + enum DataKind { + NONE, + RED, GREEN, BLUE, ALPHA, LUMINANCE, INTENSITY, + X, Y, Z, W, + S, T, Q, R, + NX, NY, NZ, + INDEX, + USER + }; + + + Component(DataKind dk, DataType dt, bool isNormalized, uint32_t bits); + virtual ~Component(); + + DataType getType() const {return mType;} + bool getIsNormalized() const {return mIsNormalized;} + DataKind getKind() const {return mKind;} + uint32_t getBits() const {return mBits;} + +protected: + + DataType mType; + bool mIsNormalized; + DataKind mKind; + uint32_t mBits; + +private: + Component(); +}; + + +} +} + +#endif //ANDROID_RS_STRUCTURED_COMPONENT_H + diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp new file mode 100644 index 0000000..78b8bf8 --- /dev/null +++ b/libs/rs/rsContext.cpp @@ -0,0 +1,378 @@ +/* + * 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. + */ + +#include "rsDevice.h" +#include "rsContext.h" +#include "rsThreadIO.h" +#include "utils/String8.h" +#include <ui/FramebufferNativeWindow.h> + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + +Context * Context::gCon = NULL; +pthread_key_t Context::gThreadTLSKey = 0; + +void Context::initEGL() +{ + mNumConfigs = -1; + + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, +#if 1 + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, +#else + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 6, + EGL_BLUE_SIZE, 5, +#endif + EGL_DEPTH_SIZE, 16, + EGL_NONE + }; + + mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion); + eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs); + + if (mWndSurface) { + mSurface = eglCreateWindowSurface(mDisplay, mConfig, mWndSurface, + NULL); + } else { + mSurface = eglCreateWindowSurface(mDisplay, mConfig, + android_createDisplaySurface(), + NULL); + } + + mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL); + eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); + eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth); + eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight); +} + +bool Context::runScript(Script *s, uint32_t launchID) +{ + ObjectBaseRef<ProgramFragment> frag(mFragment); + ObjectBaseRef<ProgramVertex> vtx(mVertex); + ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore); + + bool ret = s->run(this, launchID); + + mFragment.set(frag); + mVertex.set(vtx); + mFragmentStore.set(store); + return true; + +} + + +bool Context::runRootScript() +{ + rsAssert(mRootScript->mEnviroment.mIsRoot); + + glColor4f(1,1,1,1); + glEnable(GL_LIGHT0); + glViewport(0, 0, mWidth, mHeight); + + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glClearColor(mRootScript->mEnviroment.mClearColor[0], + mRootScript->mEnviroment.mClearColor[1], + mRootScript->mEnviroment.mClearColor[2], + mRootScript->mEnviroment.mClearColor[3]); + glClearDepthf(mRootScript->mEnviroment.mClearDepth); + glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); + + return runScript(mRootScript.get(), 0); +} + +void Context::setupCheck() +{ + if (mFragmentStore.get()) { + mFragmentStore->setupGL(); + } + if (mFragment.get()) { + mFragment->setupGL(); + } + if (mVertex.get()) { + mVertex->setupGL(); + } + +} + + +void * Context::threadProc(void *vrsc) +{ + Context *rsc = static_cast<Context *>(vrsc); + + gIO = new ThreadIO(); + rsc->initEGL(); + + ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; + if (!tlsStruct) { + LOGE("Error allocating tls storage"); + return NULL; + } + tlsStruct->mContext = rsc; + tlsStruct->mScript = NULL; + int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct); + if (status) { + LOGE("pthread_setspecific %i", status); + } + + rsc->mStateVertex.init(rsc, rsc->mWidth, rsc->mHeight); + rsc->setVertex(NULL); + rsc->mStateFragment.init(rsc, rsc->mWidth, rsc->mHeight); + rsc->setFragment(NULL); + rsc->mStateFragmentStore.init(rsc, rsc->mWidth, rsc->mHeight); + rsc->setFragmentStore(NULL); + + rsc->mRunning = true; + bool mDraw = true; + while (!rsc->mExit) { + mDraw |= gIO->playCoreCommands(rsc, !mDraw); + mDraw &= (rsc->mRootScript.get() != NULL); + + if (mDraw) { + mDraw = rsc->runRootScript(); + eglSwapBuffers(rsc->mDisplay, rsc->mSurface); + } + } + + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + eglSwapBuffers(rsc->mDisplay, rsc->mSurface); + eglTerminate(rsc->mDisplay); + return NULL; +} + +Context::Context(Device *dev, Surface *sur) +{ + dev->addContext(this); + mDev = dev; + mRunning = false; + mExit = false; + + // see comment in header + gCon = this; + + int status; + pthread_attr_t threadAttr; + + status = pthread_key_create(&gThreadTLSKey, NULL); + if (status) { + LOGE("Failed to init thread tls key."); + return; + } + + status = pthread_attr_init(&threadAttr); + if (status) { + LOGE("Failed to init thread attribute."); + return; + } + + sched_param sparam; + sparam.sched_priority = ANDROID_PRIORITY_DISPLAY; + pthread_attr_setschedparam(&threadAttr, &sparam); + + mWndSurface = sur; + + LOGV("RS Launching thread"); + status = pthread_create(&mThreadId, &threadAttr, threadProc, this); + if (status) { + LOGE("Failed to start rs context thread."); + } + + while(!mRunning) { + sleep(1); + } + + pthread_attr_destroy(&threadAttr); +} + +Context::~Context() +{ + mExit = true; + void *res; + + int status = pthread_join(mThreadId, &res); + + if (mDev) { + mDev->removeContext(this); + pthread_key_delete(gThreadTLSKey); + } +} + +void Context::swapBuffers() +{ + eglSwapBuffers(mDisplay, mSurface); +} + +void rsContextSwap(RsContext vrsc) +{ + Context *rsc = static_cast<Context *>(vrsc); + rsc->swapBuffers(); +} + +void Context::setRootScript(Script *s) +{ + mRootScript.set(s); +} + +void Context::setFragmentStore(ProgramFragmentStore *pfs) +{ + if (pfs == NULL) { + mFragmentStore.set(mStateFragmentStore.mDefault); + } else { + mFragmentStore.set(pfs); + } + mFragmentStore->setupGL(); +} + +void Context::setFragment(ProgramFragment *pf) +{ + if (pf == NULL) { + mFragment.set(mStateFragment.mDefault); + } else { + mFragment.set(pf); + } + mFragment->setupGL(); +} + +void Context::setVertex(ProgramVertex *pv) +{ + if (pv == NULL) { + mVertex.set(mStateVertex.mDefault); + } else { + mVertex.set(pv); + } + mVertex->setupGL(); +} + +void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) +{ + rsAssert(!obj->getName()); + obj->setName(name, len); + mNames.add(obj); +} + +void Context::removeName(ObjectBase *obj) +{ + for(size_t ct=0; ct < mNames.size(); ct++) { + if (obj == mNames[ct]) { + mNames.removeAt(ct); + return; + } + } +} + +ObjectBase * Context::lookupName(const char *name) const +{ + for(size_t ct=0; ct < mNames.size(); ct++) { + if (!strcmp(name, mNames[ct]->getName())) { + return mNames[ct]; + } + } + return NULL; +} + +void Context::appendNameDefines(String8 *str) const +{ + char buf[256]; + for (size_t ct=0; ct < mNames.size(); ct++) { + str->append("#define NAMED_"); + str->append(mNames[ct]->getName()); + str->append(" "); + sprintf(buf, "%i\n", (int)mNames[ct]); + str->append(buf); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// + +namespace android { +namespace renderscript { + + +void rsi_ContextBindRootScript(Context *rsc, RsScript vs) +{ + Script *s = static_cast<Script *>(vs); + rsc->setRootScript(s); +} + +void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) +{ + Sampler *s = static_cast<Sampler *>(vs); + + if (slot > RS_MAX_SAMPLER_SLOT) { + LOGE("Invalid sampler slot"); + return; + } + + s->bindToContext(&rsc->mStateSampler, slot); +} + +void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs) +{ + ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs); + rsc->setFragmentStore(pfs); +} + +void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) +{ + ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); + rsc->setFragment(pf); +} + +void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) +{ + ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); + rsc->setVertex(pv); +} + +void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len) +{ + ObjectBase *ob = static_cast<ObjectBase *>(obj); + rsc->assignName(ob, name, len); +} + + +} +} + + +RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version) +{ + Device * dev = static_cast<Device *>(vdev); + Context *rsc = new Context(dev, (Surface *)sur); + return rsc; +} + +void rsContextDestroy(RsContext vrsc) +{ + Context * rsc = static_cast<Context *>(vrsc); + delete rsc; +} + diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h new file mode 100644 index 0000000..497dbcf --- /dev/null +++ b/libs/rs/rsContext.h @@ -0,0 +1,148 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_CONTEXT_H +#define ANDROID_RS_CONTEXT_H + +#include "rsUtils.h" + +#include <utils/Vector.h> +#include <ui/Surface.h> + +#include "rsType.h" +#include "rsMatrix.h" +#include "rsAllocation.h" +#include "rsTriangleMesh.h" +#include "rsMesh.h" +#include "rsDevice.h" +#include "rsScriptC.h" +#include "rsAllocation.h" +#include "rsAdapter.h" +#include "rsSampler.h" +#include "rsLight.h" +#include "rsProgramFragment.h" +#include "rsProgramFragmentStore.h" +#include "rsProgramVertex.h" + +#include "rsgApiStructs.h" +#include "rsLocklessFifo.h" + + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class Context +{ +public: + Context(Device *, Surface *); + ~Context(); + + static pthread_key_t gThreadTLSKey; + struct ScriptTLSStruct { + Context * mContext; + Script * mScript; + }; + + + //StructuredAllocationContext mStateAllocation; + ElementState mStateElement; + TypeState mStateType; + SamplerState mStateSampler; + ProgramFragmentState mStateFragment; + ProgramFragmentStoreState mStateFragmentStore; + ProgramVertexState mStateVertex; + LightState mStateLight; + + TriangleMeshContext mStateTriangleMesh; + + ScriptCState mScriptC; + + static Context * getContext() {return gCon;} + + void swapBuffers(); + void setRootScript(Script *); + void setVertex(ProgramVertex *); + void setFragment(ProgramFragment *); + void setFragmentStore(ProgramFragmentStore *); + + void updateSurface(void *sur); + + const ProgramFragment * getFragment() {return mFragment.get();} + const ProgramFragmentStore * getFragmentStore() {return mFragmentStore.get();} + + void setupCheck(); + + void assignName(ObjectBase *obj, const char *name, uint32_t len); + void removeName(ObjectBase *obj); + ObjectBase * lookupName(const char *name) const; + void appendNameDefines(String8 *str) const; + + + ProgramFragment * getDefaultProgramFragment() const { + return mStateFragment.mDefault.get(); + } + ProgramVertex * getDefaultProgramVertex() const { + return mStateVertex.mDefault.get(); + } + ProgramFragmentStore * getDefaultProgramFragmentStore() const { + return mStateFragmentStore.mDefault.get(); + } + +protected: + Device *mDev; + + EGLint mNumConfigs; + EGLint mMajorVersion; + EGLint mMinorVersion; + EGLConfig mConfig; + EGLContext mContext; + EGLSurface mSurface; + EGLint mWidth; + EGLint mHeight; + EGLDisplay mDisplay; + + bool mRunning; + bool mExit; + + pthread_t mThreadId; + + ObjectBaseRef<Script> mRootScript; + ObjectBaseRef<ProgramFragment> mFragment; + ObjectBaseRef<ProgramVertex> mVertex; + ObjectBaseRef<ProgramFragmentStore> mFragmentStore; + +private: + Context(); + + void initEGL(); + + bool runScript(Script *s, uint32_t launchID); + bool runRootScript(); + + static void * threadProc(void *); + + // todo: put in TLS + static Context *gCon; + Surface *mWndSurface; + + Vector<ObjectBase *> mNames; +}; + + +} +} +#endif diff --git a/libs/rs/rsDevice.cpp b/libs/rs/rsDevice.cpp new file mode 100644 index 0000000..1b3c41b --- /dev/null +++ b/libs/rs/rsDevice.cpp @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#include "rsDevice.h" +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + +Device::Device() +{ + +} + +Device::~Device() +{ + +} + +void Device::addContext(Context *rsc) +{ + mContexts.add(rsc); +} + +void Device::removeContext(Context *rsc) +{ + for (size_t idx=0; idx < mContexts.size(); idx++) { + if (mContexts[idx] == rsc) { + mContexts.removeAt(idx); + break; + } + } +} + + + +RsDevice rsDeviceCreate() +{ + Device * d = new Device(); + return d; +} + +void rsDeviceDestroy(RsDevice dev) +{ + Device * d = static_cast<Device *>(dev); + delete d; + +} + diff --git a/libs/rs/rsDevice.h b/libs/rs/rsDevice.h new file mode 100644 index 0000000..156315f --- /dev/null +++ b/libs/rs/rsDevice.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_DEVICE_H +#define ANDROID_RS_DEVICE_H + +#include "rsUtils.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class Context; + +class Device { +public: + Device(); + ~Device(); + + void addContext(Context *); + void removeContext(Context *); + +protected: + Vector<Context *> mContexts; + + +}; + + + + + +} +} +#endif diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp new file mode 100644 index 0000000..069a128 --- /dev/null +++ b/libs/rs/rsElement.cpp @@ -0,0 +1,432 @@ +/* + * 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. + */ + +#include "rsContext.h" + +#include <GLES/gl.h> + +using namespace android; +using namespace android::renderscript; + +void ElementState::initPredefined() +{ + Component * u_8 = new Component(Component::USER, Component::UNSIGNED, true, 8); + Component * i_8 = new Component(Component::USER, Component::SIGNED, true, 8); + Component * u_16 = new Component(Component::USER, Component::UNSIGNED, true, 16); + Component * i_16 = new Component(Component::USER, Component::SIGNED, true, 16); + Component * u_32 = new Component(Component::USER, Component::UNSIGNED, true, 32); + Component * i_32 = new Component(Component::USER, Component::SIGNED, true, 32); + Component * f_32 = new Component(Component::USER, Component::FLOAT, true, 32); + + + Component * r_4 = new Component(Component::RED, Component::UNSIGNED, true, 4); + Component * r_5 = new Component(Component::RED, Component::UNSIGNED, true, 5); + Component * r_8 = new Component(Component::RED, Component::UNSIGNED, true, 8); + + Component * g_4 = new Component(Component::GREEN, Component::UNSIGNED, true, 4); + Component * g_5 = new Component(Component::GREEN, Component::UNSIGNED, true, 5); + Component * g_6 = new Component(Component::GREEN, Component::UNSIGNED, true, 6); + Component * g_8 = new Component(Component::GREEN, Component::UNSIGNED, true, 8); + + Component * b_4 = new Component(Component::BLUE, Component::UNSIGNED, true, 4); + Component * b_5 = new Component(Component::BLUE, Component::UNSIGNED, true, 5); + Component * b_8 = new Component(Component::BLUE, Component::UNSIGNED, true, 8); + + Component * a_1 = new Component(Component::ALPHA, Component::UNSIGNED, true, 1); + Component * a_4 = new Component(Component::ALPHA, Component::UNSIGNED, true, 4); + Component * a_8 = new Component(Component::ALPHA, Component::UNSIGNED, true, 8); + + Component * idx_16 = new Component(Component::INDEX, Component::UNSIGNED, false, 16); + Component * idx_32 = new Component(Component::INDEX, Component::UNSIGNED, false, 32); + + Component * x = new Component(Component::X, Component::FLOAT, false, 32); + Component * y = new Component(Component::Y, Component::FLOAT, false, 32); + Component * z = new Component(Component::Z, Component::FLOAT, false, 32); + + Component * nx = new Component(Component::NX, Component::FLOAT, false, 32); + Component * ny = new Component(Component::NY, Component::FLOAT, false, 32); + Component * nz = new Component(Component::NZ, Component::FLOAT, false, 32); + + Component * s = new Component(Component::S, Component::FLOAT, false, 32); + Component * t = new Component(Component::T, Component::FLOAT, false, 32); + + Element * e; + + e = new Element(1); + e->setComponent(0, u_8); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_U8, e)); + + e = new Element(1); + e->setComponent(0, i_8); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_I8, e)); + + e = new Element(1); + e->setComponent(0, u_16); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_U16, e)); + + e = new Element(1); + e->setComponent(0, i_16); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_I16, e)); + + e = new Element(1); + e->setComponent(0, u_32); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_U32, e)); + + e = new Element(1); + e->setComponent(0, i_32); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_I32, e)); + + e = new Element(1); + e->setComponent(0, f_32); + mPredefinedList.add(Predefined(RS_ELEMENT_USER_FLOAT, e)); + + e = new Element(1); + e->setComponent(0, a_8); + mPredefinedList.add(Predefined(RS_ELEMENT_A_8, e)); + + e = new Element(3); + e->setComponent(0, r_5); + e->setComponent(1, g_6); + e->setComponent(2, b_5); + mPredefinedList.add(Predefined(RS_ELEMENT_RGB_565, e)); + + e = new Element(4); + e->setComponent(0, r_5); + e->setComponent(1, g_5); + e->setComponent(2, b_5); + e->setComponent(3, a_1); + mPredefinedList.add(Predefined(RS_ELEMENT_RGBA_5551, e)); + + e = new Element(4); + e->setComponent(0, r_4); + e->setComponent(1, g_4); + e->setComponent(2, b_4); + e->setComponent(3, a_4); + mPredefinedList.add(Predefined(RS_ELEMENT_RGBA_4444, e)); + + e = new Element(3); + e->setComponent(0, r_8); + e->setComponent(1, g_8); + e->setComponent(2, b_8); + mPredefinedList.add(Predefined(RS_ELEMENT_RGB_888, e)); + + e = new Element(4); + e->setComponent(0, r_8); + e->setComponent(1, g_8); + e->setComponent(2, b_8); + e->setComponent(3, a_8); + mPredefinedList.add(Predefined(RS_ELEMENT_RGBA_8888, e)); + + e = new Element(1); + e->setComponent(0, idx_16); + mPredefinedList.add(Predefined(RS_ELEMENT_INDEX_16, e)); + + e = new Element(1); + e->setComponent(0, idx_32); + mPredefinedList.add(Predefined(RS_ELEMENT_INDEX_32, e)); + + e = new Element(2); + e->setComponent(0, x); + e->setComponent(1, y); + mPredefinedList.add(Predefined(RS_ELEMENT_XY_F32, e)); + + e = new Element(3); + e->setComponent(0, x); + e->setComponent(1, y); + e->setComponent(2, z); + mPredefinedList.add(Predefined(RS_ELEMENT_XYZ_F32, e)); + + e = new Element(4); + e->setComponent(0, s); + e->setComponent(1, t); + e->setComponent(2, x); + e->setComponent(3, y); + mPredefinedList.add(Predefined(RS_ELEMENT_ST_XY_F32, e)); + + e = new Element(5); + e->setComponent(0, s); + e->setComponent(1, t); + e->setComponent(2, x); + e->setComponent(3, y); + e->setComponent(4, z); + mPredefinedList.add(Predefined(RS_ELEMENT_ST_XYZ_F32, e)); + + e = new Element(6); + e->setComponent(0, nx); + e->setComponent(1, ny); + e->setComponent(2, nz); + e->setComponent(3, x); + e->setComponent(4, y); + e->setComponent(5, z); + mPredefinedList.add(Predefined(RS_ELEMENT_NORM_XYZ_F32, e)); + + e = new Element(8); + e->setComponent(0, nx); + e->setComponent(1, ny); + e->setComponent(2, nz); + e->setComponent(3, s); + e->setComponent(4, t); + e->setComponent(5, x); + e->setComponent(6, y); + e->setComponent(7, z); + mPredefinedList.add(Predefined(RS_ELEMENT_NORM_ST_XYZ_F32, e)); +} + + +Element::Element() +{ + mComponents = NULL; + mComponentCount = 0; +} + +Element::Element(uint32_t count) +{ + mComponents = new ObjectBaseRef<Component> [count]; + mComponentCount = count; +} + +Element::~Element() +{ + clear(); +} + +void Element::clear() +{ + delete [] mComponents; + mComponents = NULL; + mComponentCount = 0; +} + +void Element::setComponent(uint32_t idx, Component *c) +{ + rsAssert(!mComponents[idx].get()); + rsAssert(idx < mComponentCount); + mComponents[idx].set(c); + c->incRef(); +} + + +size_t Element::getSizeBits() const +{ + size_t total = 0; + for (size_t ct=0; ct < mComponentCount; ct++) { + total += mComponents[ct]->getBits(); + } + return total; +} + +size_t Element::getComponentOffsetBits(uint32_t componentNumber) const +{ + size_t offset = 0; + for (uint32_t ct = 0; ct < componentNumber; ct++) { + offset += mComponents[ct]->getBits(); + } + return offset; +} + +uint32_t Element::getGLType() const +{ + int bits[4]; + + if (mComponentCount > 4) { + return 0; + } + + for (uint32_t ct=0; ct < mComponentCount; ct++) { + bits[ct] = mComponents[ct]->getBits(); + if (mComponents[ct]->getType() != Component::UNSIGNED) { + return 0; + } + if (!mComponents[ct]->getIsNormalized()) { + return 0; + } + } + + switch(mComponentCount) { + case 1: + if (bits[0] == 8) { + return GL_UNSIGNED_BYTE; + } + return 0; + case 2: + if ((bits[0] == 8) && + (bits[1] == 8)) { + return GL_UNSIGNED_BYTE; + } + return 0; + case 3: + if ((bits[0] == 8) && + (bits[1] == 8) && + (bits[2] == 8)) { + return GL_UNSIGNED_BYTE; + } + if ((bits[0] == 5) && + (bits[1] == 6) && + (bits[2] == 5)) { + return GL_UNSIGNED_SHORT_5_6_5; + } + return 0; + case 4: + if ((bits[0] == 8) && + (bits[1] == 8) && + (bits[2] == 8) && + (bits[3] == 8)) { + return GL_UNSIGNED_BYTE; + } + if ((bits[0] == 4) && + (bits[1] == 4) && + (bits[2] == 4) && + (bits[3] == 4)) { + return GL_UNSIGNED_SHORT_4_4_4_4; + } + if ((bits[0] == 5) && + (bits[1] == 5) && + (bits[2] == 5) && + (bits[3] == 1)) { + return GL_UNSIGNED_SHORT_5_5_5_1; + } + } + return 0; +} + +uint32_t Element::getGLFormat() const +{ + switch(mComponentCount) { + case 1: + if (mComponents[0]->getKind() == Component::ALPHA) { + return GL_ALPHA; + } + if (mComponents[0]->getKind() == Component::LUMINANCE) { + return GL_LUMINANCE; + } + break; + case 2: + if ((mComponents[0]->getKind() == Component::LUMINANCE) && + (mComponents[1]->getKind() == Component::ALPHA)) { + return GL_LUMINANCE_ALPHA; + } + break; + case 3: + if ((mComponents[0]->getKind() == Component::RED) && + (mComponents[1]->getKind() == Component::GREEN) && + (mComponents[2]->getKind() == Component::BLUE)) { + return GL_RGB; + } + break; + case 4: + if ((mComponents[0]->getKind() == Component::RED) && + (mComponents[1]->getKind() == Component::GREEN) && + (mComponents[2]->getKind() == Component::BLUE) && + (mComponents[3]->getKind() == Component::ALPHA)) { + return GL_RGBA; + } + break; + } + return 0; +} + + +ElementState::ElementState() +{ +} + +ElementState::~ElementState() +{ +} + +///////////////////////////////////////// +// + +namespace android { +namespace renderscript { + +void rsi_ElementBegin(Context *rsc) +{ + rsc->mStateElement.mComponentBuildList.clear(); +} + +void rsi_ElementAddPredefined(Context *rsc, RsElementPredefined predef) +{ + ElementState * sec = &rsc->mStateElement; + + RsElement ve = rsi_ElementGetPredefined(rsc, predef); + const Element *e = static_cast<const Element *>(ve); + + for(size_t ct = 0; ct < sec->mPredefinedList[predef].mElement->getComponentCount(); ct++) { + sec->mComponentBuildList.add(sec->mPredefinedList[predef].mElement->getComponent(ct)); + } +} + +RsElement rsi_ElementGetPredefined(Context *rsc, RsElementPredefined predef) +{ + ElementState * sec = &rsc->mStateElement; + + if (!sec->mPredefinedList.size()) { + sec->initPredefined(); + } + + if ((predef < 0) || + (static_cast<uint32_t>(predef) >= sec->mPredefinedList.size())) { + LOGE("rsElementGetPredefined: Request for bad predefined type"); + // error + return NULL; + } + + rsAssert(sec->mPredefinedList[predef].mEnum == predef); + Element * e = sec->mPredefinedList[predef].mElement; + e->incRef(); + return e; +} + +void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits) +{ + ElementState * sec = &rsc->mStateElement; + +} + +RsElement rsi_ElementCreate(Context *rsc) +{ + ElementState * sec = &rsc->mStateElement; + + Element *se = new Element(sec->mComponentBuildList.size()); + sec->mAllElements.add(se); + + for (size_t ct = 0; ct < se->getComponentCount(); ct++) { + se->setComponent(ct, sec->mComponentBuildList[ct]); + } + + rsc->mStateElement.mComponentBuildList.clear(); + se->incRef(); + return se; +} + +void rsi_ElementDestroy(Context *rsc, RsElement vse) +{ + ElementState * sec = &rsc->mStateElement; + Element * se = static_cast<Element *>(vse); + + for (size_t ct = 0; ct < sec->mAllElements.size(); ct++) { + if (sec->mAllElements[ct] == se) { + sec->mAllElements.removeAt(ct); + break; + } + } + se->decRef(); +} + + +} +} diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h new file mode 100644 index 0000000..ea6fa8f --- /dev/null +++ b/libs/rs/rsElement.h @@ -0,0 +1,96 @@ +/* + * 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. + */ + +#ifndef ANDROID_STRUCTURED_ELEMENT_H +#define ANDROID_STRUCTURED_ELEMENT_H + +#include "rsComponent.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +// An element is a group of Components that occupies one cell in a structure. +class Element : public ObjectBase +{ +public: + Element(uint32_t count); + ~Element(); + + + void setComponent(uint32_t idx, Component *c); + + uint32_t getGLType() const; + uint32_t getGLFormat() const; + + + size_t getSizeBits() const; + size_t getSizeBytes() const { + return (getSizeBits() + 7) >> 3; + } + + size_t getComponentOffsetBits(uint32_t componentNumber) const; + size_t getComponentOffsetBytes(uint32_t componentNumber) const { + return (getComponentOffsetBits(componentNumber) + 7) >> 3; + } + + uint32_t getComponentCount() const {return mComponentCount;} + Component * getComponent(uint32_t idx) const {return mComponents[idx].get();} + +protected: + // deallocate any components that are part of this element. + void clear(); + + size_t mComponentCount; + ObjectBaseRef<Component> * mComponents; + //uint32_t *mOffsetTable; + + Element(); +}; + + +class ElementState { +public: + ElementState(); + ~ElementState(); + + Vector<Element *> mAllElements; + Vector<Component *> mComponentBuildList; + + + + struct Predefined { + Predefined() { + mElement = NULL; + } + Predefined(RsElementPredefined en, Element *e) { + mEnum = en; + mElement = e; + } + RsElementPredefined mEnum; + Element * mElement; + }; + Vector<Predefined> mPredefinedList; + + void initPredefined(); + +}; + + +} +} +#endif //ANDROID_STRUCTURED_ELEMENT_H diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp new file mode 100644 index 0000000..86d294b --- /dev/null +++ b/libs/rs/rsFileA3D.cpp @@ -0,0 +1,384 @@ + +/* + * 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. + */ + +#include "rsContext.h" + + +#include <utils/String8.h> +#include "rsFileA3D.h" + +#include "rsMesh.h" + +using namespace android; +using namespace android::renderscript; + + + +FileA3D::FileA3D() +{ + mRsc = NULL; +} + +FileA3D::~FileA3D() +{ +} + +bool FileA3D::load(Context *rsc, FILE *f) +{ + char magicString[12]; + size_t len; + + LOGE("file open 1"); + len = fread(magicString, 1, 12, f); + if ((len != 12) || + memcmp(magicString, "Android3D_ff", 12)) { + return false; + } + + LOGE("file open 2"); + len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f); + if (len != sizeof(mMajorVersion)) { + return false; + } + + LOGE("file open 3"); + len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f); + if (len != sizeof(mMinorVersion)) { + return false; + } + + LOGE("file open 4"); + uint32_t flags; + len = fread(&flags, 1, sizeof(flags), f); + if (len != sizeof(flags)) { + return false; + } + mUse64BitOffsets = (flags & 1) != 0; + + LOGE("file open 64bit = %i", mUse64BitOffsets); + + if (mUse64BitOffsets) { + len = fread(&mDataSize, 1, sizeof(mDataSize), f); + if (len != sizeof(mDataSize)) { + return false; + } + } else { + uint32_t tmp; + len = fread(&tmp, 1, sizeof(tmp), f); + if (len != sizeof(tmp)) { + return false; + } + mDataSize = tmp; + } + + LOGE("file open size = %lli", mDataSize); + + // We should know enough to read the file in at this point. + fseek(f, SEEK_SET, 0); + mAlloc= malloc(mDataSize); + if (!mAlloc) { + return false; + } + mData = (uint8_t *)mAlloc; + len = fread(mAlloc, 1, mDataSize, f); + if (len != mDataSize) { + return false; + } + + LOGE("file start processing"); + return process(rsc); +} + +bool FileA3D::processIndex(Context *rsc, A3DIndexEntry *ie) +{ + bool ret = false; + IO io(mData + ie->mOffset, mUse64BitOffsets); + + LOGE("process index, type %i", ie->mType); + + switch(ie->mType) { + case CHUNK_ELEMENT: + processChunk_Element(rsc, &io, ie); + break; + case CHUNK_ELEMENT_SOURCE: + processChunk_ElementSource(rsc, &io, ie); + break; + case CHUNK_VERTICIES: + processChunk_Verticies(rsc, &io, ie); + break; + case CHUNK_MESH: + processChunk_Mesh(rsc, &io, ie); + break; + case CHUNK_PRIMITIVE: + processChunk_Primitive(rsc, &io, ie); + break; + default: + LOGE("FileA3D Unknown chunk type"); + break; + } + return (ie->mRsObj != NULL); +} + +bool FileA3D::process(Context *rsc) +{ + LOGE("process"); + IO io(mData + 12, mUse64BitOffsets); + bool ret = true; + + // Build the index first + LOGE("process 1"); + io.loadU32(); // major version, already loaded + io.loadU32(); // minor version, already loaded + LOGE("process 2"); + + io.loadU32(); // flags + io.loadOffset(); // filesize, already loaded. + LOGE("process 4"); + uint64_t mIndexOffset = io.loadOffset(); + uint64_t mStringOffset = io.loadOffset(); + + LOGE("process mIndexOffset= 0x%016llx", mIndexOffset); + LOGE("process mStringOffset= 0x%016llx", mStringOffset); + + IO index(mData + mIndexOffset, mUse64BitOffsets); + IO stringTable(mData + mStringOffset, mUse64BitOffsets); + + uint32_t stringEntryCount = stringTable.loadU32(); + LOGE("stringEntryCount %i", stringEntryCount); + mStrings.setCapacity(stringEntryCount); + mStringIndexValues.setCapacity(stringEntryCount); + if (stringEntryCount) { + uint32_t stringType = stringTable.loadU32(); + LOGE("stringType %i", stringType); + rsAssert(stringType==0); + for (uint32_t ct = 0; ct < stringEntryCount; ct++) { + uint64_t offset = stringTable.loadOffset(); + LOGE("string offset 0x%016llx", offset); + IO tmp(mData + offset, mUse64BitOffsets); + String8 s; + tmp.loadString(&s); + LOGE("string %s", s.string()); + mStrings.push(s); + } + } + + LOGE("strings done"); + uint32_t indexEntryCount = index.loadU32(); + LOGE("index count %i", indexEntryCount); + mIndex.setCapacity(indexEntryCount); + for (uint32_t ct = 0; ct < indexEntryCount; ct++) { + A3DIndexEntry e; + uint32_t stringIndex = index.loadU32(); + LOGE("index %i", ct); + LOGE(" string index %i", stringIndex); + e.mType = (A3DChunkType)index.loadU32(); + LOGE(" type %i", e.mType); + e.mOffset = index.loadOffset(); + LOGE(" offset 0x%016llx", e.mOffset); + + if (stringIndex && (stringIndex < mStrings.size())) { + e.mID = mStrings[stringIndex]; + mStringIndexValues.editItemAt(stringIndex) = ct; + LOGE(" id %s", e.mID.string()); + } + + mIndex.push(e); + } + LOGE("index done"); + + // At this point the index should be fully populated. + // We can now walk though it and load all the objects. + for (uint32_t ct = 0; ct < indexEntryCount; ct++) { + LOGE("processing index entry %i", ct); + processIndex(rsc, &mIndex.editItemAt(ct)); + } + + return ret; +} + + +FileA3D::IO::IO(const uint8_t *buf, bool use64) +{ + mData = buf; + mPos = 0; + mUse64 = use64; +} + +uint64_t FileA3D::IO::loadOffset() +{ + uint64_t tmp; + if (mUse64) { + mPos = (mPos + 7) & (~7); + tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0]; + mPos += sizeof(uint64_t); + return tmp; + } + return loadU32(); +} + +void FileA3D::IO::loadString(String8 *s) +{ + LOGE("loadString"); + uint32_t len = loadU32(); + LOGE("loadString len %i", len); + s->setTo((const char *)&mData[mPos], len); + mPos += len; +} + + +void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie) +{ + Mesh * m = new Mesh; + + m->mPrimitivesCount = io->loadU32(); + m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount]; + + for (uint32_t ct = 0; ct < m->mPrimitivesCount; ct++) { + uint32_t index = io->loadU32(); + + m->mPrimitives[ct] = (Mesh::Primitive_t *)mIndex[index].mRsObj; + } + ie->mRsObj = m; +} + +void FileA3D::processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie) +{ + Mesh::Primitive_t * p = new Mesh::Primitive_t; + + p->mIndexCount = io->loadU32(); + uint32_t vertIdx = io->loadU32(); + p->mRestartCounts = io->loadU16(); + uint32_t bits = io->loadU8(); + p->mType = (RsPrimitive)io->loadU8(); + + LOGE("processChunk_Primitive count %i, bits %i", p->mIndexCount, bits); + + p->mVerticies = (Mesh::Verticies_t *)mIndex[vertIdx].mRsObj; + + p->mIndicies = new uint16_t[p->mIndexCount]; + for (uint32_t ct = 0; ct < p->mIndexCount; ct++) { + switch(bits) { + case 8: + p->mIndicies[ct] = io->loadU8(); + break; + case 16: + p->mIndicies[ct] = io->loadU16(); + break; + case 32: + p->mIndicies[ct] = io->loadU32(); + break; + } + LOGE(" idx %i", p->mIndicies[ct]); + } + + if (p->mRestartCounts) { + p->mRestarts = new uint16_t[p->mRestartCounts]; + for (uint32_t ct = 0; ct < p->mRestartCounts; ct++) { + switch(bits) { + case 8: + p->mRestarts[ct] = io->loadU8(); + break; + case 16: + p->mRestarts[ct] = io->loadU16(); + break; + case 32: + p->mRestarts[ct] = io->loadU32(); + break; + } + LOGE(" idx %i", p->mRestarts[ct]); + } + } else { + p->mRestarts = NULL; + } + + ie->mRsObj = p; +} + +void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie) +{ + Mesh::Verticies_t *cv = new Mesh::Verticies_t; + cv->mAllocationCount = io->loadU32(); + cv->mAllocations = new Allocation *[cv->mAllocationCount]; + LOGE("processChunk_Verticies count %i", cv->mAllocationCount); + for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) { + uint32_t i = io->loadU32(); + cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj; + LOGE(" idx %i", i); + } + ie->mRsObj = cv; +} + +void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie) +{ + rsi_ElementBegin(rsc); + + uint32_t count = io->loadU32(); + LOGE("processChunk_Element count %i", count); + while (count--) { + RsDataKind dk = (RsDataKind)io->loadU8(); + RsDataType dt = (RsDataType)io->loadU8(); + uint32_t bits = io->loadU8(); + bool isNorm = io->loadU8() != 0; + LOGE(" %i %i %i %i", dk, dt, bits, isNorm); + rsi_ElementAdd(rsc, dk, dt, isNorm, bits); + } + LOGE("processChunk_Element create"); + ie->mRsObj = rsi_ElementCreate(rsc); +} + +void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie) +{ + uint32_t index = io->loadU32(); + uint32_t count = io->loadU32(); + + LOGE("processChunk_ElementSource count %i, index %i", count, index); + + RsElement e = (RsElement)mIndex[index].mRsObj; + + RsAllocation a = rsi_AllocationCreateSized(rsc, e, count); + Allocation * alloc = static_cast<Allocation *>(a); + + float * data = (float *)alloc->getPtr(); + while(count--) { + *data = io->loadF(); + LOGE(" %f", *data); + data++; + } + ie->mRsObj = alloc; +} + +namespace android { +namespace renderscript { + + +RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len) +{ + FileA3D *fa3d = new FileA3D; + + FILE *f = fopen("/sdcard/test.a3d", "rb"); + if (f) { + fa3d->load(rsc, f); + fclose(f); + return fa3d; + } + delete fa3d; + return NULL; +} + + +} +} diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h new file mode 100644 index 0000000..9ee08ec --- /dev/null +++ b/libs/rs/rsFileA3D.h @@ -0,0 +1,122 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_FILE_A3D_H +#define ANDROID_RS_FILE_A3D_H + +#include "RenderScript.h" +#include "rsFileA3DDecls.h" +#include "rsMesh.h" + +#include <utils/String8.h> +#include <stdio.h> + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class FileA3D +{ +public: + FileA3D(); + ~FileA3D(); + + uint32_t mMajorVersion; + uint32_t mMinorVersion; + uint64_t mIndexOffset; + uint64_t mStringTableOffset; + bool mUse64BitOffsets; + + struct A3DIndexEntry { + String8 mID; + A3DChunkType mType; + uint64_t mOffset; + void * mRsObj; + }; + + bool load(Context *rsc, FILE *f); + +protected: + class IO + { + public: + IO(const uint8_t *, bool use64); + + float loadF() { + mPos = (mPos + 3) & (~3); + float tmp = reinterpret_cast<const float *>(&mData[mPos])[0]; + mPos += sizeof(float); + return tmp; + } + int32_t loadI32() { + mPos = (mPos + 3) & (~3); + int32_t tmp = reinterpret_cast<const int32_t *>(&mData[mPos])[0]; + mPos += sizeof(int32_t); + return tmp; + } + uint32_t loadU32() { + mPos = (mPos + 3) & (~3); + uint32_t tmp = reinterpret_cast<const uint32_t *>(&mData[mPos])[0]; + mPos += sizeof(uint32_t); + return tmp; + } + uint16_t loadU16() { + mPos = (mPos + 1) & (~1); + uint16_t tmp = reinterpret_cast<const uint16_t *>(&mData[mPos])[0]; + mPos += sizeof(uint16_t); + return tmp; + } + uint8_t loadU8() { + uint8_t tmp = reinterpret_cast<const uint8_t *>(&mData[mPos])[0]; + mPos += sizeof(uint8_t); + return tmp; + } + uint64_t loadOffset(); + void loadString(String8 *s); + uint64_t getPos() const {return mPos;} + const uint8_t * getPtr() const; + protected: + const uint8_t * mData; + uint64_t mPos; + bool mUse64; + }; + + + bool process(Context *rsc); + bool processIndex(Context *rsc, A3DIndexEntry *); + void processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie); + + const uint8_t * mData; + void * mAlloc; + uint64_t mDataSize; + Context * mRsc; + + Vector<A3DIndexEntry> mIndex; + Vector<String8> mStrings; + Vector<uint32_t> mStringIndexValues; + +}; + + +} +} +#endif //ANDROID_RS_FILE_A3D_H + + diff --git a/libs/rs/rsFileA3DDecls.h b/libs/rs/rsFileA3DDecls.h new file mode 100644 index 0000000..2a08bd3 --- /dev/null +++ b/libs/rs/rsFileA3DDecls.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_FILE_A3D_DECLS_H +#define ANDROID_RS_FILE_A3D_DECLS_H + + +#define A3D_MAGIC_KEY "Android3D_ff" + +namespace android { +namespace renderscript { + + enum A3DChunkType { + CHUNK_EMPTY, + + CHUNK_ELEMENT, + CHUNK_ELEMENT_SOURCE, + CHUNK_VERTICIES, + CHUNK_MESH, + CHUNK_PRIMITIVE, + + CHUNK_LAST + }; + + +} +} +#endif //ANDROID_RS_FILE_A3D_H + + + diff --git a/libs/rs/rsLight.cpp b/libs/rs/rsLight.cpp new file mode 100644 index 0000000..24b58b6 --- /dev/null +++ b/libs/rs/rsLight.cpp @@ -0,0 +1,134 @@ +/* + * 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. + */ + +#include "rsContext.h" + +#include <GLES/gl.h> + +using namespace android; +using namespace android::renderscript; + + +Light::Light(bool isLocal, bool isMono) +{ + mIsLocal = isLocal; + mIsMono = isMono; + + mPosition[0] = 0; + mPosition[1] = 0; + mPosition[2] = 1; + mPosition[3] = 0; + + mColor[0] = 1.f; + mColor[1] = 1.f; + mColor[2] = 1.f; + mColor[3] = 1.f; +} + +Light::~Light() +{ +} + +void Light::setPosition(float x, float y, float z) +{ + mPosition[0] = x; + mPosition[1] = y; + mPosition[2] = z; +} + +void Light::setColor(float r, float g, float b) +{ + mColor[0] = r; + mColor[1] = g; + mColor[2] = b; +} + +void Light::setupGL(uint32_t num) const +{ + glLightfv(GL_LIGHT0 + num, GL_DIFFUSE, mColor); + glLightfv(GL_LIGHT0 + num, GL_SPECULAR, mColor); + glLightfv(GL_LIGHT0 + num, GL_POSITION, mPosition); +} + +//////////////////////////////////////////// + +LightState::LightState() +{ + clear(); +} + +LightState::~LightState() +{ +} + +void LightState::clear() +{ + mIsLocal = false; + mIsMono = false; +} + + +//////////////////////////////////////////////////// +// + +namespace android { +namespace renderscript { + +void rsi_LightBegin(Context *rsc) +{ + rsc->mStateLight.clear(); +} + +void rsi_LightSetLocal(Context *rsc, bool isLocal) +{ + rsc->mStateLight.mIsLocal = isLocal; +} + +void rsi_LightSetMonochromatic(Context *rsc, bool isMono) +{ + rsc->mStateLight.mIsMono = isMono; +} + +RsLight rsi_LightCreate(Context *rsc) +{ + Light *l = new Light(rsc->mStateLight.mIsLocal, + rsc->mStateLight.mIsMono); + l->incRef(); + return l; +} + +void rsi_LightDestroy(Context *rsc, RsLight vl) +{ + Light *l = static_cast<Light *>(vl); + l->decRef(); +} + +void rsi_LightSetColor(Context *rsc, RsLight vl, float r, float g, float b) +{ + Light *l = static_cast<Light *>(vl); + l->setColor(r, g, b); +} + +void rsi_LightSetPosition(Context *rsc, RsLight vl, float x, float y, float z) +{ + Light *l = static_cast<Light *>(vl); + l->setPosition(x, y, z); +} + + + +} +} diff --git a/libs/rs/rsLight.h b/libs/rs/rsLight.h new file mode 100644 index 0000000..b0c3386 --- /dev/null +++ b/libs/rs/rsLight.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#ifndef ANDROID_LIGHT_H +#define ANDROID_LIGHT_H + + +#include "rsObjectBase.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +// An element is a group of Components that occupies one cell in a structure. +class Light : public ObjectBase +{ +public: + Light(bool isLocal, bool isMono); + virtual ~Light(); + + // Values, mutable after creation. + void setPosition(float x, float y, float z); + void setColor(float r, float g, float b); + + void setupGL(uint32_t num) const; + +protected: + float mColor[4]; + float mPosition[4]; + bool mIsLocal; + bool mIsMono; +}; + + +class LightState { +public: + LightState(); + ~LightState(); + + void clear(); + + bool mIsMono; + bool mIsLocal; +}; + + +} +} +#endif //ANDROID_LIGHT_H + diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp new file mode 100644 index 0000000..c3fee54 --- /dev/null +++ b/libs/rs/rsLocklessFifo.cpp @@ -0,0 +1,247 @@ +/* + * 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. + */ + +#include "rsLocklessFifo.h" + +using namespace android; + + +LocklessCommandFifo::LocklessCommandFifo() +{ +} + +LocklessCommandFifo::~LocklessCommandFifo() +{ +} + +bool LocklessCommandFifo::init(uint32_t sizeInBytes) +{ + // Add room for a buffer reset command + mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4)); + if (!mBuffer) { + LOGE("LocklessFifo allocation failure"); + return false; + } + + if (!mSignalToControl.init() || !mSignalToWorker.init()) { + LOGE("Signal setup failed"); + free(mBuffer); + return false; + } + + mSize = sizeInBytes; + mPut = mBuffer; + mGet = mBuffer; + mEnd = mBuffer + (sizeInBytes) - 1; + dumpState("init"); + return true; +} + +uint32_t LocklessCommandFifo::getFreeSpace() const +{ + int32_t freeSpace = 0; + //dumpState("getFreeSpace"); + + if (mPut >= mGet) { + freeSpace = mEnd - mPut; + } else { + freeSpace = mGet - mPut; + } + + if (freeSpace < 0) { + freeSpace = 0; + } + return freeSpace; +} + +bool LocklessCommandFifo::isEmpty() const +{ + return mPut == mGet; +} + + +void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) +{ + // Add space for command header and loop token; + sizeInBytes += 8; + + //dumpState("reserve"); + if (getFreeSpace() < sizeInBytes) { + makeSpace(sizeInBytes); + } + + return mPut + 4; +} + +void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) +{ + //dumpState("commit 1"); + reinterpret_cast<uint16_t *>(mPut)[0] = command; + reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes; + mPut += ((sizeInBytes + 3) & ~3) + 4; + //dumpState("commit 2"); + mSignalToWorker.set(); +} + +void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) +{ + commit(command, sizeInBytes); + flush(); +} + +void LocklessCommandFifo::flush() +{ + //dumpState("flush 1"); + while(mPut != mGet) { + mSignalToControl.wait(); + } + //dumpState("flush 2"); +} + +const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) +{ + while(1) { + //dumpState("get"); + while(isEmpty()) { + mSignalToControl.set(); + mSignalToWorker.wait(); + } + + *command = reinterpret_cast<const uint16_t *>(mGet)[0]; + *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1]; + if (*command) { + // non-zero command is valid + return mGet+4; + } + + // zero command means reset to beginning. + mGet = mBuffer; + } +} + +void LocklessCommandFifo::next() +{ + uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1]; + mGet += ((bytes + 3) & ~3) + 4; + if (isEmpty()) { + mSignalToControl.set(); + } + //dumpState("next"); +} + +void LocklessCommandFifo::makeSpace(uint32_t bytes) +{ + //dumpState("make space"); + if ((mPut+bytes) > mEnd) { + // Need to loop regardless of where get is. + while((mGet > mPut) && (mBuffer+4 >= mGet)) { + sleep(1); + } + + // Toss in a reset then the normal wait for space will do the rest. + reinterpret_cast<uint16_t *>(mPut)[0] = 0; + reinterpret_cast<uint16_t *>(mPut)[1] = 0; + mPut = mBuffer; + } + + // it will fit here so we just need to wait for space. + while(getFreeSpace() < bytes) { + sleep(1); + } + +} + +void LocklessCommandFifo::dumpState(const char *s) const +{ + LOGV("%s put %p, get %p, buf %p, end %p", s, mPut, mGet, mBuffer, mEnd); +} + +LocklessCommandFifo::Signal::Signal() +{ + mSet = true; +} + +LocklessCommandFifo::Signal::~Signal() +{ + pthread_mutex_destroy(&mMutex); + pthread_cond_destroy(&mCondition); +} + +bool LocklessCommandFifo::Signal::init() +{ + int status = pthread_mutex_init(&mMutex, NULL); + if (status) { + LOGE("LocklessFifo mutex init failure"); + return false; + } + + status = pthread_cond_init(&mCondition, NULL); + if (status) { + LOGE("LocklessFifo condition init failure"); + pthread_mutex_destroy(&mMutex); + return false; + } + + return true; +} + +void LocklessCommandFifo::Signal::set() +{ + int status; + + status = pthread_mutex_lock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i locking for set condition.", status); + return; + } + + mSet = true; + + status = pthread_cond_signal(&mCondition); + if (status) { + LOGE("LocklessCommandFifo: error %i on set condition.", status); + } + + status = pthread_mutex_unlock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i unlocking for set condition.", status); + } +} + +void LocklessCommandFifo::Signal::wait() +{ + int status; + + status = pthread_mutex_lock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i locking for condition.", status); + return; + } + + if (!mSet) { + status = pthread_cond_wait(&mCondition, &mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i waiting on condition.", status); + } + } + mSet = false; + + status = pthread_mutex_unlock(&mMutex); + if (status) { + LOGE("LocklessCommandFifo: error %i unlocking for condition.", status); + } +} + diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h new file mode 100644 index 0000000..abeddf7 --- /dev/null +++ b/libs/rs/rsLocklessFifo.h @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_LOCKLESS_FIFO_H +#define ANDROID_RS_LOCKLESS_FIFO_H + + +#include "rsUtils.h" + +namespace android { + + +// A simple FIFO to be used as a producer / consumer between two +// threads. One is writer and one is reader. The common cases +// will not require locking. It is not threadsafe for multiple +// readers or writers by design. + +class LocklessCommandFifo +{ +public: + bool init(uint32_t size); + + LocklessCommandFifo(); + ~LocklessCommandFifo(); + + +protected: + class Signal { + public: + Signal(); + ~Signal(); + + bool init(); + + void set(); + void wait(); + + protected: + bool mSet; + pthread_mutex_t mMutex; + pthread_cond_t mCondition; + }; + + uint8_t * volatile mPut; + uint8_t * volatile mGet; + uint8_t * mBuffer; + uint8_t * mEnd; + uint8_t mSize; + + Signal mSignalToWorker; + Signal mSignalToControl; + + + +public: + void * reserve(uint32_t bytes); + void commit(uint32_t command, uint32_t bytes); + void commitSync(uint32_t command, uint32_t bytes); + + void flush(); + const void * get(uint32_t *command, uint32_t *bytesData); + void next(); + + void makeSpace(uint32_t bytes); + + bool isEmpty() const; + uint32_t getFreeSpace() const; + + +private: + void dumpState(const char *) const; +}; + + +} +#endif diff --git a/libs/rs/rsMatrix.cpp b/libs/rs/rsMatrix.cpp new file mode 100644 index 0000000..5f68197 --- /dev/null +++ b/libs/rs/rsMatrix.cpp @@ -0,0 +1,159 @@ +/* + * 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. + */ + +#include "rsMatrix.h" + +#include "stdlib.h" +#include "string.h" +#include "math.h" + +using namespace android; +using namespace android::renderscript; + + + +void Matrix::loadIdentity() +{ + set(0, 0, 1); + set(1, 0, 0); + set(2, 0, 0); + set(3, 0, 0); + + set(0, 1, 0); + set(1, 1, 1); + set(2, 1, 0); + set(3, 1, 0); + + set(0, 2, 0); + set(1, 2, 0); + set(2, 2, 1); + set(3, 2, 0); + + set(0, 3, 0); + set(1, 3, 0); + set(2, 3, 0); + set(3, 3, 1); +} + +void Matrix::load(const float *v) +{ + memcpy(m, v, sizeof(m)); +} + +void Matrix::load(const Matrix *v) +{ + memcpy(m, v->m, sizeof(m)); +} + +void Matrix::loadRotate(float rot, float x, float y, float z) +{ + float c, s; + m[3] = 0; + m[7] = 0; + m[11]= 0; + m[12]= 0; + m[13]= 0; + m[14]= 0; + m[15]= 1; + rot *= float(M_PI / 180.0f); + c = cosf(rot); + s = sinf(rot); + + const float len = sqrtf(x*x + y*y + z*z); + if (!(len != 1)) { + const float recipLen = 1.f / len; + x *= recipLen; + y *= recipLen; + z *= recipLen; + } + const float nc = 1.0f - c; + const float xy = x * y; + const float yz = y * z; + const float zx = z * x; + const float xs = x * s; + const float ys = y * s; + const float zs = z * s; + m[ 0] = x*x*nc + c; + m[ 4] = xy*nc - zs; + m[ 8] = zx*nc + ys; + m[ 1] = xy*nc + zs; + m[ 5] = y*y*nc + c; + m[ 9] = yz*nc - xs; + m[ 2] = zx*nc - ys; + m[ 6] = yz*nc + xs; + m[10] = z*z*nc + c; +} + +void Matrix::loadScale(float x, float y, float z) +{ + loadIdentity(); + m[0] = x; + m[5] = y; + m[10] = z; +} + +void Matrix::loadTranslate(float x, float y, float z) +{ + loadIdentity(); + m[12] = x; + m[13] = y; + m[14] = z; +} + +void Matrix::loadMultiply(const Matrix *lhs, const Matrix *rhs) +{ + for (int i=0 ; i<4 ; i++) { + float ri0 = 0; + float ri1 = 0; + float ri2 = 0; + float ri3 = 0; + for (int j=0 ; j<4 ; j++) { + const float rhs_ij = rhs->get(i,j); + ri0 += lhs->get(j,0) * rhs_ij; + ri1 += lhs->get(j,1) * rhs_ij; + ri2 += lhs->get(j,2) * rhs_ij; + ri3 += lhs->get(j,3) * rhs_ij; + } + set(i,0, ri0); + set(i,1, ri1); + set(i,2, ri2); + set(i,3, ri3); + } +} + +void Matrix::loadOrtho(float l, float r, float b, float t, float n, float f) { + loadIdentity(); + m[0] = 2 / (r - l); + m[5] = 2 / (t - b); + m[10]= -2 / (f - n); + m[12]= -(r + l) / (r - l); + m[13]= -(t + b) / (t - b); + m[14]= -(f + n) / (f - n); +} + +void Matrix::loadFrustum(float l, float r, float b, float t, float n, float f) { + loadIdentity(); + m[0] = 2 * n / (r - l); + m[5] = 2 * n / (t - b); + m[8] = (r + l) / (r - l); + m[9] = (t + b) / (t - b); + m[10]= -(f + n) / (f - n); + m[11]= -1; + m[14]= -2*f*n / (f - n); + m[15]= 0; +} + + diff --git a/libs/rs/rsMatrix.h b/libs/rs/rsMatrix.h new file mode 100644 index 0000000..7dc4165 --- /dev/null +++ b/libs/rs/rsMatrix.h @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_MATRIX_H +#define ANDROID_RS_MATRIX_H + + + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +struct Matrix +{ + float m[16]; + + inline float get(int i, int j) const { + return m[i*4 + j]; + } + + inline void set(int i, int j, float v) { + m[i*4 + j] = v; + } + + void loadIdentity(); + void load(const float *); + void load(const Matrix *); + + void loadRotate(float rot, float x, float y, float z); + void loadScale(float x, float y, float z); + void loadTranslate(float x, float y, float z); + void loadMultiply(const Matrix *lhs, const Matrix *rhs); + + void loadOrtho(float l, float r, float b, float t, float n, float f); + void loadFrustum(float l, float r, float b, float t, float n, float f); + + void multiply(const Matrix *rhs) { + Matrix tmp; + tmp.loadMultiply(this, rhs); + load(&tmp); + } + void rotate(float rot, float x, float y, float z) { + Matrix tmp; + tmp.loadRotate(rot, x, y, z); + multiply(&tmp); + } + void scale(float x, float y, float z) { + Matrix tmp; + tmp.loadScale(x, y, z); + multiply(&tmp); + } + void translate(float x, float y, float z) { + Matrix tmp; + tmp.loadTranslate(x, y, z); + multiply(&tmp); + } + + + +}; + + + +} +} + + + + +#endif + + + + diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp new file mode 100644 index 0000000..aeb52ed --- /dev/null +++ b/libs/rs/rsMesh.cpp @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + +#include <GLES/gl.h> +#include <GLES/glext.h> + +Mesh::Mesh() +{ + mVerticies = NULL; + mVerticiesCount = 0; + mPrimitives = NULL; + mPrimitivesCount = 0; +} + +Mesh::~Mesh() +{ +} + + + +MeshContext::MeshContext() +{ +} + +MeshContext::~MeshContext() +{ +} + diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h new file mode 100644 index 0000000..be207a3 --- /dev/null +++ b/libs/rs/rsMesh.h @@ -0,0 +1,90 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_MESH_H +#define ANDROID_RS_MESH_H + + +#include "RenderScript.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +// An element is a group of Components that occupies one cell in a structure. +class Mesh : public ObjectBase +{ +public: + Mesh(); + ~Mesh(); + + struct Verticies_t + { + Allocation ** mAllocations; + uint32_t mAllocationCount; + + size_t mVertexDataSize; + + size_t mOffsetCoord; + size_t mOffsetTex; + size_t mOffsetNorm; + + size_t mSizeCoord; + size_t mSizeTex; + size_t mSizeNorm; + + uint32_t mBufferObject; + }; + + struct Primitive_t + { + RsPrimitive mType; + Verticies_t *mVerticies; + + uint32_t mIndexCount; + uint16_t *mIndicies; + + uint32_t mRestartCounts; + uint16_t *mRestarts; + }; + + Verticies_t * mVerticies; + uint32_t mVerticiesCount; + + Primitive_t ** mPrimitives; + uint32_t mPrimitivesCount; + + + + void analyzeElement(); +protected: +}; + +class MeshContext +{ +public: + MeshContext(); + ~MeshContext(); + +}; + + +} +} +#endif //ANDROID_RS_TRIANGLE_MESH_H + + diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp new file mode 100644 index 0000000..3219c39 --- /dev/null +++ b/libs/rs/rsObjectBase.cpp @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#include "rsObjectBase.h" + +using namespace android; +using namespace android::renderscript; + +ObjectBase::ObjectBase() +{ + mRefCount = 0; + mName = NULL; +} + +ObjectBase::~ObjectBase() +{ + rsAssert(!mRefCount); +} + +void ObjectBase::incRef() const +{ + mRefCount ++; + //LOGV("ObjectBase %p inc ref %i", this, mRefCount); +} + +void ObjectBase::decRef() const +{ + rsAssert(mRefCount > 0); + mRefCount --; + //LOGV("ObjectBase %p dec ref %i", this, mRefCount); + if (!mRefCount) { + delete this; + } +} + +void ObjectBase::setName(const char *name) +{ + delete mName; + mName = NULL; + if (name) { + mName = new char[strlen(name) +1]; + strcpy(mName, name); + } +} + +void ObjectBase::setName(const char *name, uint32_t len) +{ + delete mName; + mName = NULL; + if (name) { + mName = new char[len + 1]; + memcpy(mName, name, len); + mName[len] = 0; + } +} + diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h new file mode 100644 index 0000000..b2c3338 --- /dev/null +++ b/libs/rs/rsObjectBase.h @@ -0,0 +1,114 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_OBJECT_BASE_H +#define ANDROID_RS_OBJECT_BASE_H + +#include "rsUtils.h" + + +namespace android { +namespace renderscript { + +// An element is a group of Components that occupies one cell in a structure. +class ObjectBase +{ +public: + ObjectBase(); + virtual ~ObjectBase(); + + void incRef() const; + void decRef() const; + + const char * getName() const { + return mName; + } + void setName(const char *); + void setName(const char *, uint32_t len); + +private: + char * mName; + mutable int32_t mRefCount; + + +}; + +template<class T> +class ObjectBaseRef +{ +public: + ObjectBaseRef() { + mRef = NULL; + } + + ObjectBaseRef(const ObjectBaseRef &ref) { + mRef = ref.get(); + if (mRef) { + mRef->incRef(); + } + } + + ObjectBaseRef(T *ref) { + mRef = ref; + if (mRef) { + ref->incRef(); + } + } + + ~ObjectBaseRef() { + clear(); + } + + void set(T *ref) { + if (mRef != ref) { + clear(); + mRef = ref; + if (mRef) { + ref->incRef(); + } + } + } + + void set(const ObjectBaseRef &ref) { + set(ref.mRef); + } + + void clear() { + if (mRef) { + mRef->decRef(); + } + mRef = NULL; + } + + inline T * get() const { + return mRef; + } + + inline T * operator-> () const { + return mRef; + } + +protected: + T * mRef; + +}; + + +} +} + +#endif //ANDROID_RS_OBJECT_BASE_H + diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp new file mode 100644 index 0000000..5a83fb7 --- /dev/null +++ b/libs/rs/rsProgram.cpp @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#include "rsContext.h" +#include "rsProgram.h" + +using namespace android; +using namespace android::renderscript; + + +Program::Program(Element *in, Element *out) +{ + mElementIn.set(in); + mElementOut.set(out); + + +} + +Program::~Program() +{ +} + + +void Program::setAllocation(Allocation *alloc) +{ + mConstants.set(alloc); + mDirty = true; +} + +void Program::setupGL() +{ + +} + + diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h new file mode 100644 index 0000000..913fdd2 --- /dev/null +++ b/libs/rs/rsProgram.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_PROGRAM_H +#define ANDROID_RS_PROGRAM_H + +#include "rsObjectBase.h" +#include "rsElement.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + + +class Program : public ObjectBase +{ +public: + Program(Element *in, Element *out); + virtual ~Program(); + + + void setAllocation(Allocation *); + + virtual void setupGL(); + +protected: + // Components not listed in "in" will be passed though + // unless overwritten by components in out. + ObjectBaseRef<Element> mElementIn; + ObjectBaseRef<Element> mElementOut; + + ObjectBaseRef<Allocation> mConstants; + + bool mDirty; + +}; + + + +} +} +#endif + + + diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp new file mode 100644 index 0000000..628f93e --- /dev/null +++ b/libs/rs/rsProgramFragment.cpp @@ -0,0 +1,251 @@ +/* + * 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. + */ + +#include "rsContext.h" +#include "rsProgramFragment.h" + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + + +ProgramFragment::ProgramFragment(Element *in, Element *out) : + Program(in, out) +{ + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE; + mTextureDimensions[ct] = 2; + } + mTextureEnableMask = 0; + mEnvModes[1] = RS_TEX_ENV_MODE_DECAL; +} + +ProgramFragment::~ProgramFragment() +{ +} + +void ProgramFragment::setupGL() +{ + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + glActiveTexture(GL_TEXTURE0 + ct); + if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { + glDisable(GL_TEXTURE_2D); + continue; + } + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); + + switch(mEnvModes[ct]) { + case RS_TEX_ENV_MODE_REPLACE: + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + case RS_TEX_ENV_MODE_MODULATE: + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case RS_TEX_ENV_MODE_DECAL: + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + break; + } + + if (mSamplers[ct].get()) { + mSamplers[ct]->setupGL(); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + // Gross hack. + if (ct == 2) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); + } + } + + + glActiveTexture(GL_TEXTURE0); +} + + +void ProgramFragment::bindTexture(uint32_t slot, Allocation *a) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); + return; + } + + //LOGE("bindtex %i %p", slot, a); + mTextures[slot].set(a); +} + +void ProgramFragment::bindSampler(uint32_t slot, Sampler *s) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); + return; + } + + mSamplers[slot].set(s); +} + +void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to setType to a slot > MAX_TEXTURE"); + return; + } + + if (dim >= 4) { + LOGE("Attempt to setType to a dimension > 3"); + return; + } + + mTextureFormats[slot].set(e); + mTextureDimensions[slot] = dim; +} + +void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); + return; + } + + mEnvModes[slot] = env; +} + +void ProgramFragment::setTexEnable(uint32_t slot, bool enable) +{ + if (slot >= MAX_TEXTURE) { + LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE"); + return; + } + + uint32_t bit = 1 << slot; + mTextureEnableMask &= ~bit; + if (enable) { + mTextureEnableMask |= bit; + } +} + + + +ProgramFragmentState::ProgramFragmentState() +{ + mPF = NULL; +} + +ProgramFragmentState::~ProgramFragmentState() +{ + delete mPF; + +} + +void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h) +{ + ProgramFragment *pf = new ProgramFragment(NULL, NULL); + mDefault.set(pf); +} + + +namespace android { +namespace renderscript { + +void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out) +{ + delete rsc->mStateFragment.mPF; + rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out); +} + +void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a) +{ + ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); + pf->bindTexture(slot, static_cast<Allocation *>(a)); + if (pf == rsc->getFragment()) { + pf->setupGL(); + } +} + +void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s) +{ + ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); + pf->bindSampler(slot, static_cast<Sampler *>(s)); + + if (pf == rsc->getFragment()) { + pf->setupGL(); + } +} + +void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt) +{ + const Type *t = static_cast<const Type *>(vt); + uint32_t dim = 1; + if (t->getDimY()) { + dim ++; + if (t->getDimZ()) { + dim ++; + } + } + + rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim); +} + +void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env) +{ + rsc->mStateFragment.mPF->setEnvMode(slot, env); +} + +void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable) +{ + rsc->mStateFragment.mPF->setTexEnable(slot, enable); +} + +RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc) +{ + ProgramFragment *pf = rsc->mStateFragment.mPF; + pf->incRef(); + rsc->mStateFragment.mPF = 0; + return pf; +} + +void rsi_ProgramFragmentDestroy(Context *rsc, RsProgramFragment vpf) +{ + ProgramFragment *pf = (ProgramFragment *)vpf; + if (pf->getName()) { + rsc->removeName(pf); + } + pf->decRef(); +} + + +} +} + diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h new file mode 100644 index 0000000..896d8dd --- /dev/null +++ b/libs/rs/rsProgramFragment.h @@ -0,0 +1,99 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_PROGRAM_FRAGMENT_H +#define ANDROID_RS_PROGRAM_FRAGMENT_H + +#include "rsProgram.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +class ProgramFragment : public Program +{ +public: + const static uint32_t MAX_TEXTURE = 2; + const static uint32_t MAX_CONSTANTS = 2; + + + + ProgramFragment(Element *in, Element *out); + virtual ~ProgramFragment(); + + virtual void setupGL(); + + + + void bindTexture(uint32_t slot, Allocation *); + void bindSampler(uint32_t slot, Sampler *); + void setType(uint32_t slot, const Element *, uint32_t dim); + + void setEnvMode(uint32_t slot, RsTexEnvMode); + void setTexEnable(uint32_t slot, bool); + + + +protected: + // The difference between Textures and Constants is how they are accessed + // Texture lookups go though a sampler which in effect converts normalized + // coordinates into type specific. Multiple samples may also be taken + // and filtered. + // + // Constants are strictly accessed by programetic loads. + ObjectBaseRef<Allocation> mTextures[MAX_TEXTURE]; + ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE]; + ObjectBaseRef<const Element> mTextureFormats[MAX_TEXTURE]; + uint32_t mTextureDimensions[MAX_TEXTURE]; + + + ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS]; + ObjectBaseRef<Type> mConstantTypes[MAX_CONSTANTS]; + + + // Hacks to create a program for now + RsTexEnvMode mEnvModes[MAX_TEXTURE]; + uint32_t mTextureEnableMask; + + + + + +}; + +class ProgramFragmentState +{ +public: + ProgramFragmentState(); + ~ProgramFragmentState(); + + ProgramFragment *mPF; + void init(Context *rsc, int32_t w, int32_t h); + + ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE]; + ObjectBaseRef<ProgramFragment> mDefault; + Vector<ProgramFragment *> mPrograms; +}; + + +} +} +#endif + + + + diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp new file mode 100644 index 0000000..9ee270f --- /dev/null +++ b/libs/rs/rsProgramFragmentStore.cpp @@ -0,0 +1,272 @@ +/* + * 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. + */ + +#include "rsContext.h" +#include "rsProgramFragmentStore.h" + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + + +ProgramFragmentStore::ProgramFragmentStore(Element *in, Element *out) : + Program(in, out) +{ + mDitherEnable = true; + mBlendEnable = false; + mColorRWriteEnable = true; + mColorGWriteEnable = true; + mColorBWriteEnable = true; + mColorAWriteEnable = true; + mBlendSrc = GL_ONE; + mBlendDst = GL_ZERO; + + + mDepthTestEnable = false; + mDepthWriteEnable = true; + mDepthFunc = GL_LESS; + + +} + +ProgramFragmentStore::~ProgramFragmentStore() +{ +} + +void ProgramFragmentStore::setupGL() +{ + glColorMask(mColorRWriteEnable, + mColorGWriteEnable, + mColorBWriteEnable, + mColorAWriteEnable); + if (mBlendEnable) { + glEnable(GL_BLEND); + glBlendFunc(mBlendSrc, mBlendDst); + } else { + glDisable(GL_BLEND); + } + + //LOGE("pfs %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc); + + glDepthMask(mDepthWriteEnable); + if(mDepthTestEnable || mDepthWriteEnable) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(mDepthFunc); + } else { + glDisable(GL_DEPTH_TEST); + } + + if (mDitherEnable) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } + + +} + +void ProgramFragmentStore::setDitherEnable(bool enable) +{ + mDitherEnable = enable; +} + +void ProgramFragmentStore::setDepthFunc(RsDepthFunc func) +{ + mDepthTestEnable = true; + + switch(func) { + case RS_DEPTH_FUNC_ALWAYS: + mDepthTestEnable = false; + mDepthFunc = GL_ALWAYS; + break; + case RS_DEPTH_FUNC_LESS: + mDepthFunc = GL_LESS; + break; + case RS_DEPTH_FUNC_LEQUAL: + mDepthFunc = GL_LEQUAL; + break; + case RS_DEPTH_FUNC_GREATER: + mDepthFunc = GL_GREATER; + break; + case RS_DEPTH_FUNC_GEQUAL: + mDepthFunc = GL_GEQUAL; + break; + case RS_DEPTH_FUNC_EQUAL: + mDepthFunc = GL_EQUAL; + break; + case RS_DEPTH_FUNC_NOTEQUAL: + mDepthFunc = GL_NOTEQUAL; + break; + } +} + +void ProgramFragmentStore::setDepthMask(bool mask) +{ + mDepthWriteEnable = mask; +} + +void ProgramFragmentStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst) +{ + mBlendEnable = true; + if ((src == RS_BLEND_SRC_ONE) && + (dst == RS_BLEND_DST_ZERO)) { + mBlendEnable = false; + } + + switch(src) { + case RS_BLEND_SRC_ZERO: + mBlendSrc = GL_ZERO; + break; + case RS_BLEND_SRC_ONE: + mBlendSrc = GL_ONE; + break; + case RS_BLEND_SRC_DST_COLOR: + mBlendSrc = GL_DST_COLOR; + break; + case RS_BLEND_SRC_ONE_MINUS_DST_COLOR: + mBlendSrc = GL_ONE_MINUS_DST_COLOR; + break; + case RS_BLEND_SRC_SRC_ALPHA: + mBlendSrc = GL_SRC_ALPHA; + break; + case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA: + mBlendSrc = GL_ONE_MINUS_SRC_ALPHA; + break; + case RS_BLEND_SRC_DST_ALPHA: + mBlendSrc = GL_DST_ALPHA; + break; + case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA: + mBlendSrc = GL_ONE_MINUS_DST_ALPHA; + break; + case RS_BLEND_SRC_SRC_ALPHA_SATURATE: + mBlendSrc = GL_SRC_ALPHA_SATURATE; + break; + } + + switch(dst) { + case RS_BLEND_DST_ZERO: + mBlendDst = GL_ZERO; + break; + case RS_BLEND_DST_ONE: + mBlendDst = GL_ONE; + break; + case RS_BLEND_DST_SRC_COLOR: + mBlendDst = GL_SRC_COLOR; + break; + case RS_BLEND_DST_ONE_MINUS_SRC_COLOR: + mBlendDst = GL_ONE_MINUS_SRC_COLOR; + break; + case RS_BLEND_DST_SRC_ALPHA: + mBlendDst = GL_SRC_ALPHA; + break; + case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA: + mBlendDst = GL_ONE_MINUS_SRC_ALPHA; + break; + case RS_BLEND_DST_DST_ALPHA: + mBlendDst = GL_DST_ALPHA; + break; + case RS_BLEND_DST_ONE_MINUS_DST_ALPHA: + mBlendDst = GL_ONE_MINUS_DST_ALPHA; + break; + } +} + +void ProgramFragmentStore::setColorMask(bool r, bool g, bool b, bool a) +{ + mColorRWriteEnable = r; + mColorGWriteEnable = g; + mColorBWriteEnable = b; + mColorAWriteEnable = a; +} + + +ProgramFragmentStoreState::ProgramFragmentStoreState() +{ + mPFS = NULL; +} + +ProgramFragmentStoreState::~ProgramFragmentStoreState() +{ + delete mPFS; + +} + +void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h) +{ + ProgramFragmentStore *pfs = new ProgramFragmentStore(NULL, NULL); + mDefault.set(pfs); +} + + +namespace android { +namespace renderscript { + +void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out) +{ + delete rsc->mStateFragmentStore.mPFS; + rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore((Element *)in, (Element *)out); + +} + +void rsi_ProgramFragmentStoreDepthFunc(Context *rsc, RsDepthFunc func) +{ + rsc->mStateFragmentStore.mPFS->setDepthFunc(func); +} + +void rsi_ProgramFragmentStoreDepthMask(Context *rsc, bool mask) +{ + rsc->mStateFragmentStore.mPFS->setDepthMask(mask); +} + +void rsi_ProgramFragmentStoreColorMask(Context *rsc, bool r, bool g, bool b, bool a) +{ + rsc->mStateFragmentStore.mPFS->setColorMask(r, g, b, a); +} + +void rsi_ProgramFragmentStoreBlendFunc(Context *rsc, RsBlendSrcFunc src, RsBlendDstFunc dst) +{ + rsc->mStateFragmentStore.mPFS->setBlendFunc(src, dst); +} + +RsProgramFragmentStore rsi_ProgramFragmentStoreCreate(Context *rsc) +{ + ProgramFragmentStore *pfs = rsc->mStateFragmentStore.mPFS; + pfs->incRef(); + rsc->mStateFragmentStore.mPFS = 0; + return pfs; +} + +void rsi_ProgramFragmentStoreDither(Context *rsc, bool enable) +{ + rsc->mStateFragmentStore.mPFS->setDitherEnable(enable); +} + +void rsi_ProgramFragmentStoreDestroy(Context *rsc, RsProgramFragmentStore vpfs) +{ + ProgramFragmentStore *pfs = (ProgramFragmentStore *)vpfs; + if (pfs->getName()) { + rsc->removeName(pfs); + } + pfs->decRef(); +} + + + + +} +} diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h new file mode 100644 index 0000000..bd3a9f4 --- /dev/null +++ b/libs/rs/rsProgramFragmentStore.h @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_PROGRAM_FRAGMENT_STORE_H +#define ANDROID_RS_PROGRAM_FRAGMENT_STORE_H + +#include "rsProgram.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +class ProgramFragmentStore : public Program +{ +public: + + + + ProgramFragmentStore(Element *in, Element *out); + virtual ~ProgramFragmentStore(); + + virtual void setupGL(); + + + void setDepthFunc(RsDepthFunc); + void setDepthMask(bool); + + void setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst); + void setColorMask(bool, bool, bool, bool); + + void setDitherEnable(bool); + +protected: + bool mDitherEnable; + + bool mBlendEnable; + bool mColorRWriteEnable; + bool mColorGWriteEnable; + bool mColorBWriteEnable; + bool mColorAWriteEnable; + int32_t mBlendSrc; + int32_t mBlendDst; + + + + bool mDepthTestEnable; + bool mDepthWriteEnable; + int32_t mDepthFunc; + + + + bool mStencilTestEnable; + + + +}; + +class ProgramFragmentStoreState +{ +public: + ProgramFragmentStoreState(); + ~ProgramFragmentStoreState(); + void init(Context *rsc, int32_t w, int32_t h); + + ObjectBaseRef<ProgramFragmentStore> mDefault; + ProgramFragmentStore *mPFS; +}; + + +} +} +#endif + + + diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp new file mode 100644 index 0000000..417ba6a --- /dev/null +++ b/libs/rs/rsProgramVertex.cpp @@ -0,0 +1,176 @@ +/* + * 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. + */ + +#include "rsContext.h" +#include "rsProgramVertex.h" + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + + +ProgramVertex::ProgramVertex(Element *in, Element *out) : + Program(in, out) +{ + mTextureMatrixEnable = false; + mLightCount = 0; +} + +ProgramVertex::~ProgramVertex() +{ +} + +static void logMatrix(const char *txt, const float *f) +{ + LOGV("Matrix %s, %p", txt, f); + LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[0], f[4], f[8], f[12]); + LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[1], f[5], f[9], f[13]); + LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[2], f[6], f[10], f[14]); + LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]); +} + +void ProgramVertex::setupGL() +{ + const float *f = static_cast<const float *>(mConstants[0]->getPtr()); + + glMatrixMode(GL_TEXTURE); + if (mTextureMatrixEnable) { + glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); + } else { + glLoadIdentity(); + } + + + LOGE("lights %i ", mLightCount); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + if (mLightCount) { + int v = 1; + glEnable(GL_LIGHTING); + glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v); + for (uint32_t ct = 0; ct < mLightCount; ct++) { + const Light *l = mLights[ct].get(); + glEnable(GL_LIGHT0 + ct); + l->setupGL(ct); + } + for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) { + glDisable(GL_LIGHT0 + ct); + } + } else { + glDisable(GL_LIGHTING); + } + + if (!f) { + LOGE("Must bind constants to vertex program"); + } + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); +} + +void ProgramVertex::setConstantType(uint32_t slot, const Type *t) +{ + mConstantTypes[slot].set(t); +} + +void ProgramVertex::bindAllocation(uint32_t slot, Allocation *a) +{ + mConstants[slot].set(a); +} + +void ProgramVertex::addLight(const Light *l) +{ + if (mLightCount < MAX_LIGHTS) { + mLights[mLightCount].set(l); + mLightCount++; + } +} + + +ProgramVertexState::ProgramVertexState() +{ + mPV = NULL; +} + +ProgramVertexState::~ProgramVertexState() +{ + delete mPV; +} + +void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) +{ + ProgramVertex *pv = new ProgramVertex(NULL, NULL); + Allocation *alloc = (Allocation *) + rsi_AllocationCreatePredefSized(rsc, RS_ELEMENT_USER_FLOAT, 48); + mDefaultAlloc.set(alloc); + mDefault.set(pv); + + pv->bindAllocation(0, alloc); + + Matrix m; + m.loadOrtho(0,w, h,0, -1,1); + alloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0]); + + m.loadIdentity(); + alloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0]); +} + + +namespace android { +namespace renderscript { + +void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out) +{ + delete rsc->mStateVertex.mPV; + rsc->mStateVertex.mPV = new ProgramVertex((Element *)in, (Element *)out); +} + +RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) +{ + ProgramVertex *pv = rsc->mStateVertex.mPV; + pv->incRef(); + rsc->mStateVertex.mPV = 0; + return pv; +} + +void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, uint32_t slot, RsAllocation constants) +{ + ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm); + pv->bindAllocation(slot, static_cast<Allocation *>(constants)); +} + +void rsi_ProgramVertexSetType(Context *rsc, uint32_t slot, RsType constants) +{ + rsc->mStateVertex.mPV->setConstantType(slot, static_cast<const Type *>(constants)); +} + +void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) +{ + rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); +} + +void rsi_ProgramVertexAddLight(Context *rsc, RsLight light) +{ + rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light)); +} + + +} +} diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h new file mode 100644 index 0000000..ac15b70 --- /dev/null +++ b/libs/rs/rsProgramVertex.h @@ -0,0 +1,84 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_PROGRAM_VERTEX_H +#define ANDROID_RS_PROGRAM_VERTEX_H + +#include "rsProgram.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +class ProgramVertex : public Program +{ +public: + const static uint32_t MAX_CONSTANTS = 2; + const static uint32_t MAX_LIGHTS = 8; + + ProgramVertex(Element *in, Element *out); + virtual ~ProgramVertex(); + + virtual void setupGL(); + + + void setConstantType(uint32_t slot, const Type *); + void bindAllocation(uint32_t slot, Allocation *); + void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;} + void addLight(const Light *); + +protected: + bool mDirty; + uint32_t mLightCount; + + ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS]; + ObjectBaseRef<const Type> mConstantTypes[MAX_CONSTANTS]; + ObjectBaseRef<const Light> mLights[MAX_LIGHTS]; + + + // Hacks to create a program for now + bool mTextureMatrixEnable; + +}; + + +class ProgramVertexState +{ +public: + ProgramVertexState(); + ~ProgramVertexState(); + + void init(Context *rsc, int32_t w, int32_t h); + + ObjectBaseRef<ProgramVertex> mDefault; + ObjectBaseRef<Allocation> mDefaultAlloc; + + + + ProgramVertex *mPV; + + //ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE]; + + +}; + + +} +} +#endif + + diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp new file mode 100644 index 0000000..418f127 --- /dev/null +++ b/libs/rs/rsSampler.cpp @@ -0,0 +1,157 @@ +/* + * 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. + */ + +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include "rsContext.h" +#include "rsSampler.h" + + +using namespace android; +using namespace android::renderscript; + + +Sampler::Sampler() +{ + // Should not get called. + rsAssert(0); +} + +Sampler::Sampler(RsSamplerValue magFilter, + RsSamplerValue minFilter, + RsSamplerValue wrapS, + RsSamplerValue wrapT, + RsSamplerValue wrapR) +{ + mMagFilter = magFilter; + mMinFilter = minFilter; + mWrapS = wrapS; + mWrapT = wrapT; + mWrapR = wrapR; +} + +Sampler::~Sampler() +{ +} + +void Sampler::setupGL() +{ + GLenum trans[] = { + GL_NEAREST, //RS_SAMPLER_NEAREST, + GL_LINEAR, //RS_SAMPLER_LINEAR, + GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR, + GL_REPEAT, //RS_SAMPLER_WRAP, + GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP + + }; + + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, trans[mWrapS]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, trans[mWrapT]); + +} + +void Sampler::bindToContext(SamplerState *ss, uint32_t slot) +{ + ss->mSamplers[slot].set(this); + mBoundSlot = slot; +} + +void Sampler::unbindFromContext(SamplerState *ss) +{ + int32_t slot = mBoundSlot; + mBoundSlot = -1; + ss->mSamplers[slot].clear(); +} + +void SamplerState::setupGL() +{ + for (uint32_t ct=0; ct < RS_MAX_SAMPLER_SLOT; ct++) { + Sampler *s = mSamplers[ct].get(); + if (s) { + s->setupGL(); + } else { + glBindTexture(GL_TEXTURE_2D, 0); + } + } +} + +//////////////////////////////// + +namespace android { +namespace renderscript { + + +void rsi_SamplerBegin(Context *rsc) +{ + SamplerState * ss = &rsc->mStateSampler; + + ss->mMagFilter = RS_SAMPLER_LINEAR; + ss->mMinFilter = RS_SAMPLER_LINEAR; + ss->mWrapS = RS_SAMPLER_WRAP; + ss->mWrapT = RS_SAMPLER_WRAP; + ss->mWrapR = RS_SAMPLER_WRAP; +} + +void rsi_SamplerSet(Context *rsc, RsSamplerParam param, RsSamplerValue value) +{ + SamplerState * ss = &rsc->mStateSampler; + + switch(param) { + case RS_SAMPLER_MAG_FILTER: + ss->mMagFilter = value; + break; + case RS_SAMPLER_MIN_FILTER: + ss->mMinFilter = value; + break; + case RS_SAMPLER_WRAP_S: + ss->mWrapS = value; + break; + case RS_SAMPLER_WRAP_T: + ss->mWrapT = value; + break; + case RS_SAMPLER_WRAP_R: + ss->mWrapR = value; + break; + } + +} + +RsSampler rsi_SamplerCreate(Context *rsc) +{ + SamplerState * ss = &rsc->mStateSampler; + + + Sampler * s = new Sampler(ss->mMagFilter, + ss->mMinFilter, + ss->mWrapS, + ss->mWrapT, + ss->mWrapR); + return s; +} + +void rsi_SamplerDestroy(Context *rsc, RsSampler vs) +{ + Sampler * s = static_cast<Sampler *>(vs); + s->decRef(); + +} + + +}} diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h new file mode 100644 index 0000000..4b504f6 --- /dev/null +++ b/libs/rs/rsSampler.h @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_SAMPLER_H +#define ANDROID_RS_SAMPLER_H + +#include "rsAllocation.h" +#include "RenderScript.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +const static uint32_t RS_MAX_SAMPLER_SLOT = 16; + +class SamplerState; + +class Sampler : public ObjectBase +{ +public: + Sampler(RsSamplerValue magFilter, + RsSamplerValue minFilter, + RsSamplerValue wrapS, + RsSamplerValue wrapT, + RsSamplerValue wrapR); + + virtual ~Sampler(); + + void bind(Allocation *); + void setupGL(); + + void bindToContext(SamplerState *, uint32_t slot); + void unbindFromContext(SamplerState *); + +protected: + RsSamplerValue mMagFilter; + RsSamplerValue mMinFilter; + RsSamplerValue mWrapS; + RsSamplerValue mWrapT; + RsSamplerValue mWrapR; + + int32_t mBoundSlot; + +private: + Sampler(); + +}; + + +class SamplerState +{ +public: + + RsSamplerValue mMagFilter; + RsSamplerValue mMinFilter; + RsSamplerValue mWrapS; + RsSamplerValue mWrapT; + RsSamplerValue mWrapR; + + + ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT]; + + void setupGL(); + +}; + + + +} +} +#endif //ANDROID_RS_SAMPLER_H + + + diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp new file mode 100644 index 0000000..ae85c9c --- /dev/null +++ b/libs/rs/rsScript.cpp @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + +Script::Script() +{ + memset(&mEnviroment, 0, sizeof(mEnviroment)); + mEnviroment.mClearColor[0] = 0; + mEnviroment.mClearColor[1] = 0; + mEnviroment.mClearColor[2] = 0; + mEnviroment.mClearColor[3] = 1; + mEnviroment.mClearDepth = 1; +} + +Script::~Script() +{ +} + +namespace android { +namespace renderscript { + + +void rsi_ScriptDestroy(Context * rsc, RsScript vs) +{ + Script *s = static_cast<Script *>(vs); + s->decRef(); +} + +void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint32_t slot) +{ + Script *s = static_cast<Script *>(vs); + s->mSlots[slot].set(static_cast<Allocation *>(va)); +} + + +} +} + diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h new file mode 100644 index 0000000..7dd2b61 --- /dev/null +++ b/libs/rs/rsScript.h @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_SCRIPT_H +#define ANDROID_RS_SCRIPT_H + +#include "rsAllocation.h" + + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class ProgramVertex; +class ProgramFragment; +class ProgramRaster; +class ProgramFragmentStore; + +class Script : public ObjectBase +{ +public: + + Script(); + virtual ~Script(); + + + struct Enviroment_t { + bool mIsRoot; + float mClearColor[4]; + float mClearDepth; + uint32_t mClearStencil; + + ObjectBaseRef<ProgramVertex> mVertex; + ObjectBaseRef<ProgramFragment> mFragment; + //ObjectBaseRef<ProgramRaster> mRaster; + ObjectBaseRef<ProgramFragmentStore> mFragmentStore; + + }; + Enviroment_t mEnviroment; + + const Type * mConstantBufferTypes; + uint32_t mCounstantBufferCount; + + ObjectBaseRef<Allocation> mSlots[16]; + + virtual bool run(Context *, uint32_t launchID) = 0; +}; + + + +} +} +#endif + diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp new file mode 100644 index 0000000..842c836 --- /dev/null +++ b/libs/rs/rsScriptC.cpp @@ -0,0 +1,291 @@ +/* + * 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. + */ + +#include "rsContext.h" +#include "rsScriptC.h" +#include "rsMatrix.h" + +#include "acc/acc.h" +#include "utils/String8.h" + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + +#define GET_TLS() Context::ScriptTLSStruct * tls = \ + (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ + Context * rsc = tls->mContext; \ + ScriptC * sc = (ScriptC *) tls->mScript + + +ScriptC::ScriptC() +{ + mAccScript = NULL; + memset(&mProgram, 0, sizeof(mProgram)); +} + +ScriptC::~ScriptC() +{ + if (mAccScript) { + accDeleteScript(mAccScript); + } +} + + +bool ScriptC::run(Context *rsc, uint32_t launchIndex) +{ + Context::ScriptTLSStruct * tls = + (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); + + if (mEnviroment.mFragmentStore.get()) { + rsc->setFragmentStore(mEnviroment.mFragmentStore.get()); + } + if (mEnviroment.mFragment.get()) { + rsc->setFragment(mEnviroment.mFragment.get()); + } + if (mEnviroment.mVertex.get()) { + rsc->setVertex(mEnviroment.mVertex.get()); + } + + bool ret = false; + tls->mScript = this; + ret = mProgram.mScript(launchIndex) != 0; + tls->mScript = NULL; + return ret; +} + +ScriptCState::ScriptCState() +{ + clear(); +} + +ScriptCState::~ScriptCState() +{ + if (mAccScript) { + accDeleteScript(mAccScript); + } +} + +void ScriptCState::clear() +{ + memset(&mProgram, 0, sizeof(mProgram)); + + mConstantBufferTypes.clear(); + + memset(&mEnviroment, 0, sizeof(mEnviroment)); + mEnviroment.mClearColor[0] = 0; + mEnviroment.mClearColor[1] = 0; + mEnviroment.mClearColor[2] = 0; + mEnviroment.mClearColor[3] = 1; + mEnviroment.mClearDepth = 1; + mEnviroment.mClearStencil = 0; + mEnviroment.mIsRoot = false; + + mAccScript = NULL; + +} + +static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) +{ + const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name); + if (sym) { + return sym->mPtr; + } + LOGE("ScriptC sym lookup failed for %s", name); + return NULL; +} + +void ScriptCState::runCompiler(Context *rsc) +{ + mAccScript = accCreateScript(); + String8 tmp; + + rsc->appendNameDefines(&tmp); + appendDecls(&tmp); + tmp.append("#line 1\n"); + + const char* scriptSource[] = {tmp.string(), mProgram.mScriptText}; + int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ; + accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); + accRegisterSymbolCallback(mAccScript, symbolLookup, NULL); + accCompileScript(mAccScript); + accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript); + rsAssert(mProgram.mScript); + + if (!mProgram.mScript) { + ACCchar buf[4096]; + ACCsizei len; + accGetScriptInfoLog(mAccScript, sizeof(buf), &len, buf); + LOGE(buf); + + } + + mEnviroment.mFragment.set(rsc->getDefaultProgramFragment()); + mEnviroment.mVertex.set(rsc->getDefaultProgramVertex()); + mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore()); + + if (mProgram.mScript) { + const static int pragmaMax = 16; + ACCsizei pragmaCount; + ACCchar * str[pragmaMax]; + accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]); + + for (int ct=0; ct < pragmaCount; ct+=2) { + if (!strcmp(str[ct], "version")) { + continue; + } + + if (!strcmp(str[ct], "stateVertex")) { + if (!strcmp(str[ct+1], "default")) { + continue; + } + if (!strcmp(str[ct+1], "parent")) { + mEnviroment.mVertex.clear(); + continue; + } + ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]); + if (pv != NULL) { + mEnviroment.mVertex.set(pv); + continue; + } + LOGE("Unreconized value %s passed to stateVertex", str[ct+1]); + } + + if (!strcmp(str[ct], "stateRaster")) { + LOGE("Unreconized value %s passed to stateRaster", str[ct+1]); + } + + if (!strcmp(str[ct], "stateFragment")) { + if (!strcmp(str[ct+1], "default")) { + continue; + } + if (!strcmp(str[ct+1], "parent")) { + mEnviroment.mFragment.clear(); + continue; + } + ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]); + if (pf != NULL) { + mEnviroment.mFragment.set(pf); + continue; + } + LOGE("Unreconized value %s passed to stateFragment", str[ct+1]); + } + + if (!strcmp(str[ct], "stateFragmentStore")) { + if (!strcmp(str[ct+1], "default")) { + continue; + } + if (!strcmp(str[ct+1], "parent")) { + mEnviroment.mFragmentStore.clear(); + continue; + } + ProgramFragmentStore * pfs = + (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); + if (pfs != NULL) { + mEnviroment.mFragmentStore.set(pfs); + continue; + } + LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]); + } + + } + + + } else { + // Deal with an error. + } + +} + +namespace android { +namespace renderscript { + +void rsi_ScriptCBegin(Context * rsc) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->clear(); +} + +void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mEnviroment.mClearColor[0] = r; + ss->mEnviroment.mClearColor[1] = g; + ss->mEnviroment.mClearColor[2] = b; + ss->mEnviroment.mClearColor[3] = a; +} + +void rsi_ScriptCSetClearDepth(Context * rsc, float v) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mEnviroment.mClearDepth = v; +} + +void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mEnviroment.mClearStencil = v; +} + +void rsi_ScriptCAddType(Context * rsc, RsType vt) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mConstantBufferTypes.add(static_cast<const Type *>(vt)); +} + +void rsi_ScriptCSetScript(Context * rsc, void *vp) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp); +} + +void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mEnviroment.mIsRoot = isRoot; +} + +void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mProgram.mScriptText = text; + ss->mProgram.mScriptTextLength = len; +} + + +RsScript rsi_ScriptCCreate(Context * rsc) +{ + ScriptCState *ss = &rsc->mScriptC; + + ss->runCompiler(rsc); + + ScriptC *s = new ScriptC(); + s->incRef(); + s->mAccScript = ss->mAccScript; + ss->mAccScript = NULL; + s->mEnviroment = ss->mEnviroment; + s->mProgram = ss->mProgram; + ss->clear(); + + return s; +} + +} +} + + diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h new file mode 100644 index 0000000..860b4d1 --- /dev/null +++ b/libs/rs/rsScriptC.h @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_SCRIPT_C_H +#define ANDROID_RS_SCRIPT_C_H + +#include "rsScript.h" + +#include "RenderScriptEnv.h" + +struct ACCscript; + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + + +class ScriptC : public Script +{ +public: + typedef int (*RunScript_t)(uint32_t launchIndex); + + ScriptC(); + virtual ~ScriptC(); + + struct Program_t { + const char * mScriptText; + uint32_t mScriptTextLength; + + + int mVersionMajor; + int mVersionMinor; + + RunScript_t mScript; + }; + + Program_t mProgram; + + ACCscript* mAccScript; + + virtual bool run(Context *, uint32_t launchID); +}; + +class ScriptCState +{ +public: + ScriptCState(); + ~ScriptCState(); + + ACCscript* mAccScript; + + ScriptC::Program_t mProgram; + Script::Enviroment_t mEnviroment; + + Vector<const Type *> mConstantBufferTypes; + + void clear(); + void runCompiler(Context *rsc); + + struct SymbolTable_t { + const char * mName; + void * mPtr; + const char * mRet; + const char * mParam; + }; + static SymbolTable_t gSyms[]; + static const SymbolTable_t * lookupSymbol(const char *); + static void appendDecls(String8 *str); +}; + + +} +} +#endif + + + diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp new file mode 100644 index 0000000..129b19f --- /dev/null +++ b/libs/rs/rsScriptC_Lib.cpp @@ -0,0 +1,531 @@ +/* + * 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. + */ + +#include "rsContext.h" +#include "rsScriptC.h" +#include "rsMatrix.h" + +#include "acc/acc.h" +#include "utils/String8.h" + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + +#define GET_TLS() Context::ScriptTLSStruct * tls = \ + (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ + Context * rsc = tls->mContext; \ + ScriptC * sc = (ScriptC *) tls->mScript + + +////////////////////////////////////////////////////////////////////////////// +// IO routines +////////////////////////////////////////////////////////////////////////////// + +static float SC_loadF(uint32_t bank, uint32_t offset) +{ + GET_TLS(); + const void *vp = sc->mSlots[bank]->getPtr(); + const float *f = static_cast<const float *>(vp); + //LOGE("loadF %i %i = %f %x", bank, offset, f, ((int *)&f)[0]); + return f[offset]; +} + +static int32_t SC_loadI32(uint32_t bank, uint32_t offset) +{ + GET_TLS(); + const void *vp = sc->mSlots[bank]->getPtr(); + const int32_t *i = static_cast<const int32_t *>(vp); + //LOGE("loadI32 %i %i = %i", bank, offset, t); + return i[offset]; +} + +static uint32_t SC_loadU32(uint32_t bank, uint32_t offset) +{ + GET_TLS(); + const void *vp = sc->mSlots[bank]->getPtr(); + const uint32_t *i = static_cast<const uint32_t *>(vp); + return i[offset]; +} + +static void SC_loadVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v) +{ + GET_TLS(); + const void *vp = sc->mSlots[bank]->getPtr(); + const float *f = static_cast<const float *>(vp); + memcpy(v, &f[offset], sizeof(rsc_Vector4)); +} + +static void SC_loadMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m) +{ + GET_TLS(); + const void *vp = sc->mSlots[bank]->getPtr(); + const float *f = static_cast<const float *>(vp); + memcpy(m, &f[offset], sizeof(rsc_Matrix)); +} + + +static void SC_storeF(uint32_t bank, uint32_t offset, float v) +{ + //LOGE("storeF %i %i %f", bank, offset, v); + GET_TLS(); + void *vp = sc->mSlots[bank]->getPtr(); + float *f = static_cast<float *>(vp); + f[offset] = v; +} + +static void SC_storeI32(uint32_t bank, uint32_t offset, int32_t v) +{ + GET_TLS(); + void *vp = sc->mSlots[bank]->getPtr(); + int32_t *f = static_cast<int32_t *>(vp); + static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v; +} + +static void SC_storeU32(uint32_t bank, uint32_t offset, uint32_t v) +{ + GET_TLS(); + void *vp = sc->mSlots[bank]->getPtr(); + uint32_t *f = static_cast<uint32_t *>(vp); + static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v; +} + +static void SC_storeVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v) +{ + GET_TLS(); + void *vp = sc->mSlots[bank]->getPtr(); + float *f = static_cast<float *>(vp); + memcpy(&f[offset], v, sizeof(rsc_Vector4)); +} + +static void SC_storeMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m) +{ + GET_TLS(); + void *vp = sc->mSlots[bank]->getPtr(); + float *f = static_cast<float *>(vp); + memcpy(&f[offset], m, sizeof(rsc_Matrix)); +} + + +////////////////////////////////////////////////////////////////////////////// +// Math routines +////////////////////////////////////////////////////////////////////////////// + +static float SC_randf(float max) +{ + float r = (float)rand(); + return r / RAND_MAX * max; +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// Matrix routines +////////////////////////////////////////////////////////////////////////////// + + +static void SC_matrixLoadIdentity(rsc_Matrix *mat) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadIdentity(); +} + +static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->load(f); +} + +static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->load(reinterpret_cast<const Matrix *>(newmat)); +} + +static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadRotate(rot, x, y, z); +} + +static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadScale(x, y, z); +} + +static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadTranslate(x, y, z); +} + +static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadMultiply(reinterpret_cast<const Matrix *>(lhs), + reinterpret_cast<const Matrix *>(rhs)); +} + +static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->multiply(reinterpret_cast<const Matrix *>(rhs)); +} + +static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->rotate(rot, x, y, z); +} + +static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->scale(x, y, z); +} + +static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->translate(x, y, z); +} + + + + +////////////////////////////////////////////////////////////////////////////// +// Context +////////////////////////////////////////////////////////////////////////////// + +static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) +{ + GET_TLS(); + rsi_ProgramFragmentBindTexture(rsc, + static_cast<ProgramFragment *>(vpf), + slot, + static_cast<Allocation *>(va)); + +} + +static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) +{ + GET_TLS(); + rsi_ProgramFragmentBindSampler(rsc, + static_cast<ProgramFragment *>(vpf), + slot, + static_cast<Sampler *>(vs)); + +} + +static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs) +{ + GET_TLS(); + rsi_ContextBindProgramFragmentStore(rsc, pfs); + +} + +static void SC_bindProgramFragment(RsProgramFragment pf) +{ + GET_TLS(); + rsi_ContextBindProgramFragment(rsc, pf); + +} + +static void SC_bindProgramVertex(RsProgramVertex pv) +{ + GET_TLS(); + rsi_ContextBindProgramVertex(rsc, pv); + +} + +////////////////////////////////////////////////////////////////////////////// +// Drawing +////////////////////////////////////////////////////////////////////////////// + +static void SC_drawTriangleMesh(RsTriangleMesh mesh) +{ + GET_TLS(); + rsi_TriangleMeshRender(rsc, mesh); +} + +static void SC_drawTriangleMeshRange(RsTriangleMesh mesh, uint32_t start, uint32_t count) +{ + GET_TLS(); + rsi_TriangleMeshRenderRange(rsc, mesh, start, count); +} + +// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a +static void SC_drawTriangleArray(int ialloc, uint32_t count) +{ + GET_TLS(); + RsAllocation alloc = (RsAllocation)ialloc; + + const Allocation *a = (const Allocation *)alloc; + const uint32_t *ptr = (const uint32_t *)a->getPtr(); + + rsc->setupCheck(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); + + glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer(2, GL_FIXED, 12, ptr + 1); + //glTexCoordPointer(2, GL_FIXED, 24, ptr + 1); + glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); + + glDrawArrays(GL_TRIANGLES, 0, count * 3); +} + +static void SC_drawQuad(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) +{ + GET_TLS(); + + //LOGE("Quad"); + //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1); + //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2); + //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3); + //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4); + + float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4}; + static const float tex[] = {0,1, 1,1, 1,0, 0,0}; + + + rsc->setupCheck(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vtx); + + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, tex); + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, tex); + glClientActiveTexture(GL_TEXTURE0); + + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + +////////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////////// + +extern "C" const void * loadVp(uint32_t bank, uint32_t offset) +{ + GET_TLS(); + return &static_cast<const uint8_t *>(sc->mSlots[bank]->getPtr())[offset]; +} + + + +static void SC_color(float r, float g, float b, float a) +{ + glColor4f(r, g, b, a); +} + + +extern "C" void materialDiffuse(float r, float g, float b, float a) +{ + float v[] = {r, g, b, a}; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v); +} + +extern "C" void materialSpecular(float r, float g, float b, float a) +{ + float v[] = {r, g, b, a}; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v); +} + +extern "C" void lightPosition(float x, float y, float z, float w) +{ + float v[] = {x, y, z, w}; + glLightfv(GL_LIGHT0, GL_POSITION, v); +} + +extern "C" void materialShininess(float s) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s); +} + +extern "C" void uploadToTexture(RsAllocation va, uint32_t baseMipLevel) +{ + GET_TLS(); + rsi_AllocationUploadToTexture(rsc, va, baseMipLevel); +} + +extern "C" void enable(uint32_t p) +{ + glEnable(p); +} + +extern "C" void disable(uint32_t p) +{ + glDisable(p); +} + + + +static void SC_ClearColor(float r, float g, float b, float a) +{ + //LOGE("c %f %f %f %f", r, g, b, a); + GET_TLS(); + sc->mEnviroment.mClearColor[0] = r; + sc->mEnviroment.mClearColor[1] = g; + sc->mEnviroment.mClearColor[2] = b; + sc->mEnviroment.mClearColor[3] = a; +} + + + +////////////////////////////////////////////////////////////////////////////// +// Class implementation +////////////////////////////////////////////////////////////////////////////// + +ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { + // IO + { "loadI32", (void *)&SC_loadI32, + "int", "(int, int)" }, + //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" }, + { "loadF", (void *)&SC_loadF, + "float", "(int, int)" }, + { "loadVec4", (void *)&SC_loadVec4, + "void", "(int, int, float *)" }, + { "loadMatrix", (void *)&SC_loadMatrix, + "void", "(int, int, float *)" }, + { "storeI32", (void *)&SC_storeI32, + "void", "(int, int, int)" }, + //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" }, + { "storeF", (void *)&SC_storeF, + "void", "(int, int, float)" }, + { "storeVec4", (void *)&SC_storeVec4, + "void", "(int, int, float *)" }, + { "storeMatrix", (void *)&SC_storeMatrix, + "void", "(int, int, float *)" }, + + // math + { "sinf", (void *)&sinf, + "float", "(float)" }, + { "cosf", (void *)&cosf, + "float", "(float)" }, + { "fabs", (void *)&fabs, + "float", "(float)" }, + { "randf", (void *)&SC_randf, + "float", "(float)" }, + + // matrix + { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity, + "void", "(float *mat)" }, + { "matrixLoadFloat", (void *)&SC_matrixLoadFloat, + "void", "(float *mat, float *f)" }, + { "matrixLoadMat", (void *)&SC_matrixLoadMat, + "void", "(float *mat, float *newmat)" }, + { "matrixLoadRotate", (void *)&SC_matrixLoadRotate, + "void", "(float *mat, float rot, float x, float y, float z)" }, + { "matrixLoadScale", (void *)&SC_matrixLoadScale, + "void", "(float *mat, float x, float y, float z)" }, + { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate, + "void", "(float *mat, float x, float y, float z)" }, + { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply, + "void", "(float *mat, float *lhs, float *rhs)" }, + { "matrixMultiply", (void *)&SC_matrixMultiply, + "void", "(float *mat, float *rhs)" }, + { "matrixRotate", (void *)&SC_matrixRotate, + "void", "(float *mat, float rot, float x, float y, float z)" }, + { "matrixScale", (void *)&SC_matrixScale, + "void", "(float *mat, float x, float y, float z)" }, + { "matrixTranslate", (void *)&SC_matrixTranslate, + "void", "(float *mat, float x, float y, float z)" }, + + // context + { "bindProgramFragment", (void *)&SC_bindProgramFragment, + "void", "(int)" }, + { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore, + "void", "(int)" }, + { "bindProgramVertex", (void *)&SC_bindProgramVertex, + "void", "(int)" }, + { "bindSampler", (void *)&SC_bindSampler, + "void", "(int, int, int)" }, + { "bindTexture", (void *)&SC_bindTexture, + "void", "(int, int, int)" }, + + // drawing + { "drawQuad", (void *)&SC_drawQuad, + "void", "(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)" }, + { "drawTriangleArray", (void *)&SC_drawTriangleArray, + "void", "(int ialloc, int count)" }, + { "drawTriangleMesh", (void *)&SC_drawTriangleMesh, + "void", "(int mesh)" }, + { "drawTriangleMeshRange", (void *)&SC_drawTriangleMeshRange, + "void", "(int mesh, int start, int count)" }, + + + // misc + { "pfClearColor", (void *)&SC_ClearColor, + "void", "(float, float, float, float)" }, + + { "color", (void *)&SC_color, + "void", "(float, float, float, float)" }, + + { NULL, NULL, NULL, NULL } +}; + +const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) +{ + ScriptCState::SymbolTable_t *syms = gSyms; + + while (syms->mPtr) { + if (!strcmp(syms->mName, sym)) { + return syms; + } + syms++; + } + return NULL; +} + +void ScriptCState::appendDecls(String8 *str) +{ + ScriptCState::SymbolTable_t *syms = gSyms; + while (syms->mPtr) { + str->append(syms->mRet); + str->append(" "); + str->append(syms->mName); + str->append(syms->mParam); + str->append(";\n"); + syms++; + } +} + + diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp new file mode 100644 index 0000000..89df59d --- /dev/null +++ b/libs/rs/rsThreadIO.cpp @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#include "rsContext.h" + +#include "rsThreadIO.h" + +using namespace android; +using namespace android::renderscript; + +ThreadIO *android::renderscript::gIO = NULL; + +ThreadIO::ThreadIO() +{ + mToCore.init(16 * 1024); +} + +ThreadIO::~ThreadIO() +{ +} + +bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) +{ + uint32_t cmdID = 0; + uint32_t cmdSize = 0; + bool ret = false; + while(!mToCore.isEmpty() || waitForCommand) { + ret = true; + const void * data = mToCore.get(&cmdID, &cmdSize); + waitForCommand = false; + //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize); + + gPlaybackFuncs[cmdID](con, data); + mToCore.next(); + } + return ret; +} + + diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h new file mode 100644 index 0000000..72746c5 --- /dev/null +++ b/libs/rs/rsThreadIO.h @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_THREAD_IO_H +#define ANDROID_RS_THREAD_IO_H + +#include "rsUtils.h" +#include "rsLocklessFifo.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class Context; + +class ThreadIO { +public: + ThreadIO(); + ~ThreadIO(); + + // Plays back commands from the client. + // Returns true if any commands were processed. + bool playCoreCommands(Context *con, bool waitForCommand); + + + LocklessCommandFifo mToCore; + //LocklessCommandFifo mToClient; + + intptr_t mToCoreRet; + +}; + +extern ThreadIO *gIO; + + + +} +} +#endif + diff --git a/libs/rs/rsTriangleMesh.cpp b/libs/rs/rsTriangleMesh.cpp new file mode 100644 index 0000000..8c7bc92 --- /dev/null +++ b/libs/rs/rsTriangleMesh.cpp @@ -0,0 +1,286 @@ +/* + * 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. + */ + +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + +#include <GLES/gl.h> +#include <GLES/glext.h> + +TriangleMesh::TriangleMesh() +{ + mVertexElement = NULL; + mIndexElement = NULL; + mVertexData = NULL; + mIndexData = NULL; + mTriangleCount = 0; + mVertexDataSize = 0; + mIndexDataSize = 0; + + mBufferObjects[0] = 0; + mBufferObjects[1] = 0; + + mOffsetCoord = 0; + mOffsetTex = 0; + mOffsetNorm = 0; + + mSizeCoord = 0; + mSizeTex = 0; + mSizeNorm = 0; + +} + +TriangleMesh::~TriangleMesh() +{ + free(mVertexData); + free(mIndexData); +} + + + +TriangleMeshContext::TriangleMeshContext() +{ + clear(); +} + +TriangleMeshContext::~TriangleMeshContext() +{ +} + +void TriangleMeshContext::clear() +{ + mVertexElement = NULL; + mVertexSizeBits = 0; + mIndexElement = NULL; + mIndexSizeBits = 0; + mTriangleCount = 0; + mVertexData.clear(); + mIndexData.clear(); +} + +void TriangleMesh::analyzeElement() +{ + for (uint32_t ct=0; ct < mVertexElement->getComponentCount(); ct++) { + const Component *c = mVertexElement->getComponent(ct); + + if (c->getKind() == Component::X) { + rsAssert(mSizeCoord == 0); + mSizeCoord = 1; + mOffsetCoord = ct; + } + if (c->getKind() == Component::Y) { + rsAssert(mSizeCoord == 1); + mSizeCoord = 2; + } + if (c->getKind() == Component::Z) { + rsAssert(mSizeCoord == 2); + mSizeCoord = 3; + } + if (c->getKind() == Component::W) { + rsAssert(mSizeCoord == 4); + mSizeCoord = 4; + } + + if (c->getKind() == Component::NX) { + rsAssert(mSizeNorm == 0); + mSizeNorm = 1; + mOffsetNorm = ct; + } + if (c->getKind() == Component::NY) { + rsAssert(mSizeNorm == 1); + mSizeNorm = 2; + } + if (c->getKind() == Component::NZ) { + rsAssert(mSizeNorm == 2); + mSizeNorm = 3; + } + + if (c->getKind() == Component::S) { + rsAssert(mSizeTex == 0); + mSizeTex = 1; + mOffsetTex = ct; + } + if (c->getKind() == Component::T) { + rsAssert(mSizeTex == 1); + mSizeTex = 2; + } + } + LOGV("TriangleMesh %i,%i %i,%i %i,%i", mSizeCoord, mOffsetCoord, mSizeNorm, mOffsetNorm, mSizeTex, mOffsetTex); + +} + + +namespace android { +namespace renderscript { + +void rsi_TriangleMeshBegin(Context *rsc, RsElement vertex, RsElement index) +{ + TriangleMeshContext *tmc = &rsc->mStateTriangleMesh; + + tmc->clear(); + tmc->mVertexElement = static_cast<Element *>(vertex); + tmc->mVertexSizeBits = tmc->mVertexElement->getSizeBits(); + tmc->mIndexElement = static_cast<Element *>(index); + tmc->mIndexSizeBits = tmc->mIndexElement->getSizeBits(); + + assert(!(tmc->mVertexSizeBits & 0x7)); + assert(!(tmc->mIndexSizeBits & 0x7)); +} + +void rsi_TriangleMeshAddVertex(Context *rsc, const void *data) +{ + TriangleMeshContext *tmc = &rsc->mStateTriangleMesh; + + // todo: Make this efficient. + for (uint32_t ct = 0; (ct * 8) < tmc->mVertexSizeBits; ct++) { + tmc->mVertexData.add(static_cast<const uint8_t *>(data) [ct]); + } +} + +void rsi_TriangleMeshAddTriangle(Context *rsc, uint32_t idx1, uint32_t idx2, uint32_t idx3) +{ + TriangleMeshContext *tmc = &rsc->mStateTriangleMesh; + + // todo: Make this efficient. + switch(tmc->mIndexSizeBits) { + case 16: + tmc->mIndexData.add(idx1); + tmc->mIndexData.add(idx2); + tmc->mIndexData.add(idx3); + break; + default: + assert(0); + } + + tmc->mTriangleCount++; +} + +RsTriangleMesh rsi_TriangleMeshCreate(Context *rsc) +{ + TriangleMeshContext *tmc = &rsc->mStateTriangleMesh; + + TriangleMesh * tm = new TriangleMesh(); + if (!tm) { + LOGE("rsTriangleMeshCreate: Error OUT OF MEMORY"); + // error + return 0; + } + + tm->mTriangleCount = tmc->mTriangleCount; + tm->mIndexDataSize = tmc->mIndexData.size() * tmc->mIndexSizeBits >> 3; + tm->mVertexDataSize = tmc->mVertexData.size(); + tm->mIndexElement = tmc->mIndexElement; + tm->mVertexElement = tmc->mVertexElement; + + tm->mIndexData = malloc(tm->mIndexDataSize); + tm->mVertexData = malloc(tm->mVertexDataSize); + if (!tm->mIndexData || !tm->mVertexData) { + LOGE("rsTriangleMeshCreate: Error OUT OF MEMORY"); + delete tm; + return 0; + } + + memcpy(tm->mVertexData, tmc->mVertexData.array(), tm->mVertexDataSize); + memcpy(tm->mIndexData, tmc->mIndexData.array(), tm->mIndexDataSize); + tm->analyzeElement(); + + return tm; +} + +void rsi_TriangleMeshDestroy(Context *rsc, RsTriangleMesh vtm) +{ + TriangleMeshContext *tmc = &rsc->mStateTriangleMesh; + TriangleMesh * tm = static_cast<TriangleMesh *>(vtm); + + free(tm->mIndexData); + free(tm->mVertexData); + delete tm; +} + + + +void rsi_TriangleMeshRenderRange(Context *rsc, RsTriangleMesh vtm, uint32_t first, uint32_t count) +{ + TriangleMesh * tm = static_cast<TriangleMesh *>(vtm); + + rsc->setupCheck(); + + if (!tm->mBufferObjects[0]) { + glGenBuffers(2, &tm->mBufferObjects[0]); + + glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]); + glBufferData(GL_ARRAY_BUFFER, tm->mVertexDataSize, tm->mVertexData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, tm->mIndexDataSize, tm->mIndexData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + if (first >= tm->mTriangleCount) { + return; + } + if (count >= (tm->mTriangleCount - first)) { + count = tm->mTriangleCount - first; + } + if (!count) { + return; + } + + const float *f = (const float *)tm->mVertexData; + + glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(tm->mSizeCoord, + GL_FLOAT, + tm->mVertexElement->getSizeBytes(), + (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetCoord)); + + if (tm->mSizeTex) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(tm->mSizeTex, + GL_FLOAT, + tm->mVertexElement->getSizeBytes(), + (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetTex)); + } else { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + if (tm->mSizeNorm) { + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, + tm->mVertexElement->getSizeBytes(), + (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetNorm)); + } else { + glDisableClientState(GL_NORMAL_ARRAY); + } + + glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_SHORT, (GLvoid *)(first * 3 * 2)); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void rsi_TriangleMeshRender(Context *rsc, RsTriangleMesh vtm) +{ + rsi_TriangleMeshRenderRange(rsc, vtm, 0, 0xffffff); +} + +}} diff --git a/libs/rs/rsTriangleMesh.h b/libs/rs/rsTriangleMesh.h new file mode 100644 index 0000000..e56c7c2 --- /dev/null +++ b/libs/rs/rsTriangleMesh.h @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_TRIANGLE_MESH_H +#define ANDROID_RS_TRIANGLE_MESH_H + + +#include "RenderScript.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +// An element is a group of Components that occupies one cell in a structure. +class TriangleMesh : public ObjectBase +{ +public: + TriangleMesh(); + ~TriangleMesh(); + + const Element * mVertexElement; + const Element * mIndexElement; + + void * mVertexData; + void * mIndexData; + + size_t mVertexDataSize; + size_t mIndexDataSize; + uint32_t mTriangleCount; + + size_t mOffsetCoord; + size_t mOffsetTex; + size_t mOffsetNorm; + + size_t mSizeCoord; + size_t mSizeTex; + size_t mSizeNorm; + + // GL buffer info + uint32_t mBufferObjects[2]; + + void analyzeElement(); +protected: +}; + +class TriangleMeshContext +{ +public: + TriangleMeshContext(); + ~TriangleMeshContext(); + + const Element * mVertexElement; + const Element * mIndexElement; + size_t mVertexSizeBits; + size_t mIndexSizeBits; + + Vector<uint8_t> mVertexData; + Vector<uint16_t> mIndexData; + + uint32_t mTriangleCount; + + void clear(); +}; + + +} +} +#endif //ANDROID_RS_TRIANGLE_MESH_H + diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp new file mode 100644 index 0000000..bbe9720 --- /dev/null +++ b/libs/rs/rsType.cpp @@ -0,0 +1,222 @@ +/* + * 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. + */ + +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + +Type::Type() +{ + mLODs = 0; + mLODCount = 0; + clear(); +} + +Type::~Type() +{ + if (mLODs) { + delete [] mLODs; + } +} + +void Type::clear() +{ + if (mLODs) { + delete [] mLODs; + mLODs = NULL; + } + mDimX = 0; + mDimY = 0; + mDimZ = 0; + mDimLOD = 0; + mFaces = false; + mElement.clear(); +} + +TypeState::TypeState() +{ +} + +TypeState::~TypeState() +{ +} + +size_t Type::getOffsetForFace(uint32_t face) const +{ + rsAssert(mFaces); + return 0; +} + +void Type::compute() +{ + uint32_t oldLODCount = mLODCount; + if (mDimLOD) { + uint32_t l2x = rsFindHighBit(mDimX) + 1; + uint32_t l2y = rsFindHighBit(mDimY) + 1; + uint32_t l2z = rsFindHighBit(mDimZ) + 1; + + mLODCount = rsMax(l2x, l2y); + mLODCount = rsMax(mLODCount, l2z); + } else { + mLODCount = 1; + } + if (mLODCount != oldLODCount) { + delete [] mLODs; + mLODs = new LOD[mLODCount]; + } + + uint32_t tx = mDimX; + uint32_t ty = mDimY; + uint32_t tz = mDimZ; + size_t offset = 0; + for (uint32_t lod=0; lod < mLODCount; lod++) { + mLODs[lod].mX = tx; + mLODs[lod].mY = ty; + mLODs[lod].mZ = tz; + mLODs[lod].mOffset = offset; + offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); + tx = (tx + 1) >> 1; + ty = (ty + 1) >> 1; + tz = (tz + 1) >> 1; + } + + // At this point the offset is the size of a mipmap chain; + mMipChainSizeBytes = offset; + + if (mFaces) { + offset *= 6; + } + mTotalSizeBytes = offset; + +} + +uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const +{ + uint32_t offset = mLODs[lod].mOffset; + offset += x * mElement->getSizeBytes(); + return offset; +} + +uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const +{ + uint32_t offset = mLODs[lod].mOffset; + offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes(); + return offset; +} + +uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const +{ + uint32_t offset = mLODs[lod].mOffset; + offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes(); + return offset; +} + + +////////////////////////////////////////////////// +// +namespace android { +namespace renderscript { + +void rsi_TypeBegin(Context *rsc, RsElement vse) +{ + TypeState * stc = &rsc->mStateType; + + stc->mX = 0; + stc->mY = 0; + stc->mZ = 0; + stc->mLOD = false; + stc->mFaces = false; + stc->mElement.set(static_cast<const Element *>(vse)); +} + +void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value) +{ + TypeState * stc = &rsc->mStateType; + + if (dim < 0) { + //error + return; + } + + + switch (dim) { + case RS_DIMENSION_X: + stc->mX = value; + return; + case RS_DIMENSION_Y: + stc->mY = value; + return; + case RS_DIMENSION_Z: + stc->mZ = value; + return; + case RS_DIMENSION_FACE: + stc->mFaces = (value != 0); + return; + case RS_DIMENSION_LOD: + stc->mLOD = (value != 0); + return; + default: + break; + } + + + int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0; + if ((dim < 0) || (dim > RS_DIMENSION_MAX)) { + LOGE("rsTypeAdd: Bad dimension"); + //error + return; + } + + // todo: implement array support + +} + +RsType rsi_TypeCreate(Context *rsc) +{ + TypeState * stc = &rsc->mStateType; + + Type * st = new Type(); + st->setDimX(stc->mX); + st->setDimY(stc->mY); + st->setDimZ(stc->mZ); + st->setElement(stc->mElement.get()); + st->setDimLOD(stc->mLOD); + st->setDimFaces(stc->mFaces); + st->compute(); + + stc->mAllTypes.add(st); + + return st; +} + +void rsi_TypeDestroy(Context *rsc, RsType vst) +{ + TypeState * stc = &rsc->mStateType; + Type * st = static_cast<Type *>(vst); + + for (size_t ct = 0; ct < stc->mAllTypes.size(); ct++) { + if (stc->mAllTypes[ct] == st) { + stc->mAllTypes.removeAt(ct); + break; + } + } + delete st; +} + +} +} + diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h new file mode 100644 index 0000000..a717893 --- /dev/null +++ b/libs/rs/rsType.h @@ -0,0 +1,134 @@ +/* + * 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. + */ + +#ifndef ANDROID_STRUCTURED_TYPE_H +#define ANDROID_STRUCTURED_TYPE_H + +#include "rsElement.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +class Type : public ObjectBase +{ +public: + Type(); + virtual ~Type(); + + Type * createTex2D(const Element *, size_t w, size_t h, bool mip); + + + size_t getOffsetForFace(uint32_t face) const; + + size_t getSizeBytes() const {return mTotalSizeBytes;} + size_t getElementSizeBytes() const {return mElement->getSizeBytes();} + const Element * getElement() const {return mElement.get();} + + uint32_t getDimX() const {return mDimX;} + uint32_t getDimY() const {return mDimY;} + uint32_t getDimZ() const {return mDimZ;} + uint32_t getDimLOD() const {return mDimLOD;} + bool getDimFaces() const {return mFaces;} + + uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;} + uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;} + uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;} + uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;} + + uint32_t getLODOffset(uint32_t lod, uint32_t x) const; + uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const; + uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const; + + uint32_t getLODCount() const {return mLODCount;} + + + void setElement(const Element *e) {mElement.set(e);} + void setDimX(uint32_t v) {mDimX = v;} + void setDimY(uint32_t v) {mDimY = v;} + void setDimZ(uint32_t v) {mDimZ = v;} + void setDimFaces(bool v) {mFaces = v;} + void setDimLOD(bool v) {mDimLOD = v;} + + void clear(); + void compute(); + + +protected: + struct LOD { + size_t mX; + size_t mY; + size_t mZ; + size_t mOffset; + }; + + void makeLODTable(); + + // Internal structure from most to least significant. + // * Array dimensions + // * Faces + // * Mipmaps + // * xyz + + ObjectBaseRef<const Element> mElement; + + // Size of the structure in the various dimensions. A missing Dimension is + // specified as a 0 and not a 1. + size_t mDimX; + size_t mDimY; + size_t mDimZ; + bool mDimLOD; + bool mFaces; + + // A list of array dimensions. The count is the number of array dimensions and the + // sizes is a per array size. + //Vector<size_t> mDimArraysSizes; + + // count of mipmap levels, 0 indicates no mipmapping + + size_t mMipChainSizeBytes; + size_t mTotalSizeBytes; + LOD *mLODs; + uint32_t mLODCount; + +private: + Type(const Type &); +}; + + +class TypeState { +public: + TypeState(); + ~TypeState(); + + Vector<Type *> mAllTypes; + + size_t mX; + size_t mY; + size_t mZ; + uint32_t mLOD; + bool mFaces; + ObjectBaseRef<const Element> mElement; + + + +}; + + +} +} +#endif //ANDROID_STRUCTURED_TYPE diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h new file mode 100644 index 0000000..b13e88f --- /dev/null +++ b/libs/rs/rsUtils.h @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#ifndef ANDROID_RS_UTILS_H +#define ANDROID_RS_UTILS_H + +#define LOG_NDEBUG 0 +#define LOG_TAG "rs" +#include <utils/Log.h> +#include <utils/Vector.h> +#include <stdlib.h> +#include <pthread.h> + +#include <EGL/egl.h> +#include <math.h> + +#include "RenderScript.h" + +namespace android { +namespace renderscript { + +#if 1 +#define rsAssert(v) do {if(!(v)) LOGE("rsAssert failed: %s, in %s at %i", #v, __FILE__, __LINE__);} while(0) +#else +#define rsAssert(v) while(0) +#endif + +template<typename T> +T rsMin(T in1, T in2) +{ + if (in1 > in2) { + return in2; + } + return in1; +} + +template<typename T> +T rsMax(T in1, T in2) +{ + if (in1 < in2) { + return in2; + } + return in1; +} + +template<typename T> +T rsFindHighBit(T val) +{ + uint32_t bit = 0; + while(val > 1) { + bit++; + val>>=1; + } + return bit; +} + +template<typename T> +bool rsIsPow2(T val) +{ + return (val & (val-1)) == 0; +} + +template<typename T> +T rsHigherPow2(T v) +{ + if (rsIsPow2(v)) { + return v; + } + return 1 << (rsFindHighBit(v) + 1); +} + +template<typename T> +T rsLowerPow2(T v) +{ + if (rsIsPow2(v)) { + return v; + } + return 1 << rsFindHighBit(v); +} + + +static inline uint16_t rs888to565(uint32_t r, uint32_t g, uint32_t b) +{ + uint16_t t = 0; + t |= b >> 3; + t |= (g >> 2) << 5; + t |= (r >> 3) << 11; + return t; +} + +static inline uint16_t rsBoxFilter565(uint16_t i1, uint16_t i2, uint16_t i3, uint16_t i4) +{ + uint32_t r = ((i1 & 0x1f) + (i2 & 0x1f) + (i3 & 0x1f) + (i4 & 0x1f)); + uint32_t g = ((i1 >> 5) & 0x3f) + ((i2 >> 5) & 0x3f) + ((i3 >> 5) & 0x3f) + ((i4 >> 5) & 0x3f); + uint32_t b = ((i1 >> 11) + (i2 >> 11) + (i3 >> 11) + (i4 >> 11)); + return (r >> 2) | ((g >> 2) << 5) | ((b >> 2) << 11); +} + +static inline uint32_t rsBoxFilter8888(uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4) +{ + uint32_t r = (i1 & 0xff) + (i2 & 0xff) + (i3 & 0xff) + (i4 & 0xff); + uint32_t g = ((i1 >> 8) & 0xff) + ((i2 >> 8) & 0xff) + ((i3 >> 8) & 0xff) + ((i4 >> 8) & 0xff); + uint32_t b = ((i1 >> 16) & 0xff) + ((i2 >> 16) & 0xff) + ((i3 >> 16) & 0xff) + ((i4 >> 16) & 0xff); + uint32_t a = ((i1 >> 24) & 0xff) + ((i2 >> 24) & 0xff) + ((i3 >> 24) & 0xff) + ((i4 >> 24) & 0xff); + return (r >> 2) | ((g >> 2) << 8) | ((b >> 2) << 16) | ((a >> 2) << 24); +} + + + +} +} + +#endif //ANDROID_RS_OBJECT_BASE_H + + diff --git a/libs/rs/rsgApi.cpp.rsg b/libs/rs/rsgApi.cpp.rsg new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/libs/rs/rsgApi.cpp.rsg @@ -0,0 +1 @@ +2 diff --git a/libs/rs/rsgApiFuncDecl.h.rsg b/libs/rs/rsgApiFuncDecl.h.rsg new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/libs/rs/rsgApiFuncDecl.h.rsg @@ -0,0 +1 @@ +1 diff --git a/libs/rs/rsgApiReplay.cpp.rsg b/libs/rs/rsgApiReplay.cpp.rsg new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/libs/rs/rsgApiReplay.cpp.rsg @@ -0,0 +1 @@ +3 diff --git a/libs/rs/rsgApiStructs.h.rsg b/libs/rs/rsgApiStructs.h.rsg new file mode 100644 index 0000000..573541a --- /dev/null +++ b/libs/rs/rsgApiStructs.h.rsg @@ -0,0 +1 @@ +0 diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c new file mode 100644 index 0000000..a4d659d --- /dev/null +++ b/libs/rs/rsg_generator.c @@ -0,0 +1,291 @@ + + +#include "lex.yy.c" + +void printFileHeader(FILE *f) +{ + fprintf(f, "/*\n"); + fprintf(f, " * Copyright (C) 2009 The Android Open Source Project\n"); + fprintf(f, " *\n"); + fprintf(f, " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"); + fprintf(f, " * you may not use this file except in compliance with the License.\n"); + fprintf(f, " * You may obtain a copy of the License at\n"); + fprintf(f, " *\n"); + fprintf(f, " * http://www.apache.org/licenses/LICENSE-2.0\n"); + fprintf(f, " *\n"); + fprintf(f, " * Unless required by applicable law or agreed to in writing, software\n"); + fprintf(f, " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"); + fprintf(f, " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"); + fprintf(f, " * See the License for the specific language governing permissions and\n"); + fprintf(f, " * limitations under the License.\n"); + fprintf(f, " */\n\n"); +} + +void printVarType(FILE *f, const VarType *vt) +{ + int ct; + if (vt->isConst) { + fprintf(f, "const "); + } + + switch(vt->type) { + case 0: + fprintf(f, "void"); + break; + case 1: + fprintf(f, "int%i_t", vt->bits); + break; + case 2: + fprintf(f, "uint%i_t", vt->bits); + break; + case 3: + if (vt->bits == 32) + fprintf(f, "float"); + else + fprintf(f, "double"); + break; + case 4: + fprintf(f, "%s", vt->typename); + break; + } + + if(vt->ptrLevel) { + fprintf(f, " "); + for(ct=0; ct < vt->ptrLevel; ct++) { + fprintf(f, "*"); + } + } + + if(vt->name[0]) { + fprintf(f, " %s", vt->name); + } +} + +void printArgList(FILE *f, const ApiEntry * api, int assumePrevious) +{ + int ct; + for(ct=0; ct < api->paramCount; ct++) { + if (ct || assumePrevious) { + fprintf(f, ", "); + } + printVarType(f, &api->params[ct]); + } +} + +void printStructures(FILE *f) +{ + int ct; + int ct2; + + for(ct=0; ct < apiCount; ct++) { + fprintf(f, "typedef struct RS_CMD_%s_rec RS_CMD_%s;\n", apis[ct].name, apis[ct].name); + } + fprintf(f, "\n"); + + for(ct=0; ct < apiCount; ct++) { + const ApiEntry * api = &apis[ct]; + fprintf(f, "#define RS_CMD_ID_%s %i\n", api->name, ct+1); + fprintf(f, "struct RS_CMD_%s_rec {\n", api->name); + //fprintf(f, " RsCommandHeader _hdr;\n"); + + for(ct2=0; ct2 < api->paramCount; ct2++) { + fprintf(f, " "); + printVarType(f, &api->params[ct2]); + fprintf(f, ";\n"); + } + fprintf(f, "};\n\n"); + } +} + +void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext) +{ + printVarType(f, &api->ret); + fprintf(f, " %s%s (", prefix, api->name); + if (addContext) { + fprintf(f, "Context *"); + } + printArgList(f, api, addContext); + fprintf(f, ")"); +} + +void printFuncDecls(FILE *f, const char *prefix, int addContext) +{ + int ct; + for(ct=0; ct < apiCount; ct++) { + printFuncDecl(f, &apis[ct], prefix, addContext); + fprintf(f, ";\n"); + } + fprintf(f, "\n\n"); +} + +void printPlaybackFuncs(FILE *f, const char *prefix) +{ + int ct; + for(ct=0; ct < apiCount; ct++) { + fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name); + } +} + +void printApiCpp(FILE *f) +{ + int ct; + int ct2; + + fprintf(f, "#include \"rsDevice.h\"\n"); + fprintf(f, "#include \"rsContext.h\"\n"); + fprintf(f, "#include \"rsThreadIO.h\"\n"); + //fprintf(f, "#include \"rsgApiStructs.h\"\n"); + fprintf(f, "#include \"rsgApiFuncDecl.h\"\n"); + fprintf(f, "\n"); + fprintf(f, "using namespace android;\n"); + fprintf(f, "using namespace android::renderscript;\n"); + fprintf(f, "\n"); + + for(ct=0; ct < apiCount; ct++) { + int needFlush = 0; + const ApiEntry * api = &apis[ct]; + + printFuncDecl(f, api, "rs", 0); + fprintf(f, "\n{\n"); + fprintf(f, " ThreadIO *io = gIO;\n"); + //fprintf(f, " LOGE(\"add command %s\\n\");\n", api->name); + fprintf(f, " RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(sizeof(RS_CMD_%s)));\n", api->name, api->name, api->name); + fprintf(f, " uint32_t size = sizeof(RS_CMD_%s);\n", api->name); + + for(ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + needFlush += vt->ptrLevel; + fprintf(f, " cmd->%s = %s;\n", vt->name, vt->name); + } + if (api->ret.typename[0]) { + needFlush = 1; + } + + fprintf(f, " io->mToCore.commit"); + if (needFlush) { + fprintf(f, "Sync"); + } + fprintf(f, "(RS_CMD_ID_%s, size);\n", api->name); + + if (api->ret.typename[0]) { + fprintf(f, " return reinterpret_cast<"); + printVarType(f, &api->ret); + fprintf(f, ">(io->mToCoreRet);\n"); + } + fprintf(f, "};\n\n"); + } +} + +void printPlaybackCpp(FILE *f) +{ + int ct; + int ct2; + + fprintf(f, "#include \"rsDevice.h\"\n"); + fprintf(f, "#include \"rsContext.h\"\n"); + fprintf(f, "#include \"rsThreadIO.h\"\n"); + //fprintf(f, "#include \"rsgApiStructs.h\"\n"); + fprintf(f, "#include \"rsgApiFuncDecl.h\"\n"); + fprintf(f, "\n"); + fprintf(f, "namespace android {\n"); + fprintf(f, "namespace renderscript {\n"); + fprintf(f, "\n"); + + for(ct=0; ct < apiCount; ct++) { + const ApiEntry * api = &apis[ct]; + + fprintf(f, "void rsp_%s(Context *con, const void *vp)\n", api->name); + fprintf(f, "{\n"); + //fprintf(f, " LOGE(\"play command %s\\n\");\n", api->name); + fprintf(f, " const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name); + fprintf(f, " "); + if (api->ret.typename[0]) { + fprintf(f, "gIO->mToCoreRet = (intptr_t)"); + } + fprintf(f, "rsi_%s(con", api->name); + for(ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + fprintf(f, ","); + fprintf(f, "\n cmd->%s", vt->name); + } + fprintf(f, ");\n"); + + fprintf(f, "};\n\n"); + } + + fprintf(f, "RsPlaybackFunc gPlaybackFuncs[] = {\n"); + fprintf(f, " NULL,\n"); + for(ct=0; ct < apiCount; ct++) { + fprintf(f, " %s%s,\n", "rsp_", apis[ct].name); + } + fprintf(f, "};\n"); + + fprintf(f, "};\n"); + fprintf(f, "};\n"); +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "usage: %s commandFile outFile\n", argv[0]); + return 1; + } + const char* rsgFile = argv[1]; + const char* outFile = argv[2]; + FILE* input = fopen(rsgFile, "r"); + + char choice = fgetc(input); + fclose(input); + + if (choice < '0' || choice > '3') { + fprintf(stderr, "Uknown command: \'%c\'\n", choice); + return -2; + } + + yylex(); + // printf("# of lines = %d\n", num_lines); + + FILE *f = fopen(outFile, "w"); + + printFileHeader(f); + switch(choice) { + case '0': // rsgApiStructs.h + { + fprintf(f, "\n"); + fprintf(f, "#include \"rsContext.h\"\n"); + fprintf(f, "\n"); + fprintf(f, "namespace android {\n"); + fprintf(f, "namespace renderscript {\n"); + printStructures(f); + printFuncDecls(f, "rsi_", 1); + printPlaybackFuncs(f, "rsp_"); + fprintf(f, "\n\ntypedef void (*RsPlaybackFunc)(Context *, const void *);\n"); + fprintf(f, "extern RsPlaybackFunc gPlaybackFuncs[];\n"); + + fprintf(f, "}\n"); + fprintf(f, "}\n"); + } + break; + + case '1': // rsgApiFuncDecl.h + { + printFuncDecls(f, "rs", 0); + } + break; + + case '2': // rsgApi.cpp + { + printApiCpp(f); + } + break; + + case '3': // rsgApiReplay.cpp + { + printFileHeader(f); + printPlaybackCpp(f); + } + break; + } + fclose(f); + return 0; +} diff --git a/libs/rs/spec.lex b/libs/rs/spec.lex new file mode 100644 index 0000000..0f8e9ab --- /dev/null +++ b/libs/rs/spec.lex @@ -0,0 +1,171 @@ +%option stack + +%x comment +%x api_entry +%x api_entry2 +%x api_entry_param +%x var_type + +DIGIT [0-9] +ID [a-zA-Z_][a-zA-Z0-9_]* + + + int num_lines = 0; + + typedef struct { + int isConst; + int type; + int bits; + int ptrLevel; + char name[256]; + char typename[256]; + } VarType; + + VarType *currType = 0; + + typedef struct { + char name[256]; + int sync; + int paramCount; + VarType ret; + VarType params[16]; + } ApiEntry; + + ApiEntry apis[128]; + int apiCount = 0; + + int typeNextState; + +%% + +"/*" BEGIN(comment); +<comment>[^*\n]* /* eat anything that's not a '*' */ +<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +<comment>\n ++num_lines; +<comment>"*"+"/" BEGIN(INITIAL); + +<*>" " //printf("found ' '\n"); +<*>"\n" ++num_lines; //printf("found lf \n"); + +{ID} { + memset(&apis[apiCount], 0, sizeof(ApiEntry)); + memcpy(apis[apiCount].name, yytext, yyleng); + BEGIN(api_entry); + } + +<api_entry>"{" { + BEGIN(api_entry2); + } + +<api_entry2>"sync" { + apis[apiCount].sync = 1; + } + +<api_entry2>"ret" { + currType = &apis[apiCount].ret; + typeNextState = api_entry2; + BEGIN(var_type); + } + +<api_entry2>"param" { + currType = &apis[apiCount].params[apis[apiCount].paramCount]; + apis[apiCount].paramCount++; + typeNextState = api_entry_param; + BEGIN(var_type); + } + +<var_type>"const" { + currType->isConst = 1; + } + +<var_type>"i8" { + currType->type = 1; + currType->bits = 8; + BEGIN(typeNextState); + } + +<var_type>"i16" { + currType->type = 1; + currType->bits = 16; + BEGIN(typeNextState); + } + +<var_type>"i32" { + currType->type = 1; + currType->bits = 32; + BEGIN(typeNextState); + } + +<var_type>"i64" { + currType->type = 1; + currType->bits = 64; + BEGIN(typeNextState); + } + +<var_type>"u8" { + currType->type = 2; + currType->bits = 8; + BEGIN(typeNextState); + } + +<var_type>"u16" { + currType->type = 2; + currType->bits = 16; + BEGIN(typeNextState); + } + +<var_type>"u32" { + currType->type = 2; + currType->bits = 32; + BEGIN(typeNextState); + } + +<var_type>"u64" { + currType->type = 2; + currType->bits = 64; + BEGIN(typeNextState); + } + +<var_type>"f" { + currType->type = 3; + currType->bits = 32; + BEGIN(typeNextState); + } + +<var_type>"d" { + currType->type = 3; + currType->bits = 64; + BEGIN(typeNextState); + } + +<var_type>{ID} { + currType->type = 4; + currType->bits = 32; + memcpy(currType->typename, yytext, yyleng); + BEGIN(typeNextState); + } + +<api_entry_param>"*" { + currType->ptrLevel ++; + } + +<api_entry_param>{ID} { + memcpy(currType->name, yytext, yyleng); + BEGIN(api_entry2); + } + + +<api_entry2>"}" { + apiCount++; + BEGIN(INITIAL); + } + + +%% + + +int yywrap() +{ + return 1; +} + |