diff options
Diffstat (limited to 'libs/rs')
62 files changed, 9748 insertions, 0 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk new file mode 100644 index 0000000..06c0595 --- /dev/null +++ b/libs/rs/Android.mk @@ -0,0 +1,117 @@ +# Only build if BUILD_RENDERSCRIPT is defined to true in the environment. +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 \ + rsLocklessFifo.cpp \ + rsObjectBase.cpp \ + rsMatrix.cpp \ + rsProgram.cpp \ + rsProgramFragment.cpp \ + rsProgramFragmentStore.cpp \ + rsProgramVertex.cpp \ + rsSampler.cpp \ + rsScript.cpp \ + rsScriptC.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_PRELINK_MODULE := false + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + +# Include the subdirectories ==================== +include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk,\ + jni \ + java \ + )) + +endif # BUILD_RENDERSCRIPT diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h new file mode 100644 index 0000000..2b33419 --- /dev/null +++ b/libs/rs/RenderScript.h @@ -0,0 +1,186 @@ +/* + * 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 * RsSampler; +typedef void * RsScript; +typedef void * RsScriptBasicTemp; +typedef void * RsTriangleMesh; +typedef void * RsType; + +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 +}; + + + +#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..1bf5f22 --- /dev/null +++ b/libs/rs/RenderScriptEnv.h @@ -0,0 +1,97 @@ +#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 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 struct { + const void * (*loadEnvVp)(void *con, uint32_t bank, uint32_t offset); + + float (*loadEnvF)(void *con, uint32_t bank, uint32_t offset); + int32_t (*loadEnvI32)(void *con, uint32_t bank, uint32_t offset); + uint32_t (*loadEnvU32)(void *con, uint32_t bank, uint32_t offset); + void (*loadEnvVec4)(void *con, uint32_t bank, uint32_t offset, rsc_Vector4 *); + void (*loadEnvMatrix)(void *con, uint32_t bank, uint32_t offset, rsc_Matrix *); + + void (*storeEnvF)(void *con, uint32_t bank, uint32_t offset, float); + void (*storeEnvI32)(void *con, uint32_t bank, uint32_t offset, int32_t); + void (*storeEnvU32)(void *con, uint32_t bank, uint32_t offset, uint32_t); + void (*storeEnvVec4)(void *con, uint32_t bank, uint32_t offset, const rsc_Vector4 *); + void (*storeEnvMatrix)(void *con, uint32_t bank, uint32_t offset, const rsc_Matrix *); + + void (*matrixLoadIdentity)(void *con, rsc_Matrix *); + void (*matrixLoadFloat)(void *con, rsc_Matrix *, const float *); + void (*matrixLoadMat)(void *con, rsc_Matrix *, const rsc_Matrix *); + void (*matrixLoadRotate)(void *con, rsc_Matrix *, float rot, float x, float y, float z); + void (*matrixLoadScale)(void *con, rsc_Matrix *, float x, float y, float z); + void (*matrixLoadTranslate)(void *con, rsc_Matrix *, float x, float y, float z); + void (*matrixLoadMultiply)(void *con, rsc_Matrix *, const rsc_Matrix *lhs, const rsc_Matrix *rhs); + void (*matrixMultiply)(void *con, rsc_Matrix *, const rsc_Matrix *rhs); + void (*matrixRotate)(void *con, rsc_Matrix *, float rot, float x, float y, float z); + void (*matrixScale)(void *con, rsc_Matrix *, float x, float y, float z); + void (*matrixTranslate)(void *con, rsc_Matrix *, float x, float y, float z); + + void (*color)(void *con, float r, float g, float b, float a); + + void (*programFragmentBindTexture)(void *con, RsProgramFragment, uint32_t slot, RsAllocation); + void (*programFragmentBindSampler)(void *con, RsProgramFragment, uint32_t slot, RsAllocation); + + void (*materialDiffuse)(void *con, float r, float g, float b, float a); + void (*materialSpecular)(void *con, float r, float g, float b, float a); + void (*lightPosition)(void *con, float x, float y, float z, float w); + void (*materialShininess)(void *con, float s); + + void (*uploadToTexture)(void *con, RsAllocation va, uint32_t baseMipLevel); + + void (*enable)(void *con, uint32_t); + void (*disable)(void *con, uint32_t); + + uint32_t (*rand)(void *con, uint32_t max); + + void (*contextBindProgramFragment)(void *con, RsProgramFragment pf); + void (*contextBindProgramFragmentStore)(void *con, RsProgramFragmentStore pfs); + + + // Drawing funcs + void (*renderTriangleMesh)(void *con, RsTriangleMesh); + void (*renderTriangleMeshRange)(void *con, RsTriangleMesh, uint32_t start, uint32_t count); + + // Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a + void (*drawTriangleArray)(void *con, RsAllocation alloc, uint32_t count); + + void (*drawRect)(void *con, int32_t x1, int32_t x2, int32_t y1, int32_t y2); +} rsc_FunctionTable; + +typedef int (*rsc_RunScript)(void *con, const rsc_FunctionTable *, uint32_t launchID); + + +/* 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/Fountain/Android.mk b/libs/rs/java/Fountain/Android.mk new file mode 100644 index 0000000..af3d5fc --- /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..a10938b --- /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.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/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..3bd9496 --- /dev/null +++ b/libs/rs/java/Fountain/res/raw/fountain.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/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..ceb94d1 --- /dev/null +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java @@ -0,0 +1,140 @@ +/* + * 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.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.util.AttributeSet; +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 RenderScript.ProgramFragment mPF2; + private RenderScript.Allocation mTexture; + private RenderScript.Sampler mSampler; + + 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); + + { + Drawable d = mRes.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); + + mRS.samplerBegin(); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MAG, RenderScript.SamplerValue.LINEAR); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, RenderScript.SamplerValue.LINEAR); + mSampler = mRS.samplerCreate(); + + + mRS.programFragmentBegin(null, null); + mPF = mRS.programFragmentCreate(); + mPF.setName("PgmFragParts"); + + mRS.programFragmentBegin(null, null); + mRS.programFragmentSetTexEnable(0, true); + mPF2 = mRS.programFragmentCreate(); + mRS.contextBindProgramFragment(mPF2); + mPF2.bindTexture(mTexture, 0); + mPF2.bindSampler(mSampler, 0); + mPF2.setName("PgmFragBackground"); + + 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/RenderScript/Android.mk b/libs/rs/java/RenderScript/Android.mk new file mode 100644 index 0000000..616fbd2 --- /dev/null +++ b/libs/rs/java/RenderScript/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2008 Esmertec AG. +# 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) + +# the library +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + $(call all-subdir-java-files) + +LOCAL_MODULE:= android.renderscript + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/libs/rs/java/RenderScript/android/renderscript/RSSurfaceView.java b/libs/rs/java/RenderScript/android/renderscript/RSSurfaceView.java new file mode 100644 index 0000000..3d37c13 --- /dev/null +++ b/libs/rs/java/RenderScript/android/renderscript/RSSurfaceView.java @@ -0,0 +1,154 @@ +/* + * 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 android.renderscript; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + private SurfaceHolder mSurfaceHolder; + + /** + * Standard View constructor. In order to render something, you + * must call {@link #setRenderer} to register a renderer. + */ + public RSSurfaceView(Context context) { + super(context); + init(); + Log.v("***", "RSSurfaceView"); + } + + /** + * Standard View constructor. In order to render something, you + * must call {@link #setRenderer} to register a renderer. + */ + public RSSurfaceView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + Log.v("***", "RSSurfaceView"); + } + + private void init() { + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed + SurfaceHolder holder = getHolder(); + holder.addCallback(this); + holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceCreated(SurfaceHolder holder) { + Log.v("***", "surfaceCreated"); + mSurfaceHolder = holder; + //mGLThread.surfaceCreated(); + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceDestroyed(SurfaceHolder holder) { + // Surface will be destroyed when we return + Log.v("***", "surfaceDestroyed"); + //mGLThread.surfaceDestroyed(); + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + Log.v("***", "surfaceChanged"); + + //mGLThread.onWindowResize(w, h); + } + + /** + * Inform the view that the activity is paused. The owner of this view must + * call this method when the activity is paused. Calling this method will + * pause the rendering thread. + * Must not be called before a renderer has been set. + */ + public void onPause() { + Log.v("***", "onPause"); + //mGLThread.onPause(); + } + + /** + * Inform the view that the activity is resumed. The owner of this view must + * call this method when the activity is resumed. Calling this method will + * recreate the OpenGL display and resume the rendering + * thread. + * Must not be called before a renderer has been set. + */ + public void onResume() { + Log.v("***", "onResume"); + //mGLThread.onResume(); + } + + /** + * Queue a runnable to be run on the GL rendering thread. This can be used + * to communicate with the Renderer on the rendering thread. + * Must not be called before a renderer has been set. + * @param r the runnable to be run on the GL rendering thread. + */ + public void queueEvent(Runnable r) { + Log.v("***", "queueEvent"); + //mGLThread.queueEvent(r); + } + + /** + * This method is used as part of the View class and is not normally + * called or subclassed by clients of RSSurfaceView. + * Must not be called before a renderer has been set. + */ + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + //mGLThread.requestExitAndWait(); + } + + // ---------------------------------------------------------------------- + + public RenderScript createRenderScript() { + Log.v("***", "createRenderScript 1"); + Surface sur = null; + while ((sur == null) || (mSurfaceHolder == null)) { + sur = getHolder().getSurface(); + } + Log.v("***", "createRenderScript 2"); + RenderScript rs = new RenderScript(sur); + Log.v("***", "createRenderScript 3 rs"); + return rs; + } + +} + diff --git a/libs/rs/java/RenderScript/android/renderscript/RenderScript.java b/libs/rs/java/RenderScript/android/renderscript/RenderScript.java new file mode 100644 index 0000000..faa6527 --- /dev/null +++ b/libs/rs/java/RenderScript/android/renderscript/RenderScript.java @@ -0,0 +1,910 @@ +/* + * 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 android.renderscript; + +import java.io.InputStream; +import java.io.IOException; + +import android.os.Bundle; +import android.content.res.Resources; +import android.util.Log; +import android.util.Config; +import android.view.Menu; +import android.view.MenuItem; +import android.view.Window; +import android.view.View; +import android.view.Surface; +import android.graphics.Bitmap; +import android.graphics.Color; + +public class RenderScript { + 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; + + + + /* + * We use a class initializer to allow the native code to cache some + * field offsets. + */ + private static boolean sInitialized; + native private static void _nInit(); + + static { + sInitialized = false; + try { + System.loadLibrary("RS_jni"); + _nInit(); + sInitialized = true; + } catch (UnsatisfiedLinkError e) { + Log.d(LOG_TAG, "RenderScript JNI library not found!"); + } + } + + native private int nDeviceCreate(); + native private void nDeviceDestroy(int dev); + native private int nContextCreate(int dev, Surface sur, int ver); + native private void nContextDestroy(int con); + + //void rsContextBindSampler (uint32_t slot, RsSampler sampler); + //void rsContextBindRootScript (RsScript sampler); + native private void nContextBindRootScript(int script); + native private void nContextBindSampler(int sampler, int slot); + native private void nContextBindProgramFragmentStore(int pfs); + native private void nContextBindProgramFragment(int pf); + + native private void nAssignName(int obj, byte[] name); + + native private void nElementBegin(); + native private void nElementAddPredefined(int predef); + native private void nElementAdd(int kind, int type, int norm, int bits); + native private int nElementCreate(); + native private int nElementGetPredefined(int predef); + native private void nElementDestroy(int obj); + + native private void nTypeBegin(int elementID); + native private void nTypeAdd(int dim, int val); + native private int nTypeCreate(); + native private void nTypeDestroy(int id); + + native private int nAllocationCreateTyped(int type); + native private int nAllocationCreatePredefSized(int predef, int count); + native private int nAllocationCreateSized(int elem, int count); + native private int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp); + + native private void nAllocationUploadToTexture(int alloc, int baseMioLevel); + native private void nAllocationDestroy(int alloc); + native private void nAllocationData(int id, int[] d); + native private void nAllocationData(int id, float[] d); + native private void nAllocationSubData1D(int id, int off, int count, int[] d); + native private void nAllocationSubData1D(int id, int off, int count, float[] d); + native private void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d); + native private void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d); + + native private void nTriangleMeshDestroy(int id); + native private void nTriangleMeshBegin(int vertex, int index); + native private void nTriangleMeshAddVertex_XY (float x, float y); + native private void nTriangleMeshAddVertex_XYZ (float x, float y, float z); + native private void nTriangleMeshAddVertex_XY_ST (float x, float y, float s, float t); + native private void nTriangleMeshAddVertex_XYZ_ST (float x, float y, float z, float s, float t); + native private void nTriangleMeshAddTriangle(int i1, int i2, int i3); + native private int nTriangleMeshCreate(); + + native private void nAdapter1DDestroy(int id); + native private void nAdapter1DBindAllocation(int ad, int alloc); + native private void nAdapter1DSetConstraint(int ad, int dim, int value); + native private void nAdapter1DData(int ad, int[] d); + native private void nAdapter1DSubData(int ad, int off, int count, int[] d); + native private void nAdapter1DData(int ad, float[] d); + native private void nAdapter1DSubData(int ad, int off, int count, float[] d); + native private int nAdapter1DCreate(); + + native private void nScriptDestroy(int script); + native private void nScriptBindAllocation(int vtm, int alloc, int slot); + native private void nScriptCBegin(); + native private void nScriptCSetClearColor(float r, float g, float b, float a); + native private void nScriptCSetClearDepth(float depth); + native private void nScriptCSetClearStencil(int stencil); + native private void nScriptCAddType(int type); + native private void nScriptCSetRoot(boolean isRoot); + native private void nScriptCSetScript(byte[] script, int offset, int length); + native private int nScriptCCreate(); + + native private void nSamplerDestroy(int sampler); + native private void nSamplerBegin(); + native private void nSamplerSet(int param, int value); + native private int nSamplerCreate(); + + native private void nProgramFragmentStoreBegin(int in, int out); + native private void nProgramFragmentStoreDepthFunc(int func); + native private void nProgramFragmentStoreDepthMask(boolean enable); + native private void nProgramFragmentStoreColorMask(boolean r, boolean g, boolean b, boolean a); + native private void nProgramFragmentStoreBlendFunc(int src, int dst); + native private void nProgramFragmentStoreDither(boolean enable); + native private int nProgramFragmentStoreCreate(); + native private void nProgramFragmentStoreDestroy(int pgm); + + native private void nProgramFragmentBegin(int in, int out); + native private void nProgramFragmentBindTexture(int vpf, int slot, int a); + native private void nProgramFragmentBindSampler(int vpf, int slot, int s); + native private void nProgramFragmentSetType(int slot, int vt); + native private void nProgramFragmentSetEnvMode(int slot, int env); + native private void nProgramFragmentSetTexEnable(int slot, boolean enable); + native private int nProgramFragmentCreate(); + native private void nProgramFragmentDestroy(int pgm); + + native private void nProgramVertexDestroy(int pv); + native private void nProgramVertexBindAllocation(int pv, int slot, int mID); + native private void nProgramVertexBegin(int inID, int outID); + native private void nProgramVertexSetType(int slot, int mID); + native private void nProgramVertexSetCameraMode(boolean isOrtho); + native private void nProgramVertexSetTextureMatrixEnable(boolean enable); + native private void nProgramVertexSetModelMatrixEnable(boolean enable); + native private int nProgramVertexCreate(); + + + private int mDev; + private int mContext; + private Surface mSurface; + + + + /////////////////////////////////////////////////////////////////////////////////// + // + + RenderScript(Surface sur) { + mSurface = sur; + mDev = nDeviceCreate(); + mContext = nContextCreate(mDev, mSurface, 0); + } + + private class BaseObj { + BaseObj() { + mID = 0; + } + + public int getID() { + return mID; + } + + int mID; + String mName; + + public void setName(String s) throws IllegalStateException, IllegalArgumentException + { + if(s.length() < 1) { + throw new IllegalArgumentException("setName does not accept a zero length string."); + } + if(mName != null) { + throw new IllegalArgumentException("setName object already has a name."); + } + + try { + byte[] bytes = s.getBytes("UTF-8"); + nAssignName(mID, bytes); + mName = s; + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + protected void finalize() throws Throwable + { + if (mID != 0) { + Log.v(LOG_TAG, + "Element finalized without having released the RS reference."); + } + super.finalize(); + } + } + + + ////////////////////////////////////////////////////////////////////////////////// + // Element + + public enum ElementPredefined { + USER_U8 (0), + USER_I8 (1), + USER_U16 (2), + USER_I16 (3), + USER_U32 (4), + USER_I32 (5), + USER_FLOAT (6), + + A_8 (7), + RGB_565 (8), + RGB_888 (12), + RGBA_5551 (9), + RGBA_4444 (10), + RGBA_8888 (13), + + INDEX_16 (16), + INDEX_32 (17), + XY_F32 (18), + XYZ_F32 (19), + ST_XY_F32 (20), + ST_XYZ_F32 (21), + NORM_XYZ_F32 (22), + NORM_ST_XYZ_F32 (23); + + int mID; + ElementPredefined(int id) { + mID = id; + } + } + + public enum DataType { + FLOAT (0), + UNSIGNED (1), + SIGNED (2); + + int mID; + DataType(int id) { + mID = id; + } + } + + public enum DataKind { + USER (0), + RED (1), + GREEN (2), + BLUE (3), + ALPHA (4), + LUMINANCE (5), + INTENSITY (6), + X (7), + Y (8), + Z (9), + W (10), + S (11), + T (12), + Q (13), + R (14), + NX (15), + NY (16), + NZ (17), + INDEX (18); + + int mID; + DataKind(int id) { + mID = id; + } + } + + public enum DepthFunc { + ALWAYS (0), + LESS (1), + LEQUAL (2), + GREATER (3), + GEQUAL (4), + EQUAL (5), + NOTEQUAL (6); + + int mID; + DepthFunc(int id) { + mID = id; + } + } + + public enum BlendSrcFunc { + ZERO (0), + ONE (1), + DST_COLOR (2), + ONE_MINUS_DST_COLOR (3), + SRC_ALPHA (4), + ONE_MINUS_SRC_ALPHA (5), + DST_ALPHA (6), + ONE_MINUS_DST_ALPA (7), + SRC_ALPHA_SATURATE (8); + + int mID; + BlendSrcFunc(int id) { + mID = id; + } + } + + public enum BlendDstFunc { + ZERO (0), + ONE (1), + SRC_COLOR (2), + ONE_MINUS_SRC_COLOR (3), + SRC_ALPHA (4), + ONE_MINUS_SRC_ALPHA (5), + DST_ALPHA (6), + ONE_MINUS_DST_ALPA (7); + + int mID; + BlendDstFunc(int id) { + mID = id; + } + } + + public enum EnvMode { + REPLACE (0), + MODULATE (1), + DECAL (2); + + int mID; + EnvMode(int id) { + mID = id; + } + } + + public enum SamplerParam { + FILTER_MIN (0), + FILTER_MAG (1), + WRAP_MODE_S (2), + WRAP_MODE_T (3), + WRAP_MODE_R (4); + + int mID; + SamplerParam(int id) { + mID = id; + } + } + + public enum SamplerValue { + NEAREST (0), + LINEAR (1), + LINEAR_MIP_LINEAR (2), + WRAP (3), + CLAMP (4); + + int mID; + SamplerValue(int id) { + mID = id; + } + } + + + + public class Element extends BaseObj { + Element(int id) { + mID = id; + } + + public void estroy() { + nElementDestroy(mID); + mID = 0; + } + } + + public void elementBegin() { + nElementBegin(); + } + + public void elementAddPredefined(ElementPredefined e) { + nElementAddPredefined(e.mID); + } + + public void elementAdd(DataType dt, DataKind dk, boolean isNormalized, int bits) { + int norm = 0; + if (isNormalized) { + norm = 1; + } + nElementAdd(dt.mID, dk.mID, norm, bits); + } + + public Element elementCreate() { + int id = nElementCreate(); + return new Element(id); + } + + public Element elementGetPredefined(ElementPredefined predef) { + int id = nElementGetPredefined(predef.mID); + return new Element(id); + } + + + ////////////////////////////////////////////////////////////////////////////////// + // Type + + public enum Dimension { + X (0), + Y (1), + Z (2), + LOD (3), + FACE (4), + ARRAY_0 (100); + + int mID; + Dimension(int id) { + mID = id; + } + } + + public class Type extends BaseObj { + Type(int id) { + mID = id; + } + + public void destroy() { + nTypeDestroy(mID); + mID = 0; + } + } + + public void typeBegin(Element e) { + nTypeBegin(e.mID); + } + + public void typeAdd(Dimension d, int value) { + nTypeAdd(d.mID, value); + } + + public Type typeCreate() { + int id = nTypeCreate(); + return new Type(id); + } + + + ////////////////////////////////////////////////////////////////////////////////// + // Allocation + + public class Allocation extends BaseObj { + Allocation(int id) { + mID = id; + } + + public void uploadToTexture(int baseMipLevel) { + nAllocationUploadToTexture(mID, baseMipLevel); + } + + public void destroy() { + nAllocationDestroy(mID); + mID = 0; + } + + public void data(int[] d) { + nAllocationData(mID, d); + } + + public void data(float[] d) { + nAllocationData(mID, d); + } + + public void subData1D(int off, int count, int[] d) { + nAllocationSubData1D(mID, off, count, d); + } + + public void subData1D(int off, int count, float[] d) { + nAllocationSubData1D(mID, off, count, d); + } + + public void subData2D(int xoff, int yoff, int w, int h, int[] d) { + nAllocationSubData2D(mID, xoff, yoff, w, h, d); + } + + public void subData2D(int xoff, int yoff, int w, int h, float[] d) { + nAllocationSubData2D(mID, xoff, yoff, w, h, d); + } + } + + public Allocation allocationCreateTyped(Type type) { + int id = nAllocationCreateTyped(type.mID); + return new Allocation(id); + } + + public Allocation allocationCreatePredefSized(ElementPredefined e, int count) { + int id = nAllocationCreatePredefSized(e.mID, count); + return new Allocation(id); + } + + public Allocation allocationCreateSized(Element e, int count) { + int id = nAllocationCreateSized(e.mID, count); + return new Allocation(id); + } + + public Allocation allocationCreateFromBitmap(Bitmap b, ElementPredefined dstFmt, boolean genMips) { + int id = nAllocationCreateFromBitmap(dstFmt.mID, genMips, b); + return new Allocation(id); + } + + ////////////////////////////////////////////////////////////////////////////////// + // Adapter1D + + public class Adapter1D extends BaseObj { + Adapter1D(int id) { + mID = id; + } + + public void destroy() { + nAdapter1DDestroy(mID); + mID = 0; + } + + public void bindAllocation(Allocation a) { + nAdapter1DBindAllocation(mID, a.mID); + } + + public void setConstraint(Dimension dim, int value) { + nAdapter1DSetConstraint(mID, dim.mID, value); + } + + public void data(int[] d) { + nAdapter1DData(mID, d); + } + + public void subData(int off, int count, int[] d) { + nAdapter1DSubData(mID, off, count, d); + } + + public void data(float[] d) { + nAdapter1DData(mID, d); + } + + public void subData(int off, int count, float[] d) { + nAdapter1DSubData(mID, off, count, d); + } + } + + public Adapter1D adapter1DCreate() { + int id = nAdapter1DCreate(); + return new Adapter1D(id); + } + + + ////////////////////////////////////////////////////////////////////////////////// + // Triangle Mesh + + public class TriangleMesh extends BaseObj { + TriangleMesh(int id) { + mID = id; + } + + public void destroy() { + nTriangleMeshDestroy(mID); + mID = 0; + } + } + + public void triangleMeshBegin(Element vertex, Element index) { + nTriangleMeshBegin(vertex.mID, index.mID); + } + + public void triangleMeshAddVertex_XY(float x, float y) { + nTriangleMeshAddVertex_XY(x, y); + } + + public void triangleMeshAddVertex_XYZ(float x, float y, float z) { + nTriangleMeshAddVertex_XYZ(x, y, z); + } + + public void triangleMeshAddVertex_XY_ST(float x, float y, float s, float t) { + nTriangleMeshAddVertex_XY_ST(x, y, s, t); + } + + public void triangleMeshAddVertex_XYZ_ST(float x, float y, float z, float s, float t) { + nTriangleMeshAddVertex_XYZ_ST(x, y, z, s, t); + } + + public void triangleMeshAddTriangle(int i1, int i2, int i3) { + nTriangleMeshAddTriangle(i1, i2, i3); + } + + public TriangleMesh triangleMeshCreate() { + int id = nTriangleMeshCreate(); + return new TriangleMesh(id); + } + + ////////////////////////////////////////////////////////////////////////////////// + // Script + + public class Script extends BaseObj { + Script(int id) { + mID = id; + } + + public void destroy() { + nScriptDestroy(mID); + mID = 0; + } + + public void bindAllocation(Allocation va, int slot) { + nScriptBindAllocation(mID, va.mID, slot); + } + } + + public void scriptCBegin() { + nScriptCBegin(); + } + + public void scriptCSetClearColor(float r, float g, float b, float a) { + nScriptCSetClearColor(r, g, b, a); + } + + public void scriptCSetClearDepth(float d) { + nScriptCSetClearDepth(d); + } + + public void scriptCSetClearStencil(int stencil) { + nScriptCSetClearStencil(stencil); + } + + public void scriptCAddType(Type t) { + nScriptCAddType(t.mID); + } + + public void scriptCSetRoot(boolean r) { + nScriptCSetRoot(r); + } + + public void scriptCSetScript(String s) { + try { + byte[] bytes = s.getBytes("UTF-8"); + nScriptCSetScript(bytes, 0, bytes.length); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public void scriptCSetScript(Resources resources, int id) { + InputStream is = resources.openRawResource(id); + try { + try { + scriptCSetScript(is); + } finally { + is.close(); + } + } catch(IOException e) { + throw new Resources.NotFoundException(); + } + } + + public void scriptCSetScript(InputStream is) throws IOException { + byte[] buf = new byte[1024]; + int currentPos = 0; + while(true) { + int bytesLeft = buf.length - currentPos; + if (bytesLeft == 0) { + byte[] buf2 = new byte[buf.length * 2]; + System.arraycopy(buf, 0, buf2, 0, buf.length); + buf = buf2; + bytesLeft = buf.length - currentPos; + } + int bytesRead = is.read(buf, currentPos, bytesLeft); + if (bytesRead <= 0) { + break; + } + currentPos += bytesRead; + } + nScriptCSetScript(buf, 0, currentPos); + } + + public Script scriptCCreate() { + int id = nScriptCCreate(); + return new Script(id); + } + + ////////////////////////////////////////////////////////////////////////////////// + // ProgramVertex + + public class ProgramVertex extends BaseObj { + ProgramVertex(int id) { + mID = id; + } + + public void destroy() { + nProgramVertexDestroy(mID); + mID = 0; + } + + public void bindAllocation(int slot, Allocation va) { + nProgramVertexBindAllocation(mID, slot, va.mID); + } + + } + + public void programVertexBegin(Element in, Element out) { + int inID = 0; + int outID = 0; + if (in != null) { + inID = in.mID; + } + if (out != null) { + outID = out.mID; + } + nProgramVertexBegin(inID, outID); + } + + public void programVertexSetType(int slot, Type t) { + nProgramVertexSetType(slot, t.mID); + } + + public void programVertexSetCameraMode(boolean isOrtho) { + nProgramVertexSetCameraMode(isOrtho); + } + + public void programVertexSetTextureMatrixEnable(boolean enable) { + nProgramVertexSetTextureMatrixEnable(enable); + } + + public void programVertexSetModelMatrixEnable(boolean enable) { + nProgramVertexSetModelMatrixEnable(enable); + } + + public ProgramVertex programVertexCreate() { + int id = nProgramVertexCreate(); + return new ProgramVertex(id); + } + + + ////////////////////////////////////////////////////////////////////////////////// + // ProgramFragmentStore + + public class ProgramFragmentStore extends BaseObj { + ProgramFragmentStore(int id) { + mID = id; + } + + public void destroy() { + nProgramFragmentStoreDestroy(mID); + mID = 0; + } + } + + public void programFragmentStoreBegin(Element in, Element out) { + int inID = 0; + int outID = 0; + if (in != null) { + inID = in.mID; + } + if (out != null) { + outID = out.mID; + } + nProgramFragmentStoreBegin(inID, outID); + } + + public void programFragmentStoreDepthFunc(DepthFunc func) { + nProgramFragmentStoreDepthFunc(func.mID); + } + + public void programFragmentStoreDepthMask(boolean enable) { + nProgramFragmentStoreDepthMask(enable); + } + + public void programFragmentStoreColorMask(boolean r, boolean g, boolean b, boolean a) { + nProgramFragmentStoreColorMask(r,g,b,a); + } + + public void programFragmentStoreBlendFunc(BlendSrcFunc src, BlendDstFunc dst) { + nProgramFragmentStoreBlendFunc(src.mID, dst.mID); + } + + public void programFragmentStoreDitherEnable(boolean enable) { + nProgramFragmentStoreDither(enable); + } + + public ProgramFragmentStore programFragmentStoreCreate() { + int id = nProgramFragmentStoreCreate(); + return new ProgramFragmentStore(id); + } + + ////////////////////////////////////////////////////////////////////////////////// + // ProgramFragment + + public class ProgramFragment extends BaseObj { + ProgramFragment(int id) { + mID = id; + } + + public void destroy() { + nProgramFragmentDestroy(mID); + mID = 0; + } + + public void bindTexture(Allocation va, int slot) { + nProgramFragmentBindTexture(mID, slot, va.mID); + } + + public void bindSampler(Sampler vs, int slot) { + nProgramFragmentBindSampler(mID, slot, vs.mID); + } + } + + public void programFragmentBegin(Element in, Element out) { + int inID = 0; + int outID = 0; + if (in != null) { + inID = in.mID; + } + if (out != null) { + outID = out.mID; + } + nProgramFragmentBegin(inID, outID); + } + + public void programFragmentSetType(int slot, Type t) { + nProgramFragmentSetType(slot, t.mID); + } + + public void programFragmentSetType(int slot, EnvMode t) { + nProgramFragmentSetEnvMode(slot, t.mID); + } + + public void programFragmentSetTexEnable(int slot, boolean enable) { + nProgramFragmentSetTexEnable(slot, enable); + } + + public ProgramFragment programFragmentCreate() { + int id = nProgramFragmentCreate(); + return new ProgramFragment(id); + } + + ////////////////////////////////////////////////////////////////////////////////// + // Sampler + + public class Sampler extends BaseObj { + Sampler(int id) { + mID = id; + } + + public void destroy() { + nSamplerDestroy(mID); + mID = 0; + } + } + + public void samplerBegin() { + nSamplerBegin(); + } + + public void samplerSet(SamplerParam p, SamplerValue v) { + nSamplerSet(p.mID, v.mID); + } + + public Sampler samplerCreate() { + int id = nSamplerCreate(); + return new Sampler(id); + } + + + /////////////////////////////////////////////////////////////////////////////////// + // Root state + + public void contextBindRootScript(Script s) { + nContextBindRootScript(s.mID); + } + + //public void contextBindSampler(Sampler s, int slot) { + //nContextBindSampler(s.mID); + //} + + public void contextBindProgramFragmentStore(ProgramFragmentStore pfs) { + nContextBindProgramFragmentStore(pfs.mID); + } + + public void contextBindProgramFragment(ProgramFragment pf) { + nContextBindProgramFragment(pf.mID); + } + +/* + RsAdapter2D rsAdapter2DCreate (); + void rsAdapter2DBindAllocation (RsAdapter2D adapt, RsAllocation alloc); + void rsAdapter2DDestroy (RsAdapter2D adapter); + void rsAdapter2DSetConstraint (RsAdapter2D adapter, RsDimension dim, uint32_t value); + void rsAdapter2DData (RsAdapter2D adapter, const void * data); + void rsAdapter2DSubData (RsAdapter2D adapter, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void * data); + void rsSamplerBegin (); + void rsSamplerSet (RsSamplerParam p, RsSamplerValue value); + RsSampler rsSamplerCreate (); + void rsSamplerBind (RsSampler sampler, RsAllocation alloc); +*/ + +} + diff --git a/libs/rs/jni/Android.mk b/libs/rs/jni/Android.mk new file mode 100644 index 0000000..b3142ae --- /dev/null +++ b/libs/rs/jni/Android.mk @@ -0,0 +1,36 @@ +LOCAL_PATH:=$(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + RenderScript_jni.cpp + +LOCAL_SHARED_LIBRARIES := \ + libandroid_runtime \ + libacc \ + libnativehelper \ + libRS \ + libcutils \ + libsgl \ + libutils \ + libui + +LOCAL_STATIC_LIBRARIES := + +rs_generated_include_dir := $(call intermediates-dir-for,SHARED_LIBRARIES,libRS,,) + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) \ + $(rs_generated_include_dir) \ + $(call include-path-for, corecg graphics) + +LOCAL_CFLAGS += + +LOCAL_LDLIBS := -lpthread + +LOCAL_MODULE:= libRS_jni +LOCAL_PRELINK_MODULE := false + +LOCAL_ADDITIONAL_DEPENDENCIES += $(rs_generated_source) + +include $(BUILD_SHARED_LIBRARY) + diff --git a/libs/rs/jni/RenderScript_jni.cpp b/libs/rs/jni/RenderScript_jni.cpp new file mode 100644 index 0000000..ce62d81 --- /dev/null +++ b/libs/rs/jni/RenderScript_jni.cpp @@ -0,0 +1,1024 @@ +/* + * Copyright (C) 2006 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 <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <math.h> + +#include <utils/misc.h> +#include <utils/Log.h> + +#include <ui/EGLNativeWindowSurface.h> +#include <ui/Surface.h> + +#include <core/SkBitmap.h> + +#include "jni.h" +#include "JNIHelp.h" +#include "android_runtime/AndroidRuntime.h" + +#include "../RenderScript.h" +#include "../RenderScriptEnv.h" + +//#define LOG_API LOGE +#define LOG_API(...) + +using namespace android; + +// --------------------------------------------------------------------------- + +static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) +{ + jclass npeClazz = env->FindClass(exc); + env->ThrowNew(npeClazz, msg); +} + +static jfieldID gContextId = 0; +static jfieldID gNativeBitmapID = 0; + +static void _nInit(JNIEnv *_env, jclass _this) +{ + gContextId = _env->GetFieldID(_this, "mContext", "I"); + + jclass bitmapClass = _env->FindClass("android/graphics/Bitmap"); + gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); +} + + +// --------------------------------------------------------------------------- + +static void +nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAssignName, con(%p), obj(%p)", con, obj); + + jint len = _env->GetArrayLength(str); + jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); + rsAssignName((void *)obj, (const char *)cptr, len); + _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); +} + + +// --------------------------------------------------------------------------- + +static jint +nDeviceCreate(JNIEnv *_env, jobject _this) +{ + LOG_API("nDeviceCreate"); + return (jint)rsDeviceCreate(); +} + +static void +nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev) +{ + LOG_API("nDeviceDestroy"); + return rsDeviceDestroy((RsDevice)dev); +} + +static jint +nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver) +{ + LOG_API("nContextCreate"); + + if (wnd == NULL) { + not_valid_surface: + doThrow(_env, "java/lang/IllegalArgumentException", + "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface"); + return 0; + } + jclass surface_class = _env->FindClass("android/view/Surface"); + jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I"); + Surface * window = (Surface*)_env->GetIntField(wnd, surfaceFieldID); + if (window == NULL) + goto not_valid_surface; + + LOGE("nContextCreate 5"); + return (jint)rsContextCreate((RsDevice)dev, window, ver); +} + +static void +nContextDestroy(JNIEnv *_env, jobject _this, jint con) +{ + LOG_API("nContextDestroy, con(%p)", (RsContext)con); + return rsContextDestroy((RsContext)con); +} + + +static void +nElementBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementBegin, con(%p)", con); + rsElementBegin(); +} + +static void +nElementAddPredefined(JNIEnv *_env, jobject _this, jint predef) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementAddPredefined, con(%p), predef(%i)", con, predef); + rsElementAddPredefined((RsElementPredefined)predef); +} + +static void +nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jint norm, jint bits) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits); + rsElementAdd((RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits); +} + +static jint +nElementCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementCreate, con(%p)", con); + return (jint)rsElementCreate(); +} + +static jint +nElementGetPredefined(JNIEnv *_env, jobject _this, jint predef) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementGetPredefined, con(%p) predef(%i)", con, predef); + return (jint)rsElementGetPredefined((RsElementPredefined)predef); +} + +static void +nElementDestroy(JNIEnv *_env, jobject _this, jint e) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementDestroy, con(%p) e(%p)", con, (RsElement)e); + rsElementDestroy((RsElement)e); +} + +// ----------------------------------- + +static void +nTypeBegin(JNIEnv *_env, jobject _this, jint eID) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID); + rsTypeBegin((RsElement)eID); +} + +static void +nTypeAdd(JNIEnv *_env, jobject _this, jint dim, jint val) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val); + rsTypeAdd((RsDimension)dim, val); +} + +static jint +nTypeCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeCreate, con(%p)", con); + return (jint)rsTypeCreate(); +} + +static void +nTypeDestroy(JNIEnv *_env, jobject _this, jint eID) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeDestroy, con(%p), t(%p)", con, (RsType)eID); + rsTypeDestroy((RsType)eID); +} + +// ----------------------------------- + +static jint +nAllocationCreateTyped(JNIEnv *_env, jobject _this, jint e) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e); + return (jint) rsAllocationCreateTyped((RsElement)e); +} + +static jint +nAllocationCreatePredefSized(JNIEnv *_env, jobject _this, jint predef, jint count) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationCreatePredefSized, con(%p), predef(%i), count(%i)", con, predef, count); + return (jint) rsAllocationCreatePredefSized((RsElementPredefined)predef, count); +} + +static jint +nAllocationCreateSized(JNIEnv *_env, jobject _this, jint e, jint count) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationCreateSized, con(%p), e(%p), count(%i)", con, (RsElement)e, count); + return (jint) rsAllocationCreateSized((RsElement)e, count); +} + +static void +nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationUploadToTexture, con(%p), a(%p), mip(%i)", con, (RsAllocation)a, mip); + rsAllocationUploadToTexture((RsAllocation)a, mip); +} + +static RsElementPredefined SkBitmapToPredefined(SkBitmap::Config cfg) +{ + switch (cfg) { + case SkBitmap::kA8_Config: + return RS_ELEMENT_A_8; + case SkBitmap::kARGB_4444_Config: + return RS_ELEMENT_RGBA_4444; + case SkBitmap::kARGB_8888_Config: + return RS_ELEMENT_RGBA_8888; + case SkBitmap::kRGB_565_Config: + return RS_ELEMENT_RGB_565; + + default: + break; + } + // If we don't have a conversion mark it as a user type. + LOGE("Unsupported bitmap type"); + return RS_ELEMENT_USER_U8; +} + +static int +nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + SkBitmap::Config config = bitmap.getConfig(); + + RsElementPredefined e = SkBitmapToPredefined(config); + + if (e != RS_ELEMENT_USER_U8) { + bitmap.lockPixels(); + const int w = bitmap.width(); + const int h = bitmap.height(); + const void* ptr = bitmap.getPixels(); + jint id = (jint)rsAllocationCreateFromBitmap(w, h, (RsElementPredefined)dstFmt, e, genMips, ptr); + bitmap.unlockPixels(); + return id; + } + return 0; +} + + +static void +nAllocationDestroy(JNIEnv *_env, jobject _this, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationDestroy, con(%p), a(%p)", con, (RsAllocation)a); + rsAllocationDestroy((RsAllocation)a); +} + +static void +nAllocationData_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocationData((RsAllocation)alloc, ptr); + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationData_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocationData((RsAllocation)alloc, ptr); + _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocation1DSubData((RsAllocation)alloc, offset, count, ptr); + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocation1DSubData((RsAllocation)alloc, offset, count, ptr); + _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData2D_i(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocation2DSubData((RsAllocation)alloc, xoff, yoff, w, h, ptr); + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData2D_f(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocation2DSubData((RsAllocation)alloc, xoff, yoff, w, h, ptr); + _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); +} + + + +// ----------------------------------- + +static void +nTriangleMeshDestroy(JNIEnv *_env, jobject _this, jint tm) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshDestroy, con(%p), tm(%p)", con, (RsAllocation)tm); + rsTriangleMeshDestroy((RsTriangleMesh)tm); +} + +static void +nTriangleMeshBegin(JNIEnv *_env, jobject _this, jint v, jint i) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshBegin, con(%p), vertex(%p), index(%p)", con, (RsElement)v, (RsElement)i); + rsTriangleMeshBegin((RsElement)v, (RsElement)i); +} + +static void +nTriangleMeshAddVertex_XY(JNIEnv *_env, jobject _this, jfloat x, jfloat y) +{ + float v[] = {x, y}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XY, con(%p), x(%f), y(%f)", con, x, y); + rsTriangleMeshAddVertex(v); +} + +static void +nTriangleMeshAddVertex_XYZ(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z) +{ + float v[] = {x, y, z}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XYZ, con(%p), x(%f), y(%f), z(%f)", con, x, y, z); + rsTriangleMeshAddVertex(v); +} + +static void +nTriangleMeshAddVertex_XY_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat s, jfloat t) +{ + float v[] = {s, t, x, y}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XY_ST, con(%p), x(%f), y(%f), s(%f), t(%f)", con, x, y, s, t); + rsTriangleMeshAddVertex(v); +} + +static void +nTriangleMeshAddVertex_XYZ_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t) +{ + float v[] = {s, t, x, y, z}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t); + rsTriangleMeshAddVertex(v); +} + +static void +nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddTriangle, con(%p), i1(%i), i2(%i), i3(%i)", con, i1, i2, i3); + rsTriangleMeshAddTriangle(i1, i2, i3); +} + +static jint +nTriangleMeshCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshCreate, con(%p)", con); + return (jint) rsTriangleMeshCreate(); +} + +// ----------------------------------- + +static void +nAdapter1DDestroy(JNIEnv *_env, jobject _this, jint adapter) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DDestroy, con(%p), adapter(%p)", con, (RsAdapter1D)adapter); + rsAdapter1DDestroy((RsAdapter1D)adapter); +} + +static void +nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc); + rsAdapter1DBindAllocation((RsAdapter1D)adapter, (RsAllocation)alloc); +} + +static void +nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value); + rsAdapter1DSetConstraint((RsAdapter1D)adapter, (RsDimension)dim, value); +} + +static void +nAdapter1DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter1DData((RsAdapter1D)adapter, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter1DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter1DSubData((RsAdapter1D)adapter, offset, count, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter1DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter1DData((RsAdapter1D)adapter, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter1DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter1DSubData((RsAdapter1D)adapter, offset, count, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static jint +nAdapter1DCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DCreate, con(%p)", con); + return (jint)rsAdapter1DCreate(); +} + +// ----------------------------------- + +static void +nScriptDestroy(JNIEnv *_env, jobject _this, jint script) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptDestroy, con(%p), script(%p)", con, (RsScript)script); + rsScriptDestroy((RsScript)script); +} + +static void +nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint slot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot); + rsScriptBindAllocation((RsScript)script, (RsAllocation)alloc, slot); +} + +static void +nScriptCBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCBegin, con(%p)", con); + rsScriptCBegin(); +} + +static void +nScriptCSetClearColor(JNIEnv *_env, jobject _this, jfloat r, jfloat g, jfloat b, jfloat a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetClearColor, con(%p), r(%f), g(%f), b(%f), a(%f)", con, r, g, b, a); + rsScriptCSetClearColor(r, g, b, a); +} + +static void +nScriptCSetClearDepth(JNIEnv *_env, jobject _this, jfloat d) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetClearColor, con(%p), depth(%f)", con, d); + rsScriptCSetClearDepth(d); +} + +static void +nScriptCSetClearStencil(JNIEnv *_env, jobject _this, jint stencil) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetClearStencil, con(%p), stencil(%i)", con, stencil); + rsScriptCSetClearStencil(stencil); +} + +static void +nScriptCAddType(JNIEnv *_env, jobject _this, jint type) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCAddType, con(%p), type(%p)", con, (RsType)type); + rsScriptCAddType((RsType)type); +} + +static void +nScriptCSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot); + rsScriptCSetRoot(isRoot); +} + +static void +nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef, + jint offset, jint length) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("!!! nScriptCSetScript, con(%p)", con); + jint _exception = 0; + jint remaining; + jbyte* script_base = 0; + jbyte* script_ptr; + if (!scriptRef) { + _exception = 1; + //_env->ThrowNew(IAEClass, "script == null"); + goto exit; + } + if (offset < 0) { + _exception = 1; + //_env->ThrowNew(IAEClass, "offset < 0"); + goto exit; + } + if (length < 0) { + _exception = 1; + //_env->ThrowNew(IAEClass, "length < 0"); + goto exit; + } + remaining = _env->GetArrayLength(scriptRef) - offset; + if (remaining < length) { + _exception = 1; + //_env->ThrowNew(IAEClass, "length > script.length - offset"); + goto exit; + } + script_base = (jbyte *) + _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0); + script_ptr = script_base + offset; + + rsScriptCSetText((const char *)script_ptr, length); + +exit: + if (script_base) { + _env->ReleasePrimitiveArrayCritical(scriptRef, script_base, + _exception ? JNI_ABORT: 0); + } +} + +static jint +nScriptCCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCCreate, con(%p)", con); + return (jint)rsScriptCCreate(); +} + +// --------------------------------------------------------------------------- + +static void +nProgramFragmentStoreBegin(JNIEnv *_env, jobject _this, jint in, jint out) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); + rsProgramFragmentStoreBegin((RsElement)in, (RsElement)out); +} + +static void +nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func); + rsProgramFragmentStoreDepthFunc((RsDepthFunc)func); +} + +static void +nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable); + rsProgramFragmentStoreDepthMask(enable); +} + +static void +nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a); + rsProgramFragmentStoreColorMask(r, g, b, a); +} + +static void +nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst); + rsProgramFragmentStoreBlendFunc((RsBlendSrcFunc)src, (RsBlendDstFunc)dst); +} + +static void +nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable); + rsProgramFragmentStoreDither(enable); +} + +static jint +nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreCreate, con(%p)", con); + + return (jint)rsProgramFragmentStoreCreate(); +} + +static void +nProgramFragmentStoreDestroy(JNIEnv *_env, jobject _this, jint pgm) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDestroy, con(%p), pgm(%i)", con, pgm); + rsProgramFragmentStoreDestroy((RsProgramFragmentStore)pgm); +} + +// --------------------------------------------------------------------------- + +static void +nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); + rsProgramFragmentBegin((RsElement)in, (RsElement)out); +} + +static void +nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a); + rsProgramFragmentBindTexture((RsProgramFragment)vpf, slot, (RsAllocation)a); +} + +static void +nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a); + rsProgramFragmentBindSampler((RsProgramFragment)vpf, slot, (RsSampler)a); +} + +static void +nProgramFragmentSetType(JNIEnv *_env, jobject _this, jint slot, jint vt) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentSetType, con(%p), slot(%i), vt(%p)", con, slot, (RsType)vt); + rsProgramFragmentSetType(slot, (RsType)vt); +} + +static void +nProgramFragmentSetEnvMode(JNIEnv *_env, jobject _this, jint slot, jint env) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentSetEnvMode, con(%p), slot(%i), vt(%i)", con, slot, env); + rsProgramFragmentSetEnvMode(slot, (RsTexEnvMode)env); +} + +static void +nProgramFragmentSetTexEnable(JNIEnv *_env, jobject _this, jint slot, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentSetTexEnable, con(%p), slot(%i), enable(%i)", con, slot, enable); + rsProgramFragmentSetTexEnable(slot, enable); +} + +static jint +nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentCreate, con(%p)", con); + return (jint)rsProgramFragmentCreate(); +} + +static void +nProgramFragmentDestroy(JNIEnv *_env, jobject _this, jint pgm) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentDestroy, con(%p), pgm(%i)", con, pgm); + rsProgramFragmentDestroy((RsProgramFragment)pgm); +} + +// --------------------------------------------------------------------------- + +static void +nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); + rsProgramVertexBegin((RsElement)in, (RsElement)out); +} + +static void +nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint slot, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a); + rsProgramVertexBindAllocation((RsProgramFragment)vpv, slot, (RsAllocation)a); +} + +static void +nProgramVertexSetType(JNIEnv *_env, jobject _this, jint slot, jint t) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexSetType, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsType)t); + rsProgramVertexSetType(slot, (RsType)t); +} + +static void +nProgramVertexSetCameraMode(JNIEnv *_env, jobject _this, jboolean isOrtho) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexSetCameraMode, con(%p), isOrtho(%i)", con, isOrtho); + rsProgramVertexSetCameraMode(isOrtho); +} + +static void +nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable); + rsProgramVertexSetTextureMatrixEnable(enable); +} + +static void +nProgramVertexSetModelMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexSetModelMatrixEnable, con(%p), enable(%i)", con, enable); + rsProgramVertexSetModelMatrixEnable(enable); +} + +static jint +nProgramVertexCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexCreate, con(%p)", con); + return (jint)rsProgramVertexCreate(); +} + +static void +nProgramVertexDestroy(JNIEnv *_env, jobject _this, jint pgm) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentDestroy, con(%p), pgm(%i)", con, pgm); + rsProgramFragmentDestroy((RsProgramFragment)pgm); +} + + + + +// --------------------------------------------------------------------------- + +static void +nContextBindRootScript(JNIEnv *_env, jobject _this, jint script) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script); + rsContextBindRootScript((RsScript)script); +} + +static void +nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs); + rsContextBindProgramFragmentStore((RsProgramFragmentStore)pfs); +} + +static void +nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf); + rsContextBindProgramFragment((RsProgramFragment)pf); +} + +// --------------------------------------------------------------------------- + +static void +nSamplerDestroy(JNIEnv *_env, jobject _this, jint s) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerDestroy, con(%p), sampler(%p)", con, (RsSampler)s); + rsSamplerDestroy((RsSampler)s); +} + +static void +nSamplerBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerBegin, con(%p)", con); + rsSamplerBegin(); +} + +static void +nSamplerSet(JNIEnv *_env, jobject _this, jint p, jint v) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v); + rsSamplerSet((RsSamplerParam)p, (RsSamplerValue)v); +} + +static jint +nSamplerCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerCreate, con(%p), script(%p)", con, (RsScript)script); + return (jint)rsSamplerCreate(); +} + + +// --------------------------------------------------------------------------- + + +static const char *classPathName = "android/renderscript/RenderScript"; + +static JNINativeMethod methods[] = { +{"_nInit", "()V", (void*)_nInit }, +{"nDeviceCreate", "()I", (void*)nDeviceCreate }, +{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy }, +{"nContextCreate", "(ILandroid/view/Surface;I)I", (void*)nContextCreate }, +{"nContextDestroy", "(I)V", (void*)nContextDestroy }, +{"nAssignName", "(I[B)V", (void*)nAssignName }, + +{"nElementBegin", "()V", (void*)nElementBegin }, +{"nElementAddPredefined", "(I)V", (void*)nElementAddPredefined }, +{"nElementAdd", "(IIII)V", (void*)nElementAdd }, +{"nElementCreate", "()I", (void*)nElementCreate }, +{"nElementGetPredefined", "(I)I", (void*)nElementGetPredefined }, +{"nElementDestroy", "(I)V", (void*)nElementDestroy }, + +{"nTypeBegin", "(I)V", (void*)nTypeBegin }, +{"nTypeAdd", "(II)V", (void*)nTypeAdd }, +{"nTypeCreate", "()I", (void*)nTypeCreate }, +{"nTypeDestroy", "(I)V", (void*)nTypeDestroy }, + +{"nAllocationCreateTyped", "(I)I", (void*)nAllocationCreateTyped }, +{"nAllocationCreatePredefSized", "(II)I", (void*)nAllocationCreatePredefSized }, +{"nAllocationCreateSized", "(II)I", (void*)nAllocationCreateSized }, +{"nAllocationCreateFromBitmap", "(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap }, +{"nAllocationUploadToTexture", "(II)V", (void*)nAllocationUploadToTexture }, +{"nAllocationDestroy", "(I)V", (void*)nAllocationDestroy }, +{"nAllocationData", "(I[I)V", (void*)nAllocationData_i }, +{"nAllocationData", "(I[F)V", (void*)nAllocationData_f }, +{"nAllocationSubData1D", "(III[I)V", (void*)nAllocationSubData1D_i }, +{"nAllocationSubData1D", "(III[F)V", (void*)nAllocationSubData1D_f }, +{"nAllocationSubData2D", "(IIIII[I)V", (void*)nAllocationSubData2D_i }, +{"nAllocationSubData2D", "(IIIII[F)V", (void*)nAllocationSubData2D_f }, + +{"nTriangleMeshDestroy", "(I)V", (void*)nTriangleMeshDestroy }, +{"nTriangleMeshBegin", "(II)V", (void*)nTriangleMeshBegin }, +{"nTriangleMeshAddVertex_XY", "(FF)V", (void*)nTriangleMeshAddVertex_XY }, +{"nTriangleMeshAddVertex_XYZ", "(FFF)V", (void*)nTriangleMeshAddVertex_XYZ }, +{"nTriangleMeshAddVertex_XY_ST", "(FFFF)V", (void*)nTriangleMeshAddVertex_XY_ST }, +{"nTriangleMeshAddVertex_XYZ_ST", "(FFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST }, +{"nTriangleMeshAddTriangle", "(III)V", (void*)nTriangleMeshAddTriangle }, +{"nTriangleMeshCreate", "()I", (void*)nTriangleMeshCreate }, + +{"nAdapter1DDestroy", "(I)V", (void*)nAdapter1DDestroy }, +{"nAdapter1DBindAllocation", "(II)V", (void*)nAdapter1DBindAllocation }, +{"nAdapter1DSetConstraint", "(III)V", (void*)nAdapter1DSetConstraint }, +{"nAdapter1DData", "(I[I)V", (void*)nAdapter1DData_i }, +{"nAdapter1DSubData", "(III[I)V", (void*)nAdapter1DSubData_i }, +{"nAdapter1DData", "(I[F)V", (void*)nAdapter1DData_f }, +{"nAdapter1DSubData", "(III[F)V", (void*)nAdapter1DSubData_f }, +{"nAdapter1DCreate", "()I", (void*)nAdapter1DCreate }, + +{"nScriptDestroy", "(I)V", (void*)nScriptDestroy }, +{"nScriptBindAllocation", "(III)V", (void*)nScriptBindAllocation }, +{"nScriptCBegin", "()V", (void*)nScriptCBegin }, +{"nScriptCSetClearColor", "(FFFF)V", (void*)nScriptCSetClearColor }, +{"nScriptCSetClearDepth", "(F)V", (void*)nScriptCSetClearDepth }, +{"nScriptCSetClearStencil", "(I)V", (void*)nScriptCSetClearStencil }, +{"nScriptCAddType", "(I)V", (void*)nScriptCAddType }, +{"nScriptCSetRoot", "(Z)V", (void*)nScriptCSetRoot }, +{"nScriptCSetScript", "([BII)V", (void*)nScriptCSetScript }, +{"nScriptCCreate", "()I", (void*)nScriptCCreate }, + +{"nProgramFragmentStoreBegin", "(II)V", (void*)nProgramFragmentStoreBegin }, +{"nProgramFragmentStoreDepthFunc", "(I)V", (void*)nProgramFragmentStoreDepthFunc }, +{"nProgramFragmentStoreDepthMask", "(Z)V", (void*)nProgramFragmentStoreDepthMask }, +{"nProgramFragmentStoreColorMask", "(ZZZZ)V", (void*)nProgramFragmentStoreColorMask }, +{"nProgramFragmentStoreBlendFunc", "(II)V", (void*)nProgramFragmentStoreBlendFunc }, +{"nProgramFragmentStoreDither", "(Z)V", (void*)nProgramFragmentStoreDither }, +{"nProgramFragmentStoreCreate", "()I", (void*)nProgramFragmentStoreCreate }, +{"nProgramFragmentStoreDestroy", "(I)V", (void*)nProgramFragmentStoreDestroy }, + +{"nProgramFragmentBegin", "(II)V", (void*)nProgramFragmentBegin }, +{"nProgramFragmentBindTexture", "(III)V", (void*)nProgramFragmentBindTexture }, +{"nProgramFragmentBindSampler", "(III)V", (void*)nProgramFragmentBindSampler }, +{"nProgramFragmentSetType", "(II)V", (void*)nProgramFragmentSetType }, +{"nProgramFragmentSetEnvMode", "(II)V", (void*)nProgramFragmentSetEnvMode }, +{"nProgramFragmentSetTexEnable", "(IZ)V", (void*)nProgramFragmentSetTexEnable }, +{"nProgramFragmentCreate", "()I", (void*)nProgramFragmentCreate }, +{"nProgramFragmentDestroy", "(I)V", (void*)nProgramFragmentDestroy }, + +{"nProgramVertexDestroy", "(I)V", (void*)nProgramVertexDestroy }, +{"nProgramVertexBindAllocation", "(III)V", (void*)nProgramVertexBindAllocation }, +{"nProgramVertexBegin", "(II)V", (void*)nProgramVertexBegin }, +{"nProgramVertexSetType", "(II)V", (void*)nProgramVertexSetType }, +{"nProgramVertexSetCameraMode", "(Z)V", (void*)nProgramVertexSetCameraMode }, +{"nProgramVertexSetTextureMatrixEnable", "(Z)V", (void*)nProgramVertexSetTextureMatrixEnable }, +{"nProgramVertexSetModelMatrixEnable", "(Z)V", (void*)nProgramVertexSetModelMatrixEnable }, +{"nProgramVertexCreate", "()I", (void*)nProgramVertexCreate }, + +{"nContextBindRootScript", "(I)V", (void*)nContextBindRootScript }, +{"nContextBindProgramFragmentStore","(I)V", (void*)nContextBindProgramFragmentStore }, +{"nContextBindProgramFragment", "(I)V", (void*)nContextBindProgramFragment }, + +{"nSamplerDestroy", "(I)V", (void*)nSamplerDestroy }, +{"nSamplerBegin", "()V", (void*)nSamplerBegin }, +{"nSamplerSet", "(II)V", (void*)nSamplerSet }, +{"nSamplerCreate", "()I", (void*)nSamplerCreate }, + +}; + +static int registerFuncs(JNIEnv *_env) +{ + return android::AndroidRuntime::registerNativeMethods( + _env, classPathName, methods, NELEM(methods)); +} + +// --------------------------------------------------------------------------- + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + JNIEnv* env = NULL; + jint result = -1; + + LOGE("****************************************************\n"); + + if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + LOGE("ERROR: GetEnv failed\n"); + goto bail; + } + assert(env != NULL); + + if (registerFuncs(env) < 0) { + LOGE("ERROR: MediaPlayer native registration failed\n"); + goto bail; + } + + /* success -- return valid version number */ + result = JNI_VERSION_1_4; + +bail: + return result; +} diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec new file mode 100644 index 0000000..74445d3 --- /dev/null +++ b/libs/rs/rs.spec @@ -0,0 +1,417 @@ + + +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 + } + +ScriptCSetOrtho { + param bool isOrtho + } + +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 + } + +ProgramVertexSetCameraMode { + param bool ortho + } + +ProgramVertexSetTextureMatrixEnable { + param bool enable + } + +ProgramVertexSetModelMatrixEnable { + param bool enable + } + 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..3a01a75 --- /dev/null +++ b/libs/rs/rsAllocation.cpp @@ -0,0 +1,478 @@ +/* + * 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; + +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() +{ + LOGE("Allocation %p destryed", this); +} + +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()); + + //LOGE("uploadToTexture %i, lod %i", mTextureID, lodOffset); + + 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()); + + //LOGE("uploadToTexture %i, lod %i", mTextureID, lodOffset); + + 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); + 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..205e575 --- /dev/null +++ b/libs/rs/rsComponent.h @@ -0,0 +1,75 @@ +/* + * 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 <stdint.h> +#include <sys/types.h> +#include <stdlib.h> + +#include "RenderScript.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..266c455 --- /dev/null +++ b/libs/rs/rsContext.cpp @@ -0,0 +1,355 @@ +/* + * 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" + +using namespace android; +using namespace android::renderscript; + +Context * Context::gCon = NULL; + +void Context::initEGL() +{ + mNumConfigs = -1; + + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 6, + EGL_BLUE_SIZE, 5, + 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, + new EGLNativeWindowSurface(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); + + if(mRootScript->mEnviroment.mIsOrtho) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, mWidth, mHeight, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + } else { + float aspectH = ((float)mWidth) / mHeight; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-1, 1, -aspectH, aspectH, 1, 100); + glRotatef(-90, 0,0,1); + glTranslatef(0, 0, -3); + glMatrixMode(GL_MODELVIEW); + } + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + 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->mServerCommands.init(128); + rsc->mServerReturns.init(128); + + rsc->initEGL(); + rsc->mRunning = true; + bool mDraw = true; + while (!rsc->mExit) { + mDraw |= gIO->playCoreCommands(rsc); + + if (!mDraw || !rsc->mRootScript.get()) { + usleep(10000); + continue; + } + + if (rsc->mRootScript.get()) { + 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; + + mServerCommands.init(256); + mServerReturns.init(256); + + // see comment in header + gCon = this; + + int status; + pthread_attr_t threadAttr; + + 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); + + LOGE("RS Launching thread"); + status = pthread_create(&mThreadId, &threadAttr, threadProc, this); + if (status) { + LOGE("Failed to start rs context thread."); + } + + mWndSurface = sur; + 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); + } +} + +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) +{ + mFragmentStore.set(pfs); + pfs->setupGL(); +} + +void Context::setFragment(ProgramFragment *pf) +{ + mFragment.set(pf); + pf->setupGL(); +} + +void Context::setVertex(ProgramVertex *pv) +{ + mVertex.set(pv); + pv->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..21ae8c5 --- /dev/null +++ b/libs/rs/rsContext.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_RS_CONTEXT_H +#define ANDROID_RS_CONTEXT_H + +#include <utils/Vector.h> +#include <ui/EGLNativeWindowSurface.h> +#include <ui/Surface.h> + +#include "rsType.h" +#include "rsMatrix.h" +#include "rsAllocation.h" +#include "rsTriangleMesh.h" +#include "rsDevice.h" +#include "rsScriptC.h" +#include "rsAllocation.h" +#include "rsAdapter.h" +#include "rsSampler.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(); + + + //StructuredAllocationContext mStateAllocation; + ElementState mStateElement; + TypeState mStateType; + SamplerState mStateSampler; + ProgramFragmentState mStateFragment; + ProgramFragmentStoreState mStateFragmentStore; + ProgramVertexState mStateVertex; + + 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; + +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; + + LocklessCommandFifo mServerCommands; + LocklessCommandFifo mServerReturns; + + pthread_t mThreadId; + + ObjectBaseRef<Script> mRootScript; + ObjectBaseRef<ProgramFragment> mFragment; + ObjectBaseRef<ProgramVertex> mVertex; + ObjectBaseRef<ProgramFragmentStore> mFragmentStore; + + ProgramFragment * mDefaultFragment; + ProgramVertex * mDefaultVertex; + ProgramFragmentStore * mDefaultFragmentStore; + +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..3de3ffa --- /dev/null +++ b/libs/rs/rsDevice.h @@ -0,0 +1,50 @@ +/* + * 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 <utils/Vector.h> + +//#include "StructuredComponent.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..5a44f47 --- /dev/null +++ b/libs/rs/rsElement.cpp @@ -0,0 +1,434 @@ +/* + * 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(); + + LOGE("Create %p", se); + 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..2434977 --- /dev/null +++ b/libs/rs/rsElement.h @@ -0,0 +1,98 @@ +/* + * 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 <utils/Vector.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/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp new file mode 100644 index 0000000..67ab434 --- /dev/null +++ b/libs/rs/rsLocklessFifo.cpp @@ -0,0 +1,182 @@ +/* + * 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; + +#include <utils/Log.h> + +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; + } + + int status = pthread_mutex_init(&mMutex, NULL); + if (status) { + LOGE("LocklessFifo mutex init failure"); + free(mBuffer); + return false; + } + status = pthread_cond_init(&mCondition, NULL); + if (status) { + LOGE("LocklessFifo condition init failure"); + pthread_mutex_destroy(&mMutex); + 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; + } + + //LOGE("free %i", freeSpace); + 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) +{ + //LOGE("commit cmd %i size %i", command, 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"); + +} + +void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) +{ + commit(command, sizeInBytes); + flush(); +} + +void LocklessCommandFifo::flush() +{ + //dumpState("flush 1"); + while(mPut != mGet) { + usleep(1); + } + //dumpState("flush 2"); +} + +const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) +{ + while(1) { + while(isEmpty()) { + usleep(10); + } + //dumpState("get 3"); + + *command = reinterpret_cast<const uint16_t *>(mGet)[0]; + *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1]; + //LOGE("Got %i, %i", *command, *bytesData); + + 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; + //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 +{ + LOGE("%s put %p, get %p, buf %p, end %p", s, mPut, mGet, mBuffer, mEnd); +} + + diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h new file mode 100644 index 0000000..ddef382 --- /dev/null +++ b/libs/rs/rsLocklessFifo.h @@ -0,0 +1,74 @@ +/* + * 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 <stdint.h> +#include <sys/types.h> +#include <stdlib.h> +#include <pthread.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: + uint8_t * volatile mPut; + uint8_t * volatile mGet; + uint8_t * mBuffer; + uint8_t * mEnd; + uint8_t mSize; + + pthread_mutex_t mMutex; + pthread_cond_t mCondition; + +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..e68d5ac --- /dev/null +++ b/libs/rs/rsMatrix.cpp @@ -0,0 +1,139 @@ +/* + * 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" + +#include <utils/Log.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); + } +} + + diff --git a/libs/rs/rsMatrix.h b/libs/rs/rsMatrix.h new file mode 100644 index 0000000..619b494 --- /dev/null +++ b/libs/rs/rsMatrix.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_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 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/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp new file mode 100644 index 0000000..8f5232a --- /dev/null +++ b/libs/rs/rsObjectBase.cpp @@ -0,0 +1,70 @@ +/* + * 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" +#include <utils/Log.h> + +using namespace android; +using namespace android::renderscript; + +ObjectBase::ObjectBase() +{ + mRefCount = 0; + mName = NULL; +} + +ObjectBase::~ObjectBase() +{ + rsAssert(!mRefCount); +} + +void ObjectBase::incRef() const +{ + mRefCount ++; + //LOGE("ObjectBase %p inc ref %i", this, mRefCount); +} + +void ObjectBase::decRef() const +{ + rsAssert(mRefCount > 0); + mRefCount --; + //LOGE("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..316e791 --- /dev/null +++ b/libs/rs/rsProgramFragment.cpp @@ -0,0 +1,227 @@ +/* + * 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" + +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; +} + +ProgramFragment::~ProgramFragment() +{ +} + +void ProgramFragment::setupGL() +{ + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + glActiveTexture(GL_TEXTURE0 + ct); + if (!(mTextureEnableMask & (1 << ct)) || + //!mSamplers[ct].get() || + !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_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + case RS_TEX_ENV_MODE_MODULATE: + glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case RS_TEX_ENV_MODE_DECAL: + glTexEnvf(GL_TEXTURE_2D, 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_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + } + 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; + } + + 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; + +} + + + +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)); + + //LOGE("%p %p", pf, rsc->getFragment()); + 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..ed9c49b --- /dev/null +++ b/libs/rs/rsProgramFragment.h @@ -0,0 +1,98 @@ +/* + * 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; + + ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE]; + + Vector<ProgramFragment *> mPrograms; +}; + + +} +} +#endif + + + + diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp new file mode 100644 index 0000000..a1855a6 --- /dev/null +++ b/libs/rs/rsProgramFragmentStore.cpp @@ -0,0 +1,261 @@ +/* + * 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" + +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); + } + + glDepthMask(mDepthWriteEnable); + if(mDepthTestEnable) { + 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; + +} + + +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..d862775 --- /dev/null +++ b/libs/rs/rsProgramFragmentStore.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_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(); + + ProgramFragmentStore *mPFS; +}; + + +} +} +#endif + + + diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp new file mode 100644 index 0000000..a80e2f7 --- /dev/null +++ b/libs/rs/rsProgramVertex.cpp @@ -0,0 +1,132 @@ +/* + * 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" + +using namespace android; +using namespace android::renderscript; + + +ProgramVertex::ProgramVertex(Element *in, Element *out) : + Program(in, out) +{ + mTextureMatrixEnable = false; + mProjectionEnable = false; + mTransformEnable = false; +} + +ProgramVertex::~ProgramVertex() +{ +} + +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(); + } + + + glMatrixMode(GL_PROJECTION); + if (mProjectionEnable) { + //glLoadMatrixf(&f[OFFSET_PROJECTION]); + } else { + } + + glMatrixMode(GL_MODELVIEW); + if (mTransformEnable) { + glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); + } else { + glLoadIdentity(); + } + +} + +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); +} + + +ProgramVertexState::ProgramVertexState() +{ + mPV = NULL; +} + +ProgramVertexState::~ProgramVertexState() +{ + delete mPV; +} + + + +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_ProgramVertexSetCameraMode(Context *rsc, bool ortho) +{ + rsc->mStateVertex.mPV->setProjectionEnabled(!ortho); +} + +void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable) +{ + rsc->mStateVertex.mPV->setTextureMatrixEnable(enable); +} + +void rsi_ProgramVertexSetModelMatrixEnable(Context *rsc, bool enable) +{ + rsc->mStateVertex.mPV->setTransformEnable(enable); +} + + + +} +} diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h new file mode 100644 index 0000000..cd46900 --- /dev/null +++ b/libs/rs/rsProgramVertex.h @@ -0,0 +1,76 @@ +/* + * 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; + + 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 setProjectionEnabled(bool e) {mProjectionEnable = e;} + void setTransformEnable(bool e) {mTransformEnable = e;} + +protected: + bool mDirty; + + ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS]; + ObjectBaseRef<const Type> mConstantTypes[MAX_CONSTANTS]; + + // Hacks to create a program for now + bool mTextureMatrixEnable; + bool mProjectionEnable; + bool mTransformEnable; + +}; + + +class ProgramVertexState +{ +public: + ProgramVertexState(); + ~ProgramVertexState(); + + 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..d89346e --- /dev/null +++ b/libs/rs/rsSampler.cpp @@ -0,0 +1,160 @@ +/* + * 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> +#include <utils/Log.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..45d8c61 --- /dev/null +++ b/libs/rs/rsSampler.h @@ -0,0 +1,92 @@ +/* + * 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 <math.h> +#include <EGL/egl.h> +#include <GLES/gl.h> +#include <GLES/glext.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..d32f116 --- /dev/null +++ b/libs/rs/rsScript.h @@ -0,0 +1,68 @@ +/* + * 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; + bool mIsOrtho; + 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..d29eb9f --- /dev/null +++ b/libs/rs/rsScriptC.cpp @@ -0,0 +1,593 @@ +/* + * 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" + +using namespace android; +using namespace android::renderscript; + + +ScriptC::ScriptC() +{ + mAccScript = NULL; + memset(&mProgram, 0, sizeof(mProgram)); +} + +ScriptC::~ScriptC() +{ + if (mAccScript) { + accDeleteScript(mAccScript); + } +} + +extern "C" void matrixLoadIdentity(void *con, rsc_Matrix *mat) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadIdentity(); +} + +extern "C" void matrixLoadFloat(void *con, rsc_Matrix *mat, const float *f) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->load(f); +} + +extern "C" void matrixLoadMat(void *con, rsc_Matrix *mat, const rsc_Matrix *newmat) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->load(reinterpret_cast<const Matrix *>(newmat)); +} + +extern "C" void matrixLoadRotate(void *con, rsc_Matrix *mat, float rot, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadRotate(rot, x, y, z); +} + +extern "C" void matrixLoadScale(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadScale(x, y, z); +} + +extern "C" void matrixLoadTranslate(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadTranslate(x, y, z); +} + +extern "C" void matrixLoadMultiply(void *con, 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)); +} + +extern "C" void matrixMultiply(void *con, rsc_Matrix *mat, const rsc_Matrix *rhs) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->multiply(reinterpret_cast<const Matrix *>(rhs)); +} + +extern "C" void matrixRotate(void *con, rsc_Matrix *mat, float rot, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->rotate(rot, x, y, z); +} + +extern "C" void matrixScale(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->scale(x, y, z); +} + +extern "C" void matrixTranslate(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->translate(x, y, z); +} + + +extern "C" const void * loadVp(void *vp, uint32_t bank, uint32_t offset) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + return &static_cast<const uint8_t *>(env->mScript->mSlots[bank]->getPtr())[offset]; +} + +extern "C" float loadF(void *vp, uint32_t bank, uint32_t offset) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + //LOGE("bank %i, offset %i", bank, offset); + //LOGE("%p", env->mScript->mSlots[bank]->getPtr()); + return static_cast<const float *>(env->mScript->mSlots[bank]->getPtr())[offset]; +} + +extern "C" int32_t loadI32(void *vp, uint32_t bank, uint32_t offset) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + return static_cast<const int32_t *>(env->mScript->mSlots[bank]->getPtr())[offset]; +} + +extern "C" uint32_t loadU32(void *vp, uint32_t bank, uint32_t offset) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + return static_cast<const uint32_t *>(env->mScript->mSlots[bank]->getPtr())[offset]; +} + +extern "C" void loadEnvVec4(void *vp, uint32_t bank, uint32_t offset, rsc_Vector4 *v) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + memcpy(v, &static_cast<const float *>(env->mScript->mSlots[bank]->getPtr())[offset], sizeof(rsc_Vector4)); +} + +extern "C" void loadEnvMatrix(void *vp, uint32_t bank, uint32_t offset, rsc_Matrix *m) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + memcpy(m, &static_cast<const float *>(env->mScript->mSlots[bank]->getPtr())[offset], sizeof(rsc_Matrix)); +} + + +extern "C" void storeF(void *vp, uint32_t bank, uint32_t offset, float v) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + static_cast<float *>(env->mScript->mSlots[bank]->getPtr())[offset] = v; +} + +extern "C" void storeI32(void *vp, uint32_t bank, uint32_t offset, int32_t v) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + static_cast<int32_t *>(env->mScript->mSlots[bank]->getPtr())[offset] = v; +} + +extern "C" void storeU32(void *vp, uint32_t bank, uint32_t offset, uint32_t v) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + static_cast<uint32_t *>(env->mScript->mSlots[bank]->getPtr())[offset] = v; +} + +extern "C" void storeEnvVec4(void *vp, uint32_t bank, uint32_t offset, const rsc_Vector4 *v) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + memcpy(&static_cast<float *>(env->mScript->mSlots[bank]->getPtr())[offset], v, sizeof(rsc_Vector4)); +} + +extern "C" void storeEnvMatrix(void *vp, uint32_t bank, uint32_t offset, const rsc_Matrix *m) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + memcpy(&static_cast<float *>(env->mScript->mSlots[bank]->getPtr())[offset], m, sizeof(rsc_Matrix)); +} + + +extern "C" void color(void *vp, float r, float g, float b, float a) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glColor4f(r, g, b, a); +} + +extern "C" void renderTriangleMesh(void *vp, RsTriangleMesh mesh) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_TriangleMeshRender(env->mContext, mesh); +} + +extern "C" void renderTriangleMeshRange(void *vp, RsTriangleMesh mesh, uint32_t start, uint32_t count) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_TriangleMeshRenderRange(env->mContext, mesh, start, count); +} + +extern "C" void materialDiffuse(void *vp, float r, float g, float b, float a) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + float v[] = {r, g, b, a}; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v); +} + +extern "C" void materialSpecular(void *vp, float r, float g, float b, float a) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + float v[] = {r, g, b, a}; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v); +} + +extern "C" void lightPosition(void *vp, float x, float y, float z, float w) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + float v[] = {x, y, z, w}; + glLightfv(GL_LIGHT0, GL_POSITION, v); +} + +extern "C" void materialShininess(void *vp, float s) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s); +} + +extern "C" void uploadToTexture(void *vp, RsAllocation va, uint32_t baseMipLevel) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_AllocationUploadToTexture(env->mContext, va, baseMipLevel); +} + +extern "C" void enable(void *vp, uint32_t p) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glEnable(p); +} + +extern "C" void disable(void *vp, uint32_t p) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glDisable(p); +} + +extern "C" uint32_t scriptRand(void *vp, uint32_t max) +{ + return (uint32_t)(((float)rand()) * max / RAND_MAX); +} + +// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a +extern "C" void drawTriangleArray(void *vp, RsAllocation alloc, uint32_t count) +{ + const Allocation *a = (const Allocation *)alloc; + const uint32_t *ptr = (const uint32_t *)a->getPtr(); + + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + env->mContext->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); +} + +extern "C" void drawRect(void *vp, int32_t x1, int32_t x2, int32_t y1, int32_t y2) +{ + x1 = (x1 << 16); + x2 = (x2 << 16); + y1 = (y1 << 16); + y2 = (y2 << 16); + + int32_t vtx[] = {x1,y1, x1,y2, x2,y1, x2,y2}; + static const int32_t tex[] = {0,0, 0,0x10000, 0x10000,0, 0x10000,0x10000}; + + + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + env->mContext->setupCheck(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glVertexPointer(2, GL_FIXED, 8, vtx); + glTexCoordPointer(2, GL_FIXED, 8, tex); + //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + +extern "C" void pfBindTexture(void *vp, RsProgramFragment vpf, uint32_t slot, RsAllocation va) +{ + //LOGE("pfBindTexture %p", vpf); + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_ProgramFragmentBindTexture(env->mContext, + static_cast<ProgramFragment *>(vpf), + slot, + static_cast<Allocation *>(va)); + +} + +extern "C" void pfBindSampler(void *vp, RsProgramFragment vpf, uint32_t slot, RsSampler vs) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_ProgramFragmentBindSampler(env->mContext, + static_cast<ProgramFragment *>(vpf), + slot, + static_cast<Sampler *>(vs)); + +} + +extern "C" void contextBindProgramFragmentStore(void *vp, RsProgramFragmentStore pfs) +{ + //LOGE("contextBindProgramFragmentStore %p", pfs); + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_ContextBindProgramFragmentStore(env->mContext, pfs); + +} + +extern "C" void contextBindProgramFragment(void *vp, RsProgramFragment pf) +{ + //LOGE("contextBindProgramFragment %p", pf); + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_ContextBindProgramFragment(env->mContext, pf); + +} + + +static rsc_FunctionTable scriptCPtrTable = { + loadVp, + loadF, + loadI32, + loadU32, + loadEnvVec4, + loadEnvMatrix, + + storeF, + storeI32, + storeU32, + storeEnvVec4, + storeEnvMatrix, + + matrixLoadIdentity, + matrixLoadFloat, + matrixLoadMat, + matrixLoadRotate, + matrixLoadScale, + matrixLoadTranslate, + matrixLoadMultiply, + matrixMultiply, + matrixRotate, + matrixScale, + matrixTranslate, + + color, + + pfBindTexture, + pfBindSampler, + + materialDiffuse, + materialSpecular, + lightPosition, + materialShininess, + uploadToTexture, + enable, + disable, + + scriptRand, + contextBindProgramFragment, + contextBindProgramFragmentStore, + + + renderTriangleMesh, + renderTriangleMeshRange, + + drawTriangleArray, + drawRect + +}; + + +bool ScriptC::run(Context *rsc, uint32_t launchID) +{ + Env e = {rsc, this}; + + if (mEnviroment.mFragmentStore.get()) { + rsc->setFragmentStore(mEnviroment.mFragmentStore.get()); + } + if (mEnviroment.mFragment.get()) { + rsc->setFragment(mEnviroment.mFragment.get()); + } + + return mProgram.mScript(&e, &scriptCPtrTable, launchID) != 0; +} + +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; + mEnviroment.mIsOrtho = true; + + mAccScript = NULL; + +} + + +void ScriptCState::runCompiler(Context *rsc) +{ + mAccScript = accCreateScript(); + String8 tmp; + + rsc->appendNameDefines(&tmp); + + const char* scriptSource[] = {tmp.string(), mProgram.mScriptText}; + int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ; + accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); + accCompileScript(mAccScript); + accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript); + rsAssert(mProgram.mScript); + + + 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) { + LOGE("pragma %i %s %s", ct, str[ct], str[ct+1]); + + if (!strcmp(str[ct], "version")) { + continue; + + } + + + if (!strcmp(str[ct], "stateVertex")) { + 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")) { + 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")) { + ProgramFragmentStore * pfs = + (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); + if (pfs != NULL) { + mEnviroment.mFragmentStore.set(pfs); + continue; + } + + if (!strcmp(str[ct+1], "parent")) { + //mEnviroment.mStateFragmentStore = + //Script::Enviroment_t::FRAGMENT_STORE_PARENT; + 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<rsc_RunScript>(vp); +} + +void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mEnviroment.mIsRoot = isRoot; +} + +void rsi_ScriptCSetOrtho(Context * rsc, bool isOrtho) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mEnviroment.mIsOrtho = isOrtho; +} + +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..55a2cc6 --- /dev/null +++ b/libs/rs/rsScriptC.h @@ -0,0 +1,86 @@ +/* + * 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: + + ScriptC(); + virtual ~ScriptC(); + + struct Program_t { + const char * mScriptText; + uint32_t mScriptTextLength; + + + int mVersionMajor; + int mVersionMinor; + + rsc_RunScript mScript; + }; + + Program_t mProgram; + + ACCscript* mAccScript; + + virtual bool run(Context *, uint32_t launchID); + + struct Env { + Context *mContext; + ScriptC *mScript; + }; + +}; + +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); +}; + + +} +} +#endif + + + diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp new file mode 100644 index 0000000..23c808a --- /dev/null +++ b/libs/rs/rsThreadIO.cpp @@ -0,0 +1,58 @@ +/* + * 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/Log.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) +{ + //LOGE("playCoreCommands 1"); + uint32_t cmdID = 0; + uint32_t cmdSize = 0; + bool ret = false; + while(!mToCore.isEmpty()) { + ret = true; + //LOGE("playCoreCommands 2"); + const void * data = mToCore.get(&cmdID, &cmdSize); + //LOGE("playCoreCommands 3 %i %i", cmdID, cmdSize); + + gPlaybackFuncs[cmdID](con, data); + //LOGE("playCoreCommands 4"); + + mToCore.next(); + //LOGE("playCoreCommands 5"); + } + return ret; +} + + diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h new file mode 100644 index 0000000..ae2ffc0 --- /dev/null +++ b/libs/rs/rsThreadIO.h @@ -0,0 +1,57 @@ +/* + * 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 <stdlib.h> +#include <stdio.h> + +#include "RenderScript.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); + + + 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..6595ebc --- /dev/null +++ b/libs/rs/rsTriangleMesh.cpp @@ -0,0 +1,299 @@ +/* + * 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> + +#include <utils/Log.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; + } + } + LOGE("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) +{ + //LOGE("tmb %p %p", vertex, 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(); + + //LOGE("Element sizes %i %i", tmc->mVertexSizeBits, tmc->mIndexSizeBits); + + 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; + } + + LOGE("Create mesh, triangleCount %i", tm->mTriangleCount); + + 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(); + + //LOGE("1 %p ", vtm); + //LOGE("1.1 %p %p", tm->mVertexData, tm->mIndexData); + 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); + } + + //LOGE("1.2"); + if (first >= tm->mTriangleCount) { + return; + } + if (count >= (tm->mTriangleCount - first)) { + count = tm->mTriangleCount - first; + } + if (!count) { + return; + } + + const float *f = (const float *)tm->mVertexData; + + //LOGE("2"); + 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)); + + //LOGE("4"); + + 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..67f964f --- /dev/null +++ b/libs/rs/rsTriangleMesh.h @@ -0,0 +1,92 @@ +/* + * 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 <stdlib.h> +#include <stdio.h> + +#include <math.h> +#include <EGL/egl.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <utils/Vector.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: + 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 + GLuint 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..6b99820 --- /dev/null +++ b/libs/rs/rsType.cpp @@ -0,0 +1,229 @@ +/* + * 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() +{ + //LOGE("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]; + } + + //LOGE("xyz %i %i %i", mDimX, mDimY, mDimZ); + //LOGE("mips %i", mLODCount); + //LOGE("e size %i", mElement->getSizeBytes()); + 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; + //LOGE("txyz %i %i %i", tx, ty, tz); + offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes(); + tx >>= 1; + ty >>= 1; + tz >>= 1; + } + + //LOGE("size %i", offset); + + // 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..5a43fb3 --- /dev/null +++ b/libs/rs/rsUtils.h @@ -0,0 +1,120 @@ +/* + * 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 + +#include <stdint.h> +#include <sys/types.h> +#include <stdlib.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; +} + |