Merge "Add x86 server support." into jb-mr2-dev
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index d2d81c9..4368225 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -145,17 +145,21 @@
 }
 
 void Allocation::ioSendOutput() {
+#ifndef RS_COMPATIBILITY_LIB
     if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
         ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
     }
     rsAllocationIoSend(mRS->getContext(), getID());
+#endif
 }
 
 void Allocation::ioGetInput() {
+#ifndef RS_COMPATIBILITY_LIB
     if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
         ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
     }
     rsAllocationIoReceive(mRS->getContext(), getID());
+#endif
 }
 
 void Allocation::generateMipmaps() {
diff --git a/cpp/BaseObj.cpp b/cpp/BaseObj.cpp
index d0102d0..828bd87 100644
--- a/cpp/BaseObj.cpp
+++ b/cpp/BaseObj.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
 #include "RenderScript.h"
 #include <rs.h>
 
diff --git a/cpp/Element.cpp b/cpp/Element.cpp
index f3e83d0..51a96cd 100644
--- a/cpp/Element.cpp
+++ b/cpp/Element.cpp
@@ -40,7 +40,7 @@
     if (index >= mVisibleElementMap.size()) {
         mRS->throwError("Illegal sub-element index");
     }
-    return mElementNames[mVisibleElementMap[index]];
+    return mElementNames[mVisibleElementMap[index]].string();
 }
 
 size_t Element::getSubElementArraySize(uint32_t index) {
@@ -338,7 +338,7 @@
     // Skip padding fields after a vector 3 type.
     if (mSkipPadding) {
         const char *s1 = "#padding_";
-        const char *s2 = name;
+        const char *s2 = name.string();
         size_t len = strlen(s1);
         if (strlen(s2) >= len) {
             if (!memcmp(s1, s2, len)) {
diff --git a/cpp/RenderScript.cpp b/cpp/RenderScript.cpp
index 886e1d4..503798b 100644
--- a/cpp/RenderScript.cpp
+++ b/cpp/RenderScript.cpp
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
-#include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
 #include <pthread.h>
 
 #include "RenderScript.h"
 #include "rs.h"
+#include "rsUtils.h"
 
 using namespace android;
 using namespace RSC;
diff --git a/cpp/RenderScript.h b/cpp/RenderScript.h
index 9e74922..9a7a565 100644
--- a/cpp/RenderScript.h
+++ b/cpp/RenderScript.h
@@ -20,4 +20,8 @@
 #include "rsDefines.h"
 #include "rsCppStructs.h"
 
+#ifdef RS_SERVER
+#define RS_VERSION 18
+#endif
+
 #endif
diff --git a/cpp/Script.cpp b/cpp/Script.cpp
index ee03aaf..54a571a 100644
--- a/cpp/Script.cpp
+++ b/cpp/Script.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <utils/Log.h>
 #include <malloc.h>
 
 #include "RenderScript.h"
diff --git a/cpp/ScriptC.cpp b/cpp/ScriptC.cpp
index 95bd9a4..f66e0ec 100644
--- a/cpp/ScriptC.cpp
+++ b/cpp/ScriptC.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <utils/Log.h>
 #include <malloc.h>
 
 #include "RenderScript.h"
diff --git a/cpp/ScriptIntrinsics.cpp b/cpp/ScriptIntrinsics.cpp
index 4a39d0e..44e8760 100644
--- a/cpp/ScriptIntrinsics.cpp
+++ b/cpp/ScriptIntrinsics.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <utils/Log.h>
 #include <malloc.h>
 
 #include "RenderScript.h"
diff --git a/cpp/Type.cpp b/cpp/Type.cpp
index 675f66e..8fa505c 100644
--- a/cpp/Type.cpp
+++ b/cpp/Type.cpp
@@ -14,14 +14,12 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
-#include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
 
 #include <rs.h>
 #include "RenderScript.h"
+#include "rsUtils.h"
 
 using namespace android;
 using namespace RSC;
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index 67df202..97420fb 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -17,9 +17,12 @@
 #ifndef ANDROID_RSCPPSTRUCTS_H
 #define ANDROID_RSCPPSTRUCTS_H
 
-#include <utils/String8.h>
-#include <utils/Vector.h>
+#include "rsUtils.h"
+#ifndef RS_SERVER
 #include "utils/RefBase.h"
+#else
+#include "RefBase.h"
+#endif
 
 // Every row in an RS allocation is guaranteed to be aligned by this amount
 // Every row in a user-backed allocation must be aligned by this amount
diff --git a/cpu_ref/rsCpuCore.cpp b/cpu_ref/rsCpuCore.cpp
index 604f180..7facade 100644
--- a/cpu_ref/rsCpuCore.cpp
+++ b/cpu_ref/rsCpuCore.cpp
@@ -24,10 +24,20 @@
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <sched.h>
-#include <cutils/properties.h>
 #include <sys/syscall.h>
 #include <string.h>
+
+#ifndef RS_SERVER
+#include <cutils/properties.h>
 #include "utils/StopWatch.h"
+#endif
+
+#ifdef RS_SERVER
+// Android exposes gettid(), standard Linux does not
+static pid_t gettid() {
+    return syscall(SYS_gettid);
+}
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -102,8 +112,7 @@
 void * RsdCpuReferenceImpl::helperThreadProc(void *vrsc) {
     RsdCpuReferenceImpl *dc = (RsdCpuReferenceImpl *)vrsc;
 
-
-    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
+    uint32_t idx = __sync_fetch_and_add(&dc->mWorkers.mLaunchCount, 1);
 
     //ALOGV("RS helperThread starting %p idx=%i", dc, idx);
 
@@ -132,7 +141,7 @@
            // idx +1 is used because the calling thread is always worker 0.
            dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx+1);
         }
-        android_atomic_dec(&dc->mWorkers.mRunningCount);
+        __sync_fetch_and_sub(&dc->mWorkers.mRunningCount, 1);
         dc->mWorkers.mCompleteSignal.set();
     }
 
@@ -153,7 +162,9 @@
         return;
     }
 
-    android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
+    mWorkers.mRunningCount = mWorkers.mCount;
+    __sync_synchronize();
+
     for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
         mWorkers.mLaunchSignals[ct].set();
     }
@@ -164,7 +175,7 @@
         mWorkers.mLaunchCallback(mWorkers.mLaunchData, 0);
     }
 
-    while (android_atomic_acquire_load(&mWorkers.mRunningCount) != 0) {
+    while (__sync_fetch_and_or(&mWorkers.mRunningCount, 0) != 0) {
         mWorkers.mCompleteSignal.wait();
     }
 }
@@ -224,8 +235,9 @@
 
     mWorkers.mCompleteSignal.init();
 
-    android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
-    android_atomic_release_store(0, &mWorkers.mLaunchCount);
+    mWorkers.mRunningCount = mWorkers.mCount;
+    mWorkers.mLaunchCount = 0;
+    __sync_synchronize();
 
     pthread_attr_t threadAttr;
     status = pthread_attr_init(&threadAttr);
@@ -242,7 +254,7 @@
             break;
         }
     }
-    while (android_atomic_acquire_load(&mWorkers.mRunningCount) != 0) {
+    while (__sync_fetch_and_or(&mWorkers.mRunningCount, 0) != 0) {
         usleep(100);
     }
 
@@ -261,7 +273,8 @@
     mExit = true;
     mWorkers.mLaunchData = NULL;
     mWorkers.mLaunchCallback = NULL;
-    android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
+    mWorkers.mRunningCount = mWorkers.mCount;
+    __sync_synchronize();
     for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
         mWorkers.mLaunchSignals[ct].set();
     }
@@ -269,7 +282,7 @@
     for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
         pthread_join(mWorkers.mThreadId[ct], &res);
     }
-    rsAssert(android_atomic_acquire_load(&mWorkers.mRunningCount) == 0);
+    rsAssert(__sync_fetch_and_or(&mWorkers.mRunningCount, 0) == 0);
 
     // Global structure cleanup.
     lockMutex();
