eclair snapshot
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
new file mode 100644
index 0000000..262ac8d
--- /dev/null
+++ b/libs/rs/Android.mk
@@ -0,0 +1,115 @@
+
+LOCAL_PATH:=$(call my-dir)
+
+
+# Build rsg-generator ====================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := rsg-generator
+
+# These symbols are normally defined by BUILD_XXX, but we need to define them
+# here so that local-intermediates-dir works.
+
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+intermediates := $(local-intermediates-dir)
+
+LOCAL_SRC_FILES:= \
+ spec.l \
+ rsg_generator.c
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# TODO: This should go into build/core/config.mk
+RSG_GENERATOR:=$(LOCAL_BUILT_MODULE)
+
+
+
+# Build render script lib ====================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libRS
+
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+intermediates:= $(local-intermediates-dir)
+
+# Generate custom headers
+
+GEN := $(addprefix $(intermediates)/, \
+ rsgApiStructs.h \
+ rsgApiFuncDecl.h \
+ )
+
+$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(PRIVATE_PATH)/rs.spec
+$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec
+$(GEN): $(intermediates)/%.h : $(LOCAL_PATH)/%.h.rsg
+ $(transform-generated-source)
+
+# used in jni/Android.mk
+rs_generated_source += $(GEN)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+# Generate custom source files
+
+GEN := $(addprefix $(intermediates)/, \
+ rsgApi.cpp \
+ rsgApiReplay.cpp \
+ )
+
+$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(PRIVATE_PATH)/rs.spec
+$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec
+$(GEN): $(intermediates)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg
+ $(transform-generated-source)
+
+# used in jni/Android.mk
+rs_generated_source += $(GEN)
+
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+# libRS needs libacc, which isn't 64-bit clean, and so can't be built
+# for the simulator on gHardy, and therefore libRS needs to be excluded
+# from the simulator as well.
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_SRC_FILES:= \
+ rsAdapter.cpp \
+ rsAllocation.cpp \
+ rsComponent.cpp \
+ rsContext.cpp \
+ rsDevice.cpp \
+ rsElement.cpp \
+ rsFileA3D.cpp \
+ rsLight.cpp \
+ rsLocklessFifo.cpp \
+ rsObjectBase.cpp \
+ rsMatrix.cpp \
+ rsMesh.cpp \
+ rsNoise.cpp \
+ rsProgram.cpp \
+ rsProgramFragment.cpp \
+ rsProgramFragmentStore.cpp \
+ rsProgramRaster.cpp \
+ rsProgramVertex.cpp \
+ rsSampler.cpp \
+ rsScript.cpp \
+ rsScriptC.cpp \
+ rsScriptC_Lib.cpp \
+ rsSimpleMesh.cpp \
+ rsThreadIO.cpp \
+ rsType.cpp
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libui libacc
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libRS
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Include the subdirectories ====================
+include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk,\
+ java \
+ ))
+
+endif #simulator
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
new file mode 100644
index 0000000..9b04393
--- /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 * RsFile;
+typedef void * RsSampler;
+typedef void * RsScript;
+typedef void * RsScriptBasicTemp;
+typedef void * RsSimpleMesh;
+typedef void * RsType;
+typedef void * RsLight;
+
+typedef void * RsProgramVertex;
+typedef void * RsProgramFragment;
+typedef void * RsProgramFragmentStore;
+typedef void * RsProgramRaster;
+
+enum RsDeviceParam {
+ RS_DEVICE_PARAM_FORCE_SOFTWARE_GL,
+ RS_DEVICE_PARAM_COUNT
+};
+
+RsDevice rsDeviceCreate();
+void rsDeviceDestroy(RsDevice);
+void rsDeviceSetConfig(RsDevice, RsDeviceParam, int32_t value);
+
+RsContext rsContextCreate(RsDevice, void *, uint32_t version, bool useDepth);
+void rsContextDestroy(RsContext);
+void rsObjDestroyOOB(RsContext, void *);
+
+uint32_t rsContextGetMessage(RsContext, void *data, size_t *receiveLen, size_t bufferLen, bool wait);
+void rsContextInitToClient(RsContext);
+void rsContextDeinitToClient(RsContext);
+
+#define RS_MAX_TEXTURE 2
+
+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,
+ RS_KIND_POINT_SIZE
+};
+
+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, // 0
+ RS_BLEND_SRC_ONE, // 1
+ RS_BLEND_SRC_DST_COLOR, // 2
+ RS_BLEND_SRC_ONE_MINUS_DST_COLOR, // 3
+ RS_BLEND_SRC_SRC_ALPHA, // 4
+ RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_SRC_DST_ALPHA, // 6
+ RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, // 7
+ RS_BLEND_SRC_SRC_ALPHA_SATURATE // 8
+};
+
+enum RsBlendDstFunc {
+ RS_BLEND_DST_ZERO, // 0
+ RS_BLEND_DST_ONE, // 1
+ RS_BLEND_DST_SRC_COLOR, // 2
+ RS_BLEND_DST_ONE_MINUS_SRC_COLOR, // 3
+ RS_BLEND_DST_SRC_ALPHA, // 4
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_DST_DST_ALPHA, // 6
+ RS_BLEND_DST_ONE_MINUS_DST_ALPHA // 7
+};
+
+enum RsTexEnvMode {
+ RS_TEX_ENV_MODE_REPLACE,
+ RS_TEX_ENV_MODE_MODULATE,
+ RS_TEX_ENV_MODE_DECAL
+};
+
+enum RsPrimitive {
+ RS_PRIMITIVE_POINT,
+ RS_PRIMITIVE_LINE,
+ RS_PRIMITIVE_LINE_STRIP,
+ RS_PRIMITIVE_TRIANGLE,
+ RS_PRIMITIVE_TRIANGLE_STRIP,
+ RS_PRIMITIVE_TRIANGLE_FAN
+};
+
+
+#include "rsgApiFuncDecl.h"
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // RENDER_SCRIPT_H
+
+
+
diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/RenderScriptEnv.h
new file mode 100644
index 0000000..ff0a7b1
--- /dev/null
+++ b/libs/rs/RenderScriptEnv.h
@@ -0,0 +1,32 @@
+#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 * RsSimpleMesh;
+typedef void * RsType;
+typedef void * RsProgramFragment;
+typedef void * RsProgramFragmentStore;
+typedef void * RsLight;
+
+
+typedef struct {
+ float m[16];
+} rsc_Matrix;
+
+
+typedef struct {
+ float v[4];
+} rsc_Vector4;
+
+#define RS_PROGRAM_VERTEX_MODELVIEW_OFFSET 0
+#define RS_PROGRAM_VERTEX_PROJECTION_OFFSET 16
+#define RS_PROGRAM_VERTEX_TEXTURE_OFFSET 32
+
diff --git a/libs/rs/java/Android.mk b/libs/rs/java/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/libs/rs/java/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/libs/rs/java/Film/Android.mk b/libs/rs/java/Film/Android.mk
new file mode 100644
index 0000000..b7f98fc
--- /dev/null
+++ b/libs/rs/java/Film/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := Film
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Film/AndroidManifest.xml b/libs/rs/java/Film/AndroidManifest.xml
new file mode 100644
index 0000000..a5ce8a1
--- /dev/null
+++ b/libs/rs/java/Film/AndroidManifest.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.film">
+ <application android:label="Film">
+ <activity android:name="Film"
+ android:screenOrientation="portrait"
+ android:theme="@android:style/Theme.Black.NoTitleBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/rs/java/Film/res/drawable/p01.png b/libs/rs/java/Film/res/drawable/p01.png
new file mode 100644
index 0000000..a9b9bdb
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p01.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p02.png b/libs/rs/java/Film/res/drawable/p02.png
new file mode 100644
index 0000000..8162c82
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p02.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p03.png b/libs/rs/java/Film/res/drawable/p03.png
new file mode 100644
index 0000000..e3e26c0
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p03.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p04.png b/libs/rs/java/Film/res/drawable/p04.png
new file mode 100644
index 0000000..daee603
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p04.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p05.png b/libs/rs/java/Film/res/drawable/p05.png
new file mode 100644
index 0000000..fac5248
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p05.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p06.png b/libs/rs/java/Film/res/drawable/p06.png
new file mode 100644
index 0000000..3b51261
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p06.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p07.png b/libs/rs/java/Film/res/drawable/p07.png
new file mode 100644
index 0000000..d8bd938
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p07.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p08.png b/libs/rs/java/Film/res/drawable/p08.png
new file mode 100644
index 0000000..ef175e8
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p08.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p09.png b/libs/rs/java/Film/res/drawable/p09.png
new file mode 100644
index 0000000..7bf3874
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p09.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p10.png b/libs/rs/java/Film/res/drawable/p10.png
new file mode 100644
index 0000000..908827d
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p10.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p11.png b/libs/rs/java/Film/res/drawable/p11.png
new file mode 100644
index 0000000..1289f71
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p11.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p12.png b/libs/rs/java/Film/res/drawable/p12.png
new file mode 100644
index 0000000..e1af16a4
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p12.png
Binary files differ
diff --git a/libs/rs/java/Film/res/drawable/p13.png b/libs/rs/java/Film/res/drawable/p13.png
new file mode 100644
index 0000000..d08bcbe
--- /dev/null
+++ b/libs/rs/java/Film/res/drawable/p13.png
Binary files differ
diff --git a/libs/rs/java/Film/res/raw/filmimage.c b/libs/rs/java/Film/res/raw/filmimage.c
new file mode 100644
index 0000000..d154c68
--- /dev/null
+++ b/libs/rs/java/Film/res/raw/filmimage.c
@@ -0,0 +1,110 @@
+// Fountain test script
+
+#pragma version(1)
+#pragma stateVertex(orthoWindow)
+#pragma stateRaster(flat)
+#pragma stateFragment(PgmFragBackground)
+#pragma stateStore(MyBlend)
+
+
+int main(void* con, int ft, int launchID) {
+ int count, touch, x, y, rate, maxLife, lifeShift;
+ int life;
+ int ct, ct2;
+ int newPart;
+ int drawCount;
+ int dx, dy, idx;
+ int posx,posy;
+ int c;
+ int srcIdx;
+ int dstIdx;
+
+ count = loadI32(con, 0, 1);
+ touch = loadI32(con, 0, 2);
+ x = loadI32(con, 0, 3);
+ y = loadI32(con, 0, 4);
+
+ rate = 4;
+ maxLife = (count / rate) - 1;
+ lifeShift = 0;
+ {
+ life = maxLife;
+ while (life > 255) {
+ life = life >> 1;
+ lifeShift ++;
+ }
+ }
+
+ drawRect(con, 0, 256, 0, 512);
+ contextBindProgramFragment(con, NAMED_PgmFragParts);
+
+ if (touch) {
+ newPart = loadI32(con, 2, 0);
+ for (ct2=0; ct2<rate; ct2++) {
+ dx = scriptRand(con, 0x10000) - 0x8000;
+ dy = scriptRand(con, 0x10000) - 0x8000;
+
+ idx = newPart * 5 + 1;
+ storeI32(con, 2, idx, dx);
+ storeI32(con, 2, idx + 1, dy);
+ storeI32(con, 2, idx + 2, maxLife);
+ storeI32(con, 2, idx + 3, x << 16);
+ storeI32(con, 2, idx + 4, y << 16);
+
+ newPart++;
+ if (newPart >= count) {
+ newPart = 0;
+ }
+ }
+ storeI32(con, 2, 0, newPart);
+ }
+
+ drawCount = 0;
+ for (ct=0; ct < count; ct++) {
+ srcIdx = ct * 5 + 1;
+
+ dx = loadI32(con, 2, srcIdx);
+ dy = loadI32(con, 2, srcIdx + 1);
+ life = loadI32(con, 2, srcIdx + 2);
+ posx = loadI32(con, 2, srcIdx + 3);
+ posy = loadI32(con, 2, srcIdx + 4);
+
+ if (life) {
+ if (posy < (480 << 16)) {
+ dstIdx = drawCount * 9;
+ c = 0xffafcf | ((life >> lifeShift) << 24);
+
+ storeU32(con, 1, dstIdx, c);
+ storeI32(con, 1, dstIdx + 1, posx);
+ storeI32(con, 1, dstIdx + 2, posy);
+
+ storeU32(con, 1, dstIdx + 3, c);
+ storeI32(con, 1, dstIdx + 4, posx + 0x10000);
+ storeI32(con, 1, dstIdx + 5, posy + dy * 4);
+
+ storeU32(con, 1, dstIdx + 6, c);
+ storeI32(con, 1, dstIdx + 7, posx - 0x10000);
+ storeI32(con, 1, dstIdx + 8, posy + dy * 4);
+ drawCount ++;
+ } else {
+ if (dy > 0) {
+ dy = (-dy) >> 1;
+ }
+ }
+
+ posx = posx + dx;
+ posy = posy + dy;
+ dy = dy + 0x400;
+ life --;
+
+ //storeI32(con, 2, srcIdx, dx);
+ storeI32(con, 2, srcIdx + 1, dy);
+ storeI32(con, 2, srcIdx + 2, life);
+ storeI32(con, 2, srcIdx + 3, posx);
+ storeI32(con, 2, srcIdx + 4, posy);
+ }
+ }
+
+ drawTriangleArray(con, NAMED_PartBuffer, drawCount);
+ return 1;
+}
diff --git a/libs/rs/java/Film/res/raw/filmstrip.c b/libs/rs/java/Film/res/raw/filmstrip.c
new file mode 100644
index 0000000..bf75675
--- /dev/null
+++ b/libs/rs/java/Film/res/raw/filmstrip.c
@@ -0,0 +1,94 @@
+// Fountain test script
+
+#pragma version(1)
+#pragma stateVertex(PVBackground)
+#pragma stateFragment(PFBackground)
+#pragma stateStore(PSBackground)
+
+#define STATE_TRIANGLE_OFFSET_COUNT 0
+#define STATE_LAST_FOCUS 1
+
+
+// The script enviroment has 3 env allocations.
+// bank0: (r) The enviroment structure
+// bank1: (r) The position information
+// bank2: (rw) The temporary texture state
+
+int lastFocus;
+
+int main(int index)
+{
+ float mat1[16];
+
+ float trans = Pos->translate;
+ float rot = Pos->rotate;
+
+ matrixLoadScale(mat1, 2.f, 2.f, 2.f);
+ matrixTranslate(mat1, 0.f, 0.f, trans);
+ matrixRotate(mat1, 90.f, 0.f, 0.f, 1.f);
+ matrixRotate(mat1, rot, 1.f, 0.f, 0.f);
+ vpLoadModelMatrix(mat1);
+
+ // Draw the lighting effect in the strip and fill the Z buffer.
+ drawSimpleMesh(NAMED_mesh);
+
+ // Start of images.
+ bindProgramStore(NAMED_PSImages);
+ bindProgramFragment(NAMED_PFImages);
+ bindProgramVertex(NAMED_PVImages);
+
+ float focusPos = Pos->focus;
+ int focusID = 0;
+ int lastFocusID = loadI32(2, STATE_LAST_FOCUS);
+ int imgCount = 13;
+
+ if (trans > (-.3f)) {
+ focusID = -1.0f - focusPos;
+ if (focusID >= imgCount) {
+ focusID = -1;
+ }
+ } else {
+ focusID = -1;
+ }
+
+ /*
+ if (focusID != lastFocusID) {
+ if (lastFocusID >= 0) {
+ uploadToTexture(con, env->tex[lastFocusID], 1);
+ }
+ if (focusID >= 0) {
+ uploadToTexture(con, env->tex[focusID], 0);
+ }
+ }
+ */
+ lastFocus = focusID;
+
+ int triangleOffsetsCount = Pos->triangleOffsetCount;
+
+ int imgId = 0;
+ for (imgId=1; imgId <= imgCount; imgId++) {
+ float pos = focusPos + imgId + 0.4f;
+ int offset = (int)floorf(pos * 2.f);
+ pos = pos - 0.75f;
+
+ offset = offset + triangleOffsetsCount / 2;
+ if (!((offset < 0) || (offset >= triangleOffsetsCount))) {
+ int start = offset -2;
+ int end = offset + 2;
+
+ if (start < 0) {
+ start = 0;
+ }
+ if (end >= triangleOffsetsCount) {
+ end = triangleOffsetsCount-1;
+ }
+
+ bindTexture(NAMED_PFImages, 0, loadI32(0, imgId - 1));
+ matrixLoadTranslate(mat1, -pos - loadF(5, triangleOffsetsCount / 2), 0, 0);
+ vpLoadTextureMatrix(mat1);
+ drawSimpleMeshRange(NAMED_mesh, loadI32(4, start), (loadI32(4, end) - loadI32(4, start)));
+ }
+ }
+ return 0;
+}
+
diff --git a/libs/rs/java/Film/src/com/android/film/Film.java b/libs/rs/java/Film/src/com/android/film/Film.java
new file mode 100644
index 0000000..6e99816
--- /dev/null
+++ b/libs/rs/java/Film/src/com/android/film/Film.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.film;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class Film extends Activity {
+ //EventListener mListener = new EventListener();
+
+ private static final String LOG_TAG = "libRS_jni";
+ private static final boolean DEBUG = false;
+ private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+ private FilmView mView;
+
+ // get the current looper (from your Activity UI thread for instance
+
+
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Create our Preview view and set it as the content of our
+ // Activity
+ mView = new FilmView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.onPause();
+
+ Runtime.getRuntime().exit(0);
+ }
+
+
+ static void log(String message) {
+ if (LOG_ENABLED) {
+ Log.v(LOG_TAG, message);
+ }
+ }
+
+
+}
+
diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java
new file mode 100644
index 0000000..b5b6723
--- /dev/null
+++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.film;
+
+import java.io.Writer;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import android.renderscript.*;
+
+public class FilmRS {
+ class StripPosition {
+ public float translate;
+ public float rotate;
+ public float focus;
+ public int triangleOffsetCount;
+ }
+ StripPosition mPos = new StripPosition();
+
+
+ private final int STATE_LAST_FOCUS = 1;
+
+ public FilmRS() {
+ }
+
+ public void init(RenderScript rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ initRS();
+ }
+
+ public void setFilmStripPosition(int x, int y)
+ {
+ if (x < 50) {
+ x = 50;
+ }
+ if (x > 270) {
+ x = 270;
+ }
+
+ float anim = ((float)x-50) / 270.f;
+ mPos.translate = 2f * anim + 0.5f; // translation
+ mPos.rotate = (anim * 40); // rotation
+ mPos.focus = ((float)y) / 16.f - 10.f; // focusPos
+ mPos.triangleOffsetCount = mFSM.mTriangleOffsetsCount;
+ mAllocPos.data(mPos);
+ }
+
+
+ private Resources mRes;
+ private RenderScript mRS;
+ private Script mScriptStrip;
+ private Script mScriptImage;
+ private Sampler mSampler;
+ private ProgramStore mPSBackground;
+ private ProgramStore mPSImages;
+ private ProgramFragment mPFBackground;
+ private ProgramFragment mPFImages;
+ private ProgramVertex mPVBackground;
+ private ProgramVertex mPVImages;
+ private ProgramVertex.MatrixAllocation mPVA;
+ private Type mStripPositionType;
+
+ private Allocation mImages[];
+ private Allocation mAllocIDs;
+ private Allocation mAllocPos;
+ private Allocation mAllocState;
+ private Allocation mAllocPV;
+ private Allocation mAllocOffsetsTex;
+ private Allocation mAllocOffsets;
+
+ private SimpleMesh mMesh;
+ private Light mLight;
+
+ private FilmStripMesh mFSM;
+
+ private int[] mBufferIDs;
+ private float[] mBufferPos = new float[3];
+ private int[] mBufferState;
+
+ private void initPFS() {
+ ProgramStore.Builder b = new ProgramStore.Builder(mRS, null, null);
+
+ b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ b.setDitherEnable(true);
+ b.setDepthMask(true);
+ mPSBackground = b.create();
+ mPSBackground.setName("PSBackground");
+
+ b.setDepthFunc(ProgramStore.DepthFunc.EQUAL);
+ b.setDitherEnable(false);
+ b.setDepthMask(false);
+ b.setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
+ ProgramStore.BlendDstFunc.ONE);
+ mPSImages = b.create();
+ mPSImages.setName("PSImages");
+ }
+
+ private void initPF() {
+ Sampler.Builder bs = new Sampler.Builder(mRS);
+ bs.setMin(Sampler.Value.LINEAR);//_MIP_LINEAR);
+ bs.setMag(Sampler.Value.LINEAR);
+ bs.setWrapS(Sampler.Value.CLAMP);
+ bs.setWrapT(Sampler.Value.WRAP);
+ mSampler = bs.create();
+
+ ProgramFragment.Builder b = new ProgramFragment.Builder(mRS, null, null);
+
+ mPFBackground = b.create();
+ mPFBackground.setName("PFBackground");
+
+ b.setTexEnable(true, 0);
+ b.setTexEnvMode(ProgramFragment.EnvMode.REPLACE, 0);
+ mPFImages = b.create();
+ mPFImages.bindSampler(mSampler, 0);
+ mPFImages.setName("PFImages");
+ }
+
+ private void initPV() {
+ mLight = (new Light.Builder(mRS)).create();
+ mLight.setPosition(0, -0.5f, -1.0f);
+
+ ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+ pvb.addLight(mLight);
+ mPVBackground = pvb.create();
+ mPVBackground.setName("PVBackground");
+
+ pvb = new ProgramVertex.Builder(mRS, null, null);
+ pvb.setTextureMatrixEnable(true);
+ mPVImages = pvb.create();
+ mPVImages.setName("PVImages");
+ }
+
+ private void loadImages() {
+ mBufferIDs = new int[13];
+ mImages = new Allocation[13];
+ mAllocIDs = Allocation.createSized(mRS,
+ Element.USER_F32(mRS), mBufferIDs.length);
+
+ Element ie = Element.RGB_565(mRS);
+ mImages[0] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p01, ie, true);
+ mImages[1] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p02, ie, true);
+ mImages[2] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p03, ie, true);
+ mImages[3] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p04, ie, true);
+ mImages[4] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p05, ie, true);
+ mImages[5] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p06, ie, true);
+ mImages[6] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p07, ie, true);
+ mImages[7] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p08, ie, true);
+ mImages[8] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p09, ie, true);
+ mImages[9] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p10, ie, true);
+ mImages[10] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p11, ie, true);
+ mImages[11] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p12, ie, true);
+ mImages[12] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p13, ie, true);
+
+ int black[] = new int[1024];
+ for(int ct=0; ct < mImages.length; ct++) {
+ Allocation.Adapter2D a = mImages[ct].createAdapter2D();
+
+ int size = 512;
+ int mip = 0;
+ while(size >= 2) {
+ a.subData(0, 0, 2, size, black);
+ a.subData(size-2, 0, 2, size, black);
+ a.subData(0, 0, size, 2, black);
+ a.subData(0, size-2, size, 2, black);
+ size >>= 1;
+ mip++;
+ a.setConstraint(Dimension.LOD, mip);
+ }
+
+ mImages[ct].uploadToTexture(1);
+ mBufferIDs[ct] = mImages[ct].getID();
+ }
+ mAllocIDs.data(mBufferIDs);
+ }
+
+ private void initState()
+ {
+ mBufferState = new int[10];
+ mAllocState = Allocation.createSized(mRS,
+ Element.USER_F32(mRS), mBufferState.length);
+ mBufferState[STATE_LAST_FOCUS] = -1;
+ mAllocState.data(mBufferState);
+ }
+
+ private void initRS() {
+ mFSM = new FilmStripMesh();
+ mMesh = mFSM.init(mRS);
+ mMesh.setName("mesh");
+
+ initPFS();
+ initPF();
+ initPV();
+
+ Log.e("rs", "Done loading named");
+
+ mStripPositionType = Type.createFromClass(mRS, StripPosition.class, 1);
+
+ ScriptC.Builder sb = new ScriptC.Builder(mRS);
+ sb.setScript(mRes, R.raw.filmstrip);
+ sb.setRoot(true);
+ sb.setType(mStripPositionType, "Pos", 1);
+ mScriptStrip = sb.create();
+ mScriptStrip.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ mAllocPos = Allocation.createTyped(mRS, mStripPositionType);
+
+ loadImages();
+ initState();
+
+ mPVA = new ProgramVertex.MatrixAllocation(mRS);
+ mPVBackground.bindAllocation(mPVA);
+ mPVImages.bindAllocation(mPVA);
+ mPVA.setupProjectionNormalized(320, 480);
+
+
+ mScriptStrip.bindAllocation(mAllocIDs, 0);
+ mScriptStrip.bindAllocation(mAllocPos, 1);
+ mScriptStrip.bindAllocation(mAllocState, 2);
+ mScriptStrip.bindAllocation(mPVA.mAlloc, 3);
+
+
+ mAllocOffsets = Allocation.createSized(mRS,
+ Element.USER_I32(mRS), mFSM.mTriangleOffsets.length);
+ mAllocOffsets.data(mFSM.mTriangleOffsets);
+ mScriptStrip.bindAllocation(mAllocOffsets, 4);
+
+ mAllocOffsetsTex = Allocation.createSized(mRS,
+ Element.USER_F32(mRS), mFSM.mTriangleOffsetsTex.length);
+ mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex);
+ mScriptStrip.bindAllocation(mAllocOffsetsTex, 5);
+
+ setFilmStripPosition(0, 0);
+ mRS.contextBindRootScript(mScriptStrip);
+ }
+}
+
+
+
diff --git a/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java b/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java
new file mode 100644
index 0000000..448cce0
--- /dev/null
+++ b/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.film;
+
+import java.io.Writer;
+import java.lang.Math;
+import android.util.Log;
+
+import android.renderscript.RenderScript;
+import android.renderscript.SimpleMesh;
+
+
+class FilmStripMesh {
+
+ class Vertex {
+ float nx;
+ float ny;
+ float nz;
+ float s;
+ float t;
+ float x;
+ float y;
+ float z;
+
+ Vertex() {
+ nx = 0;
+ ny = 0;
+ nz = 0;
+ s = 0;
+ t = 0;
+ x = 0;
+ y = 0;
+ z = 0;
+ }
+
+ void xyz(float _x, float _y, float _z) {
+ x = _x;
+ y = _y;
+ z = _z;
+ }
+
+ void nxyz(float _x, float _y, float _z) {
+ nx = _x;
+ ny = _y;
+ nz = _z;
+ }
+
+ void st(float _s, float _t) {
+ s = _s;
+ t = _t;
+ }
+
+ void computeNorm(Vertex v1, Vertex v2) {
+ float dx = v1.x - v2.x;
+ float dy = v1.y - v2.y;
+ float dz = v1.z - v2.z;
+ float len = (float)java.lang.Math.sqrt(dx*dx + dy*dy + dz*dz);
+ dx /= len;
+ dy /= len;
+ dz /= len;
+
+ nx = dx * dz;
+ ny = dy * dz;
+ nz = (float)java.lang.Math.sqrt(dx*dx + dy*dy);
+
+ len = (float)java.lang.Math.sqrt(nx*nx + ny*ny + nz*nz);
+ nx /= len;
+ ny /= len;
+ nz /= len;
+ }
+ }
+
+ int[] mTriangleOffsets;
+ float[] mTriangleOffsetsTex;
+ int mTriangleOffsetsCount;
+
+ SimpleMesh init(RenderScript rs)
+ {
+ float vtx[] = new float[] {
+ 60.431003f, 124.482050f,
+ 60.862074f, 120.872604f,
+ 61.705303f, 117.336662f,
+ 62.949505f, 113.921127f,
+ 64.578177f, 110.671304f,
+ 66.569716f, 107.630302f,
+ 68.897703f, 104.838457f,
+ 71.531259f, 102.332803f,
+ 74.435452f, 100.146577f,
+ 77.571757f, 98.308777f,
+ 80.898574f, 96.843781f,
+ 84.371773f, 95.771023f,
+ 87.945283f, 95.104731f,
+ 98.958994f, 95.267098f,
+ 109.489523f, 98.497596f,
+ 118.699582f, 104.539366f,
+ 125.856872f, 112.912022f,
+ 130.392311f, 122.949849f,
+ 131.945283f, 133.854731f,
+ 130.392311f, 144.759613f,
+ 125.856872f, 154.797439f,
+ 118.699582f, 163.170096f,
+ 109.489523f, 169.211866f,
+ 98.958994f, 172.442364f,
+ 87.945283f, 172.604731f,
+ 72.507313f, 172.672927f,
+ 57.678920f, 168.377071f,
+ 44.668135f, 160.067134f,
+ 34.534908f, 148.420104f,
+ 28.104767f, 134.384831f,
+ 25.901557f, 119.104731f,
+ 28.104767f, 103.824631f,
+ 34.534908f, 89.789358f,
+ 44.668135f, 78.142327f,
+ 57.678920f, 69.832390f,
+ 72.507313f, 65.536534f,
+ 87.945283f, 65.604731f,
+ 106.918117f, 65.688542f,
+ 125.141795f, 60.409056f,
+ 141.131686f, 50.196376f,
+ 153.585137f, 35.882502f,
+ 161.487600f, 18.633545f,
+ 164.195283f, -0.145269f,
+ 161.487600f, -18.924084f,
+ 153.585137f, -36.173040f,
+ 141.131686f, -50.486914f,
+ 125.141795f, -60.699594f,
+ 106.918117f, -65.979081f,
+ 87.945283f, -65.895269f,
+ 80f, -65.895269f,
+ 60f, -65.895269f,
+ 40f, -65.895269f,
+ 20f, -65.895269f,
+ 0f, -65.895269f,
+ -20f, -65.895269f,
+ -40f, -65.895269f,
+ -60f, -65.895269f,
+ -80f, -65.895269f,
+ -87.945283f, -65.895269f,
+ -106.918117f, -65.979081f,
+ -125.141795f, -60.699594f,
+ -141.131686f, -50.486914f,
+ -153.585137f, -36.173040f,
+ -161.487600f, -18.924084f,
+ -164.195283f, -0.145269f,
+ -161.487600f, 18.633545f,
+ -153.585137f, 35.882502f,
+ -141.131686f, 50.196376f,
+ -125.141795f, 60.409056f,
+ -106.918117f, 65.688542f,
+ -87.945283f, 65.604731f,
+ -72.507313f, 65.536534f,
+ -57.678920f, 69.832390f,
+ -44.668135f, 78.142327f,
+ -34.534908f, 89.789358f,
+ -28.104767f, 103.824631f,
+ -25.901557f, 119.104731f,
+ -28.104767f, 134.384831f,
+ -34.534908f, 148.420104f,
+ -44.668135f, 160.067134f,
+ -57.678920f, 168.377071f,
+ -72.507313f, 172.672927f,
+ -87.945283f, 172.604731f,
+ -98.958994f, 172.442364f,
+ -109.489523f, 169.211866f,
+ -118.699582f, 163.170096f,
+ -125.856872f, 154.797439f,
+ -130.392311f, 144.759613f,
+ -131.945283f, 133.854731f,
+ -130.392311f, 122.949849f,
+ -125.856872f, 112.912022f,
+ -118.699582f, 104.539366f,
+ -109.489523f, 98.497596f,
+ -98.958994f, 95.267098f,
+ -87.945283f, 95.104731f,
+ -84.371773f, 95.771023f,
+ -80.898574f, 96.843781f,
+ -77.571757f, 98.308777f,
+ -74.435452f, 100.146577f,
+ -71.531259f, 102.332803f,
+ -68.897703f, 104.838457f,
+ -66.569716f, 107.630302f,
+ -64.578177f, 110.671304f,
+ -62.949505f, 113.921127f,
+ -61.705303f, 117.336662f,
+ -60.862074f, 120.872604f,
+ -60.431003f, 124.482050f
+ };
+
+
+ mTriangleOffsets = new int[64];
+ mTriangleOffsetsTex = new float[64];
+
+ mTriangleOffsets[0] = 0;
+ mTriangleOffsetsCount = 1;
+
+ Vertex t = new Vertex();
+ t.nxyz(1, 0, 0);
+ int count = vtx.length / 2;
+
+ SimpleMesh.TriangleMeshBuilder tm = new SimpleMesh.TriangleMeshBuilder(
+ rs, 3,
+ SimpleMesh.TriangleMeshBuilder.NORMAL | SimpleMesh.TriangleMeshBuilder.TEXTURE_0);
+
+ float runningS = 0;
+ for (int ct=0; ct < (count-1); ct++) {
+ t.x = -vtx[ct*2] / 100.f;
+ t.z = vtx[ct*2+1] / 100.f;
+ t.s = runningS;
+ t.nx = (vtx[ct*2+3] - vtx[ct*2 +1]);
+ t.ny = (vtx[ct*2+2] - vtx[ct*2 ]);
+ float len = (float)java.lang.Math.sqrt(t.nx * t.nx + t.ny * t.ny);
+ runningS += len / 100;
+ t.nx /= len;
+ t.ny /= len;
+ t.y = -0.5f;
+ t.t = 0;
+ tm.setNormal(t.nx, t.ny, t.nz);
+ tm.setTexture(t.s, t.t);
+ tm.addVertex(t.x, t.y, t.z);
+ //android.util.Log.e("rs", "vtx x="+t.x+" y="+t.y+" z="+t.z+" s="+t.s+" t="+t.t);
+ t.y = .5f;
+ t.t = 1;
+ tm.setTexture(t.s, t.t);
+ tm.addVertex(t.x, t.y, t.z);
+ //android.util.Log.e("rs", "vtx x="+t.x+" y="+t.y+" z="+t.z+" s="+t.s+" t="+t.t);
+
+ if((runningS*2) > mTriangleOffsetsCount) {
+ mTriangleOffsets[mTriangleOffsetsCount] = ct*2 * 3;
+ mTriangleOffsetsTex[mTriangleOffsetsCount] = t.s;
+ mTriangleOffsetsCount ++;
+ }
+ }
+
+ count = (count * 2 - 2);
+ for (int ct=0; ct < (count-2); ct+= 2) {
+ tm.addTriangle(ct, ct+1, ct+2);
+ tm.addTriangle(ct+1, ct+3, ct+2);
+ }
+ return tm.create();
+ }
+
+
+}
+
diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java
new file mode 100644
index 0000000..1c5b2bc
--- /dev/null
+++ b/libs/rs/java/Film/src/com/android/film/FilmView.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.film;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class FilmView extends RSSurfaceView {
+
+ public FilmView(Context context) {
+ super(context);
+
+ //setFocusable(true);
+ }
+
+ private RenderScript mRS;
+ private FilmRS mRender;
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+
+ mRS = createRenderScript(true);
+ mRender = new FilmRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ // break point at here
+ // this method doesn't work when 'extends View' include 'extends ScrollView'.
+ return super.onKeyDown(keyCode, event);
+ }
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev)
+ {
+ boolean ret = true;
+ int act = ev.getAction();
+ if (act == ev.ACTION_UP) {
+ ret = false;
+ }
+ mRender.setFilmStripPosition((int)ev.getX(), (int)ev.getY() / 5);
+ return ret;
+ }
+}
+
+
diff --git a/libs/rs/java/Fountain/Android.mk b/libs/rs/java/Fountain/Android.mk
new file mode 100644
index 0000000..b6a9f10
--- /dev/null
+++ b/libs/rs/java/Fountain/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := Fountain
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Fountain/AndroidManifest.xml b/libs/rs/java/Fountain/AndroidManifest.xml
new file mode 100644
index 0000000..1185930
--- /dev/null
+++ b/libs/rs/java/Fountain/AndroidManifest.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.fountain">
+ <application android:label="Fountain">
+ <activity android:name="Fountain">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png b/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png
new file mode 100755
index 0000000..e91bfb4
--- /dev/null
+++ b/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png
Binary files differ
diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c
new file mode 100644
index 0000000..f218f9b
--- /dev/null
+++ b/libs/rs/java/Fountain/res/raw/fountain.c
@@ -0,0 +1,54 @@
+// Fountain test script
+#pragma version(1)
+
+int newPart = 0;
+
+int main(int launchID) {
+ int ct;
+ int count = Control->count;
+ int rate = Control->rate;
+ float height = getHeight();
+ struct point_s * p = (struct point_s *)point;
+
+ if (rate) {
+ float rMax = ((float)rate) * 0.005f;
+ int x = Control->x;
+ int y = Control->y;
+ char r = Control->r * 255.f;
+ char g = Control->g * 255.f;
+ char b = Control->b * 255.f;
+ struct point_s * np = &p[newPart];
+
+ while (rate--) {
+ vec2Rand((float *)np, rMax);
+ np->x = x;
+ np->y = y;
+ np->r = r;
+ np->g = g;
+ np->b = b;
+ np->a = 0xf0;
+ newPart++;
+ np++;
+ if (newPart >= count) {
+ newPart = 0;
+ np = &p[newPart];
+ }
+ }
+ }
+
+ for (ct=0; ct < count; ct++) {
+ float dy = p->dy + 0.15f;
+ float posy = p->y + dy;
+ if ((posy > height) && (dy > 0)) {
+ dy *= -0.3f;
+ }
+ p->dy = dy;
+ p->x += p->dx;
+ p->y = posy;
+ p++;
+ }
+
+ uploadToBufferObject(NAMED_PartBuffer);
+ drawSimpleMesh(NAMED_PartMesh);
+ return 1;
+}
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
new file mode 100644
index 0000000..9ae3e67
--- /dev/null
+++ b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fountain;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class Fountain extends Activity {
+ //EventListener mListener = new EventListener();
+
+ private static final String LOG_TAG = "libRS_jni";
+ private static final boolean DEBUG = false;
+ private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+ private FountainView mView;
+
+ // get the current looper (from your Activity UI thread for instance
+
+
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Create our Preview view and set it as the content of our
+ // Activity
+ mView = new FountainView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ Log.e("rs", "onResume");
+
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ Log.e("rs", "onPause");
+
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.onPause();
+
+
+
+ //Runtime.getRuntime().exit(0);
+ }
+
+
+ static void log(String message) {
+ if (LOG_ENABLED) {
+ Log.v(LOG_TAG, message);
+ }
+ }
+
+
+}
+
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
new file mode 100644
index 0000000..f4f9b0c
--- /dev/null
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fountain;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+
+public class FountainRS {
+ public static final int PART_COUNT = 20000;
+
+ static class SomeData {
+ public int x;
+ public int y;
+ public int rate;
+ public int count;
+ public float r;
+ public float g;
+ public float b;
+ }
+
+ public FountainRS() {
+ }
+
+ public void init(RenderScript rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ initRS();
+ }
+
+ public void newTouchPosition(int x, int y, int rate) {
+ if (mSD.rate == 0) {
+ mSD.r = ((x & 0x1) != 0) ? 0.f : 1.f;
+ mSD.g = ((x & 0x2) != 0) ? 0.f : 1.f;
+ mSD.b = ((x & 0x4) != 0) ? 0.f : 1.f;
+ if ((mSD.r + mSD.g + mSD.b) < 0.9f) {
+ mSD.r = 0.8f;
+ mSD.g = 0.5f;
+ mSD.b = 1.f;
+ }
+ }
+ mSD.rate = rate;
+ mSD.x = x;
+ mSD.y = y;
+ mIntAlloc.data(mSD);
+ }
+
+
+ /////////////////////////////////////////
+
+ private Resources mRes;
+
+ private RenderScript mRS;
+ private Allocation mIntAlloc;
+ private SimpleMesh mSM;
+ private SomeData mSD;
+ private Type mSDType;
+
+ private void initRS() {
+ mSD = new SomeData();
+ mSDType = Type.createFromClass(mRS, SomeData.class, 1, "SomeData");
+ mIntAlloc = Allocation.createTyped(mRS, mSDType);
+ mSD.count = PART_COUNT;
+ mIntAlloc.data(mSD);
+
+ Element.Builder eb = new Element.Builder(mRS);
+ eb.addFloat(Element.DataKind.USER, "dx");
+ eb.addFloat(Element.DataKind.USER, "dy");
+ eb.addFloatXY("");
+ eb.addUNorm8RGBA("");
+ Element primElement = eb.create();
+
+
+ SimpleMesh.Builder smb = new SimpleMesh.Builder(mRS);
+ int vtxSlot = smb.addVertexType(primElement, PART_COUNT);
+ smb.setPrimitive(Primitive.POINT);
+ mSM = smb.create();
+ mSM.setName("PartMesh");
+
+ Allocation partAlloc = mSM.createVertexAllocation(vtxSlot);
+ partAlloc.setName("PartBuffer");
+ mSM.bindVertexAllocation(partAlloc, 0);
+
+ // All setup of named objects should be done by this point
+ // because we are about to compile the script.
+ ScriptC.Builder sb = new ScriptC.Builder(mRS);
+ sb.setScript(mRes, R.raw.fountain);
+ sb.setRoot(true);
+ sb.setType(mSDType, "Control", 0);
+ sb.setType(mSM.getVertexType(0), "point", 1);
+ Script script = sb.create();
+ script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ script.bindAllocation(mIntAlloc, 0);
+ script.bindAllocation(partAlloc, 1);
+ mRS.contextBindRootScript(script);
+ }
+
+}
+
+
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
new file mode 100644
index 0000000..cda005e
--- /dev/null
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fountain;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class FountainView extends RSSurfaceView {
+
+ public FountainView(Context context) {
+ super(context);
+ //setFocusable(true);
+ }
+
+ private RenderScript mRS;
+ private FountainRS mRender;
+
+ private void destroyRS() {
+ if(mRS != null) {
+ mRS = null;
+ destroyRenderScript();
+ }
+ java.lang.System.gc();
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+ destroyRS();
+ mRS = createRenderScript(false, true);
+ mRender = new FountainRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ // Surface will be destroyed when we return
+ destroyRS();
+ }
+
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev)
+ {
+ int act = ev.getAction();
+ if (act == ev.ACTION_UP) {
+ mRender.newTouchPosition(0, 0, 0);
+ return false;
+ }
+ float rate = (ev.getPressure() * 50.f);
+ rate *= rate;
+ if(rate > 2000.f) {
+ rate = 2000.f;
+ }
+ mRender.newTouchPosition((int)ev.getX(), (int)ev.getY(), (int)rate);
+ return true;
+ }
+}
+
+
diff --git a/libs/rs/java/ImageProcessing/Android.mk b/libs/rs/java/ImageProcessing/Android.mk
new file mode 100644
index 0000000..5a844d5
--- /dev/null
+++ b/libs/rs/java/ImageProcessing/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := ImageProcessing
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/ImageProcessing/AndroidManifest.xml b/libs/rs/java/ImageProcessing/AndroidManifest.xml
new file mode 100644
index 0000000..b48d208
--- /dev/null
+++ b/libs/rs/java/ImageProcessing/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rs.image">
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application android:label="Image Processing">
+ <activity android:name="ImageProcessingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg b/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg
new file mode 100644
index 0000000..81a87b1
--- /dev/null
+++ b/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg
Binary files differ
diff --git a/libs/rs/java/ImageProcessing/res/layout/main.xml b/libs/rs/java/ImageProcessing/res/layout/main.xml
new file mode 100644
index 0000000..0872cf2a
--- /dev/null
+++ b/libs/rs/java/ImageProcessing/res/layout/main.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <SurfaceView
+ android:id="@+id/surface"
+ android:layout_width="1dip"
+ android:layout_height="1dip" />
+
+ <ImageView
+ android:id="@+id/display"
+ android:layout_width="320dip"
+ android:layout_height="266dip" />
+
+ <SeekBar
+ android:id="@+id/threshold"
+ android:layout_marginBottom="10dip"
+ android:layout_marginLeft="10dip"
+ android:layout_marginRight="10dip"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom" />
+
+</merge>
\ No newline at end of file
diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
new file mode 100644
index 0000000..dec5587
--- /dev/null
+++ b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
@@ -0,0 +1,44 @@
+struct color_s {
+ char b;
+ char g;
+ char r;
+ char a;
+};
+
+void filter(struct color_s *in, struct color_s *out, struct vec3_s *luminanceVector) {
+ struct vec3_s pixel;
+ pixel.x = (in->r & 0xFF) / 255.0f;
+ pixel.y = (in->g & 0xFF) / 255.0f;
+ pixel.z = (in->b & 0xFF) / 255.0f;
+
+ float luminance = vec3Dot(luminanceVector, &pixel);
+ luminance = maxf(0.0f, luminance - Params->threshold);
+ vec3Scale(&pixel, signf(luminance));
+
+ out->a = in->a;
+ out->r = pixel.x * 255.0f;
+ out->g = pixel.y * 255.0f;
+ out->b = pixel.z * 255.0f;
+}
+
+void main() {
+ struct color_s *in = (struct color_s *) InPixel;
+ struct color_s *out = (struct color_s *) OutPixel;
+
+ struct vec3_s luminanceVector;
+ luminanceVector.x = 0.2125f;
+ luminanceVector.y = 0.7154f;
+ luminanceVector.z = 0.0721f;
+
+ int count = Params->inWidth * Params->inHeight;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ filter(in, out, &luminanceVector);
+
+ in++;
+ out++;
+ }
+
+ sendToClient(&count, 1, 4, 0);
+}
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
new file mode 100644
index 0000000..b1facfc
--- /dev/null
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.renderscript.ScriptC;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+
+public class ImageProcessingActivity extends Activity implements SurfaceHolder.Callback {
+ private Bitmap mBitmap;
+ private Params mParams;
+ private Script.Invokable mInvokable;
+ private int[] mOutData;
+
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript mRS;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private Type mParamsType;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private Allocation mParamsAllocation;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private Type mPixelType;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private Allocation mInPixelsAllocation;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private Allocation mOutPixelsAllocation;
+
+ private SurfaceView mSurfaceView;
+ private ImageView mDisplayView;
+
+ static class Params {
+ public int inWidth;
+ public int outWidth;
+ public int inHeight;
+ public int outHeight;
+
+ public float threshold;
+ }
+
+ static class Pixel {
+ public byte a;
+ public byte r;
+ public byte g;
+ public byte b;
+ }
+
+ class FilterCallback extends RenderScript.RSMessage {
+ private Runnable mAction = new Runnable() {
+ public void run() {
+ mOutPixelsAllocation.readData(mOutData);
+ mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0,
+ mParams.outWidth, mParams.outHeight);
+ mDisplayView.invalidate();
+ }
+ };
+
+ @Override
+ public void run() {
+ mSurfaceView.removeCallbacks(mAction);
+ mSurfaceView.post(mAction);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ mBitmap = loadBitmap(R.drawable.data);
+
+ mSurfaceView = (SurfaceView) findViewById(R.id.surface);
+ mSurfaceView.getHolder().addCallback(this);
+
+ mDisplayView = (ImageView) findViewById(R.id.display);
+ mDisplayView.setImageBitmap(mBitmap);
+
+ ((SeekBar) findViewById(R.id.threshold)).setOnSeekBarChangeListener(
+ new SeekBar.OnSeekBarChangeListener() {
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ mParams.threshold = progress / 100.0f;
+ mParamsAllocation.data(mParams);
+ mInvokable.execute();
+ }
+ }
+
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+ });
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ mParams = createParams();
+ mInvokable = createScript();
+
+ mInvokable.execute();
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ }
+
+ private Script.Invokable createScript() {
+ mRS = new RenderScript(mSurfaceView.getHolder().getSurface(), false, false);
+ mRS.mMessageCallback = new FilterCallback();
+
+ mParamsType = Type.createFromClass(mRS, Params.class, 1, "Parameters");
+ mParamsAllocation = Allocation.createTyped(mRS, mParamsType);
+ mParamsAllocation.data(mParams);
+
+ final int pixelCount = mParams.inWidth * mParams.inHeight;
+
+ mPixelType = Type.createFromClass(mRS, Pixel.class, 1, "Pixel");
+ mInPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS),
+ pixelCount);
+ mOutPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS),
+ pixelCount);
+
+ final int[] data = new int[pixelCount];
+ mBitmap.getPixels(data, 0, mParams.inWidth, 0, 0, mParams.inWidth, mParams.inHeight);
+ mInPixelsAllocation.data(data);
+
+ mOutData = new int[pixelCount];
+ mOutPixelsAllocation.data(mOutData);
+
+ ScriptC.Builder sb = new ScriptC.Builder(mRS);
+ sb.setType(mParamsType, "Params", 0);
+ sb.setType(mPixelType, "InPixel", 1);
+ sb.setType(mPixelType, "OutPixel", 2);
+ sb.setType(true, 2);
+ Script.Invokable invokable = sb.addInvokable("main");
+ sb.setScript(getResources(), R.raw.threshold);
+ sb.setRoot(true);
+
+ ScriptC script = sb.create();
+ script.bindAllocation(mParamsAllocation, 0);
+ script.bindAllocation(mInPixelsAllocation, 1);
+ script.bindAllocation(mOutPixelsAllocation, 2);
+
+ return invokable;
+ }
+
+ private Params createParams() {
+ final Params params = new Params();
+ params.inWidth = params.outWidth = mBitmap.getWidth();
+ params.inHeight = params.outHeight = mBitmap.getHeight();
+ params.threshold = 0.5f;
+ return params;
+ }
+
+ private Bitmap loadBitmap(int resource) {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options));
+ }
+
+ private static Bitmap copyBitmap(Bitmap source) {
+ Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
+ Canvas c = new Canvas(b);
+ c.drawBitmap(source, 0, 0, null);
+ source.recycle();
+ return b;
+ }
+}
diff --git a/libs/rs/java/Rollo/Android.mk b/libs/rs/java/Rollo/Android.mk
new file mode 100644
index 0000000..5a4957c
--- /dev/null
+++ b/libs/rs/java/Rollo/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := Rollo
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Rollo/AndroidManifest.xml b/libs/rs/java/Rollo/AndroidManifest.xml
new file mode 100644
index 0000000..12cb28f
--- /dev/null
+++ b/libs/rs/java/Rollo/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rollo">
+ <application
+ android:label="Rollo"
+ android:icon="@drawable/test_pattern">
+ <activity android:name="Rollo"
+ android:theme="@android:style/Theme.Translucent"
+ android:icon="@drawable/test_pattern">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/rs/java/Rollo/res/drawable/test_pattern.png b/libs/rs/java/Rollo/res/drawable/test_pattern.png
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/libs/rs/java/Rollo/res/drawable/test_pattern.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/browser.png b/libs/rs/java/Rollo/res/raw/browser.png
new file mode 100644
index 0000000..513f0be
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/browser.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/calendar.png b/libs/rs/java/Rollo/res/raw/calendar.png
new file mode 100644
index 0000000..030ae73
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/calendar.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/g1155.png b/libs/rs/java/Rollo/res/raw/g1155.png
new file mode 100644
index 0000000..68e1843
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/g1155.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/g2140.png b/libs/rs/java/Rollo/res/raw/g2140.png
new file mode 100644
index 0000000..8c4e853
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/g2140.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/maps.png b/libs/rs/java/Rollo/res/raw/maps.png
new file mode 100644
index 0000000..fd5fc39
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/maps.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/market.png b/libs/rs/java/Rollo/res/raw/market.png
new file mode 100644
index 0000000..83b6910
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/market.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path1920.png b/libs/rs/java/Rollo/res/raw/path1920.png
new file mode 100644
index 0000000..3510665
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path1920.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path1927.png b/libs/rs/java/Rollo/res/raw/path1927.png
new file mode 100644
index 0000000..fccc846
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path1927.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path3099.png b/libs/rs/java/Rollo/res/raw/path3099.png
new file mode 100644
index 0000000..527ebf6
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path3099.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path3950.png b/libs/rs/java/Rollo/res/raw/path3950.png
new file mode 100644
index 0000000..59a646a
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path3950.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path431.png b/libs/rs/java/Rollo/res/raw/path431.png
new file mode 100644
index 0000000..5d2ed75
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path431.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path4481.png b/libs/rs/java/Rollo/res/raw/path4481.png
new file mode 100644
index 0000000..78be0fc
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path4481.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path5168.png b/libs/rs/java/Rollo/res/raw/path5168.png
new file mode 100644
index 0000000..a7c3a19
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path5168.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path676.png b/libs/rs/java/Rollo/res/raw/path676.png
new file mode 100644
index 0000000..2099690
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path676.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path754.png b/libs/rs/java/Rollo/res/raw/path754.png
new file mode 100644
index 0000000..88aed5b
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path754.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/path815.png b/libs/rs/java/Rollo/res/raw/path815.png
new file mode 100644
index 0000000..407570f
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/path815.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/photos.png b/libs/rs/java/Rollo/res/raw/photos.png
new file mode 100644
index 0000000..1ed8f1e
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/photos.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/polygon2408.png b/libs/rs/java/Rollo/res/raw/polygon2408.png
new file mode 100644
index 0000000..4413954
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/polygon2408.png
Binary files differ
diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c
new file mode 100644
index 0000000..b31be81
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/rollo.c
@@ -0,0 +1,184 @@
+#pragma version(1)
+#pragma stateVertex(PV)
+#pragma stateFragment(PF)
+#pragma stateStore(PFS)
+
+// Scratch buffer layout
+#define SCRATCH_FADE 0
+#define SCRATCH_ZOOM 1
+#define SCRATCH_ROT 2
+
+//#define STATE_POS_X 0
+#define STATE_DONE 1
+//#define STATE_PRESSURE 2
+#define STATE_ZOOM 3
+//#define STATE_WARP 4
+#define STATE_ORIENTATION 5
+#define STATE_SELECTION 6
+#define STATE_FIRST_VISIBLE 7
+#define STATE_COUNT 8
+#define STATE_TOUCH 9
+
+
+float filter(float val, float target, float str)
+{
+ float delta = (target - val);
+ return val + delta * str;
+}
+
+int main(void* con, int ft, int launchID)
+{
+ int rowCount;
+ int row;
+ int col;
+ int imageID;
+ int done = loadI32(0, STATE_DONE);
+ int selectedID = loadI32(0, STATE_SELECTION);
+
+ float f = loadF(2, 0);
+
+ pfClearColor(0.0f, 0.0f, 0.0f, f);
+ if (done) {
+ if (f > 0.02f) {
+ //f = f - 0.02f;
+ //storeF(2, 0, f);
+ }
+ } else {
+ if (f < 0.8f) {
+ f = f + 0.02f;
+ storeF(2, 0, f);
+ }
+ }
+
+ float touchCut = 1.f;
+ if (loadI32(0, STATE_TOUCH)) {
+ touchCut = 4.f;
+ }
+
+
+ float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f;
+ float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut);
+ storeF(2, SCRATCH_ZOOM, zoom);
+
+ float targetRot = loadI32(0, STATE_FIRST_VISIBLE) / 180.0f * 3.14f;
+ targetRot = targetRot * 0.80f - .12f;
+ float drawRot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut);
+ storeF(2, SCRATCH_ROT, drawRot);
+
+ float diam = 8.f;
+ float scale = 1.0f / zoom;
+
+ // Bug makes 1.0f alpha fail.
+ color(1.0f, 1.0f, 1.0f, 0.99f);
+
+ float rot = drawRot * scale;
+ float rotStep = 16.0f / 180.0f * 3.14f * scale;
+ rowCount = 4;
+ int index = 0;
+ int iconCount = loadI32(0, STATE_COUNT);
+ while (iconCount) {
+ float tmpSin = sinf(rot);
+ float tmpCos = cosf(rot);
+ //debugF("rot", rot);
+
+ float tx1 = tmpSin * diam - (tmpCos * scale * 0.9f);
+ float tx2 = tx1 + (tmpCos * scale * 1.8f);
+ float tz1 = tmpCos * diam + (tmpSin * scale * 0.9f);
+ float tz2 = tz1 - (tmpSin * scale * 1.8f);
+
+ int y;
+ for (y = rowCount -1; (y >= 0) && iconCount; y--) {
+ float ty1 = ((y * 3.1f) - 5.f) * scale;
+ float ty2 = ty1 + scale * 1.8f;
+ bindTexture(NAMED_PF, 0, loadI32(1, index));
+ drawQuad(tx1, ty1, tz1,
+ tx2, ty1, tz2,
+ tx2, ty2, tz2,
+ tx1, ty2, tz1);
+
+ iconCount--;
+ index++;
+ }
+ rot = rot + rotStep;
+ }
+
+ if ((zoom < 1.1f) && (zoom > 0.9f)) {
+ bindProgramVertex(NAMED_PVOrtho);
+ bindProgramFragment(NAMED_PFText);
+ bindProgramStore(NAMED_PFSText);
+
+ rot = drawRot * scale;
+ index = 0;
+ iconCount = loadI32(0, STATE_COUNT);
+ while (iconCount) {
+ int y;
+
+ float tx = 240.f + floorf(sinf(rot) * 430.f) - 64.f + 16.f;
+
+ float alpha = 2.4f - (fabsf(tx - 240.f + 48.f) / 76.f);
+ if (alpha > 0.99f) {
+ alpha = 0.99f;
+ }
+ alpha = alpha * (1.f - (fabsf(zoom - 1.f) * 10.f));
+
+ tx = tx + 0.25f;
+
+ for (y = rowCount -1; (y >= 0) && iconCount; y--) {
+
+ if (alpha > 0) {
+ color(1.0f, 1.0f, 1.0f, alpha);
+
+ float ty = 605.f - y * 150.f;
+
+ ty = ty + 0.25f;
+
+ bindTexture(NAMED_PFText, 0, loadI32(3, index));
+ drawRect(tx, ty, tx + 128.f, ty + 32.f, 0.5f);
+ }
+ iconCount--;
+ index++;
+ }
+ rot = rot + rotStep;
+ }
+
+
+ bindProgramVertex(NAMED_PV);
+ bindProgramFragment(NAMED_PF);
+ bindProgramStore(NAMED_PFS);
+ }
+
+ // Draw the selected icon
+ color(1.0f, 1.0f, 1.0f, 0.9f);
+ rot = drawRot * scale;
+ index = 0;
+ iconCount = loadI32(0, STATE_COUNT);
+ while (iconCount) {
+ int y;
+ for (y = rowCount -1; (y >= 0) && iconCount; y--) {
+ if (index == selectedID) {
+
+ float tmpSin = sinf(rot) * scale;
+ float tmpCos = cosf(rot) * scale;
+ float tx1 = tmpSin * diam * 0.9f - tmpCos * 2.f;
+ float tx2 = tx1 + (tmpCos * 4.f);
+ float tz1 = tmpCos * diam * 0.9f + tmpSin * 2.f;
+ float tz2 = tz1 - (tmpSin * 4.f);
+
+ float ty1 = ((y * 3.1f) - 4.5f) * scale;
+ float ty2 = ty1 + scale * 4.f;
+ bindTexture(NAMED_PF, 0, loadI32(1, index));
+ drawQuad(tx1, ty1, tz1,
+ tx2, ty1, tz2,
+ tx2, ty2, tz2,
+ tx1, ty2, tz1);
+ }
+ iconCount--;
+ index++;
+ }
+ rot = rot + rotStep;
+ }
+
+ return 1;
+}
+
+
diff --git a/libs/rs/java/Rollo/res/raw/rollo2.c b/libs/rs/java/Rollo/res/raw/rollo2.c
new file mode 100644
index 0000000..5b5cb2d
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/rollo2.c
@@ -0,0 +1,155 @@
+#pragma version(1)
+#pragma stateVertex(PV)
+#pragma stateFragment(PF)
+#pragma stateStore(PFS)
+
+// Scratch buffer layout
+#define SCRATCH_FADE 0
+#define SCRATCH_ZOOM 1
+#define SCRATCH_ROT 2
+
+//#define STATE_POS_X 0
+#define STATE_DONE 1
+//#define STATE_PRESSURE 2
+#define STATE_ZOOM 3
+//#define STATE_WARP 4
+#define STATE_ORIENTATION 5
+#define STATE_SELECTION 6
+#define STATE_FIRST_VISIBLE 7
+#define STATE_COUNT 8
+#define STATE_TOUCH 9
+
+float filter(float val, float target, float str)
+{
+ float delta = (target - val);
+ return val + delta * str;
+}
+
+
+int main(void* con, int ft, int launchID)
+{
+ int rowCount;
+ int imageID;
+ int done = loadI32(0, STATE_DONE);
+ int selectedID = loadI32(0, STATE_SELECTION);
+ int iconCount = loadI32(0, STATE_COUNT);
+
+ float f = loadF(2, 0);
+
+ float iconSize = 1.f;
+ float iconSpacing = 0.2f;
+ float z = 4.f;
+
+ pfClearColor(0.0f, 0.0f, 0.0f, f);
+ if (done) {
+ } else {
+ if (f < 0.8f) {
+ f = f + 0.02f;
+ storeF(2, 0, f);
+ }
+ }
+
+ float touchCut = 1.f;
+ if (loadI32(0, STATE_TOUCH)) {
+ touchCut = 5.f;
+ }
+
+
+ float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f;
+ float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut);
+ storeF(2, SCRATCH_ZOOM, zoom);
+
+ float targetPos = loadI32(0, STATE_FIRST_VISIBLE) / (-20.0f);
+ float pos = filter(loadF(2, SCRATCH_ROT), targetPos, 0.1f * touchCut);
+ storeF(2, SCRATCH_ROT, pos);
+ pos = pos - 1.f;
+
+ color(1.0f, 1.0f, 1.0f, 1.0f);
+
+
+ // Draw flat icons first
+ int index = ((int)pos) * 4;
+ int row;
+ int col;
+ float xoffset = -0.3f;
+ float gridSize = iconSize * 4.f + iconSpacing * 3.f;
+ float yoffset = (pos - ((int)pos));
+ for (row = 0; row < 4; row ++) {
+ float ty1 = (gridSize / 2.f) - ((float)row - yoffset) * (iconSize + iconSpacing) - iconSize;
+ float ty2 = ty1 + iconSize;
+
+ for (col = 0; (col < 4) && (index < iconCount); col ++) {
+ if (index >= 0) {
+ bindTexture(NAMED_PF, 0, loadI32(1, index));
+ float fcol = col;
+ float tx1 = xoffset + (-gridSize / 2.f) + (fcol * (iconSize + iconSpacing));
+ float tx2 = tx1 + iconSize;
+
+ drawQuad(tx1, ty1, z,
+ tx2, ty1, z,
+ tx2, ty2, z,
+ tx1, ty2, z);
+ }
+ index++;
+ }
+ }
+
+ // bottom roller
+ {
+ float roll = (1.f - yoffset) * 0.5f * 3.14f;
+ float tmpSin = sinf(roll);
+ float tmpCos = cosf(roll);
+
+ for (col = 0; (col < 4) && (index < iconCount) && (index >= 0); col ++) {
+ float ty2 = (gridSize / 2.f) - ((float)row - yoffset) * (iconSize + iconSpacing);
+ float ty1 = ty2 - tmpCos * iconSize;
+
+ float tz1 = z + tmpSin * iconSize;
+ float tz2 = z;
+
+ float tx1 = xoffset + (-gridSize / 2.f) + ((float)col * (iconSize + iconSpacing));
+ float tx2 = tx1 + iconSize;
+
+ bindTexture(NAMED_PF, 0, loadI32(1, index));
+ drawQuad(tx1, ty1, tz1,
+ tx2, ty1, tz1,
+ tx2, ty2, tz2,
+ tx1, ty2, tz2);
+ index++;
+ }
+ }
+
+ // Top roller
+ {
+ index = (((int)pos) * 4) - 4;
+ float roll = yoffset * 0.5f * 3.14f;
+ float tmpSin = sinf(roll);
+ float tmpCos = cosf(roll);
+
+ for (col = 0; (col < 4) && (index < iconCount) && (index >= 0); col ++) {
+ float ty1 = (gridSize / 2.f) - ((float)-1.f - yoffset) * (iconSize + iconSpacing) - iconSize;
+ float ty2 = ty1 + tmpCos * iconSize;
+
+ float tz1 = z;
+ float tz2 = z + tmpSin * iconSize;
+
+ float tx1 = xoffset + (-gridSize / 2.f) + ((float)col * (iconSize + iconSpacing));
+ float tx2 = tx1 + iconSize;
+
+ bindTexture(NAMED_PF, 0, loadI32(1, index));
+ drawQuad(tx1, ty1, tz1,
+ tx2, ty1, tz1,
+ tx2, ty2, tz2,
+ tx1, ty2, tz2);
+ index++;
+ }
+ }
+
+
+
+
+ return 1;
+}
+
+
+
diff --git a/libs/rs/java/Rollo/res/raw/settings.png b/libs/rs/java/Rollo/res/raw/settings.png
new file mode 100644
index 0000000..dd2cd95
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/settings.png
Binary files differ
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java
new file mode 100644
index 0000000..400d801
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rollo;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class Rollo extends Activity {
+ //EventListener mListener = new EventListener();
+
+ private static final String LOG_TAG = "libRS_jni";
+ private static final boolean DEBUG = false;
+ private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+ private RolloView mView;
+
+ // get the current looper (from your Activity UI thread for instance
+
+
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Create our Preview view and set it as the content of our
+ // Activity
+ mView = new RolloView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.onPause();
+
+ Runtime.getRuntime().exit(0);
+ }
+
+
+ static void log(String message) {
+ if (LOG_ENABLED) {
+ Log.v(LOG_TAG, message);
+ }
+ }
+
+
+}
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
new file mode 100644
index 0000000..ff89bc3
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rollo;
+
+import java.io.Writer;
+
+import android.renderscript.RenderScript;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.renderscript.Allocation;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.Sampler;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.Typeface;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+public class RolloRS {
+ //public static final int STATE_SELECTED_ID = 0;
+ public static final int STATE_DONE = 1;
+ //public static final int STATE_PRESSURE = 2;
+ public static final int STATE_ZOOM = 3;
+ //public static final int STATE_WARP = 4;
+ public static final int STATE_ORIENTATION = 5;
+ public static final int STATE_SELECTION = 6;
+ public static final int STATE_FIRST_VISIBLE = 7;
+ public static final int STATE_COUNT = 8;
+ public static final int STATE_TOUCH = 9;
+
+
+ public RolloRS() {
+ }
+
+ public void init(RenderScript rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ mWidth = width;
+ mHeight = height;
+ initNamed();
+ initRS();
+ }
+
+ public void setPosition(float column) {
+ mAllocStateBuf[STATE_FIRST_VISIBLE] = (int)(column * (-20));
+ mAllocState.data(mAllocStateBuf);
+ }
+
+ public void setTouch(boolean touch) {
+ mAllocStateBuf[STATE_TOUCH] = touch ? 1 : 0;
+ mAllocState.data(mAllocStateBuf);
+ }
+
+ public void setZoom(float z) {
+ //Log.e("rs", "zoom " + Float.toString(z));
+
+ mAllocStateBuf[STATE_ZOOM] = (int)(z * 1000.f);
+ mAllocState.data(mAllocStateBuf);
+ }
+
+ public void setSelected(int index) {
+ //Log.e("rs", "setSelected " + Integer.toString(index));
+
+ mAllocStateBuf[STATE_SELECTION] = index;
+ mAllocStateBuf[STATE_DONE] = 1;
+ mAllocState.data(mAllocStateBuf);
+ }
+
+ private int mWidth;
+ private int mHeight;
+
+ private Resources mRes;
+ private RenderScript mRS;
+ private Script mScript;
+ private Sampler mSampler;
+ private Sampler mSamplerText;
+ private ProgramStore mPSBackground;
+ private ProgramStore mPSText;
+ private ProgramFragment mPFImages;
+ private ProgramFragment mPFText;
+ private ProgramVertex mPV;
+ private ProgramVertex.MatrixAllocation mPVAlloc;
+ private ProgramVertex mPVOrtho;
+ private ProgramVertex.MatrixAllocation mPVOrthoAlloc;
+ private Allocation[] mIcons;
+ private Allocation[] mLabels;
+
+ private int[] mAllocStateBuf;
+ private Allocation mAllocState;
+
+ private int[] mAllocIconIDBuf;
+ private Allocation mAllocIconID;
+
+ private int[] mAllocLabelIDBuf;
+ private Allocation mAllocLabelID;
+
+ private int[] mAllocScratchBuf;
+ private Allocation mAllocScratch;
+
+ private void initNamed() {
+ Sampler.Builder sb = new Sampler.Builder(mRS);
+ sb.setMin(Sampler.Value.LINEAR);//_MIP_LINEAR);
+ sb.setMag(Sampler.Value.LINEAR);
+ sb.setWrapS(Sampler.Value.CLAMP);
+ sb.setWrapT(Sampler.Value.CLAMP);
+ mSampler = sb.create();
+
+ sb.setMin(Sampler.Value.NEAREST);
+ sb.setMag(Sampler.Value.NEAREST);
+ mSamplerText = sb.create();
+
+
+ ProgramFragment.Builder bf = new ProgramFragment.Builder(mRS, null, null);
+ bf.setTexEnable(true, 0);
+ bf.setTexEnvMode(ProgramFragment.EnvMode.MODULATE, 0);
+ mPFImages = bf.create();
+ mPFImages.setName("PF");
+ mPFImages.bindSampler(mSampler, 0);
+
+ bf.setTexEnvMode(ProgramFragment.EnvMode.MODULATE, 0);
+ mPFText = bf.create();
+ mPFText.setName("PFText");
+ mPFText.bindSampler(mSamplerText, 0);
+
+ ProgramStore.Builder bs = new ProgramStore.Builder(mRS, null, null);
+ bs.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ bs.setDitherEnable(false);
+ bs.setDepthMask(true);
+ bs.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
+ ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ mPSBackground = bs.create();
+ mPSBackground.setName("PFS");
+
+ bs.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ bs.setDepthMask(false);
+ bs.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
+ ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ mPSText = bs.create();
+ mPSText.setName("PFSText");
+
+ mPVAlloc = new ProgramVertex.MatrixAllocation(mRS);
+ mPVAlloc.setupProjectionNormalized(mWidth, mHeight);
+
+ ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+ mPV = pvb.create();
+ mPV.setName("PV");
+ mPV.bindAllocation(mPVAlloc);
+
+ mPVOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
+ mPVOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+
+ pvb.setTextureMatrixEnable(true);
+ mPVOrtho = pvb.create();
+ mPVOrtho.setName("PVOrtho");
+ mPVOrtho.bindAllocation(mPVOrthoAlloc);
+
+ mRS.contextBindProgramVertex(mPV);
+
+ mAllocScratchBuf = new int[32];
+ mAllocScratch = Allocation.createSized(mRS,
+ Element.USER_I32(mRS), mAllocScratchBuf.length);
+ mAllocScratch.data(mAllocScratchBuf);
+
+ Log.e("rs", "Done loading named");
+
+
+
+ {
+ mIcons = new Allocation[29];
+ mAllocIconIDBuf = new int[mIcons.length];
+ mAllocIconID = Allocation.createSized(mRS,
+ Element.USER_I32(mRS), mAllocIconIDBuf.length);
+
+ mLabels = new Allocation[29];
+ mAllocLabelIDBuf = new int[mLabels.length];
+ mAllocLabelID = Allocation.createSized(mRS,
+ Element.USER_I32(mRS), mLabels.length);
+
+ Element ie8888 = Element.RGBA_8888(mRS);
+
+ mIcons[0] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.browser, ie8888, true);
+ mIcons[1] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.market, ie8888, true);
+ mIcons[2] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.photos, ie8888, true);
+ mIcons[3] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.settings, ie8888, true);
+ mIcons[4] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.calendar, ie8888, true);
+ mIcons[5] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.g1155, ie8888, true);
+ mIcons[6] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.g2140, ie8888, true);
+ mIcons[7] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.maps, ie8888, true);
+ mIcons[8] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path431, ie8888, true);
+ mIcons[9] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path676, ie8888, true);
+ mIcons[10] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path754, ie8888, true);
+ mIcons[11] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path815, ie8888, true);
+ mIcons[12] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path1920, ie8888, true);
+ mIcons[13] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path1927, ie8888, true);
+ mIcons[14] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path3099, ie8888, true);
+ mIcons[15] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path3950, ie8888, true);
+ mIcons[16] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path4481, ie8888, true);
+ mIcons[17] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.path5168, ie8888, true);
+ mIcons[18] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.polygon2408, ie8888, true);
+
+ mLabels[0] = makeTextBitmap("browser");
+ mLabels[1] = makeTextBitmap("market");
+ mLabels[2] = makeTextBitmap("photos");
+ mLabels[3] = makeTextBitmap("settings");
+ mLabels[4] = makeTextBitmap("calendar");
+ mLabels[5] = makeTextBitmap("g1155");
+ mLabels[6] = makeTextBitmap("g2140");
+ mLabels[7] = makeTextBitmap("maps");
+ mLabels[8] = makeTextBitmap("path431");
+ mLabels[9] = makeTextBitmap("path676");
+ mLabels[10] = makeTextBitmap("path754");
+ mLabels[11] = makeTextBitmap("path815");
+ mLabels[12] = makeTextBitmap("path1920");
+ mLabels[13] = makeTextBitmap("path1927");
+ mLabels[14] = makeTextBitmap("path3099");
+ mLabels[15] = makeTextBitmap("path3950");
+ mLabels[16] = makeTextBitmap("path4481");
+ mLabels[17] = makeTextBitmap("path5168");
+ mLabels[18] = makeTextBitmap("polygon2408");
+
+ mIcons[19] = mIcons[0];
+ mIcons[20] = mIcons[1];
+ mIcons[21] = mIcons[2];
+ mIcons[22] = mIcons[3];
+ mIcons[23] = mIcons[4];
+ mIcons[24] = mIcons[5];
+ mIcons[25] = mIcons[6];
+ mIcons[26] = mIcons[7];
+ mIcons[27] = mIcons[8];
+ mIcons[28] = mIcons[9];
+
+ mLabels[19] = mLabels[0];
+ mLabels[20] = mLabels[1];
+ mLabels[21] = mLabels[2];
+ mLabels[22] = mLabels[3];
+ mLabels[23] = mLabels[4];
+ mLabels[24] = mLabels[5];
+ mLabels[25] = mLabels[6];
+ mLabels[26] = mLabels[7];
+ mLabels[27] = mLabels[8];
+ mLabels[28] = mLabels[9];
+
+ for(int ct=0; ct < mIcons.length; ct++) {
+ mIcons[ct].uploadToTexture(0);
+ mLabels[ct].uploadToTexture(0);
+ mAllocIconIDBuf[ct] = mIcons[ct].getID();
+ mAllocLabelIDBuf[ct] = mLabels[ct].getID();
+ }
+ mAllocIconID.data(mAllocIconIDBuf);
+ mAllocLabelID.data(mAllocLabelIDBuf);
+ }
+
+ }
+
+ Allocation makeTextBitmap(String t) {
+ Bitmap b = Bitmap.createBitmap(128, 32, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(b);
+ Paint p = new Paint();
+ p.setTypeface(Typeface.DEFAULT_BOLD);
+ p.setTextSize(20);
+ p.setColor(0xffffffff);
+ c.drawText(t, 2, 26, p);
+ return Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true);
+ }
+
+
+ private void initRS() {
+ ScriptC.Builder sb = new ScriptC.Builder(mRS);
+ sb.setScript(mRes, R.raw.rollo);
+ //sb.setScript(mRes, R.raw.rollo2);
+ sb.setRoot(true);
+ mScript = sb.create();
+ mScript.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0};
+ mAllocState = Allocation.createSized(mRS,
+ Element.USER_I32(mRS), mAllocStateBuf.length);
+ mScript.bindAllocation(mAllocState, 0);
+ mScript.bindAllocation(mAllocIconID, 1);
+ mScript.bindAllocation(mAllocScratch, 2);
+ mScript.bindAllocation(mAllocLabelID, 3);
+ setPosition(0);
+ setZoom(1);
+
+ //RenderScript.File f = mRS.fileOpen("/sdcard/test.a3d");
+
+ mRS.contextBindRootScript(mScript);
+ }
+}
+
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
new file mode 100644
index 0000000..7524a0e
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rollo;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+import java.lang.Float;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.graphics.PixelFormat;
+
+
+public class RolloView extends RSSurfaceView {
+ public RolloView(Context context) {
+ super(context);
+ setFocusable(true);
+ getHolder().setFormat(PixelFormat.TRANSLUCENT);
+ }
+
+ private RenderScript mRS;
+ private RolloRS mRender;
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+
+ mRS = createRenderScript(false);
+ mRender = new RolloRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ // break point at here
+ // this method doesn't work when 'extends View' include 'extends ScrollView'.
+ return super.onKeyDown(keyCode, event);
+ }
+
+ boolean mControlMode = false;
+ boolean mZoomMode = false;
+ boolean mFlingMode = false;
+ float mFlingX = 0;
+ float mFlingY = 0;
+ float mColumn = -1;
+ float mOldColumn;
+ float mZoom = 1;
+
+ int mIconCount = 29;
+ int mRows = 4;
+ int mColumns = (mIconCount + mRows - 1) / mRows;
+
+ float mMaxZoom = ((float)mColumns) / 3.f;
+
+
+ void setColumn(boolean clamp)
+ {
+ //Log.e("rs", " col = " + Float.toString(mColumn));
+ float c = mColumn;
+ if(c > (mColumns -2)) {
+ c = (mColumns -2);
+ }
+ if(c < 0) {
+ c = 0;
+ }
+ mRender.setPosition(c);
+ if(clamp) {
+ mColumn = c;
+ }
+ }
+
+ void computeSelection(float x, float y)
+ {
+ float col = mColumn + (x - 0.5f) * 4 + 1.25f;
+ int iCol = (int)(col + 0.25f);
+
+ float row = (y / 0.8f) * mRows;
+ int iRow = (int)(row - 0.5f);
+
+ mRender.setSelected(iCol * mRows + iRow);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev)
+ {
+ boolean ret = true;
+ int act = ev.getAction();
+ if (act == ev.ACTION_UP) {
+ ret = false;
+ }
+
+ float nx = ev.getX() / getWidth();
+ float ny = ev.getY() / getHeight();
+
+ //Log.e("rs", "width=" + Float.toString(getWidth()));
+ //Log.e("rs", "height=" + Float.toString(getHeight()));
+
+ mRender.setTouch(ret);
+
+ if((ny > 0.85f) || mControlMode) {
+ mFlingMode = false;
+
+ // Projector control
+ if((nx > 0.2f) && (nx < 0.8f) || mControlMode) {
+ if(act != ev.ACTION_UP) {
+ float zoom = mMaxZoom;
+ if(mControlMode) {
+ if(!mZoomMode) {
+ zoom = 1.f;
+ }
+ float dx = nx - mFlingX;
+
+ if((ny < 0.9) && mZoomMode) {
+ zoom = mMaxZoom - ((0.9f - ny) * 10.f);
+ if(zoom < 1) {
+ zoom = 1;
+ mZoomMode = false;
+ }
+ mOldColumn = mColumn;
+ }
+ mColumn += dx * 4;// * zoom;
+ if(zoom > 1.01f) {
+ mColumn += (mZoom - zoom) * (nx - 0.5f) * 4 * zoom;
+ }
+ } else {
+ mOldColumn = mColumn;
+ mColumn = ((float)mColumns) / 2;
+ mControlMode = true;
+ mZoomMode = true;
+ }
+ mZoom = zoom;
+ mFlingX = nx;
+ mRender.setZoom(zoom);
+ if(mZoom < 1.01f) {
+ computeSelection(nx, ny);
+ }
+ } else {
+ mControlMode = false;
+ mColumn = mOldColumn;
+ mRender.setZoom(1.f);
+ mRender.setSelected(-1);
+ }
+ } else {
+ // Do something with corners here....
+ }
+ setColumn(true);
+
+ } else {
+ // icon control
+ if(act != ev.ACTION_UP) {
+ if(mFlingMode) {
+ mColumn += (mFlingX - nx) * 4;
+ setColumn(true);
+ }
+ mFlingMode = true;
+ mFlingX = nx;
+ mFlingY = ny;
+ } else {
+ mFlingMode = false;
+ mColumn = (float)(java.lang.Math.floor(mColumn * 0.25f + 0.3f) * 4.f) + 1.f;
+ setColumn(true);
+ }
+ }
+
+
+ return ret;
+ }
+
+ @Override
+ public boolean onTrackballEvent(MotionEvent ev)
+ {
+ float x = ev.getX();
+ float y = ev.getY();
+ //Float tx = new Float(x);
+ //Float ty = new Float(y);
+ //Log.e("rs", "tbe " + tx.toString() + ", " + ty.toString());
+
+
+ return true;
+ }
+
+}
+
+
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
new file mode 100644
index 0000000..865e435
--- /dev/null
+++ b/libs/rs/rs.spec
@@ -0,0 +1,473 @@
+
+
+ContextBindRootScript {
+ param RsScript sampler
+ }
+
+ContextBindProgramFragmentStore {
+ param RsProgramFragmentStore pgm
+ }
+
+ContextBindProgramFragment {
+ param RsProgramFragment pgm
+ }
+
+ContextBindProgramVertex {
+ param RsProgramVertex pgm
+ }
+
+ContextBindProgramRaster {
+ param RsProgramRaster pgm
+ }
+
+ContextSetDefineF {
+ param const char* name
+ param float value
+ }
+
+ContextSetDefineI32 {
+ param const char* name
+ param int32_t value
+ }
+
+ContextPause {
+ }
+
+ContextResume {
+ }
+
+ContextSetSurface {
+ param void *sur
+ }
+
+AssignName {
+ param void *obj
+ param const char *name
+ param size_t len
+ }
+
+ObjDestroy {
+ param void *obj
+ }
+
+ElementBegin {
+}
+
+ElementAdd {
+ param RsDataKind dataKind
+ param RsDataType dataType
+ param bool isNormalized
+ param size_t bits
+ param const char * name
+ }
+
+ElementCreate {
+ ret RsElement
+ }
+
+TypeBegin {
+ param RsElement type
+ }
+
+TypeAdd {
+ param RsDimension dim
+ param size_t value
+ }
+
+TypeCreate {
+ ret RsType
+ }
+
+AllocationCreateTyped {
+ param RsType type
+ ret RsAllocation
+ }
+
+AllocationCreateSized {
+ param RsElement e
+ param size_t count
+ ret RsAllocation
+ }
+
+AllocationCreateFromBitmap {
+ param uint32_t width
+ param uint32_t height
+ param RsElement dstFmt
+ param RsElement srcFmt
+ param bool genMips
+ param const void * data
+ ret RsAllocation
+ }
+
+AllocationCreateFromBitmapBoxed {
+ param uint32_t width
+ param uint32_t height
+ param RsElement dstFmt
+ param RsElement srcFmt
+ param bool genMips
+ param const void * data
+ ret RsAllocation
+ }
+
+
+AllocationUploadToTexture {
+ param RsAllocation alloc
+ param uint32_t baseMipLevel
+ }
+
+AllocationUploadToBufferObject {
+ param RsAllocation alloc
+ }
+
+
+AllocationData {
+ param RsAllocation va
+ param const void * data
+ param uint32_t bytes
+ handcodeApi
+ togglePlay
+ }
+
+Allocation1DSubData {
+ param RsAllocation va
+ param uint32_t xoff
+ param uint32_t count
+ param const void *data
+ param uint32_t bytes
+ handcodeApi
+ togglePlay
+ }
+
+Allocation2DSubData {
+ param RsAllocation va
+ param uint32_t xoff
+ param uint32_t yoff
+ param uint32_t w
+ param uint32_t h
+ param const void *data
+ param uint32_t bytes
+ }
+
+AllocationRead {
+ param RsAllocation va
+ param void * data
+ }
+
+Adapter1DCreate {
+ ret RsAdapter1D
+ }
+
+Adapter1DBindAllocation {
+ param RsAdapter1D adapt
+ param RsAllocation alloc
+ }
+
+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
+ }
+
+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
+ }
+
+
+
+ScriptBindAllocation {
+ param RsScript vtm
+ param RsAllocation va
+ param uint32_t slot
+ }
+
+
+ScriptCBegin {
+ }
+
+ScriptSetClearColor {
+ param RsScript s
+ param float r
+ param float g
+ param float b
+ param float a
+ }
+
+ScriptSetTimeZone {
+ param RsScript s
+ param const char * timeZone
+ param uint32_t length
+ }
+
+ScriptSetClearDepth {
+ param RsScript s
+ param float depth
+ }
+
+ScriptSetClearStencil {
+ param RsScript s
+ param uint32_t stencil
+ }
+
+ScriptSetType {
+ param RsType type
+ param uint32_t slot
+ param bool isWritable
+ param const char * name
+ }
+
+ScriptSetInvoke {
+ param const char * name
+ param uint32_t slot
+ }
+
+ScriptInvoke {
+ param RsScript s
+ param uint32_t slot
+ }
+
+ScriptSetRoot {
+ param bool isRoot
+ }
+
+
+
+ScriptCSetScript {
+ param void * codePtr
+ }
+
+ScriptCSetText {
+ param const char * text
+ param uint32_t length
+ }
+
+ScriptCCreate {
+ ret RsScript
+ }
+
+ScriptCSetDefineF {
+ param const char* name
+ param float value
+ }
+
+ScriptCSetDefineI32 {
+ param const char* name
+ param int32_t value
+ }
+
+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
+ }
+
+ProgramRasterCreate {
+ param RsElement in
+ param RsElement out
+ param bool pointSmooth
+ param bool lineSmooth
+ param bool pointSprite
+ ret RsProgramRaster
+}
+
+ProgramRasterSetLineWidth {
+ param RsProgramRaster pr
+ param float lw
+}
+
+ProgramRasterSetPointSize{
+ param RsProgramRaster pr
+ param float ps
+}
+
+
+ProgramFragmentBegin {
+ param RsElement in
+ param RsElement out
+ param bool pointSpriteEnable
+ }
+
+ProgramFragmentBindTexture {
+ param RsProgramFragment pf
+ param uint32_t slot
+ param RsAllocation a
+ }
+
+ProgramFragmentBindSampler {
+ param RsProgramFragment pf
+ param uint32_t slot
+ param RsSampler s
+ }
+
+ProgramFragmentSetSlot {
+ param uint32_t slot
+ param bool enable
+ param RsTexEnvMode env
+ param RsType t
+ }
+
+ProgramFragmentCreate {
+ ret RsProgramFragment
+ }
+
+
+ProgramVertexBegin {
+ param RsElement in
+ param RsElement out
+ }
+
+ProgramVertexCreate {
+ ret RsProgramVertex
+ }
+
+ProgramVertexBindAllocation {
+ param RsProgramVertex vpgm
+ param RsAllocation constants
+ }
+
+ProgramVertexSetTextureMatrixEnable {
+ param bool enable
+ }
+
+ProgramVertexAddLight {
+ param RsLight light
+ }
+
+LightBegin {
+ }
+
+LightSetLocal {
+ param bool isLocal
+ }
+
+LightSetMonochromatic {
+ param bool isMono
+ }
+
+LightCreate {
+ ret RsLight light
+ }
+
+
+LightSetPosition {
+ param RsLight light
+ param float x
+ param float y
+ param float z
+ }
+
+LightSetColor {
+ param RsLight light
+ param float r
+ param float g
+ param float b
+ }
+
+FileOpen {
+ ret RsFile
+ param const char *name
+ param size_t len
+ }
+
+
+SimpleMeshCreate {
+ ret RsSimpleMesh
+ param RsAllocation prim
+ param RsAllocation index
+ param RsAllocation *vtx
+ param uint32_t vtxCount
+ param uint32_t primType
+ }
+
+
+SimpleMeshBindIndex {
+ param RsSimpleMesh mesh
+ param RsAllocation idx
+ }
+
+SimpleMeshBindPrimitive {
+ param RsSimpleMesh mesh
+ param RsAllocation prim
+ }
+
+SimpleMeshBindVertex {
+ param RsSimpleMesh mesh
+ param RsAllocation vtx
+ param uint32_t slot
+ }
+
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
new file mode 100644
index 0000000..0d31fac
--- /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(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ reset();
+}
+
+Adapter1D::Adapter1D(Context *rsc, Allocation *a) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ 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)
+{
+ Adapter1D *a = new Adapter1D(rsc);
+ a->incUserRef();
+ return a;
+}
+
+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(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ reset();
+}
+
+Adapter2D::Adapter2D(Context *rsc, Allocation *a) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ 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)
+{
+ Adapter2D *a = new Adapter2D(rsc);
+ a->incUserRef();
+ return a;
+}
+
+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..cb2872e
--- /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(Context *);
+ Adapter1D(Context *, 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(Context *);
+ Adapter2D(Context *, 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..16029a6
--- /dev/null
+++ b/libs/rs/rsAllocation.cpp
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ 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);
+ rsAssert(type);
+ mPtr = malloc(mType->getSizeBytes());
+ if (!mPtr) {
+ LOGE("Allocation::Allocation, alloc failure");
+ }
+}
+
+Allocation::~Allocation()
+{
+ free(mPtr);
+ mPtr = NULL;
+
+ if (mBufferID) {
+ // Causes a SW crash....
+ //LOGV(" mBufferID %i", mBufferID);
+ //glDeleteBuffers(1, &mBufferID);
+ //mBufferID = 0;
+ }
+ if (mTextureID) {
+ glDeleteTextures(1, &mTextureID);
+ mTextureID = 0;
+ }
+}
+
+void Allocation::setCpuWritable(bool)
+{
+}
+
+void Allocation::setGpuWritable(bool)
+{
+}
+
+void Allocation::setCpuReadable(bool)
+{
+}
+
+void Allocation::setGpuReadable(bool)
+{
+}
+
+bool Allocation::fixAllocation()
+{
+ return false;
+}
+
+void Allocation::uploadToTexture(uint32_t lodOffset)
+{
+ //rsAssert(!mTextureId);
+ rsAssert(lodOffset < mType->getLODCount());
+
+ GLenum type = mType->getElement()->getGLType();
+ GLenum format = mType->getElement()->getGLFormat();
+
+ if (!type || !format) {
+ return;
+ }
+
+ if (!mTextureID) {
+ glGenTextures(1, &mTextureID);
+ }
+ glBindTexture(GL_TEXTURE_2D, mTextureID);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ Adapter2D adapt(getContext(), this);
+ for(uint32_t lod = 0; (lod + lodOffset) < mType->getLODCount(); lod++) {
+ adapt.setLOD(lod+lodOffset);
+
+ uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
+ glTexImage2D(GL_TEXTURE_2D, lod, format,
+ adapt.getDimX(), adapt.getDimY(),
+ 0, format, type, ptr);
+ }
+}
+
+void Allocation::uploadToBufferObject()
+{
+ rsAssert(!mType->getDimY());
+ rsAssert(!mType->getDimZ());
+
+ if (!mBufferID) {
+ glGenBuffers(1, &mBufferID);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
+ glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+
+void Allocation::data(const void *data, uint32_t sizeBytes)
+{
+ uint32_t size = mType->getSizeBytes();
+ if (size != sizeBytes) {
+ LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
+ return;
+ }
+ memcpy(mPtr, data, size);
+}
+
+void Allocation::read(void *data)
+{
+ memcpy(data, mPtr, mType->getSizeBytes());
+}
+
+void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
+{
+ uint32_t eSize = mType->getElementSizeBytes();
+ uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+ ptr += eSize * xoff;
+ uint32_t size = count * eSize;
+
+ if (size != sizeBytes) {
+ LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
+ mType->dumpLOGV("type info");
+ return;
+ }
+ memcpy(ptr, data, size);
+}
+
+void Allocation::subData(uint32_t xoff, uint32_t yoff,
+ uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
+{
+ 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);
+
+ if ((lineSize * eSize * h) != sizeBytes) {
+ rsAssert(!"Allocation::subData called with mismatched size");
+ return;
+ }
+
+ 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, uint32_t sizeBytes)
+{
+}
+
+
+
+/////////////////
+//
+
+
+namespace android {
+namespace renderscript {
+
+RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
+{
+ const Type * type = static_cast<const Type *>(vtype);
+
+ Allocation * alloc = new Allocation(rsc, type);
+ alloc->incUserRef();
+ return alloc;
+}
+
+RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
+{
+ Type * type = new Type(rsc);
+ 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();
+}
+
+static void mip565(const Adapter2D &out, const Adapter2D &in)
+{
+ uint32_t w = out.getDimX();
+ uint32_t h = out.getDimY();
+
+ for (uint32_t y=0; y < h; 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 < w; x++) {
+ *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
+ oPtr ++;
+ i1 += 2;
+ i2 += 2;
+ }
+ }
+}
+
+static void mip8888(const Adapter2D &out, const Adapter2D &in)
+{
+ uint32_t w = out.getDimX();
+ uint32_t h = out.getDimY();
+
+ for (uint32_t y=0; y < h; y++) {
+ uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
+ const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
+ const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
+
+ for (uint32_t x=0; x < w; x++) {
+ *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
+ oPtr ++;
+ i1 += 2;
+ i2 += 2;
+ }
+ }
+}
+
+static void mip(const Adapter2D &out, const Adapter2D &in)
+{
+ switch(out.getBaseType()->getElement()->getSizeBits()) {
+ case 32:
+ mip8888(out, in);
+ break;
+ case 16:
+ mip565(out, in);
+ break;
+
+ }
+
+}
+
+typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
+
+static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count)
+{
+ memcpy(dst, src, count * 2);
+}
+static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count)
+{
+ memcpy(dst, src, count);
+}
+static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count)
+{
+ memcpy(dst, src, count * 4);
+}
+
+
+static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count)
+{
+ uint16_t *d = static_cast<uint16_t *>(dst);
+ const uint8_t *s = static_cast<const uint8_t *>(src);
+
+ while(count--) {
+ *d = rs888to565(s[0], s[1], s[2]);
+ d++;
+ s+= 3;
+ }
+}
+
+static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count)
+{
+ uint16_t *d = static_cast<uint16_t *>(dst);
+ const uint8_t *s = static_cast<const uint8_t *>(src);
+
+ while(count--) {
+ *d = rs888to565(s[0], s[1], s[2]);
+ d++;
+ s+= 4;
+ }
+}
+
+static ElementConverter_t pickConverter(const Element *dst, const Element *src)
+{
+ GLenum srcGLType = src->getGLType();
+ GLenum srcGLFmt = src->getGLFormat();
+ GLenum dstGLType = dst->getGLType();
+ GLenum dstGLFmt = dst->getGLFormat();
+
+ if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
+ switch(dst->getSizeBytes()) {
+ case 4:
+ return elementConverter_cpy_32;
+ case 2:
+ return elementConverter_cpy_16;
+ case 1:
+ return elementConverter_cpy_8;
+ }
+ }
+
+ if (srcGLType == GL_UNSIGNED_BYTE &&
+ srcGLFmt == GL_RGB &&
+ dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
+ dstGLType == GL_RGB) {
+
+ return elementConverter_888_to_565;
+ }
+
+ if (srcGLType == GL_UNSIGNED_BYTE &&
+ srcGLFmt == GL_RGBA &&
+ dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
+ dstGLType == GL_RGB) {
+
+ return elementConverter_8888_to_565;
+ }
+
+ LOGE("pickConverter, unsuported combo, src %p, dst %p", src, dst);
+ return 0;
+}
+
+
+RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
+{
+ const Element *src = static_cast<const Element *>(_src);
+ const Element *dst = static_cast<const Element *>(_dst);
+ rsAssert(!(w & (w-1)));
+ rsAssert(!(h & (h-1)));
+
+ //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips);
+ rsi_TypeBegin(rsc, _dst);
+ rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
+ rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
+ if (genMips) {
+ rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
+ }
+ RsType type = rsi_TypeCreate(rsc);
+
+ RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
+ Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
+ if (texAlloc == NULL) {
+ LOGE("Memory allocation failure");
+ return NULL;
+ }
+ texAlloc->incUserRef();
+
+ ElementConverter_t cvt = pickConverter(dst, src);
+ cvt(texAlloc->getPtr(), data, w * h);
+
+ if (genMips) {
+ Adapter2D adapt(rsc, texAlloc);
+ Adapter2D adapt2(rsc, texAlloc);
+ for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+ adapt.setLOD(lod);
+ adapt2.setLOD(lod + 1);
+ mip(adapt2, adapt);
+ }
+ }
+
+ return texAlloc;
+}
+
+RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
+{
+ const Element *srcE = static_cast<const Element *>(_src);
+ const Element *dstE = static_cast<const Element *>(_dst);
+ uint32_t w2 = rsHigherPow2(w);
+ uint32_t h2 = rsHigherPow2(h);
+
+ if ((w2 == w) && (h2 == h)) {
+ return rsi_AllocationCreateFromBitmap(rsc, w, h, _dst, _src, genMips, data);
+ }
+
+ uint32_t bpp = srcE->getSizeBytes();
+ size_t size = w2 * h2 * bpp;
+ uint8_t *tmp = static_cast<uint8_t *>(malloc(size));
+ memset(tmp, 0, size);
+
+ const uint8_t * src = static_cast<const uint8_t *>(data);
+ for (uint32_t y = 0; y < h; y++) {
+ uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp];
+ memcpy(&ydst[((w2 - w) >> 1) * bpp], src, w * bpp);
+ src += w * bpp;
+ }
+
+ RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, _dst, _src, genMips, tmp);
+ free(tmp);
+ return ret;
+
+
+
+
+}
+
+void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->data(data, sizeBytes);
+ rsc->allocationCheck(a);
+}
+
+void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->subData(xoff, count, data, sizeBytes);
+ rsc->allocationCheck(a);
+}
+
+void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->subData(xoff, yoff, w, h, data, sizeBytes);
+ rsc->allocationCheck(a);
+}
+
+void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->read(data);
+}
+
+
+}
+}
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
new file mode 100644
index 0000000..1b83267
--- /dev/null
+++ b/libs/rs/rsAllocation.h
@@ -0,0 +1,101 @@
+/*
+ * 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(Context *rsc, 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, uint32_t sizeBytes);
+ void subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes);
+ void subData(uint32_t xoff, uint32_t yoff,
+ uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes);
+ void subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes);
+
+ void read(void *data);
+
+ void enableGLVertexBuffers() const;
+ void setupGLIndexBuffers() const;
+
+
+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..de074c8
--- /dev/null
+++ b/libs/rs/rsComponent.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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"
+#include <GLES/gl.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Component::Component(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mType = FLOAT;
+ mKind = USER;
+ mIsNormalized = false;
+ mBits = 0;
+}
+
+Component::Component(Context *rsc,
+ DataKind dk, DataType dt,
+ bool isNormalized, uint32_t bits, const char * name) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mType = dt;
+ mKind = dk;
+ mIsNormalized = isNormalized;
+ mBits = bits;
+ if (name) {
+ mName = name;
+ }
+}
+
+const char * Component::getCType() const
+{
+ switch(mType) {
+ case FLOAT:
+ return "float";
+ case SIGNED:
+ case UNSIGNED:
+ switch(mBits) {
+ case 32:
+ return "int";
+ case 16:
+ return "short";
+ case 8:
+ return "char";
+ }
+ break;
+ }
+ return NULL;
+}
+
+Component::~Component()
+{
+}
+
+uint32_t Component::getGLType() const
+{
+ switch(mType) {
+ case RS_TYPE_FLOAT:
+ rsAssert(mBits == 32);
+ return GL_FLOAT;
+ case RS_TYPE_SIGNED:
+ switch(mBits) {
+ case 32:
+ return 0;//GL_INT;
+ case 16:
+ return GL_SHORT;
+ case 8:
+ return GL_BYTE;
+ }
+ break;
+ case RS_TYPE_UNSIGNED:
+ switch(mBits) {
+ case 32:
+ return 0;//GL_UNSIGNED_INT;
+ case 16:
+ return GL_UNSIGNED_SHORT;
+ case 8:
+ return GL_UNSIGNED_BYTE;
+ }
+ break;
+ }
+ //rsAssert(!"Bad type");
+ //LOGE("mType %i, mKind %i, mBits %i, mIsNormalized %i", mType, mKind, mBits, mIsNormalized);
+ return 0;
+}
+
+void Component::dumpLOGV(const char *prefix) const
+{
+ ObjectBase::dumpLOGV(prefix);
+ LOGV("%s component: %i %i %i %i", prefix, mType, mKind, mIsNormalized, mBits);
+}
+
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
new file mode 100644
index 0000000..5366cc4
--- /dev/null
+++ b/libs/rs/rsComponent.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_STRUCTURED_COMPONENT_H
+#define ANDROID_RS_STRUCTURED_COMPONENT_H
+
+#include "rsUtils.h"
+#include "rsObjectBase.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Component : public ObjectBase
+{
+public:
+ enum DataType {
+ FLOAT,
+ UNSIGNED,
+ SIGNED
+ };
+
+ enum DataKind {
+ USER,
+ RED, GREEN, BLUE, ALPHA, LUMINANCE, INTENSITY,
+ X, Y, Z, W,
+ S, T, Q, R,
+ NX, NY, NZ,
+ INDEX,
+ POINT_SIZE
+ };
+
+
+ Component(Context *rsc, DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *);
+ virtual ~Component();
+
+ DataType getType() const {return mType;}
+ bool getIsNormalized() const {return mIsNormalized;}
+ DataKind getKind() const {return mKind;}
+ uint32_t getBits() const {return mBits;}
+
+ uint32_t getGLType() const;
+ const char * getCType() const;
+
+ const char * getComponentName() const {return mName.string();}
+ virtual void dumpLOGV(const char *prefix) const;
+
+protected:
+
+ DataType mType;
+ bool mIsNormalized;
+ DataKind mKind;
+ uint32_t mBits;
+ String8 mName;
+
+private:
+ Component(Context *rsc);
+};
+
+
+}
+}
+
+#endif //ANDROID_RS_STRUCTURED_COMPONENT_H
+
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
new file mode 100644
index 0000000..3e4cc36
--- /dev/null
+++ b/libs/rs/rsContext.cpp
@@ -0,0 +1,815 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsDevice.h"
+#include "rsContext.h"
+#include "rsThreadIO.h"
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+#include <cutils/properties.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+pthread_key_t Context::gThreadTLSKey = 0;
+uint32_t Context::gThreadTLSKeyCount = 0;
+uint32_t Context::gGLContextCount = 0;
+pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+ if (returnVal != EGL_TRUE) {
+ fprintf(stderr, "%s() returned %d\n", op, returnVal);
+ }
+
+ for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+ = eglGetError()) {
+ fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+ error);
+ }
+}
+
+void Context::initEGL()
+{
+ mEGL.mNumConfigs = -1;
+ EGLint configAttribs[128];
+ EGLint *configAttribsPtr = configAttribs;
+
+ memset(configAttribs, 0, sizeof(configAttribs));
+
+ configAttribsPtr[0] = EGL_SURFACE_TYPE;
+ configAttribsPtr[1] = EGL_WINDOW_BIT;
+ configAttribsPtr += 2;
+
+ if (mUseDepth) {
+ configAttribsPtr[0] = EGL_DEPTH_SIZE;
+ configAttribsPtr[1] = 16;
+ configAttribsPtr += 2;
+ }
+
+ if (mDev->mForceSW) {
+ configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
+ configAttribsPtr[1] = EGL_SLOW_CONFIG;
+ configAttribsPtr += 2;
+ }
+
+ configAttribsPtr[0] = EGL_NONE;
+ rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
+
+ LOGV("initEGL start");
+ mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ checkEglError("eglGetDisplay");
+
+ eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion);
+ checkEglError("eglInitialize");
+
+ status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig);
+ if (err) {
+ LOGE("couldn't find an EGLConfig matching the screen format\n");
+ }
+ //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
+
+
+ mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL);
+ checkEglError("eglCreateContext");
+ if (mEGL.mContext == EGL_NO_CONTEXT) {
+ LOGE("eglCreateContext returned EGL_NO_CONTEXT");
+ }
+ gGLContextCount++;
+
+ if (mWndSurface) {
+ setSurface(mWndSurface);
+ } else {
+ setSurface((Surface *)android_createDisplaySurface());
+ }
+
+ eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
+ eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
+
+
+ mGL.mVersion = glGetString(GL_VERSION);
+ mGL.mVendor = glGetString(GL_VENDOR);
+ mGL.mRenderer = glGetString(GL_RENDERER);
+ mGL.mExtensions = glGetString(GL_EXTENSIONS);
+
+ LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
+ LOGV("GL Version %s", mGL.mVersion);
+ LOGV("GL Vendor %s", mGL.mVendor);
+ LOGV("GL Renderer %s", mGL.mRenderer);
+ LOGV("GL Extensions %s", mGL.mExtensions);
+
+ if ((strlen((const char *)mGL.mVersion) < 12) || memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) {
+ LOGE("Error, OpenGL ES Lite not supported");
+ } else {
+ sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
+ }
+}
+
+void Context::deinitEGL()
+{
+ setSurface(NULL);
+ eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
+ checkEglError("eglDestroyContext");
+
+ gGLContextCount--;
+ if (!gGLContextCount) {
+ eglTerminate(mEGL.mDisplay);
+ }
+}
+
+
+bool Context::runScript(Script *s, uint32_t launchID)
+{
+ ObjectBaseRef<ProgramFragment> frag(mFragment);
+ ObjectBaseRef<ProgramVertex> vtx(mVertex);
+ ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
+ ObjectBaseRef<ProgramRaster> raster(mRaster);
+
+ bool ret = s->run(this, launchID);
+
+ mFragment.set(frag);
+ mVertex.set(vtx);
+ mFragmentStore.set(store);
+ mRaster.set(raster);
+ return ret;
+}
+
+
+bool Context::runRootScript()
+{
+ if (props.mLogTimes) {
+ timerSet(RS_TIMER_CLEAR_SWAP);
+ }
+ rsAssert(mRootScript->mEnviroment.mIsRoot);
+
+ eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
+ eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
+ glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ glClearColor(mRootScript->mEnviroment.mClearColor[0],
+ mRootScript->mEnviroment.mClearColor[1],
+ mRootScript->mEnviroment.mClearColor[2],
+ mRootScript->mEnviroment.mClearColor[3]);
+ if (mUseDepth) {
+ glDepthMask(GL_TRUE);
+ glClearDepthf(mRootScript->mEnviroment.mClearDepth);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ } else {
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ if (this->props.mLogTimes) {
+ timerSet(RS_TIMER_SCRIPT);
+ }
+ mStateFragmentStore.mLast.clear();
+ bool ret = runScript(mRootScript.get(), 0);
+
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ LOGE("Pending GL Error, 0x%x", err);
+ }
+
+ return ret;
+}
+
+uint64_t Context::getTime() const
+{
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
+}
+
+void Context::timerReset()
+{
+ for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) {
+ mTimers[ct] = 0;
+ }
+}
+
+void Context::timerInit()
+{
+ mTimeLast = getTime();
+ mTimeFrame = mTimeLast;
+ mTimeLastFrame = mTimeLast;
+ mTimerActive = RS_TIMER_INTERNAL;
+ timerReset();
+}
+
+void Context::timerFrame()
+{
+ mTimeLastFrame = mTimeFrame;
+ mTimeFrame = getTime();
+}
+
+void Context::timerSet(Timers tm)
+{
+ uint64_t last = mTimeLast;
+ mTimeLast = getTime();
+ mTimers[mTimerActive] += mTimeLast - last;
+ mTimerActive = tm;
+}
+
+void Context::timerPrint()
+{
+ double total = 0;
+ for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) {
+ total += mTimers[ct];
+ }
+ uint64_t frame = mTimeFrame - mTimeLastFrame;
+
+ LOGV("RS: Frame (%lli), Script %2.1f (%lli), Clear & Swap %2.1f (%lli), Idle %2.1f (%lli), Internal %2.1f (%lli)",
+ frame / 1000000,
+ 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimers[RS_TIMER_SCRIPT] / 1000000,
+ 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimers[RS_TIMER_CLEAR_SWAP] / 1000000,
+ 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
+ 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000);
+}
+
+void Context::setupCheck()
+{
+ mFragmentStore->setupGL(this, &mStateFragmentStore);
+ mFragment->setupGL(this, &mStateFragment);
+ mRaster->setupGL(this, &mStateRaster);
+ mVertex->setupGL(this, &mStateVertex);
+}
+
+static bool getProp(const char *str)
+{
+ char buf[PROPERTY_VALUE_MAX];
+ property_get(str, buf, "0");
+ return 0 != strcmp(buf, "0");
+}
+
+void * Context::threadProc(void *vrsc)
+{
+ Context *rsc = static_cast<Context *>(vrsc);
+
+ rsc->props.mLogTimes = getProp("debug.rs.profile");
+ rsc->props.mLogScripts = getProp("debug.rs.script");
+ rsc->props.mLogObjects = getProp("debug.rs.objects");
+
+ pthread_mutex_lock(&gInitMutex);
+ rsc->initEGL();
+ pthread_mutex_unlock(&gInitMutex);
+
+ ScriptTLSStruct *tlsStruct = new ScriptTLSStruct;
+ if (!tlsStruct) {
+ LOGE("Error allocating tls storage");
+ return NULL;
+ }
+ tlsStruct->mContext = rsc;
+ tlsStruct->mScript = NULL;
+ int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct);
+ if (status) {
+ LOGE("pthread_setspecific %i", status);
+ }
+
+ rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+ rsc->setRaster(NULL);
+ rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+ rsc->setVertex(NULL);
+ rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+ rsc->setFragment(NULL);
+ rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+ rsc->setFragmentStore(NULL);
+
+ rsc->mRunning = true;
+ bool mDraw = true;
+ while (!rsc->mExit) {
+ mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
+ mDraw &= (rsc->mRootScript.get() != NULL);
+ mDraw &= (rsc->mWndSurface != NULL);
+
+ if (mDraw) {
+ mDraw = rsc->runRootScript() && !rsc->mPaused;
+ if (rsc->props.mLogTimes) {
+ rsc->timerSet(RS_TIMER_CLEAR_SWAP);
+ }
+ eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
+ if (rsc->props.mLogTimes) {
+ rsc->timerFrame();
+ rsc->timerSet(RS_TIMER_INTERNAL);
+ rsc->timerPrint();
+ rsc->timerReset();
+ }
+ }
+ if (rsc->mObjDestroy.mNeedToEmpty) {
+ rsc->objDestroyOOBRun();
+ }
+ }
+
+ LOGV("RS Thread exiting");
+ rsc->mRaster.clear();
+ rsc->mFragment.clear();
+ rsc->mVertex.clear();
+ rsc->mFragmentStore.clear();
+ rsc->mRootScript.clear();
+ rsc->mStateRaster.deinit(rsc);
+ rsc->mStateVertex.deinit(rsc);
+ rsc->mStateFragment.deinit(rsc);
+ rsc->mStateFragmentStore.deinit(rsc);
+ ObjectBase::zeroAllUserRef(rsc);
+
+ rsc->mObjDestroy.mNeedToEmpty = true;
+ rsc->objDestroyOOBRun();
+
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
+
+ pthread_mutex_lock(&gInitMutex);
+ rsc->deinitEGL();
+ pthread_mutex_unlock(&gInitMutex);
+
+ LOGV("RS Thread exited");
+ return NULL;
+}
+
+Context::Context(Device *dev, Surface *sur, bool useDepth)
+{
+ pthread_mutex_lock(&gInitMutex);
+
+ dev->addContext(this);
+ mDev = dev;
+ mRunning = false;
+ mExit = false;
+ mUseDepth = useDepth;
+ mPaused = false;
+ mObjHead = NULL;
+
+ int status;
+ pthread_attr_t threadAttr;
+
+ if (!gThreadTLSKeyCount) {
+ status = pthread_key_create(&gThreadTLSKey, NULL);
+ if (status) {
+ LOGE("Failed to init thread tls key.");
+ pthread_mutex_unlock(&gInitMutex);
+ return;
+ }
+ }
+ gThreadTLSKeyCount++;
+ pthread_mutex_unlock(&gInitMutex);
+
+ // Global init done at this point.
+
+ status = pthread_attr_init(&threadAttr);
+ if (status) {
+ LOGE("Failed to init thread attribute.");
+ return;
+ }
+
+ sched_param sparam;
+ sparam.sched_priority = ANDROID_PRIORITY_DISPLAY;
+ pthread_attr_setschedparam(&threadAttr, &sparam);
+
+ mWndSurface = sur;
+
+ objDestroyOOBInit();
+ timerInit();
+ timerSet(RS_TIMER_INTERNAL);
+
+ LOGV("RS Launching thread");
+ status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
+ if (status) {
+ LOGE("Failed to start rs context thread.");
+ }
+
+ while(!mRunning) {
+ usleep(100);
+ }
+
+ pthread_attr_destroy(&threadAttr);
+}
+
+Context::~Context()
+{
+ LOGV("Context::~Context");
+ mExit = true;
+ mPaused = false;
+ void *res;
+
+ mIO.shutdown();
+ int status = pthread_join(mThreadId, &res);
+ mObjDestroy.mNeedToEmpty = true;
+ objDestroyOOBRun();
+
+ // Global structure cleanup.
+ pthread_mutex_lock(&gInitMutex);
+ if (mDev) {
+ mDev->removeContext(this);
+ --gThreadTLSKeyCount;
+ if (!gThreadTLSKeyCount) {
+ pthread_key_delete(gThreadTLSKey);
+ }
+ mDev = NULL;
+ }
+ pthread_mutex_unlock(&gInitMutex);
+
+ objDestroyOOBDestroy();
+}
+
+void Context::setSurface(Surface *sur)
+{
+ EGLBoolean ret;
+ if (mEGL.mSurface != NULL) {
+ ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ checkEglError("eglMakeCurrent", ret);
+
+ ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+ checkEglError("eglDestroySurface", ret);
+
+ mEGL.mSurface = NULL;
+ }
+
+ mWndSurface = sur;
+ if (mWndSurface != NULL) {
+ mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
+ checkEglError("eglCreateWindowSurface");
+ if (mEGL.mSurface == EGL_NO_SURFACE) {
+ LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
+ }
+
+ ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
+ checkEglError("eglMakeCurrent", ret);
+ }
+}
+
+void Context::pause()
+{
+ mPaused = true;
+}
+
+void Context::resume()
+{
+ mPaused = false;
+}
+
+void Context::setRootScript(Script *s)
+{
+ mRootScript.set(s);
+}
+
+void Context::setFragmentStore(ProgramFragmentStore *pfs)
+{
+ if (pfs == NULL) {
+ mFragmentStore.set(mStateFragmentStore.mDefault);
+ } else {
+ mFragmentStore.set(pfs);
+ }
+}
+
+void Context::setFragment(ProgramFragment *pf)
+{
+ if (pf == NULL) {
+ mFragment.set(mStateFragment.mDefault);
+ } else {
+ mFragment.set(pf);
+ }
+}
+
+void Context::setRaster(ProgramRaster *pr)
+{
+ if (pr == NULL) {
+ mRaster.set(mStateRaster.mDefault);
+ } else {
+ mRaster.set(pr);
+ }
+}
+
+void Context::allocationCheck(const Allocation *a)
+{
+ mVertex->checkUpdatedAllocation(a);
+ mFragment->checkUpdatedAllocation(a);
+ mFragmentStore->checkUpdatedAllocation(a);
+}
+
+void Context::setVertex(ProgramVertex *pv)
+{
+ if (pv == NULL) {
+ mVertex.set(mStateVertex.mDefault);
+ } else {
+ mVertex.set(pv);
+ }
+ mVertex->forceDirty();
+}
+
+void Context::assignName(ObjectBase *obj, const char *name, uint32_t len)
+{
+ rsAssert(!obj->getName());
+ obj->setName(name, len);
+ mNames.add(obj);
+}
+
+void Context::removeName(ObjectBase *obj)
+{
+ for(size_t ct=0; ct < mNames.size(); ct++) {
+ if (obj == mNames[ct]) {
+ mNames.removeAt(ct);
+ return;
+ }
+ }
+}
+
+ObjectBase * Context::lookupName(const char *name) const
+{
+ for(size_t ct=0; ct < mNames.size(); ct++) {
+ if (!strcmp(name, mNames[ct]->getName())) {
+ return mNames[ct];
+ }
+ }
+ return NULL;
+}
+
+void Context::appendNameDefines(String8 *str) const
+{
+ char buf[256];
+ for (size_t ct=0; ct < mNames.size(); ct++) {
+ str->append("#define NAMED_");
+ str->append(mNames[ct]->getName());
+ str->append(" ");
+ sprintf(buf, "%i\n", (int)mNames[ct]);
+ str->append(buf);
+ }
+}
+
+void Context::appendVarDefines(String8 *str) const
+{
+ char buf[256];
+ for (size_t ct=0; ct < mInt32Defines.size(); ct++) {
+ str->append("#define ");
+ str->append(mInt32Defines.keyAt(ct));
+ str->append(" ");
+ sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct));
+ str->append(buf);
+
+ }
+ for (size_t ct=0; ct < mFloatDefines.size(); ct++) {
+ str->append("#define ");
+ str->append(mFloatDefines.keyAt(ct));
+ str->append(" ");
+ sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct));
+ str->append(buf);
+ }
+}
+
+bool Context::objDestroyOOBInit()
+{
+ int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL);
+ if (status) {
+ LOGE("Context::ObjDestroyOOBInit mutex init failure");
+ return false;
+ }
+ return true;
+}
+
+void Context::objDestroyOOBRun()
+{
+ if (mObjDestroy.mNeedToEmpty) {
+ int status = pthread_mutex_lock(&mObjDestroy.mMutex);
+ if (status) {
+ LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
+ return;
+ }
+
+ for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) {
+ mObjDestroy.mDestroyList[ct]->decUserRef();
+ }
+ mObjDestroy.mDestroyList.clear();
+ mObjDestroy.mNeedToEmpty = false;
+
+ status = pthread_mutex_unlock(&mObjDestroy.mMutex);
+ if (status) {
+ LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
+ }
+ }
+}
+
+void Context::objDestroyOOBDestroy()
+{
+ rsAssert(!mObjDestroy.mNeedToEmpty);
+ pthread_mutex_destroy(&mObjDestroy.mMutex);
+}
+
+void Context::objDestroyAdd(ObjectBase *obj)
+{
+ int status = pthread_mutex_lock(&mObjDestroy.mMutex);
+ if (status) {
+ LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
+ return;
+ }
+
+ mObjDestroy.mNeedToEmpty = true;
+ mObjDestroy.mDestroyList.add(obj);
+
+ status = pthread_mutex_unlock(&mObjDestroy.mMutex);
+ if (status) {
+ LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
+ }
+}
+
+uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait)
+{
+ //LOGE("getMessageToClient %i %i", bufferLen, wait);
+ if (!wait) {
+ if (mIO.mToClient.isEmpty()) {
+ // No message to get and not going to wait for one.
+ receiveLen = 0;
+ return 0;
+ }
+ }
+
+ //LOGE("getMessageToClient 2 con=%p", this);
+ uint32_t bytesData = 0;
+ uint32_t commandID = 0;
+ const void *d = mIO.mToClient.get(&commandID, &bytesData);
+ //LOGE("getMessageToClient 3 %i %i", commandID, bytesData);
+
+ *receiveLen = bytesData;
+ if (bufferLen >= bytesData) {
+ memcpy(data, d, bytesData);
+ mIO.mToClient.next();
+ return commandID;
+ }
+ return 0;
+}
+
+bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace)
+{
+ //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace);
+ if (cmdID == 0) {
+ LOGE("Attempting to send invalid command 0 to client.");
+ return false;
+ }
+ if (!waitForSpace) {
+ if (mIO.mToClient.getFreeSpace() < len) {
+ // Not enough room, and not waiting.
+ return false;
+ }
+ }
+ //LOGE("sendMessageToClient 2");
+ void *p = mIO.mToClient.reserve(len);
+ memcpy(p, data, len);
+ mIO.mToClient.commit(cmdID, len);
+ //LOGE("sendMessageToClient 3");
+ return true;
+}
+
+void Context::initToClient()
+{
+ while(!mRunning) {
+ usleep(100);
+ }
+}
+
+void Context::deinitToClient()
+{
+ mIO.mToClient.shutdown();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//
+
+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_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr)
+{
+ ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
+ rsc->setRaster(pr);
+}
+
+void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
+{
+ ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
+ rsc->setVertex(pv);
+}
+
+void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len)
+{
+ ObjectBase *ob = static_cast<ObjectBase *>(obj);
+ rsc->assignName(ob, name, len);
+}
+
+void rsi_ObjDestroy(Context *rsc, void *obj)
+{
+ ObjectBase *ob = static_cast<ObjectBase *>(obj);
+ rsc->removeName(ob);
+ ob->decUserRef();
+}
+
+void rsi_ContextSetDefineF(Context *rsc, const char* name, float value)
+{
+ rsc->addInt32Define(name, value);
+}
+
+void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value)
+{
+ rsc->addFloatDefine(name, value);
+}
+
+void rsi_ContextPause(Context *rsc)
+{
+ rsc->pause();
+}
+
+void rsi_ContextResume(Context *rsc)
+{
+ rsc->resume();
+}
+
+void rsi_ContextSetSurface(Context *rsc, void *sur)
+{
+ rsc->setSurface((Surface *)sur);
+}
+
+}
+}
+
+
+RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version, bool useDepth)
+{
+ Device * dev = static_cast<Device *>(vdev);
+ Context *rsc = new Context(dev, (Surface *)sur, useDepth);
+ return rsc;
+}
+
+void rsContextDestroy(RsContext vrsc)
+{
+ Context * rsc = static_cast<Context *>(vrsc);
+ delete rsc;
+}
+
+void rsObjDestroyOOB(RsContext vrsc, void *obj)
+{
+ Context * rsc = static_cast<Context *>(vrsc);
+ rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
+}
+
+uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait)
+{
+ Context * rsc = static_cast<Context *>(vrsc);
+ return rsc->getMessageToClient(data, receiveLen, bufferLen, wait);
+}
+
+void rsContextInitToClient(RsContext vrsc)
+{
+ Context * rsc = static_cast<Context *>(vrsc);
+ rsc->initToClient();
+}
+
+void rsContextDeinitToClient(RsContext vrsc)
+{
+ Context * rsc = static_cast<Context *>(vrsc);
+ rsc->deinitToClient();
+}
+
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
new file mode 100644
index 0000000..bffc55b
--- /dev/null
+++ b/libs/rs/rsContext.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_CONTEXT_H
+#define ANDROID_RS_CONTEXT_H
+
+#include "rsUtils.h"
+
+#include <ui/Surface.h>
+
+#include "rsThreadIO.h"
+#include "rsType.h"
+#include "rsMatrix.h"
+#include "rsAllocation.h"
+#include "rsSimpleMesh.h"
+#include "rsMesh.h"
+#include "rsDevice.h"
+#include "rsScriptC.h"
+#include "rsAllocation.h"
+#include "rsAdapter.h"
+#include "rsSampler.h"
+#include "rsLight.h"
+#include "rsProgramFragment.h"
+#include "rsProgramFragmentStore.h"
+#include "rsProgramRaster.h"
+#include "rsProgramVertex.h"
+
+#include "rsgApiStructs.h"
+#include "rsLocklessFifo.h"
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Context
+{
+public:
+ Context(Device *, Surface *, bool useDepth);
+ ~Context();
+
+ static pthread_key_t gThreadTLSKey;
+ static uint32_t gThreadTLSKeyCount;
+ static uint32_t gGLContextCount;
+ static pthread_mutex_t gInitMutex;
+
+ struct ScriptTLSStruct {
+ Context * mContext;
+ Script * mScript;
+ };
+
+
+ //StructuredAllocationContext mStateAllocation;
+ ElementState mStateElement;
+ TypeState mStateType;
+ SamplerState mStateSampler;
+ ProgramFragmentState mStateFragment;
+ ProgramFragmentStoreState mStateFragmentStore;
+ ProgramRasterState mStateRaster;
+ ProgramVertexState mStateVertex;
+ LightState mStateLight;
+
+ ScriptCState mScriptC;
+
+ void swapBuffers();
+ void setRootScript(Script *);
+ void setRaster(ProgramRaster *);
+ 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();}
+ const ProgramRaster * getRaster() {return mRaster.get();}
+ const ProgramVertex * getVertex() {return mVertex.get();}
+
+ void setupCheck();
+ void allocationCheck(const Allocation *);
+
+ void pause();
+ void resume();
+ void setSurface(Surface *sur);
+
+ void assignName(ObjectBase *obj, const char *name, uint32_t len);
+ void removeName(ObjectBase *obj);
+ ObjectBase * lookupName(const char *name) const;
+ void appendNameDefines(String8 *str) const;
+ void appendVarDefines(String8 *str) const;
+
+ uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait);
+ bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace);
+ bool runScript(Script *s, uint32_t launchID);
+
+ void initToClient();
+ void deinitToClient();
+
+ ProgramFragment * getDefaultProgramFragment() const {
+ return mStateFragment.mDefault.get();
+ }
+ ProgramVertex * getDefaultProgramVertex() const {
+ return mStateVertex.mDefault.get();
+ }
+ ProgramFragmentStore * getDefaultProgramFragmentStore() const {
+ return mStateFragmentStore.mDefault.get();
+ }
+ ProgramRaster * getDefaultProgramRaster() const {
+ return mStateRaster.mDefault.get();
+ }
+
+ void addInt32Define(const char* name, int32_t value) {
+ mInt32Defines.add(String8(name), value);
+ }
+
+ void addFloatDefine(const char* name, float value) {
+ mFloatDefines.add(String8(name), value);
+ }
+
+ uint32_t getWidth() const {return mEGL.mWidth;}
+ uint32_t getHeight() const {return mEGL.mHeight;}
+
+
+ ThreadIO mIO;
+ void objDestroyAdd(ObjectBase *);
+
+ // Timers
+ enum Timers {
+ RS_TIMER_IDLE,
+ RS_TIMER_INTERNAL,
+ RS_TIMER_SCRIPT,
+ RS_TIMER_CLEAR_SWAP,
+ _RS_TIMER_TOTAL
+ };
+ uint64_t getTime() const;
+ void timerInit();
+ void timerReset();
+ void timerSet(Timers);
+ void timerPrint();
+ void timerFrame();
+
+ bool checkVersion1_1() const {return (mGL.mMajorVersion > 1) || (mGL.mMinorVersion >= 1); }
+ bool checkVersion2_0() const {return mGL.mMajorVersion >= 2; }
+
+ struct {
+ bool mLogTimes;
+ bool mLogScripts;
+ bool mLogObjects;
+ } props;
+
+ mutable const ObjectBase * mObjHead;
+
+protected:
+ Device *mDev;
+
+ struct {
+ EGLint mNumConfigs;
+ EGLint mMajorVersion;
+ EGLint mMinorVersion;
+ EGLConfig mConfig;
+ EGLContext mContext;
+ EGLSurface mSurface;
+ EGLint mWidth;
+ EGLint mHeight;
+ EGLDisplay mDisplay;
+ } mEGL;
+
+ struct {
+ const uint8_t * mVendor;
+ const uint8_t * mRenderer;
+ const uint8_t * mVersion;
+ const uint8_t * mExtensions;
+
+ uint32_t mMajorVersion;
+ uint32_t mMinorVersion;
+
+ } mGL;
+
+ bool mRunning;
+ bool mExit;
+ bool mUseDepth;
+ bool mPaused;
+
+ pthread_t mThreadId;
+
+ ObjectBaseRef<Script> mRootScript;
+ ObjectBaseRef<ProgramFragment> mFragment;
+ ObjectBaseRef<ProgramVertex> mVertex;
+ ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+ ObjectBaseRef<ProgramRaster> mRaster;
+
+
+ struct ObjDestroyOOB {
+ pthread_mutex_t mMutex;
+ Vector<ObjectBase *> mDestroyList;
+ bool mNeedToEmpty;
+ };
+ ObjDestroyOOB mObjDestroy;
+ bool objDestroyOOBInit();
+ void objDestroyOOBRun();
+ void objDestroyOOBDestroy();
+
+private:
+ Context();
+
+ void initEGL();
+ void deinitEGL();
+
+ bool runRootScript();
+
+ static void * threadProc(void *);
+
+ Surface *mWndSurface;
+
+ Vector<ObjectBase *> mNames;
+ KeyedVector<String8,int> mInt32Defines;
+ KeyedVector<String8,float> mFloatDefines;
+
+ uint64_t mTimers[_RS_TIMER_TOTAL];
+ Timers mTimerActive;
+ uint64_t mTimeLast;
+ uint64_t mTimeFrame;
+ uint64_t mTimeLastFrame;
+};
+
+}
+}
+#endif
diff --git a/libs/rs/rsDevice.cpp b/libs/rs/rsDevice.cpp
new file mode 100644
index 0000000..b670ad4
--- /dev/null
+++ b/libs/rs/rsDevice.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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()
+{
+ mForceSW = false;
+
+}
+
+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;
+
+}
+
+void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value)
+{
+ Device * d = static_cast<Device *>(dev);
+ if (p == RS_DEVICE_PARAM_FORCE_SOFTWARE_GL) {
+ d->mForceSW = value != 0;
+ return;
+ }
+ rsAssert(0);
+}
+
diff --git a/libs/rs/rsDevice.h b/libs/rs/rsDevice.h
new file mode 100644
index 0000000..a8a4e77
--- /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 "rsUtils.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Context;
+
+class Device {
+public:
+ Device();
+ ~Device();
+
+ void addContext(Context *);
+ void removeContext(Context *);
+
+ bool mForceSW;
+
+protected:
+ Vector<Context *> mContexts;
+
+
+};
+
+
+
+
+
+}
+}
+#endif
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
new file mode 100644
index 0000000..67e4f14
--- /dev/null
+++ b/libs/rs/rsElement.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+
+#include <GLES/gl.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Element::Element(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mComponents = NULL;
+ mComponentCount = 0;
+}
+
+Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ 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);
+
+// Fixme: This should probably not be here
+ c->incUserRef();
+}
+
+
+size_t Element::getSizeBits() const
+{
+ size_t total = 0;
+ for (size_t ct=0; ct < mComponentCount; ct++) {
+ total += mComponents[ct]->getBits();
+ }
+ return total;
+}
+
+size_t Element::getComponentOffsetBits(uint32_t componentNumber) const
+{
+ size_t offset = 0;
+ for (uint32_t ct = 0; ct < componentNumber; ct++) {
+ offset += mComponents[ct]->getBits();
+ }
+ return offset;
+}
+
+uint32_t Element::getGLType() const
+{
+ int bits[4];
+
+ if (mComponentCount > 4) {
+ return 0;
+ }
+
+ for (uint32_t ct=0; ct < mComponentCount; ct++) {
+ bits[ct] = mComponents[ct]->getBits();
+ if (mComponents[ct]->getType() != Component::UNSIGNED) {
+ return 0;
+ }
+ if (!mComponents[ct]->getIsNormalized()) {
+ return 0;
+ }
+ }
+
+ switch(mComponentCount) {
+ case 1:
+ if (bits[0] == 8) {
+ return GL_UNSIGNED_BYTE;
+ }
+ return 0;
+ case 2:
+ if ((bits[0] == 8) &&
+ (bits[1] == 8)) {
+ return GL_UNSIGNED_BYTE;
+ }
+ return 0;
+ case 3:
+ if ((bits[0] == 8) &&
+ (bits[1] == 8) &&
+ (bits[2] == 8)) {
+ return GL_UNSIGNED_BYTE;
+ }
+ if ((bits[0] == 5) &&
+ (bits[1] == 6) &&
+ (bits[2] == 5)) {
+ return GL_UNSIGNED_SHORT_5_6_5;
+ }
+ return 0;
+ case 4:
+ if ((bits[0] == 8) &&
+ (bits[1] == 8) &&
+ (bits[2] == 8) &&
+ (bits[3] == 8)) {
+ return GL_UNSIGNED_BYTE;
+ }
+ if ((bits[0] == 4) &&
+ (bits[1] == 4) &&
+ (bits[2] == 4) &&
+ (bits[3] == 4)) {
+ return GL_UNSIGNED_SHORT_4_4_4_4;
+ }
+ if ((bits[0] == 5) &&
+ (bits[1] == 5) &&
+ (bits[2] == 5) &&
+ (bits[3] == 1)) {
+ return GL_UNSIGNED_SHORT_5_5_5_1;
+ }
+ }
+ return 0;
+}
+
+uint32_t Element::getGLFormat() const
+{
+ switch(mComponentCount) {
+ case 1:
+ if (mComponents[0]->getKind() == Component::ALPHA) {
+ return GL_ALPHA;
+ }
+ if (mComponents[0]->getKind() == Component::LUMINANCE) {
+ return GL_LUMINANCE;
+ }
+ break;
+ case 2:
+ if ((mComponents[0]->getKind() == Component::LUMINANCE) &&
+ (mComponents[1]->getKind() == Component::ALPHA)) {
+ return GL_LUMINANCE_ALPHA;
+ }
+ break;
+ case 3:
+ if ((mComponents[0]->getKind() == Component::RED) &&
+ (mComponents[1]->getKind() == Component::GREEN) &&
+ (mComponents[2]->getKind() == Component::BLUE)) {
+ return GL_RGB;
+ }
+ break;
+ case 4:
+ if ((mComponents[0]->getKind() == Component::RED) &&
+ (mComponents[1]->getKind() == Component::GREEN) &&
+ (mComponents[2]->getKind() == Component::BLUE) &&
+ (mComponents[3]->getKind() == Component::ALPHA)) {
+ return GL_RGBA;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+void Element::dumpLOGV(const char *prefix) const
+{
+ ObjectBase::dumpLOGV(prefix);
+ LOGV("%s Element: components %i, size %i", prefix, mComponentCount, getSizeBytes());
+ for (uint32_t ct = 0; ct < mComponentCount; ct++) {
+ char buf[1024];
+ sprintf(buf, "%s component %i: ", prefix, ct);
+ mComponents[ct]->dumpLOGV(buf);
+ }
+}
+
+ElementState::ElementState()
+{
+}
+
+ElementState::~ElementState()
+{
+}
+
+/////////////////////////////////////////
+//
+
+namespace android {
+namespace renderscript {
+
+void rsi_ElementBegin(Context *rsc)
+{
+ rsc->mStateElement.mComponentBuildList.clear();
+}
+
+void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
+{
+ ElementState * sec = &rsc->mStateElement;
+
+ rsAssert(bits > 0);
+
+ Component *c = new Component(rsc,
+ static_cast<Component::DataKind>(dk),
+ static_cast<Component::DataType>(dt),
+ isNormalized,
+ bits,
+ name);
+ sec->mComponentBuildList.add(c);
+}
+
+RsElement rsi_ElementCreate(Context *rsc)
+{
+ ElementState * sec = &rsc->mStateElement;
+ Element *se = new Element(rsc, sec->mComponentBuildList.size());
+
+ rsAssert(se->getComponentCount() > 0);
+
+ for (size_t ct = 0; ct < se->getComponentCount(); ct++) {
+ se->setComponent(ct, sec->mComponentBuildList[ct]);
+ }
+
+ rsc->mStateElement.mComponentBuildList.clear();
+ se->incUserRef();
+ return se;
+}
+
+
+}
+}
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
new file mode 100644
index 0000000..b41c552
--- /dev/null
+++ b/libs/rs/rsElement.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STRUCTURED_ELEMENT_H
+#define ANDROID_STRUCTURED_ELEMENT_H
+
+#include "rsComponent.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class Element : public ObjectBase
+{
+public:
+ Element(Context *, uint32_t count);
+ ~Element();
+
+
+ void setComponent(uint32_t idx, Component *c);
+
+ uint32_t getGLType() const;
+ uint32_t getGLFormat() const;
+
+
+ size_t getSizeBits() const;
+ size_t getSizeBytes() const {
+ return (getSizeBits() + 7) >> 3;
+ }
+
+ size_t getComponentOffsetBits(uint32_t componentNumber) const;
+ size_t getComponentOffsetBytes(uint32_t componentNumber) const {
+ return (getComponentOffsetBits(componentNumber) + 7) >> 3;
+ }
+
+ uint32_t getComponentCount() const {return mComponentCount;}
+ Component * getComponent(uint32_t idx) const {return mComponents[idx].get();}
+
+
+ void dumpLOGV(const char *prefix) const;
+
+protected:
+ // deallocate any components that are part of this element.
+ void clear();
+
+ size_t mComponentCount;
+ ObjectBaseRef<Component> * mComponents;
+ //uint32_t *mOffsetTable;
+
+ Element(Context *);
+};
+
+
+class ElementState {
+public:
+ ElementState();
+ ~ElementState();
+
+ Vector<Component *> mComponentBuildList;
+};
+
+
+}
+}
+#endif //ANDROID_STRUCTURED_ELEMENT_H
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
new file mode 100644
index 0000000..c566665
--- /dev/null
+++ b/libs/rs/rsFileA3D.cpp
@@ -0,0 +1,384 @@
+
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+
+
+#include <utils/String8.h>
+#include "rsFileA3D.h"
+
+#include "rsMesh.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+
+FileA3D::FileA3D()
+{
+ mRsc = NULL;
+}
+
+FileA3D::~FileA3D()
+{
+}
+
+bool FileA3D::load(Context *rsc, FILE *f)
+{
+ char magicString[12];
+ size_t len;
+
+ LOGE("file open 1");
+ len = fread(magicString, 1, 12, f);
+ if ((len != 12) ||
+ memcmp(magicString, "Android3D_ff", 12)) {
+ return false;
+ }
+
+ LOGE("file open 2");
+ len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f);
+ if (len != sizeof(mMajorVersion)) {
+ return false;
+ }
+
+ LOGE("file open 3");
+ len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f);
+ if (len != sizeof(mMinorVersion)) {
+ return false;
+ }
+
+ LOGE("file open 4");
+ uint32_t flags;
+ len = fread(&flags, 1, sizeof(flags), f);
+ if (len != sizeof(flags)) {
+ return false;
+ }
+ mUse64BitOffsets = (flags & 1) != 0;
+
+ LOGE("file open 64bit = %i", mUse64BitOffsets);
+
+ if (mUse64BitOffsets) {
+ len = fread(&mDataSize, 1, sizeof(mDataSize), f);
+ if (len != sizeof(mDataSize)) {
+ return false;
+ }
+ } else {
+ uint32_t tmp;
+ len = fread(&tmp, 1, sizeof(tmp), f);
+ if (len != sizeof(tmp)) {
+ return false;
+ }
+ mDataSize = tmp;
+ }
+
+ LOGE("file open size = %lli", mDataSize);
+
+ // We should know enough to read the file in at this point.
+ fseek(f, SEEK_SET, 0);
+ mAlloc= malloc(mDataSize);
+ if (!mAlloc) {
+ return false;
+ }
+ mData = (uint8_t *)mAlloc;
+ len = fread(mAlloc, 1, mDataSize, f);
+ if (len != mDataSize) {
+ return false;
+ }
+
+ LOGE("file start processing");
+ return process(rsc);
+}
+
+bool FileA3D::processIndex(Context *rsc, A3DIndexEntry *ie)
+{
+ bool ret = false;
+ IO io(mData + ie->mOffset, mUse64BitOffsets);
+
+ LOGE("process index, type %i", ie->mType);
+
+ switch(ie->mType) {
+ case CHUNK_ELEMENT:
+ processChunk_Element(rsc, &io, ie);
+ break;
+ case CHUNK_ELEMENT_SOURCE:
+ processChunk_ElementSource(rsc, &io, ie);
+ break;
+ case CHUNK_VERTICIES:
+ processChunk_Verticies(rsc, &io, ie);
+ break;
+ case CHUNK_MESH:
+ processChunk_Mesh(rsc, &io, ie);
+ break;
+ case CHUNK_PRIMITIVE:
+ processChunk_Primitive(rsc, &io, ie);
+ break;
+ default:
+ LOGE("FileA3D Unknown chunk type");
+ break;
+ }
+ return (ie->mRsObj != NULL);
+}
+
+bool FileA3D::process(Context *rsc)
+{
+ LOGE("process");
+ IO io(mData + 12, mUse64BitOffsets);
+ bool ret = true;
+
+ // Build the index first
+ LOGE("process 1");
+ io.loadU32(); // major version, already loaded
+ io.loadU32(); // minor version, already loaded
+ LOGE("process 2");
+
+ io.loadU32(); // flags
+ io.loadOffset(); // filesize, already loaded.
+ LOGE("process 4");
+ uint64_t mIndexOffset = io.loadOffset();
+ uint64_t mStringOffset = io.loadOffset();
+
+ LOGE("process mIndexOffset= 0x%016llx", mIndexOffset);
+ LOGE("process mStringOffset= 0x%016llx", mStringOffset);
+
+ IO index(mData + mIndexOffset, mUse64BitOffsets);
+ IO stringTable(mData + mStringOffset, mUse64BitOffsets);
+
+ uint32_t stringEntryCount = stringTable.loadU32();
+ LOGE("stringEntryCount %i", stringEntryCount);
+ mStrings.setCapacity(stringEntryCount);
+ mStringIndexValues.setCapacity(stringEntryCount);
+ if (stringEntryCount) {
+ uint32_t stringType = stringTable.loadU32();
+ LOGE("stringType %i", stringType);
+ rsAssert(stringType==0);
+ for (uint32_t ct = 0; ct < stringEntryCount; ct++) {
+ uint64_t offset = stringTable.loadOffset();
+ LOGE("string offset 0x%016llx", offset);
+ IO tmp(mData + offset, mUse64BitOffsets);
+ String8 s;
+ tmp.loadString(&s);
+ LOGE("string %s", s.string());
+ mStrings.push(s);
+ }
+ }
+
+ LOGE("strings done");
+ uint32_t indexEntryCount = index.loadU32();
+ LOGE("index count %i", indexEntryCount);
+ mIndex.setCapacity(indexEntryCount);
+ for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
+ A3DIndexEntry e;
+ uint32_t stringIndex = index.loadU32();
+ LOGE("index %i", ct);
+ LOGE(" string index %i", stringIndex);
+ e.mType = (A3DChunkType)index.loadU32();
+ LOGE(" type %i", e.mType);
+ e.mOffset = index.loadOffset();
+ LOGE(" offset 0x%016llx", e.mOffset);
+
+ if (stringIndex && (stringIndex < mStrings.size())) {
+ e.mID = mStrings[stringIndex];
+ mStringIndexValues.editItemAt(stringIndex) = ct;
+ LOGE(" id %s", e.mID.string());
+ }
+
+ mIndex.push(e);
+ }
+ LOGE("index done");
+
+ // At this point the index should be fully populated.
+ // We can now walk though it and load all the objects.
+ for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
+ LOGE("processing index entry %i", ct);
+ processIndex(rsc, &mIndex.editItemAt(ct));
+ }
+
+ return ret;
+}
+
+
+FileA3D::IO::IO(const uint8_t *buf, bool use64)
+{
+ mData = buf;
+ mPos = 0;
+ mUse64 = use64;
+}
+
+uint64_t FileA3D::IO::loadOffset()
+{
+ uint64_t tmp;
+ if (mUse64) {
+ mPos = (mPos + 7) & (~7);
+ tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
+ mPos += sizeof(uint64_t);
+ return tmp;
+ }
+ return loadU32();
+}
+
+void FileA3D::IO::loadString(String8 *s)
+{
+ LOGE("loadString");
+ uint32_t len = loadU32();
+ LOGE("loadString len %i", len);
+ s->setTo((const char *)&mData[mPos], len);
+ mPos += len;
+}
+
+
+void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
+{
+ Mesh * m = new Mesh(rsc);
+
+ m->mPrimitivesCount = io->loadU32();
+ m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];
+
+ for (uint32_t ct = 0; ct < m->mPrimitivesCount; ct++) {
+ uint32_t index = io->loadU32();
+
+ m->mPrimitives[ct] = (Mesh::Primitive_t *)mIndex[index].mRsObj;
+ }
+ ie->mRsObj = m;
+}
+
+void FileA3D::processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie)
+{
+ Mesh::Primitive_t * p = new Mesh::Primitive_t;
+
+ p->mIndexCount = io->loadU32();
+ uint32_t vertIdx = io->loadU32();
+ p->mRestartCounts = io->loadU16();
+ uint32_t bits = io->loadU8();
+ p->mType = (RsPrimitive)io->loadU8();
+
+ LOGE("processChunk_Primitive count %i, bits %i", p->mIndexCount, bits);
+
+ p->mVerticies = (Mesh::Verticies_t *)mIndex[vertIdx].mRsObj;
+
+ p->mIndicies = new uint16_t[p->mIndexCount];
+ for (uint32_t ct = 0; ct < p->mIndexCount; ct++) {
+ switch(bits) {
+ case 8:
+ p->mIndicies[ct] = io->loadU8();
+ break;
+ case 16:
+ p->mIndicies[ct] = io->loadU16();
+ break;
+ case 32:
+ p->mIndicies[ct] = io->loadU32();
+ break;
+ }
+ LOGE(" idx %i", p->mIndicies[ct]);
+ }
+
+ if (p->mRestartCounts) {
+ p->mRestarts = new uint16_t[p->mRestartCounts];
+ for (uint32_t ct = 0; ct < p->mRestartCounts; ct++) {
+ switch(bits) {
+ case 8:
+ p->mRestarts[ct] = io->loadU8();
+ break;
+ case 16:
+ p->mRestarts[ct] = io->loadU16();
+ break;
+ case 32:
+ p->mRestarts[ct] = io->loadU32();
+ break;
+ }
+ LOGE(" idx %i", p->mRestarts[ct]);
+ }
+ } else {
+ p->mRestarts = NULL;
+ }
+
+ ie->mRsObj = p;
+}
+
+void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie)
+{
+ Mesh::Verticies_t *cv = new Mesh::Verticies_t;
+ cv->mAllocationCount = io->loadU32();
+ cv->mAllocations = new Allocation *[cv->mAllocationCount];
+ LOGE("processChunk_Verticies count %i", cv->mAllocationCount);
+ for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) {
+ uint32_t i = io->loadU32();
+ cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj;
+ LOGE(" idx %i", i);
+ }
+ ie->mRsObj = cv;
+}
+
+void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie)
+{
+ rsi_ElementBegin(rsc);
+
+ uint32_t count = io->loadU32();
+ LOGE("processChunk_Element count %i", count);
+ while (count--) {
+ RsDataKind dk = (RsDataKind)io->loadU8();
+ RsDataType dt = (RsDataType)io->loadU8();
+ uint32_t bits = io->loadU8();
+ bool isNorm = io->loadU8() != 0;
+ LOGE(" %i %i %i %i", dk, dt, bits, isNorm);
+ rsi_ElementAdd(rsc, dk, dt, isNorm, bits, 0);
+ }
+ LOGE("processChunk_Element create");
+ ie->mRsObj = rsi_ElementCreate(rsc);
+}
+
+void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie)
+{
+ uint32_t index = io->loadU32();
+ uint32_t count = io->loadU32();
+
+ LOGE("processChunk_ElementSource count %i, index %i", count, index);
+
+ RsElement e = (RsElement)mIndex[index].mRsObj;
+
+ RsAllocation a = rsi_AllocationCreateSized(rsc, e, count);
+ Allocation * alloc = static_cast<Allocation *>(a);
+
+ float * data = (float *)alloc->getPtr();
+ while(count--) {
+ *data = io->loadF();
+ LOGE(" %f", *data);
+ data++;
+ }
+ ie->mRsObj = alloc;
+}
+
+namespace android {
+namespace renderscript {
+
+
+RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len)
+{
+ FileA3D *fa3d = new FileA3D;
+
+ FILE *f = fopen("/sdcard/test.a3d", "rb");
+ if (f) {
+ fa3d->load(rsc, f);
+ fclose(f);
+ return fa3d;
+ }
+ delete fa3d;
+ return NULL;
+}
+
+
+}
+}
diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h
new file mode 100644
index 0000000..9ee08ec
--- /dev/null
+++ b/libs/rs/rsFileA3D.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_FILE_A3D_H
+#define ANDROID_RS_FILE_A3D_H
+
+#include "RenderScript.h"
+#include "rsFileA3DDecls.h"
+#include "rsMesh.h"
+
+#include <utils/String8.h>
+#include <stdio.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class FileA3D
+{
+public:
+ FileA3D();
+ ~FileA3D();
+
+ uint32_t mMajorVersion;
+ uint32_t mMinorVersion;
+ uint64_t mIndexOffset;
+ uint64_t mStringTableOffset;
+ bool mUse64BitOffsets;
+
+ struct A3DIndexEntry {
+ String8 mID;
+ A3DChunkType mType;
+ uint64_t mOffset;
+ void * mRsObj;
+ };
+
+ bool load(Context *rsc, FILE *f);
+
+protected:
+ class IO
+ {
+ public:
+ IO(const uint8_t *, bool use64);
+
+ float loadF() {
+ mPos = (mPos + 3) & (~3);
+ float tmp = reinterpret_cast<const float *>(&mData[mPos])[0];
+ mPos += sizeof(float);
+ return tmp;
+ }
+ int32_t loadI32() {
+ mPos = (mPos + 3) & (~3);
+ int32_t tmp = reinterpret_cast<const int32_t *>(&mData[mPos])[0];
+ mPos += sizeof(int32_t);
+ return tmp;
+ }
+ uint32_t loadU32() {
+ mPos = (mPos + 3) & (~3);
+ uint32_t tmp = reinterpret_cast<const uint32_t *>(&mData[mPos])[0];
+ mPos += sizeof(uint32_t);
+ return tmp;
+ }
+ uint16_t loadU16() {
+ mPos = (mPos + 1) & (~1);
+ uint16_t tmp = reinterpret_cast<const uint16_t *>(&mData[mPos])[0];
+ mPos += sizeof(uint16_t);
+ return tmp;
+ }
+ uint8_t loadU8() {
+ uint8_t tmp = reinterpret_cast<const uint8_t *>(&mData[mPos])[0];
+ mPos += sizeof(uint8_t);
+ return tmp;
+ }
+ uint64_t loadOffset();
+ void loadString(String8 *s);
+ uint64_t getPos() const {return mPos;}
+ const uint8_t * getPtr() const;
+ protected:
+ const uint8_t * mData;
+ uint64_t mPos;
+ bool mUse64;
+ };
+
+
+ bool process(Context *rsc);
+ bool processIndex(Context *rsc, A3DIndexEntry *);
+ void processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie);
+ void processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie);
+ void processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie);
+ void processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie);
+ void processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie);
+
+ const uint8_t * mData;
+ void * mAlloc;
+ uint64_t mDataSize;
+ Context * mRsc;
+
+ Vector<A3DIndexEntry> mIndex;
+ Vector<String8> mStrings;
+ Vector<uint32_t> mStringIndexValues;
+
+};
+
+
+}
+}
+#endif //ANDROID_RS_FILE_A3D_H
+
+
diff --git a/libs/rs/rsFileA3DDecls.h b/libs/rs/rsFileA3DDecls.h
new file mode 100644
index 0000000..2a08bd3
--- /dev/null
+++ b/libs/rs/rsFileA3DDecls.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_FILE_A3D_DECLS_H
+#define ANDROID_RS_FILE_A3D_DECLS_H
+
+
+#define A3D_MAGIC_KEY "Android3D_ff"
+
+namespace android {
+namespace renderscript {
+
+ enum A3DChunkType {
+ CHUNK_EMPTY,
+
+ CHUNK_ELEMENT,
+ CHUNK_ELEMENT_SOURCE,
+ CHUNK_VERTICIES,
+ CHUNK_MESH,
+ CHUNK_PRIMITIVE,
+
+ CHUNK_LAST
+ };
+
+
+}
+}
+#endif //ANDROID_RS_FILE_A3D_H
+
+
+
diff --git a/libs/rs/rsHandcode.h b/libs/rs/rsHandcode.h
new file mode 100644
index 0000000..800eddd
--- /dev/null
+++ b/libs/rs/rsHandcode.h
@@ -0,0 +1,47 @@
+
+#define DATA_SYNC_SIZE 1024
+
+static inline void rsHCAPI_AllocationData (RsContext rsc, RsAllocation va, const void * data, uint32_t sizeBytes)
+{
+ ThreadIO *io = &((Context *)rsc)->mIO;
+ uint32_t size = sizeof(RS_CMD_AllocationData);
+ if (sizeBytes < DATA_SYNC_SIZE) {
+ size += (sizeBytes + 3) & ~3;
+ }
+ RS_CMD_AllocationData *cmd = static_cast<RS_CMD_AllocationData *>(io->mToCore.reserve(size));
+ cmd->va = va;
+ cmd->bytes = sizeBytes;
+ cmd->data = data;
+ if (sizeBytes < DATA_SYNC_SIZE) {
+ cmd->data = (void *)(cmd+1);
+ memcpy(cmd+1, data, sizeBytes);
+ io->mToCore.commit(RS_CMD_ID_AllocationData, size);
+ } else {
+ io->mToCore.commitSync(RS_CMD_ID_AllocationData, size);
+ }
+}
+
+
+static inline void rsHCAPI_Allocation1DSubData (RsContext rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void * data, uint32_t sizeBytes)
+{
+ ThreadIO *io = &((Context *)rsc)->mIO;
+ uint32_t size = sizeof(RS_CMD_Allocation1DSubData);
+ if (sizeBytes < DATA_SYNC_SIZE) {
+ size += (sizeBytes + 3) & ~3;
+ }
+ RS_CMD_Allocation1DSubData *cmd = static_cast<RS_CMD_Allocation1DSubData *>(io->mToCore.reserve(size));
+ cmd->va = va;
+ cmd->xoff = xoff;
+ cmd->count = count;
+ cmd->data = data;
+ cmd->bytes = sizeBytes;
+ if (sizeBytes < DATA_SYNC_SIZE) {
+ cmd->data = (void *)(cmd+1);
+ memcpy(cmd+1, data, sizeBytes);
+ io->mToCore.commit(RS_CMD_ID_Allocation1DSubData, size);
+ } else {
+ io->mToCore.commitSync(RS_CMD_ID_Allocation1DSubData, size);
+ }
+
+}
+
diff --git a/libs/rs/rsLight.cpp b/libs/rs/rsLight.cpp
new file mode 100644
index 0000000..6f2cf3e
--- /dev/null
+++ b/libs/rs/rsLight.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+
+#include <GLES/gl.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Light::Light(Context *rsc, bool isLocal, bool isMono) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mIsLocal = isLocal;
+ mIsMono = isMono;
+
+ mPosition[0] = 0;
+ mPosition[1] = 0;
+ mPosition[2] = 1;
+ mPosition[3] = 0;
+
+ mColor[0] = 1.f;
+ mColor[1] = 1.f;
+ mColor[2] = 1.f;
+ mColor[3] = 1.f;
+}
+
+Light::~Light()
+{
+}
+
+void Light::setPosition(float x, float y, float z)
+{
+ mPosition[0] = x;
+ mPosition[1] = y;
+ mPosition[2] = z;
+}
+
+void Light::setColor(float r, float g, float b)
+{
+ mColor[0] = r;
+ mColor[1] = g;
+ mColor[2] = b;
+}
+
+void Light::setupGL(uint32_t num) const
+{
+ glLightfv(GL_LIGHT0 + num, GL_DIFFUSE, mColor);
+ glLightfv(GL_LIGHT0 + num, GL_SPECULAR, mColor);
+ glLightfv(GL_LIGHT0 + num, GL_POSITION, mPosition);
+}
+
+////////////////////////////////////////////
+
+LightState::LightState()
+{
+ clear();
+}
+
+LightState::~LightState()
+{
+}
+
+void LightState::clear()
+{
+ mIsLocal = false;
+ mIsMono = false;
+}
+
+
+////////////////////////////////////////////////////
+//
+
+namespace android {
+namespace renderscript {
+
+void rsi_LightBegin(Context *rsc)
+{
+ rsc->mStateLight.clear();
+}
+
+void rsi_LightSetLocal(Context *rsc, bool isLocal)
+{
+ rsc->mStateLight.mIsLocal = isLocal;
+}
+
+void rsi_LightSetMonochromatic(Context *rsc, bool isMono)
+{
+ rsc->mStateLight.mIsMono = isMono;
+}
+
+RsLight rsi_LightCreate(Context *rsc)
+{
+ Light *l = new Light(rsc, rsc->mStateLight.mIsLocal,
+ rsc->mStateLight.mIsMono);
+ l->incUserRef();
+ return l;
+}
+
+void rsi_LightSetColor(Context *rsc, RsLight vl, float r, float g, float b)
+{
+ Light *l = static_cast<Light *>(vl);
+ l->setColor(r, g, b);
+}
+
+void rsi_LightSetPosition(Context *rsc, RsLight vl, float x, float y, float z)
+{
+ Light *l = static_cast<Light *>(vl);
+ l->setPosition(x, y, z);
+}
+
+
+
+}
+}
diff --git a/libs/rs/rsLight.h b/libs/rs/rsLight.h
new file mode 100644
index 0000000..d8796e6
--- /dev/null
+++ b/libs/rs/rsLight.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LIGHT_H
+#define ANDROID_LIGHT_H
+
+
+#include "rsObjectBase.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class Light : public ObjectBase
+{
+public:
+ Light(Context *, bool isLocal, bool isMono);
+ virtual ~Light();
+
+ // Values, mutable after creation.
+ void setPosition(float x, float y, float z);
+ void setColor(float r, float g, float b);
+
+ void setupGL(uint32_t num) const;
+
+protected:
+ float mColor[4];
+ float mPosition[4];
+ bool mIsLocal;
+ bool mIsMono;
+};
+
+
+class LightState {
+public:
+ LightState();
+ ~LightState();
+
+ void clear();
+
+ bool mIsMono;
+ bool mIsLocal;
+};
+
+
+}
+}
+#endif //ANDROID_LIGHT_H
+
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
new file mode 100644
index 0000000..085a81e
--- /dev/null
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsLocklessFifo.h"
+
+using namespace android;
+
+
+LocklessCommandFifo::LocklessCommandFifo()
+{
+}
+
+LocklessCommandFifo::~LocklessCommandFifo()
+{
+ if (!mInShutdown) {
+ shutdown();
+ }
+ free(mBuffer);
+}
+
+void LocklessCommandFifo::shutdown()
+{
+ mInShutdown = true;
+ mSignalToWorker.set();
+}
+
+bool LocklessCommandFifo::init(uint32_t sizeInBytes)
+{
+ // Add room for a buffer reset command
+ mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4));
+ if (!mBuffer) {
+ LOGE("LocklessFifo allocation failure");
+ return false;
+ }
+
+ if (!mSignalToControl.init() || !mSignalToWorker.init()) {
+ LOGE("Signal setup failed");
+ free(mBuffer);
+ return false;
+ }
+
+ mInShutdown = false;
+ mSize = sizeInBytes;
+ mPut = mBuffer;
+ mGet = mBuffer;
+ mEnd = mBuffer + (sizeInBytes) - 1;
+ dumpState("init");
+ return true;
+}
+
+uint32_t LocklessCommandFifo::getFreeSpace() const
+{
+ int32_t freeSpace = 0;
+ //dumpState("getFreeSpace");
+
+ if (mPut >= mGet) {
+ freeSpace = mEnd - mPut;
+ } else {
+ freeSpace = mGet - mPut;
+ }
+
+ if (freeSpace < 0) {
+ freeSpace = 0;
+ }
+ return freeSpace;
+}
+
+bool LocklessCommandFifo::isEmpty() const
+{
+ return mPut == mGet;
+}
+
+
+void * LocklessCommandFifo::reserve(uint32_t sizeInBytes)
+{
+ // Add space for command header and loop token;
+ sizeInBytes += 8;
+
+ //dumpState("reserve");
+ if (getFreeSpace() < sizeInBytes) {
+ makeSpace(sizeInBytes);
+ }
+
+ return mPut + 4;
+}
+
+void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes)
+{
+ if (mInShutdown) {
+ return;
+ }
+ //dumpState("commit 1");
+ reinterpret_cast<uint16_t *>(mPut)[0] = command;
+ reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes;
+ mPut += ((sizeInBytes + 3) & ~3) + 4;
+ //dumpState("commit 2");
+ mSignalToWorker.set();
+}
+
+void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
+{
+ if (mInShutdown) {
+ return;
+ }
+ commit(command, sizeInBytes);
+ flush();
+}
+
+void LocklessCommandFifo::flush()
+{
+ //dumpState("flush 1");
+ while(mPut != mGet) {
+ mSignalToControl.wait();
+ }
+ //dumpState("flush 2");
+}
+
+const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData)
+{
+ while(1) {
+ //dumpState("get");
+ while(isEmpty() && !mInShutdown) {
+ mSignalToControl.set();
+ mSignalToWorker.wait();
+ }
+
+ if (mInShutdown) {
+ *command = 0;
+ *bytesData = 0;
+ return 0;
+ }
+
+ *command = reinterpret_cast<const uint16_t *>(mGet)[0];
+ *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1];
+ if (*command) {
+ // non-zero command is valid
+ return mGet+4;
+ }
+
+ // zero command means reset to beginning.
+ mGet = mBuffer;
+ }
+}
+
+void LocklessCommandFifo::next()
+{
+ uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
+ mGet += ((bytes + 3) & ~3) + 4;
+ if (isEmpty()) {
+ mSignalToControl.set();
+ }
+ //dumpState("next");
+}
+
+void LocklessCommandFifo::makeSpace(uint32_t bytes)
+{
+ //dumpState("make space");
+ if ((mPut+bytes) > mEnd) {
+ // Need to loop regardless of where get is.
+ while((mGet > mPut) && (mBuffer+4 >= mGet)) {
+ usleep(100);
+ }
+
+ // Toss in a reset then the normal wait for space will do the rest.
+ reinterpret_cast<uint16_t *>(mPut)[0] = 0;
+ reinterpret_cast<uint16_t *>(mPut)[1] = 0;
+ mPut = mBuffer;
+ }
+
+ // it will fit here so we just need to wait for space.
+ while(getFreeSpace() < bytes) {
+ usleep(100);
+ }
+
+}
+
+void LocklessCommandFifo::dumpState(const char *s) const
+{
+ LOGV("%s put %p, get %p, buf %p, end %p", s, mPut, mGet, mBuffer, mEnd);
+}
+
+LocklessCommandFifo::Signal::Signal()
+{
+ mSet = true;
+}
+
+LocklessCommandFifo::Signal::~Signal()
+{
+ pthread_mutex_destroy(&mMutex);
+ pthread_cond_destroy(&mCondition);
+}
+
+bool LocklessCommandFifo::Signal::init()
+{
+ int status = pthread_mutex_init(&mMutex, NULL);
+ if (status) {
+ LOGE("LocklessFifo mutex init failure");
+ return false;
+ }
+
+ status = pthread_cond_init(&mCondition, NULL);
+ if (status) {
+ LOGE("LocklessFifo condition init failure");
+ pthread_mutex_destroy(&mMutex);
+ return false;
+ }
+
+ return true;
+}
+
+void LocklessCommandFifo::Signal::set()
+{
+ int status;
+
+ status = pthread_mutex_lock(&mMutex);
+ if (status) {
+ LOGE("LocklessCommandFifo: error %i locking for set condition.", status);
+ return;
+ }
+
+ mSet = true;
+
+ status = pthread_cond_signal(&mCondition);
+ if (status) {
+ LOGE("LocklessCommandFifo: error %i on set condition.", status);
+ }
+
+ status = pthread_mutex_unlock(&mMutex);
+ if (status) {
+ LOGE("LocklessCommandFifo: error %i unlocking for set condition.", status);
+ }
+}
+
+void LocklessCommandFifo::Signal::wait()
+{
+ int status;
+
+ status = pthread_mutex_lock(&mMutex);
+ if (status) {
+ LOGE("LocklessCommandFifo: error %i locking for condition.", status);
+ return;
+ }
+
+ if (!mSet) {
+ status = pthread_cond_wait(&mCondition, &mMutex);
+ if (status) {
+ LOGE("LocklessCommandFifo: error %i waiting on condition.", status);
+ }
+ }
+ mSet = false;
+
+ status = pthread_mutex_unlock(&mMutex);
+ if (status) {
+ LOGE("LocklessCommandFifo: error %i unlocking for condition.", status);
+ }
+}
+
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
new file mode 100644
index 0000000..d0a4356
--- /dev/null
+++ b/libs/rs/rsLocklessFifo.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_LOCKLESS_FIFO_H
+#define ANDROID_RS_LOCKLESS_FIFO_H
+
+
+#include "rsUtils.h"
+
+namespace android {
+
+
+// A simple FIFO to be used as a producer / consumer between two
+// threads. One is writer and one is reader. The common cases
+// will not require locking. It is not threadsafe for multiple
+// readers or writers by design.
+
+class LocklessCommandFifo
+{
+public:
+ bool init(uint32_t size);
+ void shutdown();
+
+ LocklessCommandFifo();
+ ~LocklessCommandFifo();
+
+
+protected:
+ class Signal {
+ public:
+ Signal();
+ ~Signal();
+
+ bool init();
+
+ void set();
+ void wait();
+
+ protected:
+ bool mSet;
+ pthread_mutex_t mMutex;
+ pthread_cond_t mCondition;
+ };
+
+ uint8_t * volatile mPut;
+ uint8_t * volatile mGet;
+ uint8_t * mBuffer;
+ uint8_t * mEnd;
+ uint8_t mSize;
+ bool mInShutdown;
+
+ Signal mSignalToWorker;
+ Signal mSignalToControl;
+
+
+
+public:
+ void * reserve(uint32_t bytes);
+ void commit(uint32_t command, uint32_t bytes);
+ void commitSync(uint32_t command, uint32_t bytes);
+
+ void flush();
+ const void * get(uint32_t *command, uint32_t *bytesData);
+ void next();
+
+ void makeSpace(uint32_t bytes);
+
+ bool isEmpty() const;
+ uint32_t getFreeSpace() const;
+
+
+private:
+ void dumpState(const char *) const;
+};
+
+
+}
+#endif
diff --git a/libs/rs/rsMatrix.cpp b/libs/rs/rsMatrix.cpp
new file mode 100644
index 0000000..2f21405
--- /dev/null
+++ b/libs/rs/rsMatrix.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsMatrix.h"
+
+#include "stdlib.h"
+#include "string.h"
+#include "math.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+
+void Matrix::loadIdentity()
+{
+ set(0, 0, 1);
+ set(1, 0, 0);
+ set(2, 0, 0);
+ set(3, 0, 0);
+
+ set(0, 1, 0);
+ set(1, 1, 1);
+ set(2, 1, 0);
+ set(3, 1, 0);
+
+ set(0, 2, 0);
+ set(1, 2, 0);
+ set(2, 2, 1);
+ set(3, 2, 0);
+
+ set(0, 3, 0);
+ set(1, 3, 0);
+ set(2, 3, 0);
+ set(3, 3, 1);
+}
+
+void Matrix::load(const float *v)
+{
+ memcpy(m, v, sizeof(m));
+}
+
+void Matrix::load(const Matrix *v)
+{
+ memcpy(m, v->m, sizeof(m));
+}
+
+void Matrix::loadRotate(float rot, float x, float y, float z)
+{
+ float c, s;
+ m[3] = 0;
+ m[7] = 0;
+ m[11]= 0;
+ m[12]= 0;
+ m[13]= 0;
+ m[14]= 0;
+ m[15]= 1;
+ rot *= float(M_PI / 180.0f);
+ c = cosf(rot);
+ s = sinf(rot);
+
+ const float len = sqrtf(x*x + y*y + z*z);
+ if (!(len != 1)) {
+ const float recipLen = 1.f / len;
+ x *= recipLen;
+ y *= recipLen;
+ z *= recipLen;
+ }
+ const float nc = 1.0f - c;
+ const float xy = x * y;
+ const float yz = y * z;
+ const float zx = z * x;
+ const float xs = x * s;
+ const float ys = y * s;
+ const float zs = z * s;
+ m[ 0] = x*x*nc + c;
+ m[ 4] = xy*nc - zs;
+ m[ 8] = zx*nc + ys;
+ m[ 1] = xy*nc + zs;
+ m[ 5] = y*y*nc + c;
+ m[ 9] = yz*nc - xs;
+ m[ 2] = zx*nc - ys;
+ m[ 6] = yz*nc + xs;
+ m[10] = z*z*nc + c;
+}
+
+void Matrix::loadScale(float x, float y, float z)
+{
+ loadIdentity();
+ m[0] = x;
+ m[5] = y;
+ m[10] = z;
+}
+
+void Matrix::loadTranslate(float x, float y, float z)
+{
+ loadIdentity();
+ m[12] = x;
+ m[13] = y;
+ m[14] = z;
+}
+
+void Matrix::loadMultiply(const Matrix *lhs, const Matrix *rhs)
+{
+ for (int i=0 ; i<4 ; i++) {
+ float ri0 = 0;
+ float ri1 = 0;
+ float ri2 = 0;
+ float ri3 = 0;
+ for (int j=0 ; j<4 ; j++) {
+ const float rhs_ij = rhs->get(i,j);
+ ri0 += lhs->get(j,0) * rhs_ij;
+ ri1 += lhs->get(j,1) * rhs_ij;
+ ri2 += lhs->get(j,2) * rhs_ij;
+ ri3 += lhs->get(j,3) * rhs_ij;
+ }
+ set(i,0, ri0);
+ set(i,1, ri1);
+ set(i,2, ri2);
+ set(i,3, ri3);
+ }
+}
+
+void Matrix::loadOrtho(float l, float r, float b, float t, float n, float f) {
+ loadIdentity();
+ m[0] = 2 / (r - l);
+ m[5] = 2 / (t - b);
+ m[10]= -2 / (f - n);
+ m[12]= -(r + l) / (r - l);
+ m[13]= -(t + b) / (t - b);
+ m[14]= -(f + n) / (f - n);
+}
+
+void Matrix::loadFrustum(float l, float r, float b, float t, float n, float f) {
+ loadIdentity();
+ m[0] = 2 * n / (r - l);
+ m[5] = 2 * n / (t - b);
+ m[8] = (r + l) / (r - l);
+ m[9] = (t + b) / (t - b);
+ m[10]= -(f + n) / (f - n);
+ m[11]= -1;
+ m[14]= -2*f*n / (f - n);
+ m[15]= 0;
+}
+
+void Matrix::vectorMultiply(float *out, const float *in) const {
+ out[0] = (m[0] * in[0]) + (m[4] * in[1]) + (m[8] * in[2]) + m[12];
+ out[1] = (m[1] * in[0]) + (m[5] * in[1]) + (m[9] * in[2]) + m[13];
+ out[2] = (m[2] * in[0]) + (m[6] * in[1]) + (m[10] * in[2]) + m[14];
+ out[3] = (m[3] * in[0]) + (m[7] * in[1]) + (m[11] * in[2]) + m[15];
+}
diff --git a/libs/rs/rsMatrix.h b/libs/rs/rsMatrix.h
new file mode 100644
index 0000000..11ce42e
--- /dev/null
+++ b/libs/rs/rsMatrix.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_MATRIX_H
+#define ANDROID_RS_MATRIX_H
+
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+struct Matrix
+{
+ float m[16];
+
+ inline float get(int i, int j) const {
+ return m[i*4 + j];
+ }
+
+ inline void set(int i, int j, float v) {
+ m[i*4 + j] = v;
+ }
+
+ void loadIdentity();
+ void load(const float *);
+ void load(const Matrix *);
+
+ void loadRotate(float rot, float x, float y, float z);
+ void loadScale(float x, float y, float z);
+ void loadTranslate(float x, float y, float z);
+ void loadMultiply(const Matrix *lhs, const Matrix *rhs);
+
+ void loadOrtho(float l, float r, float b, float t, float n, float f);
+ void loadFrustum(float l, float r, float b, float t, float n, float f);
+
+ void vectorMultiply(float *v4out, const float *v3in) const;
+
+ void multiply(const Matrix *rhs) {
+ Matrix tmp;
+ tmp.loadMultiply(this, rhs);
+ load(&tmp);
+ }
+ void rotate(float rot, float x, float y, float z) {
+ Matrix tmp;
+ tmp.loadRotate(rot, x, y, z);
+ multiply(&tmp);
+ }
+ void scale(float x, float y, float z) {
+ Matrix tmp;
+ tmp.loadScale(x, y, z);
+ multiply(&tmp);
+ }
+ void translate(float x, float y, float z) {
+ Matrix tmp;
+ tmp.loadTranslate(x, y, z);
+ multiply(&tmp);
+ }
+
+
+
+};
+
+
+
+}
+}
+
+
+
+
+#endif
+
+
+
+
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
new file mode 100644
index 0000000..d595b4e
--- /dev/null
+++ b/libs/rs/rsMesh.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"
+
+using namespace android;
+using namespace android::renderscript;
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mVerticies = NULL;
+ mVerticiesCount = 0;
+ mPrimitives = NULL;
+ mPrimitivesCount = 0;
+}
+
+Mesh::~Mesh()
+{
+}
+
+
+
+MeshContext::MeshContext()
+{
+}
+
+MeshContext::~MeshContext()
+{
+}
+
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
new file mode 100644
index 0000000..5201abd
--- /dev/null
+++ b/libs/rs/rsMesh.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_MESH_H
+#define ANDROID_RS_MESH_H
+
+
+#include "RenderScript.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class Mesh : public ObjectBase
+{
+public:
+ Mesh(Context *);
+ ~Mesh();
+
+ struct Verticies_t
+ {
+ Allocation ** mAllocations;
+ uint32_t mAllocationCount;
+
+ size_t mVertexDataSize;
+
+ size_t mOffsetCoord;
+ size_t mOffsetTex;
+ size_t mOffsetNorm;
+
+ size_t mSizeCoord;
+ size_t mSizeTex;
+ size_t mSizeNorm;
+
+ uint32_t mBufferObject;
+ };
+
+ struct Primitive_t
+ {
+ RsPrimitive mType;
+ Verticies_t *mVerticies;
+
+ uint32_t mIndexCount;
+ uint16_t *mIndicies;
+
+ uint32_t mRestartCounts;
+ uint16_t *mRestarts;
+ };
+
+ Verticies_t * mVerticies;
+ uint32_t mVerticiesCount;
+
+ Primitive_t ** mPrimitives;
+ uint32_t mPrimitivesCount;
+
+
+
+ void analyzeElement();
+protected:
+};
+
+class MeshContext
+{
+public:
+ MeshContext();
+ ~MeshContext();
+
+};
+
+
+}
+}
+#endif //ANDROID_RS_TRIANGLE_MESH_H
+
+
diff --git a/libs/rs/rsNoise.cpp b/libs/rs/rsNoise.cpp
new file mode 100644
index 0000000..764dc1a
--- /dev/null
+++ b/libs/rs/rsNoise.cpp
@@ -0,0 +1,256 @@
+/*
+ * This implementation of the noise functions was ported from the Java
+ * implementation by Jerry Huxtable (http://www.jhlabs.com) under
+ * Apache License 2.0 (see http://jhlabs.com/ip/filters/download.html)
+ *
+ * Original header:
+ *
+ * Copyright 2006 Jerry Huxtable
+ *
+ * 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 "rsNoise.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <time.h>
+
+namespace android {
+namespace renderscript {
+
+#define B 0x100
+#define BM 0xff
+#define N 0x1000
+
+static int p[B + B + 2];
+static float g3[B + B + 2][3];
+static float g2[B + B + 2][2];
+static float g1[B + B + 2];
+static bool noise_start = true;
+
+#define lerpf(start, stop, amount) start + (stop - start) * amount
+
+static inline float noise_sCurve(float t)
+{
+ return t * t * (3.0f - 2.0f * t);
+}
+
+inline void SC_normalizef2(float v[])
+{
+ float s = (float)sqrtf(v[0] * v[0] + v[1] * v[1]);
+ v[0] = v[0] / s;
+ v[1] = v[1] / s;
+}
+
+inline void SC_normalizef3(float v[])
+{
+ float s = (float)sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ v[0] = v[0] / s;
+ v[1] = v[1] / s;
+ v[2] = v[2] / s;
+}
+
+static void noise_init()
+{
+ int i, j, k;
+
+ for (i = 0; i < B; i++) {
+ p[i] = i;
+
+ g1[i] = (float)((rand() % (B + B)) - B) / B;
+
+ for (j = 0; j < 2; j++)
+ g2[i][j] = (float)((rand() % (B + B)) - B) / B;
+ SC_normalizef2(g2[i]);
+
+ for (j = 0; j < 3; j++)
+ g3[i][j] = (float)((rand() % (B + B)) - B) / B;
+ SC_normalizef3(g3[i]);
+ }
+
+ for (i = B-1; i >= 0; i--) {
+ k = p[i];
+ p[i] = p[j = rand() % B];
+ p[j] = k;
+ }
+
+ for (i = 0; i < B + 2; i++) {
+ p[B + i] = p[i];
+ g1[B + i] = g1[i];
+ for (j = 0; j < 2; j++)
+ g2[B + i][j] = g2[i][j];
+ for (j = 0; j < 3; j++)
+ g3[B + i][j] = g3[i][j];
+ }
+}
+
+float SC_noisef(float x)
+{
+ srand(time(NULL));
+ int bx0, bx1;
+ float rx0, rx1, sx, t, u, v;
+
+ if (noise_start) {
+ noise_start = false;
+ noise_init();
+ }
+
+ t = x + N;
+ bx0 = ((int)t) & BM;
+ bx1 = (bx0+1) & BM;
+ rx0 = t - (int)t;
+ rx1 = rx0 - 1.0f;
+
+ sx = noise_sCurve(rx0);
+
+ u = rx0 * g1[p[bx0]];
+ v = rx1 * g1[p[bx1]];
+ return 2.3f * lerpf(u, v, sx);
+}
+
+float SC_noisef2(float x, float y)
+{
+ srand(time(NULL));
+ int bx0, bx1, by0, by1, b00, b10, b01, b11;
+ float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
+ float *q;
+ int i, j;
+
+ if (noise_start) {
+ noise_start = false;
+ noise_init();
+ }
+
+ t = x + N;
+ bx0 = ((int)t) & BM;
+ bx1 = (bx0+1) & BM;
+ rx0 = t - (int)t;
+ rx1 = rx0 - 1.0f;
+
+ t = y + N;
+ by0 = ((int)t) & BM;
+ by1 = (by0+1) & BM;
+ ry0 = t - (int)t;
+ ry1 = ry0 - 1.0f;
+
+ i = p[bx0];
+ j = p[bx1];
+
+ b00 = p[i + by0];
+ b10 = p[j + by0];
+ b01 = p[i + by1];
+ b11 = p[j + by1];
+
+ sx = noise_sCurve(rx0);
+ sy = noise_sCurve(ry0);
+
+ q = g2[b00]; u = rx0 * q[0] + ry0 * q[1];
+ q = g2[b10]; v = rx1 * q[0] + ry0 * q[1];
+ a = lerpf(u, v, sx);
+
+ q = g2[b01]; u = rx0 * q[0] + ry1 * q[1];
+ q = g2[b11]; v = rx1 * q[0] + ry1 * q[1];
+ b = lerpf(u, v, sx);
+
+ return 1.5f*lerpf(a, b, sy);
+}
+
+float SC_noisef3(float x, float y, float z)
+{
+ srand(time(NULL));
+ int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+ float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
+ float *q;
+ int i, j;
+
+ if (noise_start) {
+ noise_start = false;
+ noise_init();
+ }
+
+ t = x + N;
+ bx0 = ((int)t) & BM;
+ bx1 = (bx0+1) & BM;
+ rx0 = t - (int)t;
+ rx1 = rx0 - 1.0f;
+
+ t = y + N;
+ by0 = ((int)t) & BM;
+ by1 = (by0+1) & BM;
+ ry0 = t - (int)t;
+ ry1 = ry0 - 1.0f;
+
+ t = z + N;
+ bz0 = ((int)t) & BM;
+ bz1 = (bz0+1) & BM;
+ rz0 = t - (int)t;
+ rz1 = rz0 - 1.0f;
+
+ i = p[bx0];
+ j = p[bx1];
+
+ b00 = p[i + by0];
+ b10 = p[j + by0];
+ b01 = p[i + by1];
+ b11 = p[j + by1];
+
+ t = noise_sCurve(rx0);
+ sy = noise_sCurve(ry0);
+ sz = noise_sCurve(rz0);
+
+ q = g3[b00 + bz0]; u = rx0 * q[0] + ry0 * q[1] + rz0 * q[2];
+ q = g3[b10 + bz0]; v = rx1 * q[0] + ry0 * q[1] + rz0 * q[2];
+ a = lerpf(u, v, t);
+
+ q = g3[b01 + bz0]; u = rx0 * q[0] + ry1 * q[1] + rz0 * q[2];
+ q = g3[b11 + bz0]; v = rx1 * q[0] + ry1 * q[1] + rz0 * q[2];
+ b = lerpf(u, v, t);
+
+ c = lerpf(a, b, sy);
+
+ q = g3[b00 + bz1]; u = rx0 * q[0] + ry0 * q[1] + rz1 * q[2];
+ q = g3[b10 + bz1]; v = rx1 * q[0] + ry0 * q[1] + rz1 * q[2];
+ a = lerpf(u, v, t);
+
+ q = g3[b01 + bz1]; u = rx0 * q[0] + ry1 * q[1] + rz1 * q[2];
+ q = g3[b11 + bz1]; v = rx1 * q[0] + ry1 * q[1] + rz1 * q[2];
+ b = lerpf(u, v, t);
+
+ d = lerpf(a, b, sy);
+
+ return 1.5f*lerpf(c, d, sz);
+}
+
+float SC_turbulencef2(float x, float y, float octaves)
+{
+ srand(time(NULL));
+ float t = 0.0f;
+
+ for (float f = 1.0f; f <= octaves; f *= 2)
+ t += fabs(SC_noisef2(f * x, f * y)) / f;
+ return t;
+}
+
+float SC_turbulencef3(float x, float y, float z, float octaves)
+{
+ srand(time(NULL));
+ float t = 0.0f;
+
+ for (float f = 1.0f; f <= octaves; f *= 2)
+ t += fabs(SC_noisef3(f * x, f * y, f * z)) / f;
+ return t;
+}
+
+}
+}
\ No newline at end of file
diff --git a/libs/rs/rsNoise.h b/libs/rs/rsNoise.h
new file mode 100644
index 0000000..9040751
--- /dev/null
+++ b/libs/rs/rsNoise.h
@@ -0,0 +1,35 @@
+/*
+ * 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_NOISE_H
+#define ANDROID_RS_NOISE_H
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+void SC_normalizef2(float v[]);
+void SC_normalizef3(float v[]);
+float SC_noisef(float x);
+float SC_noisef2(float x, float y);
+float SC_noisef3(float x, float y, float z);
+float SC_turbulencef2(float x, float y, float octaves);
+float SC_turbulencef3(float x, float y, float z, float octaves);
+
+}
+}
+
+#endif
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
new file mode 100644
index 0000000..b7d67cc
--- /dev/null
+++ b/libs/rs/rsObjectBase.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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 "rsContext.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+ObjectBase::ObjectBase(Context *rsc)
+{
+ mUserRefCount = 0;
+ mSysRefCount = 0;
+ mName = NULL;
+ mRSC = NULL;
+ mNext = NULL;
+ mPrev = NULL;
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ setContext(rsc);
+}
+
+ObjectBase::~ObjectBase()
+{
+ //LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount);
+ rsAssert(!mUserRefCount);
+ rsAssert(!mSysRefCount);
+ remove();
+ delete[] mName;
+}
+
+void ObjectBase::dumpLOGV(const char *op) const
+{
+ if (mName) {
+ LOGV("%s RSobj %p, name %s, refs %i,%i from %s,%i links %p,%p,%p",
+ op, this, mName, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+ } else {
+ LOGV("%s RSobj %p, no-name, refs %i,%i from %s,%i links %p,%p,%p",
+ op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+ }
+}
+
+void ObjectBase::setContext(Context *rsc)
+{
+ if (mRSC) {
+ remove();
+ }
+ mRSC = rsc;
+ if (rsc) {
+ add();
+ }
+}
+
+void ObjectBase::incUserRef() const
+{
+ mUserRefCount ++;
+ //LOGV("ObjectBase %p inc ref %i", this, mRefCount);
+}
+
+void ObjectBase::incSysRef() const
+{
+ mSysRefCount ++;
+ //LOGV("ObjectBase %p inc ref %i", this, mRefCount);
+}
+
+bool ObjectBase::checkDelete() const
+{
+ if (!(mSysRefCount | mUserRefCount)) {
+ if (mRSC && mRSC->props.mLogObjects) {
+ dumpLOGV("checkDelete");
+ }
+ delete this;
+ return true;
+ }
+ return false;
+}
+
+bool ObjectBase::decUserRef() const
+{
+ rsAssert(mUserRefCount > 0);
+ mUserRefCount --;
+ //dumpObj("decUserRef");
+ return checkDelete();
+}
+
+bool ObjectBase::zeroUserRef() const
+{
+ mUserRefCount = 0;
+ //dumpObj("zeroUserRef");
+ return checkDelete();
+}
+
+bool ObjectBase::decSysRef() const
+{
+ rsAssert(mSysRefCount > 0);
+ mSysRefCount --;
+ //dumpObj("decSysRef");
+ return checkDelete();
+}
+
+void ObjectBase::setName(const char *name)
+{
+ setName(name, strlen(name));
+}
+
+void ObjectBase::setName(const char *name, uint32_t len)
+{
+ delete mName;
+ mName = NULL;
+ if (name) {
+ mName = new char[len + 1];
+ memcpy(mName, name, len);
+ mName[len] = 0;
+ }
+}
+
+void ObjectBase::add() const
+{
+ rsAssert(!mNext);
+ rsAssert(!mPrev);
+ //LOGV("calling add rsc %p", mRSC);
+ mNext = mRSC->mObjHead;
+ if (mRSC->mObjHead) {
+ mRSC->mObjHead->mPrev = this;
+ }
+ mRSC->mObjHead = this;
+}
+
+void ObjectBase::remove() const
+{
+ //LOGV("calling remove rsc %p", mRSC);
+ if (!mRSC) {
+ rsAssert(!mPrev);
+ rsAssert(!mNext);
+ return;
+ }
+ if (mRSC->mObjHead == this) {
+ mRSC->mObjHead = mNext;
+ }
+ if (mPrev) {
+ mPrev->mNext = mNext;
+ }
+ if (mNext) {
+ mNext->mPrev = mPrev;
+ }
+ mPrev = NULL;
+ mNext = NULL;
+}
+
+void ObjectBase::zeroAllUserRef(Context *rsc)
+{
+ if (rsc->props.mLogObjects) {
+ LOGV("Forcing release of all outstanding user refs.");
+ }
+
+ // This operation can be slow, only to be called during context cleanup.
+ const ObjectBase * o = rsc->mObjHead;
+ while (o) {
+ //LOGE("o %p", o);
+ if (o->zeroUserRef()) {
+ // deleted the object and possibly others, restart from head.
+ o = rsc->mObjHead;
+ //LOGE("o head %p", o);
+ } else {
+ o = o->mNext;
+ //LOGE("o next %p", o);
+ }
+ }
+
+ if (rsc->props.mLogObjects) {
+ LOGV("Objects remaining.");
+ o = rsc->mObjHead;
+ while (o) {
+ o->dumpLOGV(" ");
+ o = o->mNext;
+ }
+ }
+}
+
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
new file mode 100644
index 0000000..dc85ac7
--- /dev/null
+++ b/libs/rs/rsObjectBase.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_OBJECT_BASE_H
+#define ANDROID_RS_OBJECT_BASE_H
+
+#include "rsUtils.h"
+
+
+namespace android {
+namespace renderscript {
+
+class Context;
+
+// An element is a group of Components that occupies one cell in a structure.
+class ObjectBase
+{
+public:
+ ObjectBase(Context *rsc);
+ virtual ~ObjectBase();
+
+ void incSysRef() const;
+ bool decSysRef() const;
+
+ void incUserRef() const;
+ bool decUserRef() const;
+ bool zeroUserRef() const;
+
+ const char * getName() const {
+ return mName;
+ }
+ void setName(const char *);
+ void setName(const char *, uint32_t len);
+
+ Context * getContext() const {return mRSC;}
+ void setContext(Context *);
+
+ static void zeroAllUserRef(Context *rsc);
+
+ virtual void dumpLOGV(const char *prefix) const;
+
+protected:
+ const char *mAllocFile;
+ uint32_t mAllocLine;
+
+private:
+ void add() const;
+ void remove() const;
+
+ bool checkDelete() const;
+
+ char * mName;
+ Context *mRSC;
+ mutable int32_t mSysRefCount;
+ mutable int32_t mUserRefCount;
+
+ mutable const ObjectBase * mPrev;
+ mutable const ObjectBase * mNext;
+};
+
+template<class T>
+class ObjectBaseRef
+{
+public:
+ ObjectBaseRef() {
+ mRef = NULL;
+ }
+
+ ObjectBaseRef(const ObjectBaseRef &ref) {
+ mRef = ref.get();
+ if (mRef) {
+ mRef->incSysRef();
+ }
+ }
+
+ ObjectBaseRef(T *ref) {
+ mRef = ref;
+ if (mRef) {
+ ref->incSysRef();
+ }
+ }
+
+ ~ObjectBaseRef() {
+ clear();
+ }
+
+ void set(T *ref) {
+ if (mRef != ref) {
+ clear();
+ mRef = ref;
+ if (mRef) {
+ ref->incSysRef();
+ }
+ }
+ }
+
+ void set(const ObjectBaseRef &ref) {
+ set(ref.mRef);
+ }
+
+ void clear() {
+ if (mRef) {
+ mRef->decSysRef();
+ }
+ mRef = NULL;
+ }
+
+ inline T * get() const {
+ return mRef;
+ }
+
+ inline T * operator-> () const {
+ return mRef;
+ }
+
+protected:
+ T * mRef;
+
+};
+
+
+}
+}
+
+#endif //ANDROID_RS_OBJECT_BASE_H
+
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
new file mode 100644
index 0000000..5f2a609
--- /dev/null
+++ b/libs/rs/rsProgram.cpp
@@ -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.
+ */
+
+#include "rsContext.h"
+#include "rsProgram.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+
+ mElementIn.set(in);
+ mElementOut.set(out);
+}
+
+Program::~Program()
+{
+}
+
+
+void Program::bindAllocation(Allocation *alloc)
+{
+ mConstants.set(alloc);
+ mDirty = true;
+}
+
+void Program::checkUpdatedAllocation(const Allocation *alloc)
+{
+ if (mConstants.get() == alloc) {
+ mDirty = true;
+ }
+}
+
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
new file mode 100644
index 0000000..57c654f
--- /dev/null
+++ b/libs/rs/rsProgram.h
@@ -0,0 +1,60 @@
+/*
+ * 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(Context *, Element *in, Element *out);
+ virtual ~Program();
+
+ void bindAllocation(Allocation *);
+ void checkUpdatedAllocation(const Allocation *);
+
+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;
+
+ mutable bool mDirty;
+
+
+public:
+ void forceDirty() {mDirty = true;}
+};
+
+
+
+}
+}
+#endif
+
+
+
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
new file mode 100644
index 0000000..708a0e0
--- /dev/null
+++ b/libs/rs/rsProgramFragment.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsProgramFragment.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
+ Program(rsc, in, out)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
+ mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
+ mTextureDimensions[ct] = 2;
+ }
+ mTextureEnableMask = 0;
+ mPointSpriteEnable = pointSpriteEnable;
+ mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
+}
+
+ProgramFragment::~ProgramFragment()
+{
+}
+
+void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
+{
+ if ((state->mLast.get() == this) && !mDirty) {
+ return;
+ }
+ state->mLast.set(this);
+
+ for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
+ glActiveTexture(GL_TEXTURE0 + ct);
+ if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
+ glDisable(GL_TEXTURE_2D);
+ continue;
+ }
+
+ glEnable(GL_TEXTURE_2D);
+ if (rsc->checkVersion1_1()) {
+ if (mPointSpriteEnable) {
+ glEnable(GL_POINT_SPRITE_OES);
+ } else {
+ glDisable(GL_POINT_SPRITE_OES);
+ }
+ glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
+ }
+ glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
+
+ switch(mEnvModes[ct]) {
+ case RS_TEX_ENV_MODE_REPLACE:
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ break;
+ case RS_TEX_ENV_MODE_MODULATE:
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ break;
+ case RS_TEX_ENV_MODE_DECAL:
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+ break;
+ }
+
+ if (mSamplers[ct].get()) {
+ mSamplers[ct]->setupGL();
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+
+ // Gross hack.
+ if (ct == 2) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+ }
+ }
+ glActiveTexture(GL_TEXTURE0);
+ mDirty = false;
+}
+
+
+void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
+{
+ if (slot >= MAX_TEXTURE) {
+ LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
+ return;
+ }
+
+ //LOGE("bindtex %i %p", slot, a);
+ mTextures[slot].set(a);
+ mDirty = true;
+}
+
+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);
+ mDirty = true;
+}
+
+void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
+{
+ if (slot >= MAX_TEXTURE) {
+ LOGE("Attempt to setType to a slot > MAX_TEXTURE");
+ return;
+ }
+
+ if (dim >= 4) {
+ LOGE("Attempt to setType to a dimension > 3");
+ return;
+ }
+
+ mTextureFormats[slot].set(e);
+ mTextureDimensions[slot] = dim;
+}
+
+void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
+{
+ if (slot >= MAX_TEXTURE) {
+ LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
+ return;
+ }
+
+ mEnvModes[slot] = env;
+}
+
+void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
+{
+ if (slot >= MAX_TEXTURE) {
+ LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
+ return;
+ }
+
+ uint32_t bit = 1 << slot;
+ mTextureEnableMask &= ~bit;
+ if (enable) {
+ mTextureEnableMask |= bit;
+ }
+}
+
+
+
+ProgramFragmentState::ProgramFragmentState()
+{
+ mPF = NULL;
+}
+
+ProgramFragmentState::~ProgramFragmentState()
+{
+ delete mPF;
+
+}
+
+void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
+{
+ ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
+ mDefault.set(pf);
+}
+
+void ProgramFragmentState::deinit(Context *rsc)
+{
+ mDefault.clear();
+ mLast.clear();
+}
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
+{
+ delete rsc->mStateFragment.mPF;
+ rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
+}
+
+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));
+}
+
+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));
+}
+
+void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
+{
+ const Type *t = static_cast<const Type *>(vt);
+ if (t) {
+ uint32_t dim = 1;
+ if (t->getDimY()) {
+ dim ++;
+ if (t->getDimZ()) {
+ dim ++;
+ }
+ }
+ rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
+ }
+ rsc->mStateFragment.mPF->setEnvMode(slot, env);
+ rsc->mStateFragment.mPF->setTexEnable(slot, enable);
+}
+
+RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
+{
+ ProgramFragment *pf = rsc->mStateFragment.mPF;
+ pf->incUserRef();
+ rsc->mStateFragment.mPF = 0;
+ return pf;
+}
+
+
+}
+}
+
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
new file mode 100644
index 0000000..e26c6e8
--- /dev/null
+++ b/libs/rs/rsProgramFragment.h
@@ -0,0 +1,94 @@
+/*
+ * 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 ProgramFragmentState;
+
+class ProgramFragment : public Program
+{
+public:
+ const static uint32_t MAX_TEXTURE = 2;
+
+
+
+ ProgramFragment(Context *, Element *in, Element *out, bool pointSpriteEnable);
+ virtual ~ProgramFragment();
+
+ virtual void setupGL(const Context *, ProgramFragmentState *);
+
+
+
+ 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];
+
+
+ // Hacks to create a program for now
+ RsTexEnvMode mEnvModes[MAX_TEXTURE];
+ uint32_t mTextureEnableMask;
+ bool mPointSpriteEnable;
+};
+
+class ProgramFragmentState
+{
+public:
+ ProgramFragmentState();
+ ~ProgramFragmentState();
+
+ ProgramFragment *mPF;
+ void init(Context *rsc, int32_t w, int32_t h);
+ void deinit(Context *rsc);
+
+ ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
+ ObjectBaseRef<ProgramFragment> mDefault;
+ Vector<ProgramFragment *> mPrograms;
+
+ ObjectBaseRef<ProgramFragment> mLast;
+};
+
+
+}
+}
+#endif
+
+
+
+
diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp
new file mode 100644
index 0000000..de33d9c
--- /dev/null
+++ b/libs/rs/rsProgramFragmentStore.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsProgramFragmentStore.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramFragmentStore::ProgramFragmentStore(Context *rsc, Element *in, Element *out) :
+ Program(rsc, in, out)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ 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(const Context *rsc, ProgramFragmentStoreState *state)
+{
+ if (state->mLast.get() == this) {
+ return;
+ }
+ state->mLast.set(this);
+
+ glColorMask(mColorRWriteEnable,
+ mColorGWriteEnable,
+ mColorBWriteEnable,
+ mColorAWriteEnable);
+ if (mBlendEnable) {
+ glEnable(GL_BLEND);
+ glBlendFunc(mBlendSrc, mBlendDst);
+ } else {
+ glDisable(GL_BLEND);
+ }
+
+ //LOGE("pfs %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc);
+
+ glDepthMask(mDepthWriteEnable);
+ if(mDepthTestEnable || mDepthWriteEnable) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(mDepthFunc);
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ if (mDitherEnable) {
+ glEnable(GL_DITHER);
+ } else {
+ glDisable(GL_DITHER);
+ }
+
+
+}
+
+void ProgramFragmentStore::setDitherEnable(bool enable)
+{
+ mDitherEnable = enable;
+}
+
+void ProgramFragmentStore::setDepthFunc(RsDepthFunc func)
+{
+ mDepthTestEnable = true;
+
+ switch(func) {
+ case RS_DEPTH_FUNC_ALWAYS:
+ mDepthTestEnable = false;
+ mDepthFunc = GL_ALWAYS;
+ break;
+ case RS_DEPTH_FUNC_LESS:
+ mDepthFunc = GL_LESS;
+ break;
+ case RS_DEPTH_FUNC_LEQUAL:
+ mDepthFunc = GL_LEQUAL;
+ break;
+ case RS_DEPTH_FUNC_GREATER:
+ mDepthFunc = GL_GREATER;
+ break;
+ case RS_DEPTH_FUNC_GEQUAL:
+ mDepthFunc = GL_GEQUAL;
+ break;
+ case RS_DEPTH_FUNC_EQUAL:
+ mDepthFunc = GL_EQUAL;
+ break;
+ case RS_DEPTH_FUNC_NOTEQUAL:
+ mDepthFunc = GL_NOTEQUAL;
+ break;
+ }
+}
+
+void ProgramFragmentStore::setDepthMask(bool mask)
+{
+ mDepthWriteEnable = mask;
+}
+
+void ProgramFragmentStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst)
+{
+ mBlendEnable = true;
+ if ((src == RS_BLEND_SRC_ONE) &&
+ (dst == RS_BLEND_DST_ZERO)) {
+ mBlendEnable = false;
+ }
+
+ switch(src) {
+ case RS_BLEND_SRC_ZERO:
+ mBlendSrc = GL_ZERO;
+ break;
+ case RS_BLEND_SRC_ONE:
+ mBlendSrc = GL_ONE;
+ break;
+ case RS_BLEND_SRC_DST_COLOR:
+ mBlendSrc = GL_DST_COLOR;
+ break;
+ case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
+ mBlendSrc = GL_ONE_MINUS_DST_COLOR;
+ break;
+ case RS_BLEND_SRC_SRC_ALPHA:
+ mBlendSrc = GL_SRC_ALPHA;
+ break;
+ case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
+ mBlendSrc = GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case RS_BLEND_SRC_DST_ALPHA:
+ mBlendSrc = GL_DST_ALPHA;
+ break;
+ case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
+ mBlendSrc = GL_ONE_MINUS_DST_ALPHA;
+ break;
+ case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
+ mBlendSrc = GL_SRC_ALPHA_SATURATE;
+ break;
+ }
+
+ switch(dst) {
+ case RS_BLEND_DST_ZERO:
+ mBlendDst = GL_ZERO;
+ break;
+ case RS_BLEND_DST_ONE:
+ mBlendDst = GL_ONE;
+ break;
+ case RS_BLEND_DST_SRC_COLOR:
+ mBlendDst = GL_SRC_COLOR;
+ break;
+ case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
+ mBlendDst = GL_ONE_MINUS_SRC_COLOR;
+ break;
+ case RS_BLEND_DST_SRC_ALPHA:
+ mBlendDst = GL_SRC_ALPHA;
+ break;
+ case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
+ mBlendDst = GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case RS_BLEND_DST_DST_ALPHA:
+ mBlendDst = GL_DST_ALPHA;
+ break;
+ case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
+ mBlendDst = GL_ONE_MINUS_DST_ALPHA;
+ break;
+ }
+}
+
+void ProgramFragmentStore::setColorMask(bool r, bool g, bool b, bool a)
+{
+ mColorRWriteEnable = r;
+ mColorGWriteEnable = g;
+ mColorBWriteEnable = b;
+ mColorAWriteEnable = a;
+}
+
+
+ProgramFragmentStoreState::ProgramFragmentStoreState()
+{
+ mPFS = NULL;
+}
+
+ProgramFragmentStoreState::~ProgramFragmentStoreState()
+{
+ delete mPFS;
+
+}
+
+void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h)
+{
+ ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc, NULL, NULL);
+ mDefault.set(pfs);
+}
+
+void ProgramFragmentStoreState::deinit(Context *rsc)
+{
+ mDefault.clear();
+ mLast.clear();
+}
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out)
+{
+ delete rsc->mStateFragmentStore.mPFS;
+ rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc, (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->incUserRef();
+ 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..a344387
--- /dev/null
+++ b/libs/rs/rsProgramFragmentStore.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_PROGRAM_FRAGMENT_STORE_H
+#define ANDROID_RS_PROGRAM_FRAGMENT_STORE_H
+
+#include "rsProgram.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class ProgramFragmentStoreState;
+
+class ProgramFragmentStore : public Program
+{
+public:
+ ProgramFragmentStore(Context *, Element *in, Element *out);
+ virtual ~ProgramFragmentStore();
+
+ virtual void setupGL(const Context *, ProgramFragmentStoreState *);
+
+ void setDepthFunc(RsDepthFunc);
+ void setDepthMask(bool);
+
+ void setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst);
+ void setColorMask(bool, bool, bool, bool);
+
+ void setDitherEnable(bool);
+
+protected:
+ bool mDitherEnable;
+
+ bool mBlendEnable;
+ bool mColorRWriteEnable;
+ bool mColorGWriteEnable;
+ bool mColorBWriteEnable;
+ bool mColorAWriteEnable;
+ int32_t mBlendSrc;
+ int32_t mBlendDst;
+
+ bool mDepthTestEnable;
+ bool mDepthWriteEnable;
+ int32_t mDepthFunc;
+
+ bool mStencilTestEnable;
+};
+
+class ProgramFragmentStoreState
+{
+public:
+ ProgramFragmentStoreState();
+ ~ProgramFragmentStoreState();
+ void init(Context *rsc, int32_t w, int32_t h);
+ void deinit(Context *rsc);
+
+ ObjectBaseRef<ProgramFragmentStore> mDefault;
+ ObjectBaseRef<ProgramFragmentStore> mLast;
+
+
+ ProgramFragmentStore *mPFS;
+};
+
+
+}
+}
+#endif
+
+
+
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
new file mode 100644
index 0000000..51ae7cf
--- /dev/null
+++ b/libs/rs/rsProgramRaster.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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 "rsProgramRaster.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramRaster::ProgramRaster(Context *rsc,
+ Element *in,
+ Element *out,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite) :
+ Program(rsc, in, out)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mPointSmooth = pointSmooth;
+ mLineSmooth = lineSmooth;
+ mPointSprite = pointSprite;
+
+ mPointSize = 1.0f;
+ mLineWidth = 1.0f;
+}
+
+ProgramRaster::~ProgramRaster()
+{
+}
+
+void ProgramRaster::setLineWidth(float s)
+{
+ mLineWidth = s;
+}
+
+void ProgramRaster::setPointSize(float s)
+{
+ mPointSize = s;
+}
+
+void ProgramRaster::setupGL(const Context *rsc, ProgramRasterState *state)
+{
+ if (state->mLast.get() == this) {
+ return;
+ }
+ state->mLast.set(this);
+
+ glPointSize(mPointSize);
+ if (mPointSmooth) {
+ glEnable(GL_POINT_SMOOTH);
+ } else {
+ glDisable(GL_POINT_SMOOTH);
+ }
+
+ glLineWidth(mLineWidth);
+ if (mLineSmooth) {
+ glEnable(GL_LINE_SMOOTH);
+ } else {
+ glDisable(GL_LINE_SMOOTH);
+ }
+
+ if (rsc->checkVersion1_1()) {
+ if (mPointSprite) {
+ glEnable(GL_POINT_SPRITE_OES);
+ } else {
+ glDisable(GL_POINT_SPRITE_OES);
+ }
+ }
+}
+
+
+
+ProgramRasterState::ProgramRasterState()
+{
+}
+
+ProgramRasterState::~ProgramRasterState()
+{
+}
+
+void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h)
+{
+ ProgramRaster *pr = new ProgramRaster(rsc, NULL, NULL, false, false, false);
+ mDefault.set(pr);
+}
+
+void ProgramRasterState::deinit(Context *rsc)
+{
+ mDefault.clear();
+ mLast.clear();
+}
+
+
+namespace android {
+namespace renderscript {
+
+RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, RsElement in, RsElement out,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite)
+{
+ ProgramRaster *pr = new ProgramRaster(rsc,
+ static_cast<Element *>(in),
+ static_cast<Element *>(out),
+ pointSmooth,
+ lineSmooth,
+ pointSprite);
+ pr->incUserRef();
+ return pr;
+}
+
+void rsi_ProgramRasterSetPointSize(Context * rsc, RsProgramRaster vpr, float s)
+{
+ ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
+ pr->setPointSize(s);
+}
+
+void rsi_ProgramRasterSetLineWidth(Context * rsc, RsProgramRaster vpr, float s)
+{
+ ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
+ pr->setLineWidth(s);
+}
+
+
+}
+}
+
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
new file mode 100644
index 0000000..a6d5ba8
--- /dev/null
+++ b/libs/rs/rsProgramRaster.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_PROGRAM_RASTER_H
+#define ANDROID_RS_PROGRAM_RASTER_H
+
+#include "rsProgram.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class ProgramRasterState;
+
+class ProgramRaster : public Program
+{
+public:
+ ProgramRaster(Context *rsc,
+ Element *in,
+ Element *out,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite);
+ virtual ~ProgramRaster();
+
+ virtual void setupGL(const Context *, ProgramRasterState *);
+
+ void setLineWidth(float w);
+ void setPointSize(float s);
+
+protected:
+ bool mPointSmooth;
+ bool mLineSmooth;
+ bool mPointSprite;
+
+ float mPointSize;
+ float mLineWidth;
+
+
+};
+
+class ProgramRasterState
+{
+public:
+ ProgramRasterState();
+ ~ProgramRasterState();
+ void init(Context *rsc, int32_t w, int32_t h);
+ void deinit(Context *rsc);
+
+ ObjectBaseRef<ProgramRaster> mDefault;
+ ObjectBaseRef<ProgramRaster> mLast;
+};
+
+
+}
+}
+#endif
+
+
+
+
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
new file mode 100644
index 0000000..eea8b3b
--- /dev/null
+++ b/libs/rs/rsProgramVertex.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsProgramVertex.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) :
+ Program(rsc, in, out)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mTextureMatrixEnable = false;
+ mLightCount = 0;
+}
+
+ProgramVertex::~ProgramVertex()
+{
+}
+
+static void logMatrix(const char *txt, const float *f)
+{
+ LOGV("Matrix %s, %p", txt, f);
+ LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[0], f[4], f[8], f[12]);
+ LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[1], f[5], f[9], f[13]);
+ LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[2], f[6], f[10], f[14]);
+ LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]);
+}
+
+void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
+{
+ if ((state->mLast.get() == this) && !mDirty) {
+ return;
+ }
+ state->mLast.set(this);
+
+ const float *f = static_cast<const float *>(mConstants->getPtr());
+
+ glMatrixMode(GL_TEXTURE);
+ if (mTextureMatrixEnable) {
+ glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
+ } else {
+ glLoadIdentity();
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ if (mLightCount) {
+ int v = 0;
+ glEnable(GL_LIGHTING);
+ glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v);
+ for (uint32_t ct = 0; ct < mLightCount; ct++) {
+ const Light *l = mLights[ct].get();
+ glEnable(GL_LIGHT0 + ct);
+ l->setupGL(ct);
+ }
+ for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) {
+ glDisable(GL_LIGHT0 + ct);
+ }
+ } else {
+ glDisable(GL_LIGHTING);
+ }
+
+ if (!f) {
+ LOGE("Must bind constants to vertex program");
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
+
+ mDirty = false;
+}
+
+void ProgramVertex::addLight(const Light *l)
+{
+ if (mLightCount < MAX_LIGHTS) {
+ mLights[mLightCount].set(l);
+ mLightCount++;
+ }
+}
+
+void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
+{
+ float *f = static_cast<float *>(mConstants->getPtr());
+ memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
+ mDirty = true;
+}
+
+void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
+{
+ float *f = static_cast<float *>(mConstants->getPtr());
+ memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
+ mDirty = true;
+}
+
+void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
+{
+ float *f = static_cast<float *>(mConstants->getPtr());
+ memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
+ mDirty = true;
+}
+
+void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const
+{
+ float *f = static_cast<float *>(mConstants->getPtr());
+ Matrix mvp;
+ mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
+ (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
+ mvp.vectorMultiply(v4out, v3in);
+}
+
+ProgramVertexState::ProgramVertexState()
+{
+ mPV = NULL;
+}
+
+ProgramVertexState::~ProgramVertexState()
+{
+ delete mPV;
+}
+
+void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
+{
+ rsi_ElementBegin(rsc);
+ rsi_ElementAdd(rsc, RS_KIND_USER, RS_TYPE_FLOAT, false, 32, NULL);
+ RsElement e = rsi_ElementCreate(rsc);
+
+ rsi_TypeBegin(rsc, e);
+ rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
+ mAllocType.set((Type *)rsi_TypeCreate(rsc));
+
+ ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL);
+ Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get());
+ mDefaultAlloc.set(alloc);
+ mDefault.set(pv);
+
+ pv->bindAllocation(alloc);
+
+ Matrix m;
+ m.loadOrtho(0,w, h,0, -1,1);
+ alloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
+
+ m.loadIdentity();
+ alloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
+}
+
+void ProgramVertexState::deinit(Context *rsc)
+{
+ mDefaultAlloc.clear();
+ mDefault.clear();
+ mAllocType.clear();
+ mLast.clear();
+ delete mPV;
+ mPV = NULL;
+}
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out)
+{
+ delete rsc->mStateVertex.mPV;
+ rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out);
+}
+
+RsProgramVertex rsi_ProgramVertexCreate(Context *rsc)
+{
+ ProgramVertex *pv = rsc->mStateVertex.mPV;
+ pv->incUserRef();
+ rsc->mStateVertex.mPV = 0;
+ return pv;
+}
+
+void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants)
+{
+ ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm);
+ pv->bindAllocation(static_cast<Allocation *>(constants));
+}
+
+void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable)
+{
+ rsc->mStateVertex.mPV->setTextureMatrixEnable(enable);
+}
+
+void rsi_ProgramVertexAddLight(Context *rsc, RsLight light)
+{
+ rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light));
+}
+
+
+}
+}
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
new file mode 100644
index 0000000..493668c
--- /dev/null
+++ b/libs/rs/rsProgramVertex.h
@@ -0,0 +1,85 @@
+/*
+ * 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 ProgramVertexState;
+
+class ProgramVertex : public Program
+{
+public:
+ const static uint32_t MAX_LIGHTS = 8;
+
+ ProgramVertex(Context *, Element *in, Element *out);
+ virtual ~ProgramVertex();
+
+ virtual void setupGL(const Context *rsc, ProgramVertexState *state);
+
+
+ void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
+ void addLight(const Light *);
+
+ void setProjectionMatrix(const rsc_Matrix *) const;
+ void setModelviewMatrix(const rsc_Matrix *) const;
+ void setTextureMatrix(const rsc_Matrix *) const;
+
+ void transformToScreen(const Context *, float *v4out, const float *v3in) const;
+
+
+protected:
+ uint32_t mLightCount;
+ ObjectBaseRef<const Light> mLights[MAX_LIGHTS];
+
+ // Hacks to create a program for now
+ bool mTextureMatrixEnable;
+};
+
+
+class ProgramVertexState
+{
+public:
+ ProgramVertexState();
+ ~ProgramVertexState();
+
+ void init(Context *rsc, int32_t w, int32_t h);
+ void deinit(Context *rsc);
+
+ ObjectBaseRef<ProgramVertex> mDefault;
+ ObjectBaseRef<ProgramVertex> mLast;
+ ObjectBaseRef<Allocation> mDefaultAlloc;
+
+ ObjectBaseRef<Type> mAllocType;
+
+ 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..b793750
--- /dev/null
+++ b/libs/rs/rsSampler.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include "rsContext.h"
+#include "rsSampler.h"
+
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Sampler::Sampler(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ // Should not get called.
+ rsAssert(0);
+}
+
+Sampler::Sampler(Context *rsc,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mMagFilter = magFilter;
+ mMinFilter = minFilter;
+ mWrapS = wrapS;
+ mWrapT = wrapT;
+ mWrapR = wrapR;
+}
+
+Sampler::~Sampler()
+{
+}
+
+void Sampler::setupGL()
+{
+ GLenum trans[] = {
+ GL_NEAREST, //RS_SAMPLER_NEAREST,
+ GL_LINEAR, //RS_SAMPLER_LINEAR,
+ GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
+ GL_REPEAT, //RS_SAMPLER_WRAP,
+ GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
+
+ };
+
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, trans[mWrapS]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, trans[mWrapT]);
+
+}
+
+void Sampler::bindToContext(SamplerState *ss, uint32_t slot)
+{
+ ss->mSamplers[slot].set(this);
+ mBoundSlot = slot;
+}
+
+void Sampler::unbindFromContext(SamplerState *ss)
+{
+ int32_t slot = mBoundSlot;
+ mBoundSlot = -1;
+ ss->mSamplers[slot].clear();
+}
+
+void SamplerState::setupGL()
+{
+ for (uint32_t ct=0; ct < RS_MAX_SAMPLER_SLOT; ct++) {
+ Sampler *s = mSamplers[ct].get();
+ if (s) {
+ s->setupGL();
+ } else {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ }
+}
+
+////////////////////////////////
+
+namespace android {
+namespace renderscript {
+
+
+void rsi_SamplerBegin(Context *rsc)
+{
+ SamplerState * ss = &rsc->mStateSampler;
+
+ ss->mMagFilter = RS_SAMPLER_LINEAR;
+ ss->mMinFilter = RS_SAMPLER_LINEAR;
+ ss->mWrapS = RS_SAMPLER_WRAP;
+ ss->mWrapT = RS_SAMPLER_WRAP;
+ ss->mWrapR = RS_SAMPLER_WRAP;
+}
+
+void rsi_SamplerSet(Context *rsc, RsSamplerParam param, RsSamplerValue value)
+{
+ SamplerState * ss = &rsc->mStateSampler;
+
+ switch(param) {
+ case RS_SAMPLER_MAG_FILTER:
+ ss->mMagFilter = value;
+ break;
+ case RS_SAMPLER_MIN_FILTER:
+ ss->mMinFilter = value;
+ break;
+ case RS_SAMPLER_WRAP_S:
+ ss->mWrapS = value;
+ break;
+ case RS_SAMPLER_WRAP_T:
+ ss->mWrapT = value;
+ break;
+ case RS_SAMPLER_WRAP_R:
+ ss->mWrapR = value;
+ break;
+ }
+
+}
+
+RsSampler rsi_SamplerCreate(Context *rsc)
+{
+ SamplerState * ss = &rsc->mStateSampler;
+
+
+ Sampler * s = new Sampler(rsc,
+ ss->mMagFilter,
+ ss->mMinFilter,
+ ss->mWrapS,
+ ss->mWrapT,
+ ss->mWrapR);
+ s->incUserRef();
+ return s;
+}
+
+
+}}
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
new file mode 100644
index 0000000..ccf9b4d
--- /dev/null
+++ b/libs/rs/rsSampler.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_SAMPLER_H
+#define ANDROID_RS_SAMPLER_H
+
+#include "rsAllocation.h"
+#include "RenderScript.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+const static uint32_t RS_MAX_SAMPLER_SLOT = 16;
+
+class SamplerState;
+
+class Sampler : public ObjectBase
+{
+public:
+ Sampler(Context *,
+ 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(Context *);
+
+};
+
+
+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..cb1436b
--- /dev/null
+++ b/libs/rs/rsScript.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ memset(&mEnviroment, 0, sizeof(mEnviroment));
+ mEnviroment.mClearColor[0] = 0;
+ mEnviroment.mClearColor[1] = 0;
+ mEnviroment.mClearColor[2] = 0;
+ mEnviroment.mClearColor[3] = 1;
+ mEnviroment.mClearDepth = 1;
+ mEnviroment.mClearStencil = 0;
+ mEnviroment.mIsRoot = false;
+}
+
+Script::~Script()
+{
+}
+
+namespace android {
+namespace renderscript {
+
+
+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));
+}
+
+void rsi_ScriptSetClearColor(Context * rsc, RsScript vs, float r, float g, float b, float a)
+{
+ Script *s = static_cast<Script *>(vs);
+ s->mEnviroment.mClearColor[0] = r;
+ s->mEnviroment.mClearColor[1] = g;
+ s->mEnviroment.mClearColor[2] = b;
+ s->mEnviroment.mClearColor[3] = a;
+}
+
+void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, uint32_t length)
+{
+ Script *s = static_cast<Script *>(vs);
+ s->mEnviroment.mTimeZone = timeZone;
+}
+
+void rsi_ScriptSetClearDepth(Context * rsc, RsScript vs, float v)
+{
+ Script *s = static_cast<Script *>(vs);
+ s->mEnviroment.mClearDepth = v;
+}
+
+void rsi_ScriptSetClearStencil(Context * rsc, RsScript vs, uint32_t v)
+{
+ Script *s = static_cast<Script *>(vs);
+ s->mEnviroment.mClearStencil = v;
+}
+
+void rsi_ScriptSetType(Context * rsc, RsType vt, uint32_t slot, bool writable, const char *name)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ const Type *t = static_cast<const Type *>(vt);
+ ss->mConstantBufferTypes[slot].set(t);
+ ss->mSlotWritable[slot] = writable;
+ if (name) {
+ ss->mSlotNames[slot].setTo(name);
+ } else {
+ ss->mSlotNames[slot].setTo("");
+ }
+}
+
+void rsi_ScriptSetInvoke(Context *rsc, const char *name, uint32_t slot)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mInvokableNames[slot] = name;
+}
+
+void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot)
+{
+ Script *s = static_cast<Script *>(vs);
+ s->setupScript();
+ s->mEnviroment.mInvokables[slot]();
+}
+
+
+void rsi_ScriptSetRoot(Context * rsc, bool isRoot)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mScript->mEnviroment.mIsRoot = isRoot;
+}
+
+
+}
+}
+
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
new file mode 100644
index 0000000..bc40854
--- /dev/null
+++ b/libs/rs/rsScript.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_SCRIPT_H
+#define ANDROID_RS_SCRIPT_H
+
+#include "rsAllocation.h"
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class ProgramVertex;
+class ProgramFragment;
+class ProgramRaster;
+class ProgramFragmentStore;
+
+#define MAX_SCRIPT_BANKS 16
+
+class Script : public ObjectBase
+{
+public:
+ typedef void (* InvokeFunc_t)(void);
+
+ Script(Context *);
+ virtual ~Script();
+
+
+ struct Enviroment_t {
+ bool mIsRoot;
+ float mClearColor[4];
+ float mClearDepth;
+ uint32_t mClearStencil;
+
+ uint32_t mStartTimeMillis;
+ const char* mTimeZone;
+
+ ObjectBaseRef<ProgramVertex> mVertex;
+ ObjectBaseRef<ProgramFragment> mFragment;
+ ObjectBaseRef<ProgramRaster> mRaster;
+ ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+ InvokeFunc_t mInvokables[MAX_SCRIPT_BANKS];
+ char * mScriptText;
+ uint32_t mScriptTextLength;
+ };
+ Enviroment_t mEnviroment;
+
+ uint32_t mCounstantBufferCount;
+
+
+ ObjectBaseRef<Allocation> mSlots[MAX_SCRIPT_BANKS];
+ ObjectBaseRef<const Type> mTypes[MAX_SCRIPT_BANKS];
+ String8 mSlotNames[MAX_SCRIPT_BANKS];
+ bool mSlotWritable[MAX_SCRIPT_BANKS];
+
+
+
+ virtual void setupScript() = 0;
+ virtual bool run(Context *, uint32_t launchID) = 0;
+};
+
+
+
+}
+}
+#endif
+
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
new file mode 100644
index 0000000..073d98b
--- /dev/null
+++ b/libs/rs/rsScriptC.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+#include "rsMatrix.h"
+
+#include "acc/acc.h"
+#include "utils/Timers.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define GET_TLS() Context::ScriptTLSStruct * tls = \
+ (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+ Context * rsc = tls->mContext; \
+ ScriptC * sc = (ScriptC *) tls->mScript
+
+
+ScriptC::ScriptC(Context *rsc) : Script(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mAccScript = NULL;
+ memset(&mProgram, 0, sizeof(mProgram));
+}
+
+ScriptC::~ScriptC()
+{
+ if (mAccScript) {
+ accDeleteScript(mAccScript);
+ }
+ free(mEnviroment.mScriptText);
+ mEnviroment.mScriptText = NULL;
+}
+
+void ScriptC::setupScript()
+{
+ for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+ if (mProgram.mSlotPointers[ct]) {
+ *mProgram.mSlotPointers[ct] = mSlots[ct]->getPtr();
+ }
+ }
+}
+
+
+bool ScriptC::run(Context *rsc, uint32_t launchIndex)
+{
+ Context::ScriptTLSStruct * tls =
+ (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
+ rsAssert(tls);
+
+ if (mEnviroment.mFragmentStore.get()) {
+ rsc->setFragmentStore(mEnviroment.mFragmentStore.get());
+ }
+ if (mEnviroment.mFragment.get()) {
+ rsc->setFragment(mEnviroment.mFragment.get());
+ }
+ if (mEnviroment.mVertex.get()) {
+ rsc->setVertex(mEnviroment.mVertex.get());
+ }
+ if (mEnviroment.mRaster.get()) {
+ rsc->setRaster(mEnviroment.mRaster.get());
+ }
+
+ if (launchIndex == 0) {
+ mEnviroment.mStartTimeMillis
+ = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
+ }
+ setupScript();
+
+ bool ret = false;
+ tls->mScript = this;
+ ret = mProgram.mScript(launchIndex) != 0;
+ tls->mScript = NULL;
+ return ret;
+}
+
+ScriptCState::ScriptCState()
+{
+ mScript = NULL;
+ clear();
+}
+
+ScriptCState::~ScriptCState()
+{
+ delete mScript;
+ mScript = NULL;
+}
+
+void ScriptCState::clear()
+{
+ for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+ mConstantBufferTypes[ct].clear();
+ mSlotNames[ct].setTo("");
+ mInvokableNames[ct].setTo("");
+ mSlotWritable[ct] = false;
+ }
+
+ delete mScript;
+ mScript = new ScriptC(NULL);
+
+ mInt32Defines.clear();
+ mFloatDefines.clear();
+}
+
+static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name)
+{
+ const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name);
+ if (sym) {
+ return sym->mPtr;
+ }
+ LOGE("ScriptC sym lookup failed for %s", name);
+ return NULL;
+}
+
+void ScriptCState::runCompiler(Context *rsc, ScriptC *s)
+{
+ s->mAccScript = accCreateScript();
+ String8 tmp;
+
+ rsc->appendNameDefines(&tmp);
+ appendDecls(&tmp);
+ rsc->appendVarDefines(&tmp);
+ appendVarDefines(rsc, &tmp);
+ appendTypes(rsc, &tmp);
+ tmp.append("#line 1\n");
+
+ const char* scriptSource[] = {tmp.string(), s->mEnviroment.mScriptText};
+ int scriptLength[] = {tmp.length(), s->mEnviroment.mScriptTextLength} ;
+ accScriptSource(s->mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
+ accRegisterSymbolCallback(s->mAccScript, symbolLookup, NULL);
+ accCompileScript(s->mAccScript);
+ accGetScriptLabel(s->mAccScript, "main", (ACCvoid**) &s->mProgram.mScript);
+ accGetScriptLabel(s->mAccScript, "init", (ACCvoid**) &s->mProgram.mInit);
+ rsAssert(s->mProgram.mScript);
+
+ if (!s->mProgram.mScript) {
+ ACCchar buf[4096];
+ ACCsizei len;
+ accGetScriptInfoLog(s->mAccScript, sizeof(buf), &len, buf);
+ LOGV(buf);
+ }
+
+ if (s->mProgram.mInit) {
+ s->mProgram.mInit();
+ }
+
+ for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+ if (mSlotNames[ct].length() > 0) {
+ accGetScriptLabel(s->mAccScript,
+ mSlotNames[ct].string(),
+ (ACCvoid**) &s->mProgram.mSlotPointers[ct]);
+ }
+ }
+
+ for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+ if (mInvokableNames[ct].length() > 0) {
+ accGetScriptLabel(s->mAccScript,
+ mInvokableNames[ct].string(),
+ (ACCvoid**) &s->mEnviroment.mInvokables[ct]);
+ }
+ }
+
+ s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
+ s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
+ s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+ s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
+
+ if (s->mProgram.mScript) {
+ const static int pragmaMax = 16;
+ ACCsizei pragmaCount;
+ ACCchar * str[pragmaMax];
+ accGetPragmas(s->mAccScript, &pragmaCount, pragmaMax, &str[0]);
+
+ for (int ct=0; ct < pragmaCount; ct+=2) {
+ if (!strcmp(str[ct], "version")) {
+ continue;
+ }
+
+ if (!strcmp(str[ct], "stateVertex")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ s->mEnviroment.mVertex.clear();
+ continue;
+ }
+ ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
+ if (pv != NULL) {
+ s->mEnviroment.mVertex.set(pv);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateRaster")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ s->mEnviroment.mRaster.clear();
+ continue;
+ }
+ ProgramRaster * pr = (ProgramRaster *)rsc->lookupName(str[ct+1]);
+ if (pr != NULL) {
+ s->mEnviroment.mRaster.set(pr);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateFragment")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ s->mEnviroment.mFragment.clear();
+ continue;
+ }
+ ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
+ if (pf != NULL) {
+ s->mEnviroment.mFragment.set(pf);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateStore")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ s->mEnviroment.mFragmentStore.clear();
+ continue;
+ }
+ ProgramFragmentStore * pfs =
+ (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
+ if (pfs != NULL) {
+ s->mEnviroment.mFragmentStore.set(pfs);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateStore", str[ct+1]);
+ }
+
+ }
+
+
+ } else {
+ // Deal with an error.
+ }
+}
+
+static void appendElementBody(String8 *s, const Element *e)
+{
+ s->append(" {\n");
+ for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
+ const Component *c = e->getComponent(ct2);
+ s->append(" ");
+ s->append(c->getCType());
+ s->append(" ");
+ s->append(c->getComponentName());
+ s->append(";\n");
+ }
+ s->append("}");
+}
+
+void ScriptCState::appendVarDefines(const Context *rsc, String8 *str)
+{
+ char buf[256];
+ if (rsc->props.mLogScripts) {
+ LOGD("appendVarDefines mInt32Defines.size()=%d mFloatDefines.size()=%d\n",
+ mInt32Defines.size(), mFloatDefines.size());
+ }
+ for (size_t ct=0; ct < mInt32Defines.size(); ct++) {
+ str->append("#define ");
+ str->append(mInt32Defines.keyAt(ct));
+ str->append(" ");
+ sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct));
+ str->append(buf);
+ }
+ for (size_t ct=0; ct < mFloatDefines.size(); ct++) {
+ str->append("#define ");
+ str->append(mFloatDefines.keyAt(ct));
+ str->append(" ");
+ sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct));
+ str->append(buf);
+ }
+}
+
+
+
+void ScriptCState::appendTypes(const Context *rsc, String8 *str)
+{
+ char buf[256];
+ String8 tmp;
+
+ str->append("struct vec2_s {float x; float y;};");
+ str->append("struct vec3_s {float x; float y; float z;};");
+ str->append("struct vec4_s {float x; float y; float z; float w;};");
+
+ for (size_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+ const Type *t = mConstantBufferTypes[ct].get();
+ if (!t) {
+ continue;
+ }
+ const Element *e = t->getElement();
+ if (e->getName() && (e->getComponentCount() > 1)) {
+ String8 s("struct struct_");
+ s.append(e->getName());
+ appendElementBody(&s, e);
+ s.append(";\n");
+ s.append("#define ");
+ s.append(e->getName());
+ s.append("_t struct struct_");
+ s.append(e->getName());
+ s.append("\n\n");
+ if (rsc->props.mLogScripts) {
+ LOGV(s);
+ }
+ str->append(s);
+ }
+
+ if (t->getName()) {
+ for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
+ const Component *c = e->getComponent(ct2);
+ tmp.setTo("#define OFFSETOF_");
+ tmp.append(t->getName());
+ tmp.append("_");
+ tmp.append(c->getComponentName());
+ sprintf(buf, " %i\n", ct2);
+ tmp.append(buf);
+ if (rsc->props.mLogScripts) {
+ LOGV(tmp);
+ }
+ str->append(tmp);
+ }
+ }
+
+ if (mSlotNames[ct].length() > 0) {
+ String8 s;
+ if (e->getComponentCount() > 1) {
+ if (e->getName()) {
+ // Use the named struct
+ s.setTo(e->getName());
+ s.append("_t *");
+ } else {
+ // create an struct named from the slot.
+ s.setTo("struct ");
+ s.append(mSlotNames[ct]);
+ s.append("_s");
+ appendElementBody(&s, e);
+ s.append(";\n");
+ s.append("struct ");
+ s.append(mSlotNames[ct]);
+ s.append("_s * ");
+ }
+ } else {
+ // Just make an array
+ s.setTo(e->getComponent(0)->getCType());
+ s.append("_t *");
+ }
+ s.append(mSlotNames[ct]);
+ s.append(";\n");
+ if (rsc->props.mLogScripts) {
+ LOGV(s);
+ }
+ str->append(s);
+ }
+ }
+}
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ScriptCBegin(Context * rsc)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->clear();
+}
+
+void rsi_ScriptCSetScript(Context * rsc, void *vp)
+{
+ rsAssert(0);
+ //ScriptCState *ss = &rsc->mScriptC;
+ //ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
+}
+
+void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+
+ char *t = (char *)malloc(len + 1);
+ memcpy(t, text, len);
+ t[len] = 0;
+ ss->mScript->mEnviroment.mScriptText = t;
+ ss->mScript->mEnviroment.mScriptTextLength = len;
+}
+
+
+RsScript rsi_ScriptCCreate(Context * rsc)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+
+ ScriptC *s = ss->mScript;
+ ss->mScript = NULL;
+
+ ss->runCompiler(rsc, s);
+ s->incUserRef();
+ s->setContext(rsc);
+ for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+ s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
+ s->mSlotNames[ct] = ss->mSlotNames[ct];
+ s->mSlotWritable[ct] = ss->mSlotWritable[ct];
+ }
+
+ ss->clear();
+ return s;
+}
+
+void rsi_ScriptCSetDefineF(Context *rsc, const char* name, float value)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mFloatDefines.add(String8(name), value);
+}
+
+void rsi_ScriptCSetDefineI32(Context *rsc, const char* name, int32_t value)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mInt32Defines.add(String8(name), value);
+}
+
+}
+}
+
+
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
new file mode 100644
index 0000000..69afc18
--- /dev/null
+++ b/libs/rs/rsScriptC.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_SCRIPT_C_H
+#define ANDROID_RS_SCRIPT_C_H
+
+#include "rsScript.h"
+
+#include "RenderScriptEnv.h"
+
+#include <utils/KeyedVector.h>
+
+struct ACCscript;
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+
+class ScriptC : public Script
+{
+public:
+ typedef int (*RunScript_t)(uint32_t launchIndex);
+ typedef void (*VoidFunc_t)();
+
+ ScriptC(Context *);
+ virtual ~ScriptC();
+
+ struct Program_t {
+ int mVersionMajor;
+ int mVersionMinor;
+
+ RunScript_t mScript;
+ VoidFunc_t mInit;
+
+ void ** mSlotPointers[MAX_SCRIPT_BANKS];
+ };
+
+ Program_t mProgram;
+
+ ACCscript* mAccScript;
+
+ virtual void setupScript();
+ virtual bool run(Context *, uint32_t launchID);
+};
+
+class ScriptCState
+{
+public:
+ ScriptCState();
+ ~ScriptCState();
+
+ ScriptC *mScript;
+
+ ObjectBaseRef<const Type> mConstantBufferTypes[MAX_SCRIPT_BANKS];
+ String8 mSlotNames[MAX_SCRIPT_BANKS];
+ bool mSlotWritable[MAX_SCRIPT_BANKS];
+ String8 mInvokableNames[MAX_SCRIPT_BANKS];
+
+ void clear();
+ void runCompiler(Context *rsc, ScriptC *s);
+ void appendVarDefines(const Context *rsc, String8 *str);
+ void appendTypes(const Context *rsc, String8 *str);
+
+ struct SymbolTable_t {
+ const char * mName;
+ void * mPtr;
+ const char * mRet;
+ const char * mParam;
+ };
+ static SymbolTable_t gSyms[];
+ static const SymbolTable_t * lookupSymbol(const char *);
+ static void appendDecls(String8 *str);
+
+ KeyedVector<String8,int> mInt32Defines;
+ KeyedVector<String8,float> mFloatDefines;
+};
+
+
+}
+}
+#endif
+
+
+
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
new file mode 100644
index 0000000..5aef56d
--- /dev/null
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -0,0 +1,1407 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+#include "rsMatrix.h"
+#include "rsNoise.h"
+
+#include "acc/acc.h"
+#include "utils/Timers.h"
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <time.h>
+#include <cutils/tztime.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define GET_TLS() Context::ScriptTLSStruct * tls = \
+ (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+ Context * rsc = tls->mContext; \
+ ScriptC * sc = (ScriptC *) tls->mScript
+
+typedef struct {
+ float x;
+ float y;
+ float z;
+} vec3_t;
+
+typedef struct {
+ float x;
+ float y;
+ float z;
+ float w;
+} vec4_t;
+
+typedef struct {
+ float x;
+ float y;
+} vec2_t;
+
+//////////////////////////////////////////////////////////////////////////////
+// IO routines
+//////////////////////////////////////////////////////////////////////////////
+
+static float SC_loadF(uint32_t bank, uint32_t offset)
+{
+ GET_TLS();
+ const void *vp = sc->mSlots[bank]->getPtr();
+ const float *f = static_cast<const float *>(vp);
+ //LOGE("loadF %i %i = %f %x", bank, offset, f, ((int *)&f)[0]);
+ return f[offset];
+}
+
+static int32_t SC_loadI32(uint32_t bank, uint32_t offset)
+{
+ GET_TLS();
+ const void *vp = sc->mSlots[bank]->getPtr();
+ const int32_t *i = static_cast<const int32_t *>(vp);
+ //LOGE("loadI32 %i %i = %i", bank, offset, t);
+ return i[offset];
+}
+
+static float* SC_loadArrayF(uint32_t bank, uint32_t offset)
+{
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ float *f = static_cast<float *>(vp);
+ return f + offset;
+}
+
+static int32_t* SC_loadArrayI32(uint32_t bank, uint32_t offset)
+{
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ int32_t *i = static_cast<int32_t *>(vp);
+ return i + offset;
+}
+
+static float* SC_loadSimpleMeshVerticesF(RsSimpleMesh mesh, uint32_t idx)
+{
+ SimpleMesh *tm = static_cast<SimpleMesh *>(mesh);
+ void *vp = tm->mVertexBuffers[idx]->getPtr();;
+ return static_cast<float *>(vp);
+}
+
+static void SC_updateSimpleMesh(RsSimpleMesh mesh)
+{
+ SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
+ sm->uploadAll();
+}
+
+static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
+{
+ GET_TLS();
+ const void *vp = sc->mSlots[bank]->getPtr();
+ const uint32_t *i = static_cast<const uint32_t *>(vp);
+ return i[offset];
+}
+
+static void SC_loadVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v)
+{
+ GET_TLS();
+ const void *vp = sc->mSlots[bank]->getPtr();
+ const float *f = static_cast<const float *>(vp);
+ memcpy(v, &f[offset], sizeof(rsc_Vector4));
+}
+
+static void SC_loadMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m)
+{
+ GET_TLS();
+ const void *vp = sc->mSlots[bank]->getPtr();
+ const float *f = static_cast<const float *>(vp);
+ memcpy(m, &f[offset], sizeof(rsc_Matrix));
+}
+
+
+static void SC_storeF(uint32_t bank, uint32_t offset, float v)
+{
+ //LOGE("storeF %i %i %f", bank, offset, v);
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ float *f = static_cast<float *>(vp);
+ f[offset] = v;
+}
+
+static void SC_storeI32(uint32_t bank, uint32_t offset, int32_t v)
+{
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ int32_t *f = static_cast<int32_t *>(vp);
+ static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
+}
+
+static void SC_storeU32(uint32_t bank, uint32_t offset, uint32_t v)
+{
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ uint32_t *f = static_cast<uint32_t *>(vp);
+ static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
+}
+
+static void SC_storeVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v)
+{
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ float *f = static_cast<float *>(vp);
+ memcpy(&f[offset], v, sizeof(rsc_Vector4));
+}
+
+static void SC_storeMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m)
+{
+ GET_TLS();
+ void *vp = sc->mSlots[bank]->getPtr();
+ float *f = static_cast<float *>(vp);
+ memcpy(&f[offset], m, sizeof(rsc_Matrix));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Vec3 routines
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_vec3Norm(vec3_t *v)
+{
+ float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
+ len = 1 / len;
+ v->x *= len;
+ v->y *= len;
+ v->z *= len;
+}
+
+static float SC_vec3Length(const vec3_t *v)
+{
+ return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
+}
+
+static void SC_vec3Add(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
+{
+ dest->x = lhs->x + rhs->x;
+ dest->y = lhs->y + rhs->y;
+ dest->z = lhs->z + rhs->z;
+}
+
+static void SC_vec3Sub(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
+{
+ dest->x = lhs->x - rhs->x;
+ dest->y = lhs->y - rhs->y;
+ dest->z = lhs->z - rhs->z;
+}
+
+static void SC_vec3Cross(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
+{
+ float x = lhs->y * rhs->z - lhs->z * rhs->y;
+ float y = lhs->z * rhs->x - lhs->x * rhs->z;
+ float z = lhs->x * rhs->y - lhs->y * rhs->x;
+ dest->x = x;
+ dest->y = y;
+ dest->z = z;
+}
+
+static float SC_vec3Dot(const vec3_t *lhs, const vec3_t *rhs)
+{
+ return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z;
+}
+
+static void SC_vec3Scale(vec3_t *lhs, float scale)
+{
+ lhs->x *= scale;
+ lhs->y *= scale;
+ lhs->z *= scale;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Vec4 routines
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_vec4Norm(vec4_t *v)
+{
+ float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
+ len = 1 / len;
+ v->x *= len;
+ v->y *= len;
+ v->z *= len;
+ v->w *= len;
+}
+
+static float SC_vec4Length(const vec4_t *v)
+{
+ return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
+}
+
+static void SC_vec4Add(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
+{
+ dest->x = lhs->x + rhs->x;
+ dest->y = lhs->y + rhs->y;
+ dest->z = lhs->z + rhs->z;
+ dest->w = lhs->w + rhs->w;
+}
+
+static void SC_vec4Sub(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
+{
+ dest->x = lhs->x - rhs->x;
+ dest->y = lhs->y - rhs->y;
+ dest->z = lhs->z - rhs->z;
+ dest->w = lhs->w - rhs->w;
+}
+
+static float SC_vec4Dot(const vec4_t *lhs, const vec4_t *rhs)
+{
+ return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z + lhs->w * rhs->w;
+}
+
+static void SC_vec4Scale(vec4_t *lhs, float scale)
+{
+ lhs->x *= scale;
+ lhs->y *= scale;
+ lhs->z *= scale;
+ lhs->w *= scale;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Math routines
+//////////////////////////////////////////////////////////////////////////////
+
+#define PI 3.1415926f
+#define DEG_TO_RAD PI / 180.0f
+#define RAD_TO_DEG 180.0f / PI
+
+static float SC_sinf_fast(float x)
+{
+ const float A = 1.0f / (2.0f * M_PI);
+ const float B = -16.0f;
+ const float C = 8.0f;
+
+ // scale angle for easy argument reduction
+ x *= A;
+
+ if (fabsf(x) >= 0.5f) {
+ // argument reduction
+ x = x - ceilf(x + 0.5f) + 1.0f;
+ }
+
+ const float y = B * x * fabsf(x) + C * x;
+ return 0.2215f * (y * fabsf(y) - y) + y;
+}
+
+static float SC_cosf_fast(float x)
+{
+ x += float(M_PI / 2);
+
+ const float A = 1.0f / (2.0f * M_PI);
+ const float B = -16.0f;
+ const float C = 8.0f;
+
+ // scale angle for easy argument reduction
+ x *= A;
+
+ if (fabsf(x) >= 0.5f) {
+ // argument reduction
+ x = x - ceilf(x + 0.5f) + 1.0f;
+ }
+
+ const float y = B * x * fabsf(x) + C * x;
+ return 0.2215f * (y * fabsf(y) - y) + y;
+}
+
+static float SC_randf(float max)
+{
+ float r = (float)rand();
+ return r / RAND_MAX * max;
+}
+
+static float SC_randf2(float min, float max)
+{
+ float r = (float)rand();
+ return r / RAND_MAX * (max - min) + min;
+}
+
+static int SC_sign(int value)
+{
+ return (value > 0) - (value < 0);
+}
+
+static float SC_signf(float value)
+{
+ return (value > 0) - (value < 0);
+}
+
+static float SC_clampf(float amount, float low, float high)
+{
+ return amount < low ? low : (amount > high ? high : amount);
+}
+
+static int SC_clamp(int amount, int low, int high)
+{
+ return amount < low ? low : (amount > high ? high : amount);
+}
+
+static float SC_maxf(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+static float SC_minf(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+static float SC_sqrf(float v)
+{
+ return v * v;
+}
+
+static int SC_sqr(int v)
+{
+ return v * v;
+}
+
+static float SC_fracf(float v)
+{
+ return v - floorf(v);
+}
+
+static float SC_roundf(float v)
+{
+ return floorf(v + 0.4999999999);
+}
+
+static float SC_distf2(float x1, float y1, float x2, float y2)
+{
+ float x = x2 - x1;
+ float y = y2 - y1;
+ return sqrtf(x * x + y * y);
+}
+
+static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ float x = x2 - x1;
+ float y = y2 - y1;
+ float z = z2 - z1;
+ return sqrtf(x * x + y * y + z * z);
+}
+
+static float SC_magf2(float a, float b)
+{
+ return sqrtf(a * a + b * b);
+}
+
+static float SC_magf3(float a, float b, float c)
+{
+ return sqrtf(a * a + b * b + c * c);
+}
+
+static float SC_radf(float degrees)
+{
+ return degrees * DEG_TO_RAD;
+}
+
+static float SC_degf(float radians)
+{
+ return radians * RAD_TO_DEG;
+}
+
+static float SC_lerpf(float start, float stop, float amount)
+{
+ return start + (stop - start) * amount;
+}
+
+static float SC_normf(float start, float stop, float value)
+{
+ return (value - start) / (stop - start);
+}
+
+static float SC_mapf(float minStart, float minStop, float maxStart, float maxStop, float value)
+{
+ return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Time routines
+//////////////////////////////////////////////////////////////////////////////
+
+static int32_t SC_second()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_sec;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_sec;
+ }
+}
+
+static int32_t SC_minute()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_min;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_min;
+ }
+}
+
+static int32_t SC_hour()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_hour;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_hour;
+ }
+}
+
+static int32_t SC_day()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_mday;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_mday;
+ }
+}
+
+static int32_t SC_month()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_mon;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_mon;
+ }
+}
+
+static int32_t SC_year()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_year;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_year;
+ }
+}
+
+static int32_t SC_uptimeMillis()
+{
+ return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
+}
+
+static int32_t SC_startTimeMillis()
+{
+ GET_TLS();
+ return sc->mEnviroment.mStartTimeMillis;
+}
+
+static int32_t SC_elapsedTimeMillis()
+{
+ GET_TLS();
+ return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC))
+ - sc->mEnviroment.mStartTimeMillis;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Matrix routines
+//////////////////////////////////////////////////////////////////////////////
+
+
+static void SC_matrixLoadIdentity(rsc_Matrix *mat)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->loadIdentity();
+}
+
+static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->load(f);
+}
+
+static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->load(reinterpret_cast<const Matrix *>(newmat));
+}
+
+static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->loadRotate(rot, x, y, z);
+}
+
+static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->loadScale(x, y, z);
+}
+
+static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->loadTranslate(x, y, z);
+}
+
+static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
+ reinterpret_cast<const Matrix *>(rhs));
+}
+
+static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->multiply(reinterpret_cast<const Matrix *>(rhs));
+}
+
+static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->rotate(rot, x, y, z);
+}
+
+static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->scale(x, y, z);
+}
+
+static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z)
+{
+ Matrix *m = reinterpret_cast<Matrix *>(mat);
+ m->translate(x, y, z);
+}
+
+
+static void SC_vec2Rand(float *vec, float maxLen)
+{
+ float angle = SC_randf(PI * 2);
+ float len = SC_randf(maxLen);
+ vec[0] = len * sinf(angle);
+ vec[1] = len * cosf(angle);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Context
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
+{
+ GET_TLS();
+ rsi_ProgramFragmentBindTexture(rsc,
+ static_cast<ProgramFragment *>(vpf),
+ slot,
+ static_cast<Allocation *>(va));
+
+}
+
+static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
+{
+ GET_TLS();
+ rsi_ProgramFragmentBindSampler(rsc,
+ static_cast<ProgramFragment *>(vpf),
+ slot,
+ static_cast<Sampler *>(vs));
+
+}
+
+static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs)
+{
+ GET_TLS();
+ rsi_ContextBindProgramFragmentStore(rsc, pfs);
+
+}
+
+static void SC_bindProgramFragment(RsProgramFragment pf)
+{
+ GET_TLS();
+ rsi_ContextBindProgramFragment(rsc, pf);
+
+}
+
+static void SC_bindProgramVertex(RsProgramVertex pv)
+{
+ GET_TLS();
+ rsi_ContextBindProgramVertex(rsc, pv);
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// VP
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
+{
+ GET_TLS();
+ rsc->getVertex()->setModelviewMatrix(m);
+}
+
+static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
+{
+ GET_TLS();
+ rsc->getVertex()->setTextureMatrix(m);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Drawing
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_drawLine(float x1, float y1, float z1,
+ float x2, float y2, float z2)
+{
+ GET_TLS();
+ rsc->setupCheck();
+
+ float vtx[] = { x1, y1, z1, x2, y2, z2 };
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vtx);
+
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glDrawArrays(GL_LINES, 0, 2);
+}
+
+static void SC_drawPoint(float x, float y, float z)
+{
+ GET_TLS();
+ rsc->setupCheck();
+
+ float vtx[] = { x, y, z };
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vtx);
+
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glDrawArrays(GL_POINTS, 0, 1);
+}
+
+static void SC_drawQuadTexCoords(float x1, float y1, float z1,
+ float u1, float v1,
+ float x2, float y2, float z2,
+ float u2, float v2,
+ float x3, float y3, float z3,
+ float u3, float v3,
+ float x4, float y4, float z4,
+ float u4, float v4)
+{
+ GET_TLS();
+
+ //LOGE("Quad");
+ //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
+ //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
+ //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
+ //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
+
+ float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
+ const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
+
+ rsc->setupCheck();
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vtx);
+
+ glClientActiveTexture(GL_TEXTURE0);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+ glClientActiveTexture(GL_TEXTURE1);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+ glClientActiveTexture(GL_TEXTURE0);
+
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+static void SC_drawQuad(float x1, float y1, float z1,
+ float x2, float y2, float z2,
+ float x3, float y3, float z3,
+ float x4, float y4, float z4)
+{
+ SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
+ x2, y2, z2, 1, 1,
+ x3, y3, z3, 1, 0,
+ x4, y4, z4, 0, 0);
+}
+
+static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
+{
+ GET_TLS();
+ rsc->setupCheck();
+
+ GLint crop[4] = {0, h, w, -h};
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+ glDrawTexfOES(x, y, z, w, h);
+}
+
+static void SC_drawSprite(float x, float y, float z, float w, float h)
+{
+ GET_TLS();
+ rsc->setupCheck();
+
+ float vin[3] = {x, y, z};
+ float vout[4];
+
+ //LOGE("ds in %f %f %f", x, y, z);
+ rsc->getVertex()->transformToScreen(rsc, vout, vin);
+ //LOGE("ds out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
+ vout[0] /= vout[3];
+ vout[1] /= vout[3];
+ vout[2] /= vout[3];
+
+ vout[0] *= rsc->getWidth() / 2;
+ vout[1] *= rsc->getHeight() / 2;
+ vout[0] += rsc->getWidth() / 2;
+ vout[1] += rsc->getHeight() / 2;
+
+ vout[0] -= w/2;
+ vout[1] -= h/2;
+
+ //LOGE("ds out2 %f %f %f", vout[0], vout[1], vout[2]);
+
+ // U, V, W, H
+ GLint crop[4] = {0, h, w, -h};
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+ glDrawTexiOES(vout[0], vout[1], 0/*vout[2]*/, w, h);
+}
+
+
+static void SC_drawRect(float x1, float y1,
+ float x2, float y2, float z)
+{
+ SC_drawQuad(x1, y2, z,
+ x2, y2, z,
+ x2, y1, z,
+ x1, y1, z);
+}
+
+static void SC_drawSimpleMesh(RsSimpleMesh vsm)
+{
+ GET_TLS();
+ SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
+ rsc->setupCheck();
+ sm->render();
+}
+
+static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
+{
+ GET_TLS();
+ SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
+ rsc->setupCheck();
+ sm->renderRange(start, len);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_color(float r, float g, float b, float a)
+{
+ glColor4f(r, g, b, a);
+}
+
+static void SC_ambient(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
+}
+
+static void SC_diffuse(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
+}
+
+static void SC_specular(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
+}
+
+static void SC_emission(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
+}
+
+static void SC_shininess(float s)
+{
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
+}
+
+static void SC_pointAttenuation(float a, float b, float c)
+{
+ GLfloat params[] = { a, b, c };
+ glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
+}
+
+static void SC_hsbToRgb(float h, float s, float b, float* rgb)
+{
+ float red = 0.0f;
+ float green = 0.0f;
+ float blue = 0.0f;
+
+ float x = h;
+ float y = s;
+ float z = b;
+
+ float hf = (x - (int) x) * 6.0f;
+ int ihf = (int) hf;
+ float f = hf - ihf;
+ float pv = z * (1.0f - y);
+ float qv = z * (1.0f - y * f);
+ float tv = z * (1.0f - y * (1.0f - f));
+
+ switch (ihf) {
+ case 0: // Red is the dominant color
+ red = z;
+ green = tv;
+ blue = pv;
+ break;
+ case 1: // Green is the dominant color
+ red = qv;
+ green = z;
+ blue = pv;
+ break;
+ case 2:
+ red = pv;
+ green = z;
+ blue = tv;
+ break;
+ case 3: // Blue is the dominant color
+ red = pv;
+ green = qv;
+ blue = z;
+ break;
+ case 4:
+ red = tv;
+ green = pv;
+ blue = z;
+ break;
+ case 5: // Red is the dominant color
+ red = z;
+ green = pv;
+ blue = qv;
+ break;
+ }
+
+ rgb[0] = red;
+ rgb[1] = green;
+ rgb[2] = blue;
+}
+
+static int SC_hsbToAbgr(float h, float s, float b, float a)
+{
+ float rgb[3];
+ SC_hsbToRgb(h, s, b, rgb);
+ return int(a * 255.0f) << 24 |
+ int(rgb[2] * 255.0f) << 16 |
+ int(rgb[1] * 255.0f) << 8 |
+ int(rgb[0] * 255.0f);
+}
+
+static void SC_hsb(float h, float s, float b, float a)
+{
+ float rgb[3];
+ SC_hsbToRgb(h, s, b, rgb);
+ glColor4f(rgb[0], rgb[1], rgb[2], a);
+}
+
+static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
+{
+ GET_TLS();
+ rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
+}
+
+static void SC_uploadToBufferObject(RsAllocation va)
+{
+ GET_TLS();
+ rsi_AllocationUploadToBufferObject(rsc, va);
+}
+
+static void SC_ClearColor(float r, float g, float b, float a)
+{
+ //LOGE("c %f %f %f %f", r, g, b, a);
+ GET_TLS();
+ sc->mEnviroment.mClearColor[0] = r;
+ sc->mEnviroment.mClearColor[1] = g;
+ sc->mEnviroment.mClearColor[2] = b;
+ sc->mEnviroment.mClearColor[3] = a;
+}
+
+static void SC_debugF(const char *s, float f)
+{
+ LOGE("%s %f", s, f);
+}
+
+static void SC_debugHexF(const char *s, float f)
+{
+ LOGE("%s 0x%x", s, *((int *) (&f)));
+}
+
+static void SC_debugI32(const char *s, int32_t i)
+{
+ LOGE("%s %i", s, i);
+}
+
+static void SC_debugHexI32(const char *s, int32_t i)
+{
+ LOGE("%s 0x%x", s, i);
+}
+
+static uint32_t SC_getWidth()
+{
+ GET_TLS();
+ return rsc->getWidth();
+}
+
+static uint32_t SC_getHeight()
+{
+ GET_TLS();
+ return rsc->getHeight();
+}
+
+static uint32_t SC_colorFloatRGBAtoUNorm8(float r, float g, float b, float a)
+{
+ uint32_t c = 0;
+ c |= (uint32_t)(r * 255.f + 0.5f);
+ c |= ((uint32_t)(g * 255.f + 0.5f)) << 8;
+ c |= ((uint32_t)(b * 255.f + 0.5f)) << 16;
+ c |= ((uint32_t)(a * 255.f + 0.5f)) << 24;
+ return c;
+}
+
+static uint32_t SC_colorFloatRGBAto565(float r, float g, float b)
+{
+ uint32_t ir = (uint32_t)(r * 255.f + 0.5f);
+ uint32_t ig = (uint32_t)(g * 255.f + 0.5f);
+ uint32_t ib = (uint32_t)(b * 255.f + 0.5f);
+ return rs888to565(ir, ig, ib);
+}
+
+static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
+{
+ GET_TLS();
+ return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
+}
+
+static void SC_scriptCall(int scriptID)
+{
+ GET_TLS();
+ rsc->runScript((Script *)scriptID, 0);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Class implementation
+//////////////////////////////////////////////////////////////////////////////
+
+ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
+ // IO
+ { "loadI32", (void *)&SC_loadI32,
+ "int", "(int, int)" },
+ //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
+ { "loadF", (void *)&SC_loadF,
+ "float", "(int, int)" },
+ { "loadArrayF", (void *)&SC_loadArrayF,
+ "float*", "(int, int)" },
+ { "loadArrayI32", (void *)&SC_loadArrayI32,
+ "int*", "(int, int)" },
+ { "loadVec4", (void *)&SC_loadVec4,
+ "void", "(int, int, float *)" },
+ { "loadMatrix", (void *)&SC_loadMatrix,
+ "void", "(int, int, float *)" },
+ { "storeI32", (void *)&SC_storeI32,
+ "void", "(int, int, int)" },
+ //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
+ { "storeF", (void *)&SC_storeF,
+ "void", "(int, int, float)" },
+ { "storeVec4", (void *)&SC_storeVec4,
+ "void", "(int, int, float *)" },
+ { "storeMatrix", (void *)&SC_storeMatrix,
+ "void", "(int, int, float *)" },
+ { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF,
+ "float*", "(int, int)" },
+ { "updateSimpleMesh", (void *)&SC_updateSimpleMesh,
+ "void", "(int)" },
+
+ // math
+ { "modf", (void *)&fmod,
+ "float", "(float, float)" },
+ { "abs", (void *)&abs,
+ "int", "(int)" },
+ { "absf", (void *)&fabsf,
+ "float", "(float)" },
+ { "sinf_fast", (void *)&SC_sinf_fast,
+ "float", "(float)" },
+ { "cosf_fast", (void *)&SC_cosf_fast,
+ "float", "(float)" },
+ { "sinf", (void *)&sinf,
+ "float", "(float)" },
+ { "cosf", (void *)&cosf,
+ "float", "(float)" },
+ { "asinf", (void *)&asinf,
+ "float", "(float)" },
+ { "acosf", (void *)&acosf,
+ "float", "(float)" },
+ { "atanf", (void *)&atanf,
+ "float", "(float)" },
+ { "atan2f", (void *)&atan2f,
+ "float", "(float, float)" },
+ { "fabsf", (void *)&fabsf,
+ "float", "(float)" },
+ { "randf", (void *)&SC_randf,
+ "float", "(float)" },
+ { "randf2", (void *)&SC_randf2,
+ "float", "(float, float)" },
+ { "floorf", (void *)&floorf,
+ "float", "(float)" },
+ { "fracf", (void *)&SC_fracf,
+ "float", "(float)" },
+ { "ceilf", (void *)&ceilf,
+ "float", "(float)" },
+ { "roundf", (void *)&SC_roundf,
+ "float", "(float)" },
+ { "expf", (void *)&expf,
+ "float", "(float)" },
+ { "logf", (void *)&logf,
+ "float", "(float)" },
+ { "powf", (void *)&powf,
+ "float", "(float, float)" },
+ { "maxf", (void *)&SC_maxf,
+ "float", "(float, float)" },
+ { "minf", (void *)&SC_minf,
+ "float", "(float, float)" },
+ { "sqrt", (void *)&sqrt,
+ "int", "(int)" },
+ { "sqrtf", (void *)&sqrtf,
+ "float", "(float)" },
+ { "sqr", (void *)&SC_sqr,
+ "int", "(int)" },
+ { "sqrf", (void *)&SC_sqrf,
+ "float", "(float)" },
+ { "sign", (void *)&SC_sign,
+ "int", "(int)" },
+ { "signf", (void *)&SC_signf,
+ "float", "(float)" },
+ { "clamp", (void *)&SC_clamp,
+ "int", "(int, int, int)" },
+ { "clampf", (void *)&SC_clampf,
+ "float", "(float, float, float)" },
+ { "distf2", (void *)&SC_distf2,
+ "float", "(float, float, float, float)" },
+ { "distf3", (void *)&SC_distf3,
+ "float", "(float, float, float, float, float, float)" },
+ { "magf2", (void *)&SC_magf2,
+ "float", "(float, float)" },
+ { "magf3", (void *)&SC_magf3,
+ "float", "(float, float, float)" },
+ { "radf", (void *)&SC_radf,
+ "float", "(float)" },
+ { "degf", (void *)&SC_degf,
+ "float", "(float)" },
+ { "lerpf", (void *)&SC_lerpf,
+ "float", "(float, float, float)" },
+ { "normf", (void *)&SC_normf,
+ "float", "(float, float, float)" },
+ { "mapf", (void *)&SC_mapf,
+ "float", "(float, float, float, float, float)" },
+ { "noisef", (void *)&SC_noisef,
+ "float", "(float)" },
+ { "noisef2", (void *)&SC_noisef2,
+ "float", "(float, float)" },
+ { "noisef3", (void *)&SC_noisef3,
+ "float", "(float, float, float)" },
+ { "turbulencef2", (void *)&SC_turbulencef2,
+ "float", "(float, float, float)" },
+ { "turbulencef3", (void *)&SC_turbulencef3,
+ "float", "(float, float, float, float)" },
+
+ // time
+ { "second", (void *)&SC_second,
+ "int", "()" },
+ { "minute", (void *)&SC_minute,
+ "int", "()" },
+ { "hour", (void *)&SC_hour,
+ "int", "()" },
+ { "day", (void *)&SC_day,
+ "int", "()" },
+ { "month", (void *)&SC_month,
+ "int", "()" },
+ { "year", (void *)&SC_year,
+ "int", "()" },
+ { "uptimeMillis", (void*)&SC_uptimeMillis,
+ "int", "()" }, // TODO: use long instead
+ { "startTimeMillis", (void*)&SC_startTimeMillis,
+ "int", "()" }, // TODO: use long instead
+ { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis,
+ "int", "()" }, // TODO: use long instead
+
+ // matrix
+ { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
+ "void", "(float *mat)" },
+ { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
+ "void", "(float *mat, float *f)" },
+ { "matrixLoadMat", (void *)&SC_matrixLoadMat,
+ "void", "(float *mat, float *newmat)" },
+ { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
+ "void", "(float *mat, float rot, float x, float y, float z)" },
+ { "matrixLoadScale", (void *)&SC_matrixLoadScale,
+ "void", "(float *mat, float x, float y, float z)" },
+ { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
+ "void", "(float *mat, float x, float y, float z)" },
+ { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
+ "void", "(float *mat, float *lhs, float *rhs)" },
+ { "matrixMultiply", (void *)&SC_matrixMultiply,
+ "void", "(float *mat, float *rhs)" },
+ { "matrixRotate", (void *)&SC_matrixRotate,
+ "void", "(float *mat, float rot, float x, float y, float z)" },
+ { "matrixScale", (void *)&SC_matrixScale,
+ "void", "(float *mat, float x, float y, float z)" },
+ { "matrixTranslate", (void *)&SC_matrixTranslate,
+ "void", "(float *mat, float x, float y, float z)" },
+
+ // vector
+ { "vec2Rand", (void *)&SC_vec2Rand,
+ "void", "(float *vec, float maxLen)" },
+
+ // vec3
+ { "vec3Norm", (void *)&SC_vec3Norm,
+ "void", "(struct vec3_s *)" },
+ { "vec3Length", (void *)&SC_vec3Length,
+ "float", "(struct vec3_s *)" },
+ { "vec3Add", (void *)&SC_vec3Add,
+ "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
+ { "vec3Sub", (void *)&SC_vec3Sub,
+ "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
+ { "vec3Cross", (void *)&SC_vec3Cross,
+ "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
+ { "vec3Dot", (void *)&SC_vec3Dot,
+ "float", "(struct vec3_s *lhs, struct vec3_s *rhs)" },
+ { "vec3Scale", (void *)&SC_vec3Scale,
+ "void", "(struct vec3_s *lhs, float scale)" },
+
+ // vec4
+ { "vec4Norm", (void *)&SC_vec4Norm,
+ "void", "(struct vec4_s *)" },
+ { "vec4Length", (void *)&SC_vec4Length,
+ "float", "(struct vec4_s *)" },
+ { "vec4Add", (void *)&SC_vec4Add,
+ "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" },
+ { "vec4Sub", (void *)&SC_vec4Sub,
+ "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" },
+ { "vec4Dot", (void *)&SC_vec4Dot,
+ "float", "(struct vec4_s *lhs, struct vec4_s *rhs)" },
+ { "vec4Scale", (void *)&SC_vec4Scale,
+ "void", "(struct vec4_s *lhs, float scale)" },
+
+ // context
+ { "bindProgramFragment", (void *)&SC_bindProgramFragment,
+ "void", "(int)" },
+ { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
+ "void", "(int)" },
+ { "bindProgramStore", (void *)&SC_bindProgramFragmentStore,
+ "void", "(int)" },
+ { "bindProgramVertex", (void *)&SC_bindProgramVertex,
+ "void", "(int)" },
+ { "bindSampler", (void *)&SC_bindSampler,
+ "void", "(int, int, int)" },
+ { "bindTexture", (void *)&SC_bindTexture,
+ "void", "(int, int, int)" },
+
+ // vp
+ { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix,
+ "void", "(void *)" },
+ { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix,
+ "void", "(void *)" },
+
+
+
+ // drawing
+ { "drawRect", (void *)&SC_drawRect,
+ "void", "(float x1, float y1, float x2, float y2, float z)" },
+ { "drawQuad", (void *)&SC_drawQuad,
+ "void", "(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)" },
+ { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords,
+ "void", "(float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float x4, float y4, float z4, float u4, float v4)" },
+ { "drawSprite", (void *)&SC_drawSprite,
+ "void", "(float x, float y, float z, float w, float h)" },
+ { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace,
+ "void", "(float x, float y, float z, float w, float h)" },
+ { "drawLine", (void *)&SC_drawLine,
+ "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
+ { "drawPoint", (void *)&SC_drawPoint,
+ "void", "(float x1, float y1, float z1)" },
+ { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
+ "void", "(int ism)" },
+ { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
+ "void", "(int ism, int start, int len)" },
+
+
+ // misc
+ { "pfClearColor", (void *)&SC_ClearColor,
+ "void", "(float, float, float, float)" },
+ { "color", (void *)&SC_color,
+ "void", "(float, float, float, float)" },
+ { "hsb", (void *)&SC_hsb,
+ "void", "(float, float, float, float)" },
+ { "hsbToRgb", (void *)&SC_hsbToRgb,
+ "void", "(float, float, float, float*)" },
+ { "hsbToAbgr", (void *)&SC_hsbToAbgr,
+ "int", "(float, float, float, float)" },
+ { "ambient", (void *)&SC_ambient,
+ "void", "(float, float, float, float)" },
+ { "diffuse", (void *)&SC_diffuse,
+ "void", "(float, float, float, float)" },
+ { "specular", (void *)&SC_specular,
+ "void", "(float, float, float, float)" },
+ { "emission", (void *)&SC_emission,
+ "void", "(float, float, float, float)" },
+ { "shininess", (void *)&SC_shininess,
+ "void", "(float)" },
+ { "pointAttenuation", (void *)&SC_pointAttenuation,
+ "void", "(float, float, float)" },
+
+ { "uploadToTexture", (void *)&SC_uploadToTexture,
+ "void", "(int, int)" },
+ { "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
+ "void", "(int)" },
+
+ { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
+ "int", "(float, float, float, float)" },
+ { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
+ "int", "(float, float, float)" },
+
+
+ { "getWidth", (void *)&SC_getWidth,
+ "int", "()" },
+ { "getHeight", (void *)&SC_getHeight,
+ "int", "()" },
+
+ { "sendToClient", (void *)&SC_toClient,
+ "int", "(void *data, int cmdID, int len, int waitForSpace)" },
+
+
+ { "debugF", (void *)&SC_debugF,
+ "void", "(void *, float)" },
+ { "debugI32", (void *)&SC_debugI32,
+ "void", "(void *, int)" },
+ { "debugHexF", (void *)&SC_debugHexF,
+ "void", "(void *, float)" },
+ { "debugHexI32", (void *)&SC_debugHexI32,
+ "void", "(void *, int)" },
+
+ { "scriptCall", (void *)&SC_scriptCall,
+ "void", "(int)" },
+
+
+ { NULL, NULL, NULL, NULL }
+};
+
+const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
+{
+ ScriptCState::SymbolTable_t *syms = gSyms;
+
+ while (syms->mPtr) {
+ if (!strcmp(syms->mName, sym)) {
+ return syms;
+ }
+ syms++;
+ }
+ return NULL;
+}
+
+void ScriptCState::appendDecls(String8 *str)
+{
+ ScriptCState::SymbolTable_t *syms = gSyms;
+ while (syms->mPtr) {
+ str->append(syms->mRet);
+ str->append(" ");
+ str->append(syms->mName);
+ str->append(syms->mParam);
+ str->append(";\n");
+ syms++;
+ }
+}
+
+
diff --git a/libs/rs/rsSimpleMesh.cpp b/libs/rs/rsSimpleMesh.cpp
new file mode 100644
index 0000000..b082fd7
--- /dev/null
+++ b/libs/rs/rsSimpleMesh.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+}
+
+SimpleMesh::~SimpleMesh()
+{
+ delete[] mVertexTypes;
+ delete[] mVertexBuffers;
+}
+
+void SimpleMesh::render() const
+{
+ if (mPrimitiveType.get()) {
+ renderRange(0, mPrimitiveType->getDimX());
+ return;
+ }
+
+ if (mIndexType.get()) {
+ renderRange(0, mIndexType->getDimX());
+ return;
+ }
+
+ renderRange(0, mVertexTypes[0]->getDimX());
+}
+
+void SimpleMesh::renderRange(uint32_t start, uint32_t len) const
+{
+ if (len < 1) {
+ return;
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) {
+ glClientActiveTexture(GL_TEXTURE0 + ct);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ glClientActiveTexture(GL_TEXTURE0);
+
+ for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
+ glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[ct]->getBufferObjectID());
+ mVertexTypes[ct]->enableGLVertexBuffer();
+ }
+
+ if (mIndexType.get()) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID());
+ glDrawElements(mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
+ } else {
+ glDrawArrays(mGLPrimitive, start, len);
+ }
+}
+
+void SimpleMesh::uploadAll()
+{
+ for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
+ if (mVertexBuffers[ct].get()) {
+ mVertexBuffers[ct]->uploadToBufferObject();
+ }
+ }
+ if (mIndexBuffer.get()) {
+ mIndexBuffer->uploadToBufferObject();
+ }
+ if (mPrimitiveBuffer.get()) {
+ mPrimitiveBuffer->uploadToBufferObject();
+ }
+}
+
+
+SimpleMeshContext::SimpleMeshContext()
+{
+}
+
+SimpleMeshContext::~SimpleMeshContext()
+{
+}
+
+
+namespace android {
+namespace renderscript {
+
+
+RsSimpleMesh rsi_SimpleMeshCreate(Context *rsc, RsType prim, RsType idx, RsType *vtx, uint32_t vtxCount, uint32_t primType)
+{
+ SimpleMesh *sm = new SimpleMesh(rsc);
+ sm->incUserRef();
+
+ sm->mIndexType.set((const Type *)idx);
+ sm->mPrimitiveType.set((const Type *)prim);
+
+ sm->mVertexTypeCount = vtxCount;
+ sm->mVertexTypes = new ObjectBaseRef<const Type>[vtxCount];
+ sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
+ for (uint32_t ct=0; ct < vtxCount; ct++) {
+ sm->mVertexTypes[ct].set((const Type *)vtx[ct]);
+ }
+
+ sm->mPrimitive = (RsPrimitive)primType;
+ switch(sm->mPrimitive) {
+ case RS_PRIMITIVE_POINT: sm->mGLPrimitive = GL_POINTS; break;
+ case RS_PRIMITIVE_LINE: sm->mGLPrimitive = GL_LINES; break;
+ case RS_PRIMITIVE_LINE_STRIP: sm->mGLPrimitive = GL_LINE_STRIP; break;
+ case RS_PRIMITIVE_TRIANGLE: sm->mGLPrimitive = GL_TRIANGLES; break;
+ case RS_PRIMITIVE_TRIANGLE_STRIP: sm->mGLPrimitive = GL_TRIANGLE_STRIP; break;
+ case RS_PRIMITIVE_TRIANGLE_FAN: sm->mGLPrimitive = GL_TRIANGLE_FAN; break;
+ }
+ return sm;
+}
+
+void rsi_SimpleMeshBindVertex(Context *rsc, RsSimpleMesh mv, RsAllocation va, uint32_t slot)
+{
+ SimpleMesh *sm = static_cast<SimpleMesh *>(mv);
+ rsAssert(slot < sm->mVertexTypeCount);
+
+ sm->mVertexBuffers[slot].set((Allocation *)va);
+}
+
+void rsi_SimpleMeshBindIndex(Context *rsc, RsSimpleMesh mv, RsAllocation va)
+{
+ SimpleMesh *sm = static_cast<SimpleMesh *>(mv);
+ sm->mIndexBuffer.set((Allocation *)va);
+}
+
+void rsi_SimpleMeshBindPrimitive(Context *rsc, RsSimpleMesh mv, RsAllocation va)
+{
+ SimpleMesh *sm = static_cast<SimpleMesh *>(mv);
+ sm->mPrimitiveBuffer.set((Allocation *)va);
+}
+
+
+
+
+}}
+
diff --git a/libs/rs/rsSimpleMesh.h b/libs/rs/rsSimpleMesh.h
new file mode 100644
index 0000000..1e5c908
--- /dev/null
+++ b/libs/rs/rsSimpleMesh.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_SIMPLE_MESH_H
+#define ANDROID_RS_SIMPLE_MESH_H
+
+
+#include "RenderScript.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class SimpleMesh : public ObjectBase
+{
+public:
+ SimpleMesh(Context *);
+ ~SimpleMesh();
+
+ ObjectBaseRef<const Type> mIndexType;
+ ObjectBaseRef<const Type> mPrimitiveType;
+ ObjectBaseRef<const Type> *mVertexTypes;
+ uint32_t mVertexTypeCount;
+
+ ObjectBaseRef<Allocation> mIndexBuffer;
+ ObjectBaseRef<Allocation> mPrimitiveBuffer;
+ ObjectBaseRef<Allocation> *mVertexBuffers;
+
+ RsPrimitive mPrimitive;
+ uint32_t mGLPrimitive;
+
+
+ void render() const;
+ void renderRange(uint32_t start, uint32_t len) const;
+ void uploadAll();
+
+
+protected:
+};
+
+class SimpleMeshContext
+{
+public:
+ SimpleMeshContext();
+ ~SimpleMeshContext();
+
+
+};
+
+
+}
+}
+#endif //ANDROID_RS_SIMPLE_MESH_H
+
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
new file mode 100644
index 0000000..527b3d7
--- /dev/null
+++ b/libs/rs/rsThreadIO.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+
+#include "rsThreadIO.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+ThreadIO::ThreadIO()
+{
+ mToCore.init(16 * 1024);
+ mToClient.init(1024);
+}
+
+ThreadIO::~ThreadIO()
+{
+}
+
+void ThreadIO::shutdown()
+{
+ mToCore.shutdown();
+}
+
+bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand)
+{
+ bool ret = false;
+ while(!mToCore.isEmpty() || waitForCommand) {
+ uint32_t cmdID = 0;
+ uint32_t cmdSize = 0;
+ ret = true;
+ if (con->props.mLogTimes) {
+ con->timerSet(Context::RS_TIMER_IDLE);
+ }
+ const void * data = mToCore.get(&cmdID, &cmdSize);
+ if (!cmdSize) {
+ // exception occured, probably shutdown.
+ return false;
+ }
+ if (con->props.mLogTimes) {
+ con->timerSet(Context::RS_TIMER_INTERNAL);
+ }
+ waitForCommand = false;
+ //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
+
+ gPlaybackFuncs[cmdID](con, data);
+ mToCore.next();
+ }
+ return ret;
+}
+
+
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
new file mode 100644
index 0000000..95270f5
--- /dev/null
+++ b/libs/rs/rsThreadIO.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_THREAD_IO_H
+#define ANDROID_RS_THREAD_IO_H
+
+#include "rsUtils.h"
+#include "rsLocklessFifo.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Context;
+
+class ThreadIO {
+public:
+ ThreadIO();
+ ~ThreadIO();
+
+ void shutdown();
+
+ // Plays back commands from the client.
+ // Returns true if any commands were processed.
+ bool playCoreCommands(Context *con, bool waitForCommand);
+
+
+ LocklessCommandFifo mToCore;
+ LocklessCommandFifo mToClient;
+
+ intptr_t mToCoreRet;
+
+};
+
+
+}
+}
+#endif
+
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
new file mode 100644
index 0000000..ddaa2f0
--- /dev/null
+++ b/libs/rs/rsType.cpp
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include <GLES/gl.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+Type::Type(Context *rsc) : ObjectBase(rsc)
+{
+ mAllocFile = __FILE__;
+ mAllocLine = __LINE__;
+ mLODs = 0;
+ mLODCount = 0;
+ memset(&mGL, 0, sizeof(mGL));
+ clear();
+}
+
+Type::~Type()
+{
+ if (mLODs) {
+ delete [] mLODs;
+ }
+}
+
+void Type::clear()
+{
+ if (mLODs) {
+ delete [] mLODs;
+ mLODs = NULL;
+ }
+ mDimX = 0;
+ mDimY = 0;
+ mDimZ = 0;
+ mDimLOD = 0;
+ mFaces = false;
+ mElement.clear();
+}
+
+TypeState::TypeState()
+{
+}
+
+TypeState::~TypeState()
+{
+}
+
+size_t Type::getOffsetForFace(uint32_t face) const
+{
+ rsAssert(mFaces);
+ return 0;
+}
+
+void Type::compute()
+{
+ uint32_t oldLODCount = mLODCount;
+ if (mDimLOD) {
+ uint32_t l2x = rsFindHighBit(mDimX) + 1;
+ uint32_t l2y = rsFindHighBit(mDimY) + 1;
+ uint32_t l2z = rsFindHighBit(mDimZ) + 1;
+
+ mLODCount = rsMax(l2x, l2y);
+ mLODCount = rsMax(mLODCount, l2z);
+ } else {
+ mLODCount = 1;
+ }
+ if (mLODCount != oldLODCount) {
+ delete [] mLODs;
+ mLODs = new LOD[mLODCount];
+ }
+
+ uint32_t tx = mDimX;
+ uint32_t ty = mDimY;
+ uint32_t tz = mDimZ;
+ size_t offset = 0;
+ for (uint32_t lod=0; lod < mLODCount; lod++) {
+ mLODs[lod].mX = tx;
+ mLODs[lod].mY = ty;
+ mLODs[lod].mZ = tz;
+ mLODs[lod].mOffset = offset;
+ offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
+ tx = (tx + 1) >> 1;
+ ty = (ty + 1) >> 1;
+ tz = (tz + 1) >> 1;
+ }
+
+ // At this point the offset is the size of a mipmap chain;
+ mMipChainSizeBytes = offset;
+
+ if (mFaces) {
+ offset *= 6;
+ }
+ mTotalSizeBytes = offset;
+
+ makeGLComponents();
+}
+
+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;
+}
+
+
+void Type::makeGLComponents()
+{
+ uint32_t texNum = 0;
+ memset(&mGL, 0, sizeof(mGL));
+
+ for (uint32_t ct=0; ct < getElement()->getComponentCount(); ct++) {
+ const Component *c = getElement()->getComponent(ct);
+
+ switch(c->getKind()) {
+ case Component::X:
+ rsAssert(mGL.mVtx.size == 0);
+ mGL.mVtx.size = 1;
+ mGL.mVtx.offset = mElement->getComponentOffsetBytes(ct);
+ mGL.mVtx.type = c->getGLType();
+ break;
+ case Component::Y:
+ rsAssert(mGL.mVtx.size == 1);
+ rsAssert(mGL.mVtx.type == c->getGLType());
+ mGL.mVtx.size = 2;
+ break;
+ case Component::Z:
+ rsAssert(mGL.mVtx.size == 2);
+ rsAssert(mGL.mVtx.type == c->getGLType());
+ mGL.mVtx.size = 3;
+ break;
+ case Component::W:
+ rsAssert(mGL.mVtx.size == 4);
+ rsAssert(mGL.mVtx.type == c->getGLType());
+ mGL.mVtx.size = 4;
+ break;
+
+ case Component::RED:
+ rsAssert(mGL.mColor.size == 0);
+ mGL.mColor.size = 1;
+ mGL.mColor.offset = mElement->getComponentOffsetBytes(ct);
+ mGL.mColor.type = c->getGLType();
+ break;
+ case Component::GREEN:
+ rsAssert(mGL.mColor.size == 1);
+ rsAssert(mGL.mColor.type == c->getGLType());
+ mGL.mColor.size = 2;
+ break;
+ case Component::BLUE:
+ rsAssert(mGL.mColor.size == 2);
+ rsAssert(mGL.mColor.type == c->getGLType());
+ mGL.mColor.size = 3;
+ break;
+ case Component::ALPHA:
+ // Can be RGBA or A at this point
+ if (mGL.mColor.size > 0) {
+ rsAssert(mGL.mColor.size == 3);
+ rsAssert(mGL.mColor.type == c->getGLType());
+ mGL.mColor.size = 4;
+ } else {
+ mGL.mColor.size = 1;
+ mGL.mColor.offset = mElement->getComponentOffsetBytes(ct);
+ mGL.mColor.type = c->getGLType();
+ }
+ break;
+
+ case Component::NX:
+ rsAssert(mGL.mNorm.size == 0);
+ mGL.mNorm.size = 1;
+ mGL.mNorm.offset = mElement->getComponentOffsetBytes(ct);
+ mGL.mNorm.type = c->getGLType();
+ break;
+ case Component::NY:
+ rsAssert(mGL.mNorm.size == 1);
+ rsAssert(mGL.mNorm.type == c->getGLType());
+ mGL.mNorm.size = 2;
+ break;
+ case Component::NZ:
+ rsAssert(mGL.mNorm.size == 2);
+ rsAssert(mGL.mNorm.type == c->getGLType());
+ mGL.mNorm.size = 3;
+ break;
+
+ case Component::S:
+ if (mGL.mTex[texNum].size) {
+ texNum++;
+ }
+ mGL.mTex[texNum].size = 1;
+ mGL.mTex[texNum].offset = mElement->getComponentOffsetBytes(ct);
+ mGL.mTex[texNum].type = c->getGLType();
+ break;
+ case Component::T:
+ rsAssert(mGL.mTex[texNum].size == 1);
+ rsAssert(mGL.mTex[texNum].type == c->getGLType());
+ mGL.mTex[texNum].size = 2;
+ break;
+ case Component::R:
+ rsAssert(mGL.mTex[texNum].size == 2);
+ rsAssert(mGL.mTex[texNum].type == c->getGLType());
+ mGL.mTex[texNum].size = 3;
+ break;
+ case Component::Q:
+ rsAssert(mGL.mTex[texNum].size == 3);
+ rsAssert(mGL.mTex[texNum].type == c->getGLType());
+ mGL.mTex[texNum].size = 4;
+ break;
+
+ case Component::POINT_SIZE:
+ rsAssert(!mGL.mPointSize.size);
+ mGL.mPointSize.size = 1;
+ mGL.mPointSize.offset = mElement->getComponentOffsetBytes(ct);
+ mGL.mPointSize.type = c->getGLType();
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Type::enableGLVertexBuffer() const
+{
+ // Note: We are only going to enable buffers and never disable them
+ // here. The reasonis more than one Allocation may be used as a vertex
+ // source. So we cannot disable arrays that may have been in use by
+ // another allocation.
+
+ uint32_t stride = mElement->getSizeBytes();
+ if (mGL.mVtx.size) {
+ //LOGE("va vtx %i %x, %i, %p", mGL.mVtx.size, mGL.mVtx.type, stride, (void *)mGL.mVtx.offset);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(mGL.mVtx.size,
+ mGL.mVtx.type,
+ stride,
+ (void *)mGL.mVtx.offset);
+ }
+
+ if (mGL.mNorm.size) {
+ //LOGE("va norm %i %x, %i, %p", mGL.mNorm.size, mGL.mNorm.type, stride, (void *)mGL.mNorm.offset);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ rsAssert(mGL.mNorm.size == 3);
+ glNormalPointer(mGL.mNorm.type,
+ stride,
+ (void *)mGL.mNorm.offset);
+ }
+
+ if (mGL.mColor.size) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(mGL.mColor.size,
+ mGL.mColor.type,
+ stride,
+ (void *)mGL.mColor.offset);
+ }
+
+ for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) {
+ if (mGL.mTex[ct].size) {
+ //LOGE("va tex%i %i %x, %i, %p", ct, mGL.mTex[ct].size, mGL.mTex[ct].type, stride, (void *)mGL.mTex[ct].offset);
+ glClientActiveTexture(GL_TEXTURE0 + ct);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(mGL.mTex[ct].size,
+ mGL.mTex[ct].type,
+ stride,
+ (void *)mGL.mTex[ct].offset);
+ }
+ }
+ glClientActiveTexture(GL_TEXTURE0);
+
+ if (mGL.mPointSize.size) {
+ glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
+ glPointSizePointerOES(mGL.mPointSize.type,
+ stride,
+ (void *)mGL.mPointSize.offset);
+ }
+
+}
+
+
+void Type::dumpLOGV(const char *prefix) const
+{
+ char buf[1024];
+ ObjectBase::dumpLOGV(prefix);
+ LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
+ sprintf(buf, "%s element: ", prefix);
+ mElement->dumpLOGV(buf);
+}
+
+
+//////////////////////////////////////////////////
+//
+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(rsc);
+ st->incUserRef();
+ 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->mElement.clear();
+
+ return st;
+}
+
+
+}
+}
+
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
new file mode 100644
index 0000000..2c43405
--- /dev/null
+++ b/libs/rs/rsType.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STRUCTURED_TYPE_H
+#define ANDROID_STRUCTURED_TYPE_H
+
+#include "rsElement.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+class Type : public ObjectBase
+{
+public:
+ Type(Context *);
+ 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();
+
+ void enableGLVertexBuffer() const;
+
+ void dumpLOGV(const char *prefix) const;
+
+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;
+
+ struct VertexComponent_t {
+ uint32_t offset;
+ uint32_t type;
+ uint32_t size;
+ uint32_t stride;
+ };
+ struct GLState_t {
+ VertexComponent_t mVtx;
+ VertexComponent_t mNorm;
+ VertexComponent_t mColor;
+ VertexComponent_t mTex[RS_MAX_TEXTURE];
+ VertexComponent_t mPointSize;
+ };
+ GLState_t mGL;
+ void makeGLComponents();
+
+private:
+ Type(const Type &);
+};
+
+
+class TypeState {
+public:
+ TypeState();
+ ~TypeState();
+
+ 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..63d73a1
--- /dev/null
+++ b/libs/rs/rsUtils.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_UTILS_H
+#define ANDROID_RS_UTILS_H
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "rs"
+#include <utils/Log.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <EGL/egl.h>
+#include <math.h>
+
+#include "RenderScript.h"
+
+namespace android {
+namespace renderscript {
+
+#if 1
+#define rsAssert(v) do {if(!(v)) LOGE("rsAssert failed: %s, in %s at %i", #v, __FILE__, __LINE__);} while(0)
+#else
+#define rsAssert(v) while(0)
+#endif
+
+template<typename T>
+T rsMin(T in1, T in2)
+{
+ if (in1 > in2) {
+ return in2;
+ }
+ return in1;
+}
+
+template<typename T>
+T rsMax(T in1, T in2)
+{
+ if (in1 < in2) {
+ return in2;
+ }
+ return in1;
+}
+
+template<typename T>
+T rsFindHighBit(T val)
+{
+ uint32_t bit = 0;
+ while(val > 1) {
+ bit++;
+ val>>=1;
+ }
+ return bit;
+}
+
+template<typename T>
+bool rsIsPow2(T val)
+{
+ return (val & (val-1)) == 0;
+}
+
+template<typename T>
+T rsHigherPow2(T v)
+{
+ if (rsIsPow2(v)) {
+ return v;
+ }
+ return 1 << (rsFindHighBit(v) + 1);
+}
+
+template<typename T>
+T rsLowerPow2(T v)
+{
+ if (rsIsPow2(v)) {
+ return v;
+ }
+ return 1 << rsFindHighBit(v);
+}
+
+
+static inline uint16_t rs888to565(uint32_t r, uint32_t g, uint32_t b)
+{
+ uint16_t t = 0;
+ t |= b >> 3;
+ t |= (g >> 2) << 5;
+ t |= (r >> 3) << 11;
+ return t;
+}
+
+static inline uint16_t rsBoxFilter565(uint16_t i1, uint16_t i2, uint16_t i3, uint16_t i4)
+{
+ uint32_t r = ((i1 & 0x1f) + (i2 & 0x1f) + (i3 & 0x1f) + (i4 & 0x1f));
+ uint32_t g = ((i1 >> 5) & 0x3f) + ((i2 >> 5) & 0x3f) + ((i3 >> 5) & 0x3f) + ((i4 >> 5) & 0x3f);
+ uint32_t b = ((i1 >> 11) + (i2 >> 11) + (i3 >> 11) + (i4 >> 11));
+ return (r >> 2) | ((g >> 2) << 5) | ((b >> 2) << 11);
+}
+
+static inline uint32_t rsBoxFilter8888(uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4)
+{
+ uint32_t r = (i1 & 0xff) + (i2 & 0xff) + (i3 & 0xff) + (i4 & 0xff);
+ uint32_t g = ((i1 >> 8) & 0xff) + ((i2 >> 8) & 0xff) + ((i3 >> 8) & 0xff) + ((i4 >> 8) & 0xff);
+ uint32_t b = ((i1 >> 16) & 0xff) + ((i2 >> 16) & 0xff) + ((i3 >> 16) & 0xff) + ((i4 >> 16) & 0xff);
+ uint32_t a = ((i1 >> 24) & 0xff) + ((i2 >> 24) & 0xff) + ((i3 >> 24) & 0xff) + ((i4 >> 24) & 0xff);
+ return (r >> 2) | ((g >> 2) << 8) | ((b >> 2) << 16) | ((a >> 2) << 24);
+}
+
+
+
+}
+}
+
+#endif //ANDROID_RS_OBJECT_BASE_H
+
+
diff --git a/libs/rs/rsgApi.cpp.rsg b/libs/rs/rsgApi.cpp.rsg
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/libs/rs/rsgApi.cpp.rsg
@@ -0,0 +1 @@
+2
diff --git a/libs/rs/rsgApiFuncDecl.h.rsg b/libs/rs/rsgApiFuncDecl.h.rsg
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/libs/rs/rsgApiFuncDecl.h.rsg
@@ -0,0 +1 @@
+1
diff --git a/libs/rs/rsgApiReplay.cpp.rsg b/libs/rs/rsgApiReplay.cpp.rsg
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/libs/rs/rsgApiReplay.cpp.rsg
@@ -0,0 +1 @@
+3
diff --git a/libs/rs/rsgApiStructs.h.rsg b/libs/rs/rsgApiStructs.h.rsg
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/libs/rs/rsgApiStructs.h.rsg
@@ -0,0 +1 @@
+0
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
new file mode 100644
index 0000000..74ba248
--- /dev/null
+++ b/libs/rs/rsg_generator.c
@@ -0,0 +1,306 @@
+
+#include "spec.h"
+#include <stdio.h>
+
+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 *");
+ } else {
+ fprintf(f, "RsContext rsc");
+ }
+ printArgList(f, api, 1);
+ 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, "#include \"rsHandcode.h\"\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");
+ if (api->handcodeApi) {
+ fprintf(f, " rsHCAPI_%s(rsc", api->name);
+ for(ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ fprintf(f, ", %s", vt->name);
+ }
+ fprintf(f, ");\n");
+ } else {
+ fprintf(f, " ThreadIO *io = &((Context *)rsc)->mIO;\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, "#include \"rsHandcode.h\"\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");
+ if (api->handcodePlay) {
+ fprintf(f, " rsHCPLAY_%s(con, vp);\n", api->name);
+ } else {
+ //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, "con->mIO.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, ",\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.h b/libs/rs/spec.h
new file mode 100644
index 0000000..82650a7
--- /dev/null
+++ b/libs/rs/spec.h
@@ -0,0 +1,43 @@
+#ifndef SPEC_H
+#define SPEC_H
+
+#include <string.h>
+#include <stdlib.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+extern int num_lines;
+
+typedef struct {
+ int isConst;
+ int type;
+ int bits;
+ int ptrLevel;
+ char name[256];
+ char typeName[256];
+} VarType;
+
+extern VarType *currType;
+
+typedef struct {
+ char name[256];
+ int sync;
+ int handcodeApi;
+ int handcodePlay;
+ int paramCount;
+ VarType ret;
+ VarType params[16];
+} ApiEntry;
+
+extern ApiEntry apis[128];
+extern int apiCount;
+
+extern int typeNextState;
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // SPEC_H
diff --git a/libs/rs/spec.l b/libs/rs/spec.l
new file mode 100644
index 0000000..d81d47e
--- /dev/null
+++ b/libs/rs/spec.l
@@ -0,0 +1,165 @@
+%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_]*
+
+ #include "spec.h"
+
+ int num_lines = 0;
+
+ VarType *currType = 0;
+
+ ApiEntry apis[128];
+ int apiCount = 0;
+
+ int typeNextState;
+
+ extern "C" int yylex();
+
+%%
+
+"/*" 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>"handcodeApi" {
+ apis[apiCount].handcodeApi = 1;
+ }
+
+<api_entry2>"handcodePlay" {
+ apis[apiCount].handcodePlay = 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;
+}
+