diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-22 17:13:58 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-22 17:13:58 -0700 |
commit | aaafa4fb1cda4dd4e1a261a1c196865ac0a14105 (patch) | |
tree | 3f9516a11fccda38aa4cbe21248429ec2d5daf18 /libs | |
parent | 22075a3b7430958ea81cb75eb305ccd254c0e38f (diff) | |
parent | d19f10d43aa400e1183aa21a97099d02074131a2 (diff) | |
download | frameworks_base-aaafa4fb1cda4dd4e1a261a1c196865ac0a14105.zip frameworks_base-aaafa4fb1cda4dd4e1a261a1c196865ac0a14105.tar.gz frameworks_base-aaafa4fb1cda4dd4e1a261a1c196865ac0a14105.tar.bz2 |
Merge change 2362
* changes:
Add the Renderscript library. (Not in the build by default yet.)
Diffstat (limited to 'libs')
50 files changed, 7445 insertions, 0 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk new file mode 100644 index 0000000..73c1eea --- /dev/null +++ b/libs/rs/Android.mk @@ -0,0 +1,132 @@ +# Only build if BUILD_RENDERSCRIPT is defined to true in the environment. +ifeq ($(BUILD_RENDERSCRIPT),true) + +TOP_LOCAL_PATH:=$(call my-dir) +LOCAL_PATH:= $(TOP_LOCAL_PATH) + + +# Build rsg-generator + +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) + +RSG_GENERATOR:=$(LOCAL_BUILT_MODULE) + +# Build render script lib + +include $(CLEAR_VARS) +LOCAL_MODULE := libRS + +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +intermediates:= $(local-intermediates-dir) + +RS_GENERATED_INCLUDE_DIR:=$(intermediates) + +# Generate custom headers + +GEN := $(addprefix $(intermediates)/, \ + rsgApiStructs.h \ + rsgApiFuncDecl.h \ + ) + +$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(LOCAL_PATH)/rs.spec +$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec +$(GEN): $(intermediates)/%.h : $(LOCAL_PATH)/%.h.rsg + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + +# Generate custom source files + +GEN := $(addprefix $(intermediates)/, \ + rsgApi.cpp \ + rsgApiReplay.cpp \ + ) + +$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(LOCAL_PATH)/rs.spec +$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec +$(GEN): $(intermediates)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg + $(transform-generated-source) +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 +LOCAL_LDLIBS := -lpthread -ldl +LOCAL_MODULE:= libRS + +#LOCAL_MODULE_TAGS := tests + +include $(BUILD_SHARED_LIBRARY) + +# Build JNI library + +LOCAL_PATH:= $(TOP_LOCAL_PATH)/jni +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + RenderScript_jni.cpp + +LOCAL_SHARED_LIBRARIES := \ + libandroid_runtime \ + libnativehelper \ + libRS \ + libcutils \ + libutils \ + libui + +LOCAL_STATIC_LIBRARIES := + +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 + +include $(BUILD_SHARED_LIBRARY) + +endif # BUILD_RENDERSCRIPT
\ No newline at end of file diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h new file mode 100644 index 0000000..e1a4b6d --- /dev/null +++ b/libs/rs/RenderScript.h @@ -0,0 +1,185 @@ +/* + * 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_RGB_565, + RS_ELEMENT_RGBA_5551, + RS_ELEMENT_RGBA_4444, + RS_ELEMENT_RGB_888, + RS_ELEMENT_RGBA_8888, + + RS_ELEMENT_INDEX_16, + 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..9ba1a00 --- /dev/null +++ b/libs/rs/RenderScriptEnv.h @@ -0,0 +1,93 @@ +#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 (*renderTriangleMesh)(void *con, RsTriangleMesh); + void (*renderTriangleMeshRange)(void *con, RsTriangleMesh, uint32_t start, uint32_t count); + + 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); + + // Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a + void (*drawTriangleArray)(void *con, RsAllocation alloc, uint32_t count); + + void (*contextBindProgramFragment)(void *con, RsProgramFragment pf); + void (*contextBindProgramFragmentStore)(void *con, RsProgramFragmentStore pfs); +} rsc_FunctionTable; + +typedef void (*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/jni/RenderScript_jni.cpp b/libs/rs/jni/RenderScript_jni.cpp new file mode 100644 index 0000000..5b226a5 --- /dev/null +++ b/libs/rs/jni/RenderScript_jni.cpp @@ -0,0 +1,897 @@ +/* + * 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 "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; + +extern "C" void test_script(void *con, const rsc_FunctionTable *ft, uint32_t launchID); + +void test_script(void *con, const rsc_FunctionTable *ft, uint32_t launchID) +{ + int count = ft->loadEnvI32(con, 0, 1); + int touch = ft->loadEnvI32(con, 0, 2); + int x = ft->loadEnvI32(con, 0, 3); + int y = 480 - ft->loadEnvI32(con, 0, 4); + + int rate = 4; + int maxLife = (count / rate) - 1; + int lifeShift = 0; + { + int life = maxLife; + while (life > 255) { + life >>= 1; + lifeShift ++; + } + } + + if (touch) { + int newPart = ft->loadEnvI32(con, 2, 0); + for (int ct2=0; ct2<rate; ct2++) { + int dx = ft->rand(con, 0x10000) - 0x8000; + int dy = ft->rand(con, 0x10000) - 0x8000; + + int idx = newPart * 5 + 1; + ft->storeEnvI32(con, 2, idx, dx); + ft->storeEnvI32(con, 2, idx + 1, dy); + ft->storeEnvI32(con, 2, idx + 2, maxLife); + ft->storeEnvI32(con, 2, idx + 3, x << 16); + ft->storeEnvI32(con, 2, idx + 4, y << 16); + + newPart++; + if (newPart >= count) { + newPart = 0; + } + } + ft->storeEnvI32(con, 2, 0, newPart); + } + + // Emulate intrinsic perf... + int32_t * partPtr = (int32_t *)ft->loadEnvVp(con, 2, 4); + int32_t * vertPtr = (int32_t *)ft->loadEnvVp(con, 1, 0); + + int drawCount = 0; + for (int ct=0; ct < count; ct++) { + //int srcIdx = ct * 5 + 1; + //int dstIdx = ct * 3 * 3; + + int dx = partPtr[0]; //ft->loadEnvI32(con, 2, srcIdx); + int dy = partPtr[1]; //ft->loadEnvI32(con, 2, srcIdx + 1); + int life = partPtr[2]; //ft->loadEnvI32(con, 2, srcIdx + 2); + int posx = partPtr[3]; //ft->loadEnvI32(con, 2, srcIdx + 3); + int posy = partPtr[4]; //ft->loadEnvI32(con, 2, srcIdx + 4); + + if (life) { + if (posy > 0) { + uint32_t c = 0xffafcf | ((life >> lifeShift) << 24); + + ((uint32_t *)vertPtr)[0] = c; //ft->storeEnvU32(con, 1, dstIdx, c); + vertPtr[1] = posx; //ft->storeEnvI32(con, 1, dstIdx + 1, posx); + vertPtr[2] = posy; //ft->storeEnvI32(con, 1, dstIdx + 2, posy); + + ((uint32_t *)vertPtr)[3] = c; //ft->storeEnvU32(con, 1, dstIdx + 3, c); + vertPtr[4] = posx + 0x10000; //ft->storeEnvI32(con, 1, dstIdx + 4, posx + 0x10000); + vertPtr[5] = posy + dy * 4; //ft->storeEnvI32(con, 1, dstIdx + 5, posy); + + ((uint32_t *)vertPtr)[6] = c; //ft->storeEnvU32(con, 1, dstIdx + 6, c); + vertPtr[7] = posx - 0x10000; //ft->storeEnvI32(con, 1, dstIdx + 7, posx + 0x0800); + vertPtr[8] = posy + dy * 4; //ft->storeEnvI32(con, 1, dstIdx + 8, posy + 0x10000); + + vertPtr += 9; + drawCount ++; + } else { + if (dy < 0) { + dy = (-dy) >> 1; + } + } + + posx += dx; + posy += dy; + dy -= 0x400; + life --; + + partPtr[0] = dx; //ft->storeEnvI32(con, 2, srcIdx, dx); + partPtr[1] = dy; //ft->storeEnvI32(con, 2, srcIdx + 1, dy); + partPtr[2] = life; //ft->storeEnvI32(con, 2, srcIdx + 2, life); + partPtr[3] = posx; //ft->storeEnvI32(con, 2, srcIdx + 3, posx); + partPtr[4] = posy; //ft->storeEnvI32(con, 2, srcIdx + 4, posy); + } + + partPtr += 5; + } + + ft->drawTriangleArray(con, (RsAllocation)ft->loadEnvI32(con, 0, 5), drawCount); +} + + +// --------------------------------------------------------------------------- + +static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) +{ + jclass npeClazz = env->FindClass(exc); + env->ThrowNew(npeClazz, msg); +} + +static jfieldID gContextId; + +static void _nInit(JNIEnv *_env, jclass _this) +{ + LOGE("_nInit"); + gContextId = _env->GetFieldID(_this, "mContext", "I"); +} + + +// --------------------------------------------------------------------------- + +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 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, jboolean isRoot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("!!! nScriptCSetScript, con(%p)", con); + //nScriptCSetScript(isRoot); + rsScriptCSetScript((void *)test_script); +} + +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 +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 +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 +nContextBindSampler(JNIEnv *_env, jobject _this, jint sampler, jint slot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindSampler, con(%p), sampler(%p), slot(%i)", con, (RsSampler)sampler, slot); + rsContextBindSampler(slot, (RsSampler)sampler); +} + +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 const char *classPathName = "com/android/calc/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 }, + +{"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", "(I)V", (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", "(Ljava/lang/String;)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 }, + +{"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 }, + +{"nContextBindRootScript", "(I)V", (void*)nContextBindRootScript }, +//{"nContextBindSampler", "(II)V", (void*)nContextBindSampler }, +{"nContextBindProgramFragmentStore","(I)V", (void*)nContextBindProgramFragmentStore }, +{"nContextBindProgramFragment", "(I)V", (void*)nContextBindProgramFragment }, + +}; + +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..6168bd7 --- /dev/null +++ b/libs/rs/rs.spec @@ -0,0 +1,392 @@ + + +ContextBindSampler { + param uint32_t slot + param RsSampler sampler + } + +ContextBindRootScript { + param RsScript sampler + } + +ContextBindProgramFragmentStore { + param RsProgramFragmentStore pgm + } + +ContextBindProgramFragment { + param RsProgramFragment pgm + } + +ContextBindProgramVertex { + param RsProgramVertex pgm + } + + +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 + } + +AllocationCreateFromBitmap { + param const char *file + param bool genMips + 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 + } + + +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 * ptr + } + +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 + } + + + +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 + } + + + +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..f3f2e46 --- /dev/null +++ b/libs/rs/rsAllocation.cpp @@ -0,0 +1,325 @@ +/* + * 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() +{ +} + +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); + + 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, GL_RGB, + adapt.getDimX(), adapt.getDimY(), + 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 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 mip(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[2], i2[0], i2[1]); + oPtr ++; + i1 += 2; + i2 += 2; + } + } + +} + + +RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, const char *file, bool genMips) +{ + 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); + + 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; + 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], fileInBuf[x*3 + 1], fileInBuf[x*3 + 2]); + 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); + mip(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..163cf4d --- /dev/null +++ b/libs/rs/rsContext.cpp @@ -0,0 +1,308 @@ +/* + * 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" + + +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 + }; + + LOGE("EGL 1"); + mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + LOGE("EGL 2 %p", mDisplay); + eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion); + LOGE("EGL 3 %i %i", mMajorVersion, mMinorVersion); + eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs); + LOGE("EGL 4 %p", mConfig); + + if (mWndSurface) { + mSurface = eglCreateWindowSurface(mDisplay, mConfig, + new EGLNativeWindowSurface(mWndSurface), + NULL); + } else { + mSurface = eglCreateWindowSurface(mDisplay, mConfig, + android_createDisplaySurface(), + NULL); + } + + LOGE("EGL 5"); + mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL); + eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); + eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth); + eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight); + LOGE("EGL 9"); + +} + +void Context::runRootScript() +{ + rsAssert(mRootScript->mIsRoot); + + glViewport(0, 0, 320, 480); + float aspectH = 480.f / 320.f; + + if(mRootScript->mIsOrtho) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, 320, 0, 480, 0, 1); + glMatrixMode(GL_MODELVIEW); + } else { + 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->mClearColor[0], + mRootScript->mClearColor[1], + mRootScript->mClearColor[2], + mRootScript->mClearColor[3]); + glClearDepthf(mRootScript->mClearDepth); + glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); + + mRootScript->run(this, 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); + + LOGE("TP 1"); + gIO = new ThreadIO(); + + rsc->mServerCommands.init(128); + rsc->mServerReturns.init(128); + + rsc->initEGL(); + + LOGE("TP 2"); + + rsc->mRunning = true; + while (!rsc->mExit) { + gIO->playCoreCommands(rsc); + + if (!rsc->mRootScript.get()) { + continue; + } + + + glColor4f(1,1,1,1); + glEnable(GL_LIGHT0); + + if (rsc->mRootScript.get()) { + rsc->runRootScript(); + } + + eglSwapBuffers(rsc->mDisplay, rsc->mSurface); + + usleep(10000); + } + + LOGE("TP 6"); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + eglSwapBuffers(rsc->mDisplay, rsc->mSurface); + eglTerminate(rsc->mDisplay); + + LOGE("TP 7"); + + return NULL; +} + +Context::Context(Device *dev, Surface *sur) +{ + LOGE("CC 1"); + dev->addContext(this); + mDev = dev; + mRunning = false; + mExit = false; + + mServerCommands.init(256); + mServerReturns.init(256); + + // see comment in header + gCon = this; + + LOGE("CC 2"); + int status = pthread_create(&mThreadId, NULL, threadProc, this); + if (status) { + LOGE("Failed to start rs context thread."); + } + + LOGE("CC 3"); + mWndSurface = sur; + while(!mRunning) { + sleep(1); + } + LOGE("CC 4"); + + + +} + +Context::~Context() +{ + mExit = true; + void *res; + + LOGE("DES 1"); + int status = pthread_join(mThreadId, &res); + LOGE("DES 2"); + + if (mDev) { + mDev->removeContext(this); + } + LOGE("DES 3"); +} + +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(); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// + +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); +} + + + +} +} + + +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..9d96a06 --- /dev/null +++ b/libs/rs/rsContext.h @@ -0,0 +1,123 @@ +/* + * 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(); + +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; + +private: + Context(); + + void initEGL(); + + void runRootScript(); + + static void * threadProc(void *); + + // todo: put in TLS + static Context *gCon; + Surface *mWndSurface; +}; + + +} +} +#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..1637544 --- /dev/null +++ b/libs/rs/rsElement.cpp @@ -0,0 +1,326 @@ +/* + * 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; + +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(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; +} + +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..7852ffc --- /dev/null +++ b/libs/rs/rsElement.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STRUCTURED_ELEMENT_H +#define ANDROID_STRUCTURED_ELEMENT_H + +#include <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); + + + + 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..3f51e04 --- /dev/null +++ b/libs/rs/rsLocklessFifo.cpp @@ -0,0 +1,180 @@ +/* + * 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; + } + + return freeSpace; +} + +bool LocklessCommandFifo::isEmpty() const +{ + return mPut == mGet; +} + + +void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) +{ + // Add space for command header; + sizeInBytes += 4; + + //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) +{ + if ((mPut+bytes) > mEnd) { + // Need to loop regardless of where get is. + while((mGet > mPut) && (mPut+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 += 4; + } + + // 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..7d22ae0 --- /dev/null +++ b/libs/rs/rsMatrix.cpp @@ -0,0 +1,138 @@ +/* + * 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 "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..f9cb9c8 --- /dev/null +++ b/libs/rs/rsObjectBase.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 "rsObjectBase.h" +#include <utils/Log.h> + +using namespace android; +using namespace android::renderscript; + +ObjectBase::ObjectBase() +{ + mRefCount = 0; +} + +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; + } +} + diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h new file mode 100644 index 0000000..7761e49 --- /dev/null +++ b/libs/rs/rsObjectBase.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RS_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; + +private: + mutable int32_t mRefCount; + + +}; + +template<class T> +class ObjectBaseRef +{ +public: + ObjectBaseRef() { + mRef = NULL; + } + + ~ObjectBaseRef() { + clear(); + } + + void set(T *ref) { + if (mRef != ref) { + clear(); + mRef = ref; + ref->incRef(); + } + } + + void clear() { + if (mRef) { + mRef->decRef(); + } + mRef = NULL; + } + + inline T * get() const { + return mRef; + } + + inline T * operator-> () const { + return mRef; + } + +protected: + T * mRef; + +private: + ObjectBaseRef(const ObjectBaseRef &) {}; + +}; + + +} +} + +#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..5367c53 --- /dev/null +++ b/libs/rs/rsProgramFragment.cpp @@ -0,0 +1,212 @@ +/* + * 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; + } + + mSamplers[ct]->setupGL(); + } + 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; +} + + + +} +} + diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h new file mode 100644 index 0000000..cc08aea --- /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]; + + +}; + + +} +} +#endif + + + + diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp new file mode 100644 index 0000000..7f5d5f4 --- /dev/null +++ b/libs/rs/rsProgramFragmentStore.cpp @@ -0,0 +1,252 @@ +/* + * 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); +} + + +} +} diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h new file mode 100644 index 0000000..bbd0f38 --- /dev/null +++ b/libs/rs/rsProgramFragmentStore.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RS_PROGRAM_FRAGMENT_STORE_H +#define ANDROID_RS_PROGRAM_FRAGMENT_STORE_H + +#include "rsProgram.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +class ProgramFragmentStore : public Program +{ +public: + + + + ProgramFragmentStore(Element *in, Element *out); + virtual ~ProgramFragmentStore(); + + virtual void setupGL(); + + + void setDepthFunc(RsDepthFunc); + void setDepthMask(bool); + + void setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst); + void setColorMask(bool, bool, bool, bool); + + void setDitherEnable(bool); + +protected: + bool mDitherEnable; + + bool mBlendEnable; + bool mColorRWriteEnable; + bool mColorGWriteEnable; + bool mColorBWriteEnable; + bool mColorAWriteEnable; + int32_t mBlendSrc; + int32_t mBlendDst; + + + + bool mDepthTestEnable; + bool mDepthWriteEnable; + int32_t mDepthFunc; + + + + bool mStencilTestEnable; + + + +}; + +class ProgramFragmentStoreState +{ +public: + ProgramFragmentStoreState(); + ~ProgramFragmentStoreState(); + + ProgramFragmentStore *mPFS; + + +}; + + +} +} +#endif + + + diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp new file mode 100644 index 0000000..8e2b82d --- /dev/null +++ b/libs/rs/rsProgramVertex.cpp @@ -0,0 +1,133 @@ +/* + * 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..3c008c9 --- /dev/null +++ b/libs/rs/rsSampler.cpp @@ -0,0 +1,143 @@ +/* + * 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() +{ + //LOGE("setup gl"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + +} + +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 < 1/*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; +} + +}} 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..24a630c --- /dev/null +++ b/libs/rs/rsScript.cpp @@ -0,0 +1,54 @@ +/* + * 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() +{ + mClearColor[0] = 0; + mClearColor[1] = 0; + mClearColor[2] = 0; + mClearColor[3] = 1; + 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..1932870 --- /dev/null +++ b/libs/rs/rsScript.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_SCRIPT_H +#define ANDROID_RS_SCRIPT_H + +#include "rsAllocation.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + + +class Script : public ObjectBase +{ +public: + + Script(); + virtual ~Script(); + + + bool mIsRoot; + bool mIsOrtho; + + float mClearColor[4]; + float mClearDepth; + uint32_t mClearStencil; + + + const Type * mConstantBufferTypes; + uint32_t mCounstantBufferCount; + + ObjectBaseRef<Allocation> mSlots[16]; + + virtual void 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..f825e6e --- /dev/null +++ b/libs/rs/rsScriptC.cpp @@ -0,0 +1,454 @@ +/* + * 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" + +using namespace android; +using namespace android::renderscript; + + +ScriptC::ScriptC() +{ + mScript = NULL; +} + +ScriptC::~ScriptC() +{ +} + +static void matrixLoadIdentity(void *con, rsc_Matrix *mat) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadIdentity(); +} + +static void matrixLoadFloat(void *con, rsc_Matrix *mat, const float *f) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->load(f); +} + +static void matrixLoadMat(void *con, rsc_Matrix *mat, const rsc_Matrix *newmat) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->load(reinterpret_cast<const Matrix *>(newmat)); +} + +static 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); +} + +static void matrixLoadScale(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadScale(x, y, z); +} + +static void matrixLoadTranslate(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->loadTranslate(x, y, z); +} + +static 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)); +} + +static void matrixMultiply(void *con, rsc_Matrix *mat, const rsc_Matrix *rhs) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->multiply(reinterpret_cast<const Matrix *>(rhs)); +} + +static 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); +} + +static void matrixScale(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->scale(x, y, z); +} + +static void matrixTranslate(void *con, rsc_Matrix *mat, float x, float y, float z) +{ + Matrix *m = reinterpret_cast<Matrix *>(mat); + m->translate(x, y, z); +} + + +static 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]; +} + +static 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]; +} + +static 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]; +} + +static 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]; +} + +static 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)); +} + +static 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)); +} + + +static 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; +} + +static 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; +} + +static 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; +} + +static 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)); +} + +static 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)); +} + + +static 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); +} + +static void renderTriangleMesh(void *vp, RsTriangleMesh mesh) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_TriangleMeshRender(env->mContext, mesh); +} + +static 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); +} + +static 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); +} + +static 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); +} + +static 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); +} + +static void materialShininess(void *vp, float s) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s); +} + +static void uploadToTexture(void *vp, RsAllocation va, uint32_t baseMipLevel) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_AllocationUploadToTexture(env->mContext, va, baseMipLevel); +} + +static void enable(void *vp, uint32_t p) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glEnable(p); +} + +static void disable(void *vp, uint32_t p) +{ + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + glDisable(p); +} + +static 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 +static 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); +} + +static 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)); + +} + +static 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)); + +} + +static void contextBindProgramFragmentStore(void *vp, RsProgramFragmentStore pfs) +{ + //LOGE("contextBindProgramFragmentStore %p", pfs); + ScriptC::Env * env = static_cast<ScriptC::Env *>(vp); + rsi_ContextBindProgramFragmentStore(env->mContext, pfs); + +} + +static 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, + renderTriangleMesh, + renderTriangleMeshRange, + + pfBindTexture, + pfBindSampler, + + materialDiffuse, + materialSpecular, + lightPosition, + materialShininess, + uploadToTexture, + enable, + disable, + + scriptRand, + drawTriangleArray, + contextBindProgramFragment, + contextBindProgramFragmentStore +}; + + +void ScriptC::run(Context *rsc, uint32_t launchID) +{ + Env e = {rsc, this}; + mScript(&e, &scriptCPtrTable, launchID); +} + +ScriptCState::ScriptCState() +{ + clear(); +} + +ScriptCState::~ScriptCState() +{ +} + +void ScriptCState::clear() +{ + mConstantBufferTypes.clear(); + mClearColor[0] = 0; + mClearColor[1] = 0; + mClearColor[2] = 0; + mClearColor[3] = 1; + mClearDepth = 1; + mClearStencil = 0; + mScript = NULL; + mIsRoot = false; + mIsOrtho = true; +} + +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->mClearColor[0] = r; + ss->mClearColor[1] = g; + ss->mClearColor[2] = b; + ss->mClearColor[3] = a; +} + +void rsi_ScriptCSetClearDepth(Context * rsc, float v) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mClearDepth = v; +} + +void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->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->mScript = reinterpret_cast<rsc_RunScript>(vp); +} + +void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mIsRoot = isRoot; +} + +void rsi_ScriptCSetOrtho(Context * rsc, bool isOrtho) +{ + ScriptCState *ss = &rsc->mScriptC; + ss->mIsOrtho = isOrtho; +} + +RsScript rsi_ScriptCCreate(Context * rsc) +{ + ScriptCState *ss = &rsc->mScriptC; + + ScriptC *s = new ScriptC(); + s->mScript = ss->mScript; + s->mClearColor[0] = ss->mClearColor[0]; + s->mClearColor[1] = ss->mClearColor[1]; + s->mClearColor[2] = ss->mClearColor[2]; + s->mClearColor[3] = ss->mClearColor[3]; + s->mClearDepth = ss->mClearDepth; + s->mClearStencil = ss->mClearStencil; + s->mIsRoot = ss->mIsRoot; + s->mIsOrtho = ss->mIsOrtho; + + return s; +} + +} +} + + diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h new file mode 100644 index 0000000..f35a130 --- /dev/null +++ b/libs/rs/rsScriptC.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_SCRIPT_C_H +#define ANDROID_RS_SCRIPT_C_H + +#include "rsScript.h" + +#include "RenderScriptEnv.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + + +class ScriptC : public Script +{ +public: + + ScriptC(); + virtual ~ScriptC(); + + + virtual void run(Context *, uint32_t launchID); + + + rsc_RunScript mScript; + + + struct Env { + Context *mContext; + ScriptC *mScript; + }; + +}; + +class ScriptCState +{ +public: + ScriptCState(); + ~ScriptCState(); + + + rsc_RunScript mScript; + float mClearColor[4]; + float mClearDepth; + uint32_t mClearStencil; + bool mIsRoot; + bool mIsOrtho; + + Vector<const Type *> mConstantBufferTypes; + + void clear(); +}; + + +} +} +#endif + + + diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp new file mode 100644 index 0000000..d5ac70b --- /dev/null +++ b/libs/rs/rsThreadIO.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" + +#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() +{ +} + +void ThreadIO::playCoreCommands(Context *con) +{ + //LOGE("playCoreCommands 1"); + uint32_t cmdID = 0; + uint32_t cmdSize = 0; + while(!mToCore.isEmpty()) { + //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"); + } +} + + diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h new file mode 100644 index 0000000..f8ba37d --- /dev/null +++ b/libs/rs/rsThreadIO.h @@ -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. + */ + +#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(); + + void 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..683c96e --- /dev/null +++ b/libs/rs/rsUtils.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_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 |= r >> 3; + t |= (g >> 2) << 5; + t |= (b >> 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) + ((i1 >> 5) & 0x3f); + uint32_t b = ((i1 >> 11) + (i2 >> 11) + (i3 >> 11) + (i4 >> 11)); + return (r >> 2) | ((g >> 2) << 5) | ((b >> 2) << 11); +} + + + + + + +} +} + +#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; +} + |