@@ -292,7 +305,7 @@
 
     outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
     while (1) {
-        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
+        uint32_t slice = (uint32_t)__sync_fetch_and_add(&mtls->mSliceNum, 1);
         uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
         uint32_t yEnd = yStart + mtls->mSliceSize;
         yEnd = rsMin(yEnd, mtls->yEnd);
@@ -322,7 +335,7 @@
 
     outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
     while (1) {
-        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
+        uint32_t slice = (uint32_t)__sync_fetch_and_add(&mtls->mSliceNum, 1);
         uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
         uint32_t xEnd = xStart + mtls->mSliceSize;
         xEnd = rsMin(xEnd, mtls->xEnd);
diff --git a/cpu_ref/rsCpuIntrinsic3DLUT.cpp b/cpu_ref/rsCpuIntrinsic3DLUT.cpp
index 2eca373..03f24d8 100644
--- a/cpu_ref/rsCpuIntrinsic3DLUT.cpp
+++ b/cpu_ref/rsCpuIntrinsic3DLUT.cpp
@@ -135,7 +135,7 @@
         uint4 v2 = (v + 0x7f) >> (int4)8;
 
         uchar4 ret = convert_uchar4(v2);
-        ret.a = in->a;
+        ret.w = in->w;
 
         #if 0
         if (!x1) {
diff --git a/cpu_ref/rsCpuIntrinsicBlend.cpp b/cpu_ref/rsCpuIntrinsicBlend.cpp
index d7b01b6..4e9470e 100644
--- a/cpu_ref/rsCpuIntrinsicBlend.cpp
+++ b/cpu_ref/rsCpuIntrinsicBlend.cpp
@@ -143,7 +143,7 @@
         for (;x1 < x2; x1++, out++, in++) {
             short4 in_s = convert_short4(*in);
             short4 out_s = convert_short4(*out);
-            in_s = in_s + ((out_s * (short4)(255 - in_s.a)) >> (short4)8);
+            in_s = in_s + ((out_s * (short4)(255 - in_s.w)) >> (short4)8);
             *out = convert_uchar4(in_s);
         }
         break;
@@ -160,7 +160,7 @@
         for (;x1 < x2; x1++, out++, in++) {
             short4 in_s = convert_short4(*in);
             short4 out_s = convert_short4(*out);
-            in_s = out_s + ((in_s * (short4)(255 - out_s.a)) >> (short4)8);
+            in_s = out_s + ((in_s * (short4)(255 - out_s.w)) >> (short4)8);
             *out = convert_uchar4(in_s);
         }
         break;
@@ -176,7 +176,7 @@
 #endif
         for (;x1 < x2; x1++, out++, in++) {
             short4 in_s = convert_short4(*in);
-            in_s = (in_s * out->a) >> (short4)8;
+            in_s = (in_s * out->w) >> (short4)8;
             *out = convert_uchar4(in_s);
         }
         break;
@@ -192,7 +192,7 @@
 #endif
         for (;x1 < x2; x1++, out++, in++) {
             short4 out_s = convert_short4(*out);
-            out_s = (out_s * in->a) >> (short4)8;
+            out_s = (out_s * in->w) >> (short4)8;
             *out = convert_uchar4(out_s);
         }
         break;
@@ -208,7 +208,7 @@
 #endif
         for (;x1 < x2; x1++, out++, in++) {
             short4 in_s = convert_short4(*in);
-            in_s = (in_s * (short4)(255 - out->a)) >> (short4)8;
+            in_s = (in_s * (short4)(255 - out->w)) >> (short4)8;
             *out = convert_uchar4(in_s);
         }
         break;
@@ -224,7 +224,7 @@
 #endif
         for (;x1 < x2; x1++, out++, in++) {
             short4 out_s = convert_short4(*out);
-            out_s = (out_s * (short4)(255 - in->a)) >> (short4)8;
+            out_s = (out_s * (short4)(255 - in->w)) >> (short4)8;
             *out = convert_uchar4(out_s);
         }
         break;
@@ -241,8 +241,8 @@
         for (;x1 < x2; x1++, out++, in++) {
             short4 in_s = convert_short4(*in);
             short4 out_s = convert_short4(*out);
-            out_s.rgb = ((in_s.rgb * out_s.a) +
-              (out_s.rgb * ((short3)255 - (short3)in_s.a))) >> (short3)8;
+            out_s.xyz = ((in_s.xyz * out_s.w) +
+              (out_s.xyz * ((short3)255 - (short3)in_s.w))) >> (short3)8;
             *out = convert_uchar4(out_s);
         }
         break;
@@ -259,8 +259,8 @@
         for (;x1 < x2; x1++, out++, in++) {
             short4 in_s = convert_short4(*in);
             short4 out_s = convert_short4(*out);
-            out_s.rgb = ((out_s.rgb * in_s.a) +
-              (in_s.rgb * ((short3)255 - (short3)out_s.a))) >> (short3)8;
+            out_s.xyz = ((out_s.xyz * in_s.w) +
+              (in_s.xyz * ((short3)255 - (short3)out_s.w))) >> (short3)8;
             *out = convert_uchar4(out_s);
         }
         break;
@@ -388,12 +388,12 @@
         }
 #endif
         for (;x1 < x2; x1++, out++, in++) {
-            uint32_t iR = in->r, iG = in->g, iB = in->b, iA = in->a,
-                oR = out->r, oG = out->g, oB = out->b, oA = out->a;
-            out->r = (oR + iR) > 255 ? 255 : oR + iR;
-            out->g = (oG + iG) > 255 ? 255 : oG + iG;
-            out->b = (oB + iB) > 255 ? 255 : oB + iB;
-            out->a = (oA + iA) > 255 ? 255 : oA + iA;
+            uint32_t iR = in->x, iG = in->y, iB = in->z, iA = in->w,
+                oR = out->x, oG = out->y, oB = out->z, oA = out->w;
+            out->x = (oR + iR) > 255 ? 255 : oR + iR;
+            out->y = (oG + iG) > 255 ? 255 : oG + iG;
+            out->z = (oB + iB) > 255 ? 255 : oB + iB;
+            out->w = (oA + iA) > 255 ? 255 : oA + iA;
         }
         break;
     case BLEND_SUBTRACT:
@@ -407,12 +407,12 @@
         }
 #endif
         for (;x1 < x2; x1++, out++, in++) {
-            int32_t iR = in->r, iG = in->g, iB = in->b, iA = in->a,
-                oR = out->r, oG = out->g, oB = out->b, oA = out->a;
-            out->r = (oR - iR) < 0 ? 0 : oR - iR;
-            out->g = (oG - iG) < 0 ? 0 : oG - iG;
-            out->b = (oB - iB) < 0 ? 0 : oB - iB;
-            out->a = (oA - iA) < 0 ? 0 : oA - iA;
+            int32_t iR = in->x, iG = in->y, iB = in->z, iA = in->w,
+                oR = out->x, oG = out->y, oB = out->z, oA = out->w;
+            out->x = (oR - iR) < 0 ? 0 : oR - iR;
+            out->y = (oG - iG) < 0 ? 0 : oG - iG;
+            out->z = (oB - iB) < 0 ? 0 : oB - iB;
+            out->w = (oA - iA) < 0 ? 0 : oA - iA;
         }
         break;
     case BLEND_STAMP:
diff --git a/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp b/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp
index bcd5ffd..112f377 100644
--- a/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp
+++ b/cpu_ref/rsCpuIntrinsicConvolve5x5.cpp
@@ -113,7 +113,7 @@
         //ALOGE("x %i  %i,%i,%i,%i  %i,%i,%i,%i", x, o.x, o.y, o.z, o.w, out[0].x, out[0].y, out[0].z, out[0].w);
     //}
     //o.w = 0xff;
-    out->rgba = o.rgba;
+    out->xyzw = o.xyzw;
 }
 
 extern "C" void rsdIntrinsicConvolve5x5_K(void *dst, const void *y0, const void *y1,
diff --git a/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp b/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp
index bb8cde1..3a49c0d 100644
--- a/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp
+++ b/cpu_ref/rsCpuIntrinsicYuvToRGB.cpp
@@ -61,30 +61,30 @@
     short V = ((short)v) - 128;
 
     short4 p;
-    p.r = (Y * 298 + V * 409 + 128) >> 8;
-    p.g = (Y * 298 - U * 100 - V * 208 + 128) >> 8;
-    p.b = (Y * 298 + U * 516 + 128) >> 8;
-    p.a = 255;
-    if(p.r < 0) {
-        p.r = 0;
+    p.x = (Y * 298 + V * 409 + 128) >> 8;
+    p.y = (Y * 298 - U * 100 - V * 208 + 128) >> 8;
+    p.z = (Y * 298 + U * 516 + 128) >> 8;
+    p.w = 255;
+    if(p.x < 0) {
+        p.x = 0;
     }
-    if(p.r > 255) {
-        p.r = 255;
+    if(p.x > 255) {
+        p.x = 255;
     }
-    if(p.g < 0) {
-        p.g = 0;
+    if(p.y < 0) {
+        p.y = 0;
     }
-    if(p.g > 255) {
-        p.g = 255;
+    if(p.y > 255) {
+        p.y = 255;
     }
-    if(p.b < 0) {
-        p.b = 0;
+    if(p.z < 0) {
+        p.z = 0;
     }
-    if(p.b > 255) {
-        p.b = 255;
+    if(p.z > 255) {
+        p.z = 255;
     }
 
-    return (uchar4){p.r, p.g, p.b, p.a};
+    return (uchar4){p.x, p.y, p.z, p.w};
 }
 
 
diff --git a/cpu_ref/rsCpuRuntimeMath.cpp b/cpu_ref/rsCpuRuntimeMath.cpp
index f66677b..6c02303 100644
--- a/cpu_ref/rsCpuRuntimeMath.cpp
+++ b/cpu_ref/rsCpuRuntimeMath.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
+#ifndef RS_SERVER
 #include <cutils/compiler.h>
+#endif
 
 #include "rsContext.h"
 #include "rsScriptC.h"
diff --git a/cpu_ref/rsCpuRuntimeStubs.cpp b/cpu_ref/rsCpuRuntimeStubs.cpp
index ceea9c4..7b8d557 100644
--- a/cpu_ref/rsCpuRuntimeStubs.cpp
+++ b/cpu_ref/rsCpuRuntimeStubs.cpp
@@ -21,12 +21,15 @@
 #include "rsMatrix2x2.h"
 #include "rsRuntime.h"
 
-#include "utils/Timers.h"
 #include "rsCpuCore.h"
 #include "rsCpuScript.h"
 
 #include <time.h>
 
+#ifndef RS_SERVER
+#include "utils/Timers.h"
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index 2ae4d83..7887474 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -23,10 +23,11 @@
 //#include "rsdAllocation.h"
 //#include "rsCpuIntrinsics.h"
 
-
+#ifndef RS_SERVER
 #include "utils/Vector.h"
 #include "utils/Timers.h"
 #include "utils/StopWatch.h"
+#endif
 
 #ifdef RS_COMPATIBILITY_LIB
     #include <dlfcn.h>
@@ -177,10 +178,14 @@
 
 #else
 
+#ifndef RS_SERVER
     String8 scriptSOName(cacheDir);
     scriptSOName = scriptSOName.getPathDir();
     scriptSOName.appendPath("lib");
     scriptSOName.append("/librs.");
+#else
+    String8 scriptSOName("lib");
+#endif
     scriptSOName.append(resName);
     scriptSOName.append(".so");
 
diff --git a/cpu_ref/rsCpuScriptGroup.cpp b/cpu_ref/rsCpuScriptGroup.cpp
index d418c22..b3b5bf9 100644
--- a/cpu_ref/rsCpuScriptGroup.cpp
+++ b/cpu_ref/rsCpuScriptGroup.cpp
@@ -18,10 +18,12 @@
 #include "rsCpuScript.h"
 #include "rsCpuScriptGroup.h"
 
+#ifndef RS_SERVER
 #include <bcc/BCCContext.h>
 #include <bcc/Renderscript/RSCompilerDriver.h>
 #include <bcc/Renderscript/RSExecutable.h>
 #include <bcc/Renderscript/RSInfo.h>
+#endif
 
 #include "rsScript.h"
 #include "rsScriptGroup.h"
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index ed27dca..cdcf48f 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
-
 #include "rsdCore.h"
 #include "rsdAllocation.h"
 
 #include "rsAllocation.h"
 
+#ifndef RS_SERVER
 #include "system/window.h"
 #include "ui/Rect.h"
 #include "ui/GraphicBufferMapper.h"
+#endif
 
 #ifndef RS_COMPATIBILITY_LIB
 #include "rsdFrameBufferObj.h"
@@ -36,6 +37,11 @@
 #include <GLES/glext.h>
 #endif
 
+#ifdef RS_SERVER
+// server requires malloc.h for memalign
+#include <malloc.h>
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -241,10 +247,12 @@
 #endif
 }
 
+
 static size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
     // YUV only supports basic 2d
     // so we can stash the plane pointers in the mipmap levels.
     size_t uvSize = 0;
+#ifndef RS_SERVER
     switch(yuv) {
     case HAL_PIXEL_FORMAT_YV12:
         state->lod[1].dimX = state->lod[0].dimX / 2;
@@ -275,6 +283,7 @@
     default:
         rsAssert(0);
     }
+#endif
     return uvSize;
 }
 
@@ -406,6 +415,7 @@
         rsAssert(!"Size mismatch");
     }
 
+#ifndef RS_SERVER
     drv->glTarget = GL_NONE;
     if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
         if (alloc->mHal.state.hasFaces) {
@@ -418,6 +428,7 @@
             drv->glTarget = GL_ARRAY_BUFFER;
         }
     }
+#endif
 
 #ifndef RS_COMPATIBILITY_LIB
     drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
diff --git a/driver/rsdAllocation.h b/driver/rsdAllocation.h
index d8f46c5..c209203 100644
--- a/driver/rsdAllocation.h
+++ b/driver/rsdAllocation.h
@@ -22,11 +22,13 @@
 #include <rsAllocation.h>
 
 #include "../cpu_ref/rsd_cpu.h"
+
+#ifndef RS_SERVER
 #include "gui/CpuConsumer.h"
 #include "gui/GLConsumer.h"
-
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
+#endif
 
 class RsdFrameBufferObj;
 struct ANativeWindow;
@@ -65,8 +67,10 @@
     ANativeWindow *wnd;
     ANativeWindowBuffer *wndBuffer;
 
+#ifndef RS_SERVER
     android::sp< android::CpuConsumer > cpuConsumer;
     android::CpuConsumer::LockedBuffer lb;
+#endif
 };
 
 #ifndef RS_COMPATIBILITY_LIB
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
index 436b9b2..77e0576 100644
--- a/driver/rsdBcc.cpp
+++ b/driver/rsdBcc.cpp
@@ -25,9 +25,11 @@
 #include "rsElement.h"
 #include "rsScriptC.h"
 
+#ifndef RS_SERVER
 #include "utils/Vector.h"
 #include "utils/Timers.h"
 #include "utils/StopWatch.h"
+#endif
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/driver/rsdCore.cpp b/driver/rsdCore.cpp
index 367a50b..9e55524 100644
--- a/driver/rsdCore.cpp
+++ b/driver/rsdCore.cpp
@@ -38,10 +38,13 @@
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <sched.h>
-#include <cutils/properties.h>
 #include <sys/syscall.h>
 #include <string.h>
 
+#ifndef RS_SERVER
+#include <cutils/properties.h>
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
index 92af7ce..8e7d9ee 100644
--- a/driver/rsdRuntimeStubs.cpp
+++ b/driver/rsdRuntimeStubs.cpp
@@ -21,7 +21,6 @@
 #include "rsMatrix2x2.h"
 #include "rsRuntime.h"
 
-#include "utils/Timers.h"
 #include "rsdCore.h"
 #include "rsdBcc.h"
 
@@ -69,7 +68,9 @@
 typedef uint8_t uchar;
 typedef uint16_t ushort;
 typedef uint32_t uint;
+#ifndef RS_SERVER
 typedef uint64_t ulong;
+#endif
 
 //////////////////////////////////////////////////////////////////////////////
 // Allocation
@@ -1050,8 +1051,10 @@
     { "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
     { "_Z20rsgAllocationSyncAll13rs_allocation24rs_allocation_usage_type", (void *)&SC_AllocationSyncAll2, false },
     { "_Z15rsGetAllocationPKv", (void *)&SC_GetAllocation, true },
+#ifndef RS_COMPATIBILITY_LIB
     { "_Z18rsAllocationIoSend13rs_allocation", (void *)&SC_AllocationIoSend, false },
     { "_Z21rsAllocationIoReceive13rs_allocation", (void *)&SC_AllocationIoReceive, false },
+#endif
     { "_Z23rsAllocationCopy1DRange13rs_allocationjjjS_jj", (void *)&SC_AllocationCopy1DRange, false },
     { "_Z23rsAllocationCopy2DRange13rs_allocationjjj26rs_allocation_cubemap_facejjS_jjjS0_", (void *)&SC_AllocationCopy2DRange, false },
 
@@ -1061,7 +1064,7 @@
     { "_Z14rsSendToClientiPKvj", (void *)&SC_ToClient2, false },
     { "_Z22rsSendToClientBlockingi", (void *)&SC_ToClientBlocking, false },
     { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_ToClientBlocking2, false },
-
+#ifndef RS_COMPATIBILITY_LIB
     { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_BindProgramFragment, false },
     { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_BindProgramStore, false },
     { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_BindProgramVertex, false },
@@ -1111,6 +1114,7 @@
     { "_Z19rsgClearColorTargetj", (void *)&SC_ClearFrameBufferObjectColorTarget, false },
     { "_Z19rsgClearDepthTargetv", (void *)&SC_ClearFrameBufferObjectDepthTarget, false },
     { "_Z24rsgClearAllRenderTargetsv", (void *)&SC_ClearFrameBufferObjectTargets, false },
+#endif // RS_COMPATIBILITY_LIB
 
     { "_Z9rsForEach9rs_script13rs_allocationS0_", (void *)&SC_ForEach_SAA, true },
     { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach_SAAU, true },
@@ -1126,12 +1130,346 @@
     { "_Z7rsGetDtv", (void*)&SC_GetDt, false },
 
     // misc
+#ifndef RS_COMPATIBILITY_LIB
     { "_Z5colorffff", (void *)&SC_Color, false },
     { "_Z9rsgFinishv", (void *)&SC_Finish, false },
+#endif
 
     { NULL, NULL, false }
 };
 
+#ifdef RS_COMPATIBILITY_LIB
+
+uint32_t rsSendToClientBlocking(int cmdID) {
+    Context *rsc = RsdCpuReference::getTlsContext();
+    return rsrToClientBlocking(rsc, cmdID, NULL, 0);
+}
+
+static void SC_debugF(const char *s, float f) {
+    ALOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
+}
+static void SC_debugFv2(const char *s, float f1, float f2) {
+    ALOGD("%s {%f, %f}", s, f1, f2);
+}
+static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
+    ALOGD("%s {%f, %f, %f}", s, f1, f2, f3);
+}
+static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
+    ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
+}
+static void SC_debugF2(const char *s, float2 f) {
+    ALOGD("%s {%f, %f}", s, f.x, f.y);
+}
+static void SC_debugF3(const char *s, float3 f) {
+    ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z);
+}
+static void SC_debugF4(const char *s, float4 f) {
+    ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w);
+}
+static void SC_debugD(const char *s, double d) {
+    ALOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
+}
+static void SC_debugFM4v4(const char *s, const float *f) {
+    ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
+    ALOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
+    ALOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
+    ALOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
+}
+static void SC_debugFM3v3(const char *s, const float *f) {
+    ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
+    ALOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
+    ALOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
+}
+static void SC_debugFM2v2(const char *s, const float *f) {
+    ALOGD("%s {%f, %f", s, f[0], f[2]);
+    ALOGD("%s  %f, %f}",s, f[1], f[3]);
+}
+static void SC_debugI8(const char *s, char c) {
+    ALOGD("%s %hhd  0x%hhx", s, c, (unsigned char)c);
+}
+static void SC_debugC2(const char *s, char2 c) {
+    ALOGD("%s {%hhd, %hhd}  0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x, (unsigned char)c.y);
+}
+static void SC_debugC3(const char *s, char3 c) {
+    ALOGD("%s {%hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z);
+}
+static void SC_debugC4(const char *s, char4 c) {
+    ALOGD("%s {%hhd, %hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z, (unsigned char)c.w);
+}
+static void SC_debugU8(const char *s, unsigned char c) {
+    ALOGD("%s %hhu  0x%hhx", s, c, c);
+}
+static void SC_debugUC2(const char *s, uchar2 c) {
+    ALOGD("%s {%hhu, %hhu}  0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y);
+}
+static void SC_debugUC3(const char *s, uchar3 c) {
+    ALOGD("%s {%hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x, c.y, c.z);
+}
+static void SC_debugUC4(const char *s, uchar4 c) {
+    ALOGD("%s {%hhu, %hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
+}
+static void SC_debugI16(const char *s, short c) {
+    ALOGD("%s %hd  0x%hx", s, c, c);
+}
+static void SC_debugS2(const char *s, short2 c) {
+    ALOGD("%s {%hd, %hd}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
+}
+static void SC_debugS3(const char *s, short3 c) {
+    ALOGD("%s {%hd, %hd, %hd}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
+}
+static void SC_debugS4(const char *s, short4 c) {
+    ALOGD("%s {%hd, %hd, %hd, %hd}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
+}
+static void SC_debugU16(const char *s, unsigned short c) {
+    ALOGD("%s %hu  0x%hx", s, c, c);
+}
+static void SC_debugUS2(const char *s, ushort2 c) {
+    ALOGD("%s {%hu, %hu}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
+}
+static void SC_debugUS3(const char *s, ushort3 c) {
+    ALOGD("%s {%hu, %hu, %hu}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
+}
+static void SC_debugUS4(const char *s, ushort4 c) {
+    ALOGD("%s {%hu, %hu, %hu, %hu}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
+}
+static void SC_debugI32(const char *s, int32_t i) {
+    ALOGD("%s %d  0x%x", s, i, i);
+}
+static void SC_debugI2(const char *s, int2 i) {
+    ALOGD("%s {%d, %d}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
+}
+static void SC_debugI3(const char *s, int3 i) {
+    ALOGD("%s {%d, %d, %d}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
+}
+static void SC_debugI4(const char *s, int4 i) {
+    ALOGD("%s {%d, %d, %d, %d}  0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w);
+}
+static void SC_debugU32(const char *s, uint32_t i) {
+    ALOGD("%s %u  0x%x", s, i, i);
+}
+static void SC_debugUI2(const char *s, uint2 i) {
+    ALOGD("%s {%u, %u}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
+}
+static void SC_debugUI3(const char *s, uint3 i) {
+    ALOGD("%s {%u, %u, %u}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
+}
+static void SC_debugUI4(const char *s, uint4 i) {
+    ALOGD("%s {%u, %u, %u, %u}  0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w);
+}
+static void SC_debugLL64(const char *s, long long ll) {
+    ALOGD("%s %lld  0x%llx", s, ll, ll);
+}
+static void SC_debugL2(const char *s, long2 ll) {
+    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, ll.x, ll.y, ll.x, ll.y);
+}
+static void SC_debugL3(const char *s, long3 ll) {
+    ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.x, ll.y, ll.z);
+}
+static void SC_debugL4(const char *s, long4 ll) {
+    ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.w, ll.x, ll.y, ll.z, ll.w);
+}
+static void SC_debugULL64(const char *s, unsigned long long ll) {
+    ALOGD("%s %llu  0x%llx", s, ll, ll);
+}
+static void SC_debugUL2(const char *s, ulong2 ll) {
+    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, ll.x, ll.y, ll.x, ll.y);
+}
+static void SC_debugUL3(const char *s, ulong3 ll) {
+    ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.x, ll.y, ll.z);
+}
+static void SC_debugUL4(const char *s, ulong4 ll) {
+    ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.w, ll.x, ll.y, ll.z, ll.w);
+}
+static void SC_debugP(const char *s, const void *p) {
+    ALOGD("%s %p", s, p);
+}
+
+// TODO: allocation ops, messaging, time
+
+void rsDebug(const char *s, float f) {
+    SC_debugF(s, f);
+}
+
+void rsDebug(const char *s, float f1, float f2) {
+    SC_debugFv2(s, f1, f2);
+}
+
+void rsDebug(const char *s, float f1, float f2, float f3) {
+    SC_debugFv3(s, f1, f2, f3);
+}
+
+void rsDebug(const char *s, float f1, float f2, float f3, float f4) {
+    SC_debugFv4(s, f1, f2, f3, f4);
+}
+
+void rsDebug(const char *s, float2 f) {
+    SC_debugF2(s, f);
+}
+
+void rsDebug(const char *s, float3 f) {
+    SC_debugF3(s, f);
+}
+
+void rsDebug(const char *s, float4 f) {
+    SC_debugF4(s, f);
+}
+
+void rsDebug(const char *s, double d) {
+    SC_debugD(s, d);
+}
+
+void rsDebug(const char *s, rs_matrix4x4 *m) {
+    SC_debugFM4v4(s, (float *) m);
+}
+
+void rsDebug(const char *s, rs_matrix3x3 *m) {
+    SC_debugFM4v4(s, (float *) m);
+}
+
+void rsDebug(const char *s, rs_matrix2x2 *m) {
+    SC_debugFM4v4(s, (float *) m);
+}
+
+void rsDebug(const char *s, char c) {
+    SC_debugI8(s, c);
+}
+
+void rsDebug(const char *s, char2 c) {
+    SC_debugC2(s, c);
+}
+
+void rsDebug(const char *s, char3 c) {
+    SC_debugC3(s, c);
+}
+
+void rsDebug(const char *s, char4 c) {
+    SC_debugC4(s, c);
+}
+
+void rsDebug(const char *s, unsigned char c) {
+    SC_debugU8(s, c);
+}
+
+void rsDebug(const char *s, uchar2 c) {
+    SC_debugUC2(s, c);
+}
+
+void rsDebug(const char *s, uchar3 c) {
+    SC_debugUC3(s, c);
+}
+
+void rsDebug(const char *s, uchar4 c) {
+    SC_debugUC4(s, c);
+}
+
+void rsDebug(const char *s, short c) {
+    SC_debugI16(s, c);
+}
+
+void rsDebug(const char *s, short2 c) {
+    SC_debugS2(s, c);
+}
+
+void rsDebug(const char *s, short3 c) {
+    SC_debugS3(s, c);
+}
+
+void rsDebug(const char *s, short4 c) {
+    SC_debugS4(s, c);
+}
+
+void rsDebug(const char *s, unsigned short c) {
+    SC_debugU16(s, c);
+}
+
+void rsDebug(const char *s, ushort2 c) {
+    SC_debugUS2(s, c);
+}
+
+void rsDebug(const char *s, ushort3 c) {
+    SC_debugUS3(s, c);
+}
+
+void rsDebug(const char *s, ushort4 c) {
+    SC_debugUS4(s, c);
+}
+
+void rsDebug(const char *s, int c) {
+    SC_debugI32(s, c);
+}
+
+void rsDebug(const char *s, int2 c) {
+    SC_debugI2(s, c);
+}
+
+void rsDebug(const char *s, int3 c) {
+    SC_debugI3(s, c);
+}
+
+void rsDebug(const char *s, int4 c) {
+    SC_debugI4(s, c);
+}
+
+void rsDebug(const char *s, unsigned int c) {
+    SC_debugU32(s, c);
+}
+
+void rsDebug(const char *s, uint2 c) {
+    SC_debugUI2(s, c);
+}
+
+void rsDebug(const char *s, uint3 c) {
+    SC_debugUI3(s, c);
+}
+
+void rsDebug(const char *s, uint4 c) {
+    SC_debugUI4(s, c);
+}
+
+void rsDebug(const char *s, long c) {
+    SC_debugLL64(s, c);
+}
+
+void rsDebug(const char *s, long long c) {
+    SC_debugLL64(s, c);
+}
+
+void rsDebug(const char *s, long2 c) {
+    SC_debugL2(s, c);
+}
+
+void rsDebug(const char *s, long3 c) {
+    SC_debugL3(s, c);
+}
+
+void rsDebug(const char *s, long4 c) {
+    SC_debugL4(s, c);
+}
+
+void rsDebug(const char *s, unsigned long c) {
+    SC_debugULL64(s, c);
+}
+
+void rsDebug(const char *s, unsigned long long c) {
+    SC_debugULL64(s, c);
+}
+
+void rsDebug(const char *s, ulong2 c) {
+    SC_debugUL2(s, c);
+}
+
+void rsDebug(const char *s, ulong3 c) {
+    SC_debugUL3(s, c);
+}
+
+void rsDebug(const char *s, ulong4 c) {
+    SC_debugUL4(s, c);
+}
+
+void rsDebug(const char *s, const void *p) {
+    SC_debugP(s, p);
+}
+#endif // RS_COMPATIBILITY_LIB
 
 extern const RsdCpuReference::CpuSymbol * rsdLookupRuntimeStub(Context * pContext, char const* name) {
     ScriptC *s = (ScriptC *)pContext;
diff --git a/driver/rsdShaderCache.h b/driver/rsdShaderCache.h
index 88aa32d..1ac1aa1 100644
--- a/driver/rsdShaderCache.h
+++ b/driver/rsdShaderCache.h
@@ -25,8 +25,12 @@
 }
 }
 
+#ifndef RS_SERVER
 #include <utils/String8.h>
 #include <utils/Vector.h>
+#else
+#include "rsUtils.h"
+#endif
 class RsdShader;
 
 // ---------------------------------------------------------------------------
diff --git a/driver/rsdVertexArray.h b/driver/rsdVertexArray.h
index 3e807a3..9c655df 100644
--- a/driver/rsdVertexArray.h
+++ b/driver/rsdVertexArray.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_RSD_VERTEX_ARRAY_H
 #define ANDROID_RSD_VERTEX_ARRAY_H
 
+#include "rsUtils.h"
+
 namespace android {
 namespace renderscript {
 
@@ -25,8 +27,6 @@
 }
 }
 
-#include <utils/String8.h>
-
 // An element is a group of Components that occupies one cell in a structure.
 class RsdVertexArray {
 public:
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 7c7bc40..30176ec 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -19,8 +19,10 @@
 #include "rsAdapter.h"
 #include "rs_hal.h"
 
+#ifndef RS_SERVER
 #include "system/window.h"
 #include "gui/GLConsumer.h"
+#endif
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/rsComponent.h b/rsComponent.h
index a2e8c0f..4d11718 100644
--- a/rsComponent.h
+++ b/rsComponent.h
@@ -19,7 +19,7 @@
 
 #include "rsUtils.h"
 #include "rsDefines.h"
-
+#include "rsStream.h"
 // ---------------------------------------------------------------------------
 namespace android {
 namespace renderscript {
diff --git a/rsContext.cpp b/rsContext.cpp
index 8d972a2..eec2dcd 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -29,12 +29,21 @@
 #include <sys/resource.h>
 #include <sched.h>
 
-#include <cutils/properties.h>
-
 #include <sys/syscall.h>
 #include <string.h>
 #include <dlfcn.h>
 
+#ifndef RS_SERVER
+#include <cutils/properties.h>
+#endif
+
+#ifdef RS_SERVER
+// Android exposes gettid(), standard Linux does not
+static pid_t gettid() {
+    return syscall(SYS_gettid);
+}
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -194,9 +203,13 @@
 #endif
 
 static uint32_t getProp(const char *str) {
+#ifndef RS_SERVER
     char buf[PROPERTY_VALUE_MAX];
     property_get(str, buf, "0");
     return atoi(buf);
+#else
+    return 0;
+#endif
 }
 
 void Context::displayDebugStats() {
diff --git a/rsFifoSocket.cpp b/rsFifoSocket.cpp
index 44379b2..c10ec4f 100644
--- a/rsFifoSocket.cpp
+++ b/rsFifoSocket.cpp
@@ -15,8 +15,6 @@
  */
 
 #include "rsFifoSocket.h"
-#include "utils/Timers.h"
-#include "utils/StopWatch.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -26,6 +24,11 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
+#ifndef RS_SERVER
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index 162f162..b66bb73 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -69,12 +69,12 @@
 }
 
 void ObjectBase::incUserRef() const {
-    android_atomic_inc(&mUserRefCount);
+    __sync_fetch_and_add(&mUserRefCount, 1);
     //ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
 }
 
 void ObjectBase::incSysRef() const {
-    android_atomic_inc(&mSysRefCount);
+    __sync_fetch_and_add(&mSysRefCount, 1);
     //ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
 }
 
@@ -118,18 +118,23 @@
 #endif
 
 
-    if ((android_atomic_dec(&mUserRefCount) <= 1) &&
-        (android_atomic_acquire_load(&mSysRefCount) <= 0)) {
-        return checkDelete(this);
+    if ((__sync_fetch_and_sub(&mUserRefCount, 1) <= 1)) {
+        __sync_synchronize();
+        if (mSysRefCount <= 0) {
+            return checkDelete(this);
+        }
     }
     return false;
 }
 
 bool ObjectBase::zeroUserRef() const {
     //ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
-    android_atomic_acquire_store(0, &mUserRefCount);
-    if (android_atomic_acquire_load(&mSysRefCount) <= 0) {
-        return checkDelete(this);
+    __sync_and_and_fetch(&mUserRefCount, 0);
+    if ((__sync_fetch_and_sub(&mUserRefCount, 1) <= 1)) {
+        __sync_synchronize();
+        if (mSysRefCount <= 0) {
+            return checkDelete(this);
+        }
     }
     return false;
 }
@@ -137,9 +142,11 @@
 bool ObjectBase::decSysRef() const {
     //ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
     rsAssert(mSysRefCount > 0);
-    if ((android_atomic_dec(&mSysRefCount) <= 1) &&
-        (android_atomic_acquire_load(&mUserRefCount) <= 0)) {
-        return checkDelete(this);
+    if ((__sync_fetch_and_sub(&mSysRefCount, 1) <= 1)) {
+        __sync_synchronize();
+        if (mUserRefCount <= 0) {
+            return checkDelete(this);
+        }
     }
     return false;
 }
diff --git a/rsObjectBase.h b/rsObjectBase.h
index f16acd9..a111e0c 100644
--- a/rsObjectBase.h
+++ b/rsObjectBase.h
@@ -22,7 +22,9 @@
 
 #define RS_OBJECT_DEBUG 0
 
+#ifndef RS_SERVER
 #include <utils/CallStack.h>
+#endif
 
 namespace android {
 namespace renderscript {
diff --git a/rsRuntime.h b/rsRuntime.h
index 390338b..d55042c 100644
--- a/rsRuntime.h
+++ b/rsRuntime.h
@@ -17,7 +17,9 @@
 #include "rsContext.h"
 #include "rsScriptC.h"
 
+#ifndef RS_SERVER
 #include "utils/Timers.h"
+#endif
 
 #include <time.h>
 
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 757d3ca..56c9f06 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -16,8 +16,6 @@
 
 #include "rsContext.h"
 #include "rsScriptC.h"
-#include "utils/Timers.h"
-#include "utils/StopWatch.h"
 
 #ifndef RS_COMPATIBILITY_LIB
 #ifndef ANDROID_RS_SERIALIZE
@@ -26,6 +24,11 @@
 #endif
 #endif
 
+#ifndef RS_SERVER
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+#endif
+
 #include <sys/stat.h>
 
 using namespace android;
@@ -99,8 +102,10 @@
 #endif
 
 void ScriptC::setupScript(Context *rsc) {
+#ifndef RS_SERVER
     mEnviroment.mStartTimeMillis
                 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
+#endif
 
     for (uint32_t ct=0; ct < mHal.info.exportedVariableCount; ct++) {
         if (mSlots[ct].get() && !mTypes[ct].get()) {
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index a8591f5..cd5cc3b 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -21,7 +21,9 @@
 #include "rsMatrix2x2.h"
 #include "rsgApiStructs.h"
 
+#ifndef RS_SERVER
 #include "utils/Timers.h"
+#endif
 
 #include <time.h>
 
@@ -103,17 +105,29 @@
 }
 
 int64_t rsrUptimeMillis(Context *rsc) {
+#ifndef RS_SERVER
     return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
+#else
+    return 0;
+#endif
 }
 
 int64_t rsrUptimeNanos(Context *rsc) {
+#ifndef RS_SERVER
     return systemTime(SYSTEM_TIME_MONOTONIC);
+#else
+    return 0;
+#endif
 }
 
 float rsrGetDt(Context *rsc, const Script *sc) {
+#ifndef RS_SERVER
     int64_t l = sc->mEnviroment.mLastDtTime;
     sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC);
     return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9;
+#else
+    return 0.f;
+#endif
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/rsScriptGroup.cpp b/rsScriptGroup.cpp
index 9230485..f157fee 100644
--- a/rsScriptGroup.cpp
+++ b/rsScriptGroup.cpp
@@ -78,6 +78,7 @@
     return ret;
 }
 
+#ifndef RS_SERVER
 static int CompareNodeForSort(ScriptGroup::Node *const* lhs,
                               ScriptGroup::Node *const* rhs) {
     if (lhs[0]->mOrder > rhs[0]->mOrder) {
@@ -85,7 +86,18 @@
     }
     return 0;
 }
-
+#else
+class NodeCompare {
+public:
+    bool operator() (const ScriptGroup::Node* lhs,
+                     const ScriptGroup::Node* rhs) {
+        if (lhs->mOrder > rhs->mOrder) {
+            return true;
+        }
+        return false;
+    }
+};
+#endif
 
 bool ScriptGroup::calcOrder() {
     // Make nodes
@@ -169,7 +181,11 @@
     }
 
     // sort
+#ifndef RS_SERVER
     mNodes.sort(&CompareNodeForSort);
+#else
+    std::sort(mNodes.begin(), mNodes.end(), NodeCompare());
+#endif
 
     return ret;
 }
diff --git a/rsSignal.cpp b/rsSignal.cpp
index 3f6a13c..c59b39e 100644
--- a/rsSignal.cpp
+++ b/rsSignal.cpp
@@ -95,9 +95,11 @@
         mSet = false;
         ret = true;
     } else {
+#ifndef RS_SERVER
         if (status != ETIMEDOUT) {
             ALOGE("LocklessCommandFifo: error %i waiting for condition.", status);
         }
+#endif
     }
 
     status = pthread_mutex_unlock(&mMutex);
diff --git a/rsStream.h b/rsStream.h
index 62bcf94..8a192e6 100644
--- a/rsStream.h
+++ b/rsStream.h
@@ -17,8 +17,8 @@
 #ifndef ANDROID_RS_STREAM_H
 #define ANDROID_RS_STREAM_H
 
-#include <utils/String8.h>
 #include <stdio.h>
+#include "rsUtils.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
diff --git a/rsType.cpp b/rsType.cpp
index 74a1a54..dacf5e0 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -16,7 +16,9 @@
 
 #include "rsContext.h"
 
+#ifndef RS_SERVER
 #include "system/graphics.h"
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -108,7 +110,7 @@
     if (mHal.state.faces) {
         offset *= 6;
     }
-
+#ifndef RS_SERVER
     // YUV only supports basic 2d
     // so we can stash the plane pointers in the mipmap levels.
     if (mHal.state.dimYuv) {
@@ -133,7 +135,7 @@
             rsAssert(0);
         }
     }
-
+#endif
     mTotalSizeBytes = offset;
     mHal.state.element = mElement.get();
 }
diff --git a/rsUtils.h b/rsUtils.h
index 78341d7..3ef6b5a 100644
--- a/rsUtils.h
+++ b/rsUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2013 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.
@@ -20,20 +20,112 @@
 #define LOG_NDEBUG 0
 #define LOG_TAG "RenderScript"
 
+#ifndef RS_SERVER
 #include <utils/Log.h>
-
-#include "rsStream.h"
-
 #include <utils/String8.h>
 #include <utils/Vector.h>
+#include <cutils/atomic.h>
+#endif
+
+#include <stdint.h>
 
 #include <stdlib.h>
 #include <pthread.h>
 #include <time.h>
-#include <cutils/atomic.h>
 
 #include <math.h>
 
+#ifdef RS_SERVER
+
+#include <string>
+#include <vector>
+#include <algorithm>
+
+#define ALOGE(...)
+#define ALOGV(...)
+#define ALOGW(...)
+#define ALOGD(...)
+
+namespace android {
+
+    // server has no Vector or String8 classes; implement on top of STL
+    class String8: public std::string {
+    public:
+    String8(const char *ptr) : std::string(ptr) {
+
+        }
+    String8() : std::string() {
+
+        }
+
+        const char* string() const {
+            return this->c_str();
+        }
+
+        void setTo(const char* str, ssize_t len) {
+            this->assign(str, len);
+        }
+        void setTo(const char* str) {
+            this->assign(str);
+        }
+
+    };
+
+    template <class T> class Vector: public std::vector<T> {
+    public:
+        void push(T obj) {
+            this->push_back(obj);
+        }
+        void removeAt(uint32_t index) {
+            this->erase(this->begin() + index);
+        }
+        ssize_t add(const T& obj) {
+            this->push_back(obj);
+            return this->size() - 1;
+        }
+        void setCapacity(ssize_t capacity) {
+            this->resize(capacity);
+        }
+
+        T* editArray() {
+            return this->data();
+        }
+
+        const T* array() {
+            return this->data();
+        }
+
+    };
+
+    template<> class Vector<bool>: public std::vector<char> {
+    public:
+        void push(bool obj) {
+            this->push_back(obj);
+        }
+        void removeAt(uint32_t index) {
+            this->erase(this->begin() + index);
+        }
+        ssize_t add(const bool& obj) {
+            this->push_back(obj);
+            return this->size() - 1;
+        }
+        void setCapacity(ssize_t capacity) {
+            this->resize(capacity);
+        }
+
+        bool* editArray() {
+            return (bool*)this->data();
+        }
+
+        const bool* array() {
+            return (const bool*)this->data();
+        }
+    };
+
+}
+
+#endif // RS_SERVER
+
 namespace android {
 namespace renderscript {
 
diff --git a/server/RefBase.h b/server/RefBase.h
new file mode 100644
index 0000000..e1e5007
--- /dev/null
+++ b/server/RefBase.h
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2013 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_REF_BASE_H
+#define ANDROID_REF_BASE_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "StrongPointer.h"
+#include "TypeHelpers.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class TextOutput;
+TextOutput& printWeakPointer(TextOutput& to, const void* val);
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE_WEAK(_op_)                                      \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}
+
+// ---------------------------------------------------------------------------
+class ReferenceMover;
+class ReferenceConverterBase {
+public:
+    virtual size_t getReferenceTypeSize() const = 0;
+    virtual void* getReferenceBase(void const*) const = 0;
+    inline virtual ~ReferenceConverterBase() { }
+};
+
+// ---------------------------------------------------------------------------
+
+class RefBase
+{
+public:
+            void            incStrong(const void* id) const;
+            void            decStrong(const void* id) const;
+
+            void            forceIncStrong(const void* id) const;
+
+            //! DEBUGGING ONLY: Get current strong ref count.
+            int32_t         getStrongCount() const;
+
+    class weakref_type
+    {
+    public:
+        RefBase*            refBase() const;
+
+        void                incWeak(const void* id);
+        void                decWeak(const void* id);
+
+        // acquires a strong reference if there is already one.
+        bool                attemptIncStrong(const void* id);
+
+        // acquires a weak reference if there is already one.
+        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
+        // for proper use.
+        bool                attemptIncWeak(const void* id);
+
+        //! DEBUGGING ONLY: Get current weak ref count.
+        int32_t             getWeakCount() const;
+
+        //! DEBUGGING ONLY: Print references held on object.
+        void                printRefs() const;
+
+        //! DEBUGGING ONLY: Enable tracking for this object.
+        // enable -- enable/disable tracking
+        // retain -- when tracking is enable, if true, then we save a stack trace
+        //           for each reference and dereference; when retain == false, we
+        //           match up references and dereferences and keep only the
+        //           outstanding ones.
+
+        void                trackMe(bool enable, bool retain);
+    };
+
+            weakref_type*   createWeak(const void* id) const;
+
+            weakref_type*   getWeakRefs() const;
+
+            //! DEBUGGING ONLY: Print references held on object.
+    inline  void            printRefs() const { getWeakRefs()->printRefs(); }
+
+            //! DEBUGGING ONLY: Enable tracking of object.
+    inline  void            trackMe(bool enable, bool retain)
+    {
+        getWeakRefs()->trackMe(enable, retain);
+    }
+
+    typedef RefBase basetype;
+
+protected:
+                            RefBase();
+    virtual                 ~RefBase();
+
+    //! Flags for extendObjectLifetime()
+    enum {
+        OBJECT_LIFETIME_STRONG  = 0x0000,
+        OBJECT_LIFETIME_WEAK    = 0x0001,
+        OBJECT_LIFETIME_MASK    = 0x0001
+    };
+
+            void            extendObjectLifetime(int32_t mode);
+
+    //! Flags for onIncStrongAttempted()
+    enum {
+        FIRST_INC_STRONG = 0x0001
+    };
+
+    virtual void            onFirstRef();
+    virtual void            onLastStrongRef(const void* id);
+    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
+    virtual void            onLastWeakRef(const void* id);
+
+private:
+    friend class ReferenceMover;
+    static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster);
+
+private:
+    friend class weakref_type;
+    class weakref_impl;
+
+                            RefBase(const RefBase& o);
+            RefBase&        operator=(const RefBase& o);
+
+        weakref_impl* const mRefs;
+};
+
+// ---------------------------------------------------------------------------
+
+template <class T>
+class LightRefBase
+{
+public:
+    inline LightRefBase() : mCount(0) { }
+    inline void incStrong(__attribute__((unused)) const void* id) const {
+        __sync_fetch_and_add(&mCount, 1);
+    }
+    inline void decStrong(__attribute__((unused)) const void* id) const {
+        if (__sync_fetch_and_sub(&mCount, 1) == 1) {
+            delete static_cast<const T*>(this);
+        }
+    }
+    //! DEBUGGING ONLY: Get current strong ref count.
+    inline int32_t getStrongCount() const {
+        return mCount;
+    }
+
+    typedef LightRefBase<T> basetype;
+
+protected:
+    inline ~LightRefBase() { }
+
+private:
+    friend class ReferenceMover;
+    inline static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster) { }
+
+private:
+    mutable volatile int32_t mCount;
+};
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class wp
+{
+public:
+    typedef typename RefBase::weakref_type weakref_type;
+
+    inline wp() : m_ptr(0) { }
+
+    wp(T* other);
+    wp(const wp<T>& other);
+    wp(const sp<T>& other);
+    template<typename U> wp(U* other);
+    template<typename U> wp(const sp<U>& other);
+    template<typename U> wp(const wp<U>& other);
+
+    ~wp();
+
+    // Assignment
+
+    wp& operator = (T* other);
+    wp& operator = (const wp<T>& other);
+    wp& operator = (const sp<T>& other);
+
+    template<typename U> wp& operator = (U* other);
+    template<typename U> wp& operator = (const wp<U>& other);
+    template<typename U> wp& operator = (const sp<U>& other);
+
+    void set_object_and_refs(T* other, weakref_type* refs);
+
+    // promotion to sp
+
+    sp<T> promote() const;
+
+    // Reset
+
+    void clear();
+
+    // Accessors
+
+    inline  weakref_type* get_refs() const { return m_refs; }
+
+    inline  T* unsafe_get() const { return m_ptr; }
+
+    // Operators
+
+    COMPARE_WEAK(==)
+    COMPARE_WEAK(!=)
+    COMPARE_WEAK(>)
+    COMPARE_WEAK(<)
+    COMPARE_WEAK(<=)
+    COMPARE_WEAK(>=)
+
+    inline bool operator == (const wp<T>& o) const {
+        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
+    }
+    template<typename U>
+    inline bool operator == (const wp<U>& o) const {
+        return m_ptr == o.m_ptr;
+    }
+
+    inline bool operator > (const wp<T>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
+    }
+    template<typename U>
+    inline bool operator > (const wp<U>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
+    }
+
+    inline bool operator < (const wp<T>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
+    }
+    template<typename U>
+    inline bool operator < (const wp<U>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
+    }
+                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
+    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
+                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
+    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
+                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
+    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
+
+private:
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+
+    T*              m_ptr;
+    weakref_type*   m_refs;
+};
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const wp<T>& val);
+
+#undef COMPARE_WEAK
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+wp<T>::wp(T* other)
+    : m_ptr(other)
+{
+    if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const wp<T>& other)
+    : m_ptr(other.m_ptr), m_refs(other.m_refs)
+{
+    if (m_ptr) m_refs->incWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const sp<T>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = m_ptr->createWeak(this);
+    }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(U* other)
+    : m_ptr(other)
+{
+    if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const wp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = other.m_refs;
+        m_refs->incWeak(this);
+    }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const sp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = m_ptr->createWeak(this);
+    }
+}
+
+template<typename T>
+wp<T>::~wp()
+{
+    if (m_ptr) m_refs->decWeak(this);
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (T* other)
+{
+    weakref_type* newRefs =
+        other ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const wp<T>& other)
+{
+    weakref_type* otherRefs(other.m_refs);
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
+    return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const sp<T>& other)
+{
+    weakref_type* newRefs =
+        other != NULL ? other->createWeak(this) : 0;
+    T* otherPtr(other.m_ptr);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (U* other)
+{
+    weakref_type* newRefs =
+        other ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const wp<U>& other)
+{
+    weakref_type* otherRefs(other.m_refs);
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const sp<U>& other)
+{
+    weakref_type* newRefs =
+        other != NULL ? other->createWeak(this) : 0;
+    U* otherPtr(other.m_ptr);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T>
+void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
+{
+    if (other) refs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = refs;
+}
+
+template<typename T>
+sp<T> wp<T>::promote() const
+{
+    sp<T> result;
+    if (m_ptr && m_refs->attemptIncStrong(&result)) {
+        result.set_pointer(m_ptr);
+    }
+    return result;
+}
+
+template<typename T>
+void wp<T>::clear()
+{
+    if (m_ptr) {
+        m_refs->decWeak(this);
+        m_ptr = 0;
+    }
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
+{
+    return printWeakPointer(to, val.unsafe_get());
+}
+
+// ---------------------------------------------------------------------------
+
+// this class just serves as a namespace so TYPE::moveReferences can stay
+// private.
+
+class ReferenceMover {
+    // StrongReferenceCast and WeakReferenceCast do the impedance matching
+    // between the generic (void*) implementation in Refbase and the strongly typed
+    // template specializations below.
+
+    template <typename TYPE>
+    struct StrongReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->get());
+        }
+    };
+
+    template <typename TYPE>
+    struct WeakReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
+        }
+    };
+
+public:
+    template<typename TYPE> static inline
+    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(sp<TYPE>));
+        StrongReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+    template<typename TYPE> static inline
+    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(wp<TYPE>));
+        WeakReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+};
+
+// specialization for moving sp<> and wp<> types.
+// these are used by the [Sorted|Keyed]Vector<> implementations
+// sp<> and wp<> need to be handled specially, because they do not
+// have trivial copy operation in the general case (see RefBase.cpp
+// when DEBUG ops are enabled), but can be implemented very
+// efficiently in most cases.
+
+template<typename TYPE> inline
+void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_REF_BASE_H
diff --git a/server/StrongPointer.h b/server/StrongPointer.h
new file mode 100644
index 0000000..8983bd7
--- /dev/null
+++ b/server/StrongPointer.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2013 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_STRONG_POINTER_H
+#define ANDROID_STRONG_POINTER_H
+
+//#include <cutils/atomic.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class TextOutput;
+TextOutput& printStrongPointer(TextOutput& to, const void* val);
+
+template<typename T> class wp;
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE(_op_)                                           \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+inline bool operator _op_ (const wp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const wp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class sp
+{
+public:
+    inline sp() : m_ptr(0) { }
+
+    sp(T* other);
+    sp(const sp<T>& other);
+    template<typename U> sp(U* other);
+    template<typename U> sp(const sp<U>& other);
+
+    ~sp();
+
+    // Assignment
+
+    sp& operator = (T* other);
+    sp& operator = (const sp<T>& other);
+
+    template<typename U> sp& operator = (const sp<U>& other);
+    template<typename U> sp& operator = (U* other);
+
+    //! Special optimization for use by ProcessState (and nobody else).
+    void force_set(T* other);
+
+    // Reset
+
+    void clear();
+
+    // Accessors
+
+    inline  T&      operator* () const  { return *m_ptr; }
+    inline  T*      operator-> () const { return m_ptr;  }
+    inline  T*      get() const         { return m_ptr; }
+
+    // Operators
+
+    COMPARE(==)
+    COMPARE(!=)
+    COMPARE(>)
+    COMPARE(<)
+    COMPARE(<=)
+    COMPARE(>=)
+
+private:
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+    void set_pointer(T* ptr);
+    T* m_ptr;
+};
+
+#undef COMPARE
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const sp<T>& val);
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+sp<T>::sp(T* other)
+: m_ptr(other)
+  {
+    if (other) other->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::sp(const sp<T>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T> template<typename U>
+sp<T>::sp(U* other) : m_ptr(other)
+{
+    if (other) ((T*)other)->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(const sp<U>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::~sp()
+{
+    if (m_ptr) m_ptr->decStrong(this);
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (const sp<T>& other) {
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (T* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (const sp<U>& other)
+{
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (U* other)
+{
+    if (other) ((T*)other)->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T>
+void sp<T>::force_set(T* other)
+{
+    other->forceIncStrong(this);
+    m_ptr = other;
+}
+
+template<typename T>
+void sp<T>::clear()
+{
+    if (m_ptr) {
+        m_ptr->decStrong(this);
+        m_ptr = 0;
+    }
+}
+
+template<typename T>
+void sp<T>::set_pointer(T* ptr) {
+    m_ptr = ptr;
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
+{
+    return printStrongPointer(to, val.get());
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRONG_POINTER_H
diff --git a/server/TypeHelpers.h b/server/TypeHelpers.h
new file mode 100644
index 0000000..c74f945
--- /dev/null
+++ b/server/TypeHelpers.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2013 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_TYPE_HELPERS_H
+#define ANDROID_TYPE_HELPERS_H
+
+#include <new>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*
+ * Types traits
+ */
+
+template <typename T> struct trait_trivial_ctor { enum { value = false }; };
+template <typename T> struct trait_trivial_dtor { enum { value = false }; };
+template <typename T> struct trait_trivial_copy { enum { value = false }; };
+template <typename T> struct trait_trivial_move { enum { value = false }; };
+template <typename T> struct trait_pointer      { enum { value = false }; };
+template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
+
+template <typename TYPE>
+struct traits {
+    enum {
+        // whether this type is a pointer
+        is_pointer          = trait_pointer<TYPE>::value,
+        // whether this type's constructor is a no-op
+        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
+        // whether this type's destructor is a no-op
+        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
+        // whether this type type can be copy-constructed with memcpy
+        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
+        // whether this type can be moved with memmove
+        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
+    };
+};
+
+template <typename T, typename U>
+struct aggregate_traits {
+    enum {
+        is_pointer          = false,
+        has_trivial_ctor    =
+            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
+        has_trivial_dtor    =
+            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
+        has_trivial_copy    =
+            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
+        has_trivial_move    =
+            traits<T>::has_trivial_move && traits<U>::has_trivial_move
+    };
+};
+
+#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
+    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
+
+#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
+    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
+
+#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
+    template<> struct trait_trivial_copy< T >   { enum { value = true }; };
+
+#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
+    template<> struct trait_trivial_move< T >   { enum { value = true }; };
+
+#define ANDROID_BASIC_TYPES_TRAITS( T ) \
+    ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
+    ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
+    ANDROID_TRIVIAL_COPY_TRAIT( T ) \
+    ANDROID_TRIVIAL_MOVE_TRAIT( T )
+
+// ---------------------------------------------------------------------------
+
+/*
+ * basic types traits
+ */
+
+ANDROID_BASIC_TYPES_TRAITS( void )
+ANDROID_BASIC_TYPES_TRAITS( bool )
+ANDROID_BASIC_TYPES_TRAITS( char )
+ANDROID_BASIC_TYPES_TRAITS( unsigned char )
+ANDROID_BASIC_TYPES_TRAITS( short )
+ANDROID_BASIC_TYPES_TRAITS( unsigned short )
+ANDROID_BASIC_TYPES_TRAITS( int )
+ANDROID_BASIC_TYPES_TRAITS( unsigned int )
+ANDROID_BASIC_TYPES_TRAITS( long )
+ANDROID_BASIC_TYPES_TRAITS( unsigned long )
+ANDROID_BASIC_TYPES_TRAITS( long long )
+ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
+ANDROID_BASIC_TYPES_TRAITS( float )
+ANDROID_BASIC_TYPES_TRAITS( double )
+
+// ---------------------------------------------------------------------------
+
+
+/*
+ * compare and order types
+ */
+
+template<typename TYPE> inline
+int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
+    return (lhs < rhs) ? 1 : 0;
+}
+
+template<typename TYPE> inline
+int compare_type(const TYPE& lhs, const TYPE& rhs) {
+    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
+}
+
+/*
+ * create, destroy, copy and move types...
+ */
+
+template<typename TYPE> inline
+void construct_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_ctor) {
+        while (n--) {
+            new(p++) TYPE;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void destroy_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_dtor) {
+        while (n--) {
+            p->~TYPE();
+            p++;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void copy_type(TYPE* d, const TYPE* s, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n--) {
+            new(d) TYPE(*s);
+            d++, s++;
+        }
+    } else {
+        memcpy(d,s,n*sizeof(TYPE));
+    }
+}
+
+template<typename TYPE> inline
+void splat_type(TYPE* where, const TYPE* what, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n--) {
+            new(where) TYPE(*what);
+            where++;
+        }
+    } else {
+        while (n--) {
+            *where++ = *what;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
+            || traits<TYPE>::has_trivial_move)
+    {
+        memmove(d,s,n*sizeof(TYPE));
+    } else {
+        d += n;
+        s += n;
+        while (n--) {
+            --d, --s;
+            if (!traits<TYPE>::has_trivial_copy) {
+                new(d) TYPE(*s);
+            } else {
+                *d = *s;
+            }
+            if (!traits<TYPE>::has_trivial_dtor) {
+                s->~TYPE();
+            }
+        }
+    }
+}
+
+template<typename TYPE> inline
+void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
+            || traits<TYPE>::has_trivial_move)
+    {
+        memmove(d,s,n*sizeof(TYPE));
+    } else {
+        while (n--) {
+            if (!traits<TYPE>::has_trivial_copy) {
+                new(d) TYPE(*s);
+            } else {
+                *d = *s;
+            }
+            if (!traits<TYPE>::has_trivial_dtor) {
+                s->~TYPE();
+            }
+            d++, s++;
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+/*
+ * a key/value pair
+ */
+
+template <typename KEY, typename VALUE>
+struct key_value_pair_t {
+    typedef KEY key_t;
+    typedef VALUE value_t;
+
+    KEY     key;
+    VALUE   value;
+    key_value_pair_t() { }
+    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
+    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
+    key_value_pair_t(const KEY& k) : key(k) { }
+    inline bool operator < (const key_value_pair_t& o) const {
+        return strictly_order_type(key, o.key);
+    }
+    inline const KEY& getKey() const {
+        return key;
+    }
+    inline const VALUE& getValue() const {
+        return value;
+    }
+};
+
+template <typename K, typename V>
+struct trait_trivial_ctor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
+template <typename K, typename V>
+struct trait_trivial_dtor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
+template <typename K, typename V>
+struct trait_trivial_copy< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
+template <typename K, typename V>
+struct trait_trivial_move< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Hash codes.
+ */
+typedef uint32_t hash_t;
+
+template <typename TKey>
+hash_t hash_type(const TKey& key);
+
+/* Built-in hash code specializations.
+ * Assumes pointers are 32bit. */
+#define ANDROID_INT32_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
+#define ANDROID_INT64_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_t((value >> 32) ^ value); }
+#define ANDROID_REINTERPRET_HASH(T, R) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_type(*reinterpret_cast<const R*>(&value)); }
+
+ANDROID_INT32_HASH(bool)
+ANDROID_INT32_HASH(int8_t)
+ANDROID_INT32_HASH(uint8_t)
+ANDROID_INT32_HASH(int16_t)
+ANDROID_INT32_HASH(uint16_t)
+ANDROID_INT32_HASH(int32_t)
+ANDROID_INT32_HASH(uint32_t)
+ANDROID_INT64_HASH(int64_t)
+ANDROID_INT64_HASH(uint64_t)
+ANDROID_REINTERPRET_HASH(float, uint32_t)
+ANDROID_REINTERPRET_HASH(double, uint64_t)
+
+template <typename T> inline hash_t hash_type(T* const & value) {
+    return hash_type(uintptr_t(value));
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_TYPE_HELPERS_H