summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorTim Murray <timmurray@google.com>2013-07-29 14:30:02 -0700
committerTim Murray <timmurray@google.com>2013-08-01 14:14:07 -0700
commit89daad6bae798779e57f252e9da4fe4e62337124 (patch)
treec55735f278a67b2fe5b74b42581cbfae9c99846c /cpp
parentdcfaa3c0bf151da7be31463bb3fa4e2b4aea6b8c (diff)
downloadrs-89daad6bae798779e57f252e9da4fe4e62337124.tar.gz
Add basic support for intrinsics. Move sp<> into RScpp.
Change-Id: I74cdee7069a624ded5091d53db3a4b8ce9894033
Diffstat (limited to 'cpp')
-rw-r--r--cpp/Allocation.cpp54
-rw-r--r--cpp/Android.mk61
-rw-r--r--cpp/BaseObj.cpp7
-rw-r--r--cpp/Element.cpp49
-rw-r--r--cpp/RenderScript.cpp2
-rw-r--r--cpp/RenderScript.h1
-rw-r--r--cpp/Sampler.cpp3
-rw-r--r--cpp/Script.cpp1
-rw-r--r--cpp/ScriptC.cpp1
-rw-r--r--cpp/ScriptIntrinsics.cpp104
-rw-r--r--cpp/Type.cpp1
-rw-r--r--cpp/rsCppStructs.h329
-rw-r--r--cpp/util/RefBase.h529
-rw-r--r--cpp/util/StrongPointer.h222
-rw-r--r--cpp/util/TypeHelpers.h302
15 files changed, 1440 insertions, 226 deletions
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index a613e454..f05b005d 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -15,7 +15,6 @@
*/
#include "RenderScript.h"
-#include <rs.h>
using namespace android;
using namespace RSC;
@@ -64,11 +63,14 @@ Allocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) :
mType = t;
mUsage = usage;
- if (t.get() != NULL) {
+ if (t != NULL) {
updateCacheInfo(t);
}
+
}
+
+
void Allocation::validateIsInt32() {
RsDataType dt = mType->getElement()->getDataType();
if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
@@ -178,7 +180,7 @@ void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) {
}
RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data,
- count * mType->getElement()->getSizeBytes());
+ count * mType->getElement()->getSizeBytes());
}
void Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) {
@@ -192,16 +194,16 @@ void Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) {
}
RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data,
- count * mType->getElement()->getSizeBytes());
+ count * mType->getElement()->getSizeBytes());
}
void Allocation::copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data,
uint32_t dataOff) {
RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
- mSelectedLOD, mSelectedFace,
- count, 1, data->getIDSafe(), dataOff, 0,
- data->mSelectedLOD, data->mSelectedFace);
+ mSelectedLOD, mSelectedFace,
+ count, 1, data->getIDSafe(), dataOff, 0,
+ data->mSelectedLOD, data->mSelectedFace);
}
void Allocation::copy1DFrom(const void* data) {
@@ -227,30 +229,30 @@ void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint3
const void *data) {
validate2DRange(xoff, yoff, w, h);
RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
- w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
+ w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
}
void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff) {
validate2DRange(xoff, yoff, w, h);
RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff,
- mSelectedLOD, mSelectedFace,
- w, h, data->getIDSafe(), dataXoff, dataYoff,
- data->mSelectedLOD, data->mSelectedFace);
+ mSelectedLOD, mSelectedFace,
+ w, h, data->getIDSafe(), dataXoff, dataYoff,
+ data->mSelectedLOD, data->mSelectedFace);
}
void Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
void* data) {
validate2DRange(xoff, yoff, w, h);
RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
- w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
+ w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
}
void Allocation::copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
const void *data, size_t stride) {
validate2DRange(xoff, yoff, w, h);
RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
- w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
+ w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
}
void Allocation::copy2DStridedFrom(const void* data, size_t stride) {
@@ -261,15 +263,15 @@ void Allocation::copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint3
void *data, size_t stride) {
validate2DRange(xoff, yoff, w, h);
RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
- w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
+ w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
}
void Allocation::copy2DStridedTo(void* data, size_t stride) {
copy2DStridedTo(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
}
-android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
- RsAllocationMipmapControl mips, uint32_t usage) {
+sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+ RsAllocationMipmapControl mips, uint32_t usage) {
void *id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 0);
if (id == 0) {
ALOGE("Allocation creation failed.");
@@ -278,24 +280,24 @@ android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
return new Allocation(id, rs, type, usage);
}
-android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
- RsAllocationMipmapControl mips, uint32_t usage,
- void *pointer) {
+sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+ RsAllocationMipmapControl mips, uint32_t usage,
+ void *pointer) {
void *id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mips, usage,
- (uintptr_t)pointer);
+ (uintptr_t)pointer);
if (id == 0) {
ALOGE("Allocation creation failed.");
}
return new Allocation(id, rs, type, usage);
}
-android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
- uint32_t usage) {
+sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+ uint32_t usage) {
return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
}
-android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
- size_t count, uint32_t usage) {
+sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
+ size_t count, uint32_t usage) {
Type::Builder b(rs, e);
b.setX(count);
sp<const Type> t = b.create();
@@ -303,8 +305,8 @@ android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
return createTyped(rs, t, usage);
}
-android::sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
- size_t x, size_t y, uint32_t usage) {
+sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
+ size_t x, size_t y, uint32_t usage) {
Type::Builder b(rs, e);
b.setX(x);
b.setY(y);
diff --git a/cpp/Android.mk b/cpp/Android.mk
index 3613eae8..d266d149 100644
--- a/cpp/Android.mk
+++ b/cpp/Android.mk
@@ -1,3 +1,14 @@
+rs_cpp_SRC_FILES := \
+ RenderScript.cpp \
+ BaseObj.cpp \
+ Element.cpp \
+ Type.cpp \
+ Allocation.cpp \
+ Script.cpp \
+ ScriptC.cpp \
+ ScriptIntrinsics.cpp \
+ Sampler.cpp
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -11,38 +22,50 @@ else
endif
local_cflags_for_rs_cpp += -DRS_VERSION=$(RS_VERSION)
-LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
+LOCAL_SRC_FILES := $(rs_cpp_SRC_FILES)
-LOCAL_SRC_FILES:= \
- RenderScript.cpp \
- BaseObj.cpp \
- Element.cpp \
- Type.cpp \
- Allocation.cpp \
- Script.cpp \
- ScriptC.cpp \
- ScriptIntrinsics.cpp \
- Sampler.cpp
+LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
LOCAL_SHARED_LIBRARIES := \
libz \
libcutils \
libutils \
liblog \
- libdl
+ libdl \
+ libstlport
LOCAL_MODULE:= libRScpp
LOCAL_MODULE_TAGS := optional
-intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
-librs_generated_headers := \
- $(intermediates)/rsgApiStructs.h \
- $(intermediates)/rsgApiFuncDecl.h
-LOCAL_GENERATED_SOURCES := $(librs_generated_headers)
-
LOCAL_C_INCLUDES += frameworks/rs
+LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
LOCAL_C_INCLUDES += $(intermediates)
-
include $(BUILD_SHARED_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
+
+LOCAL_SRC_FILES := $(rs_cpp_SRC_FILES)
+
+LOCAL_STATIC_LIBRARIES := \
+ libz \
+ libcutils \
+ libutils \
+ liblog \
+ libstlport_static
+
+LOCAL_SHARED_LIBRARIES := libdl
+
+LOCAL_MODULE:= libRScpp_static
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES += frameworks/rs
+LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
+LOCAL_C_INCLUDES += $(intermediates)
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/cpp/BaseObj.cpp b/cpp/BaseObj.cpp
index 814e552c..efcb83a2 100644
--- a/cpp/BaseObj.cpp
+++ b/cpp/BaseObj.cpp
@@ -15,7 +15,6 @@
*/
#include "RenderScript.h"
-#include <rs.h>
using namespace android;
using namespace RSC;
@@ -28,7 +27,7 @@ void * BaseObj::getID() const {
}
void * BaseObj::getObjID(sp<const BaseObj> o) {
- return o.get() == NULL ? NULL : o->getID();
+ return o == NULL ? NULL : o->getID();
}
@@ -55,9 +54,9 @@ void BaseObj::updateFromNative() {
mName = name;
}
-bool BaseObj::equals(const BaseObj *obj) {
+bool BaseObj::equals(sp<const BaseObj> obj) {
// Early-out check to see if both BaseObjs are actually the same
- if (this == obj)
+ if (this == obj.get())
return true;
return mID == obj->mID;
}
diff --git a/cpp/Element.cpp b/cpp/Element.cpp
index 1289c6ec..d4b2c66a 100644
--- a/cpp/Element.cpp
+++ b/cpp/Element.cpp
@@ -18,12 +18,11 @@
#include <string.h>
#include "RenderScript.h"
-#include <rs.h>
using namespace android;
using namespace RSC;
-sp<const Element> Element::getSubElement(uint32_t index) {
+android::RSC::sp<const Element> Element::getSubElement(uint32_t index) {
if (!mVisibleElementMap.size()) {
mRS->throwError("Element contains no sub-elements");
}
@@ -64,7 +63,7 @@ uint32_t Element::getSubElementOffsetBytes(uint32_t index) {
}
-#define CREATE_USER(N, T) sp<const Element> Element::N(sp<RS> rs) { \
+#define CREATE_USER(N, T) android::RSC::sp<const Element> Element::N(android::RSC::sp<RS> rs) { \
if (rs->mElements.N == NULL) { \
rs->mElements.N = (createUser(rs, RS_TYPE_##T)).get(); \
} \
@@ -96,7 +95,7 @@ CREATE_USER(MATRIX_4X4, MATRIX_4X4);
CREATE_USER(MATRIX_3X3, MATRIX_3X3);
CREATE_USER(MATRIX_2X2, MATRIX_2X2);
-#define CREATE_PIXEL(N, T, K) sp<const Element> Element::N(sp<RS> rs) { \
+#define CREATE_PIXEL(N, T, K) android::RSC::sp<const Element> Element::N(android::RSC::sp<RS> rs) { \
return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
}
CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
@@ -105,13 +104,13 @@ CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB);
CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
-#define CREATE_VECTOR(N, T) sp<const Element> Element::N##_2(sp<RS> rs) { \
+#define CREATE_VECTOR(N, T) android::RSC::sp<const Element> Element::N##_2(android::RSC::sp<RS> rs) { \
return createVector(rs, RS_TYPE_##T, 2); \
} \
-sp<const Element> Element::N##_3(sp<RS> rs) { \
+android::RSC::sp<const Element> Element::N##_3(android::RSC::sp<RS> rs) { \
return createVector(rs, RS_TYPE_##T, 3); \
} \
-sp<const Element> Element::N##_4(sp<RS> rs) { \
+android::RSC::sp<const Element> Element::N##_4(android::RSC::sp<RS> rs) { \
return createVector(rs, RS_TYPE_##T, 4); \
}
CREATE_VECTOR(U8, UNSIGNED_8);
@@ -144,15 +143,15 @@ void Element::updateVisibleSubElements() {
// Make a map that points us at non-padding elements
for (size_t ct = 0; ct < fieldCount; ct ++) {
if (mElementNames[ct].string()[0] != '#') {
- mVisibleElementMap.push((uint32_t)ct);
+ mVisibleElementMap.push_back((uint32_t)ct);
}
}
}
-Element::Element(void *id, sp<RS> rs,
- android::Vector<sp<Element> > &elements,
- android::Vector<android::String8> &elementNames,
- android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
+Element::Element(void *id, android::RSC::sp<RS> rs,
+ std::vector<android::RSC::sp<Element> > &elements,
+ std::vector<android::String8> &elementNames,
+ std::vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
mSizeBytes = 0;
mVectorSize = 1;
mElements = elements;
@@ -163,7 +162,7 @@ Element::Element(void *id, sp<RS> rs,
mKind = RS_KIND_USER;
for (size_t ct = 0; ct < mElements.size(); ct++ ) {
- mOffsetInBytes.push(mSizeBytes);
+ mOffsetInBytes.push_back(mSizeBytes);
mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct];
}
updateVisibleSubElements();
@@ -223,7 +222,7 @@ static uint32_t GetSizeInBytesForType(RsDataType dt) {
return 0;
}
-Element::Element(void *id, sp<RS> rs,
+Element::Element(void *id, android::RSC::sp<RS> rs,
RsDataType dt, RsDataKind dk, bool norm, uint32_t size) :
BaseObj(id, rs)
{
@@ -253,12 +252,12 @@ void Element::updateFromNative() {
updateVisibleSubElements();
}
-sp<const Element> Element::createUser(sp<RS> rs, RsDataType dt) {
+android::RSC::sp<const Element> Element::createUser(android::RSC::sp<RS> rs, RsDataType dt) {
void * id = RS::dispatch->ElementCreate(rs->getContext(), dt, RS_KIND_USER, false, 1);
return new Element(id, rs, dt, RS_KIND_USER, false, 1);
}
-sp<const Element> Element::createVector(sp<RS> rs, RsDataType dt, uint32_t size) {
+android::RSC::sp<const Element> Element::createVector(android::RSC::sp<RS> rs, RsDataType dt, uint32_t size) {
if (size < 2 || size > 4) {
rs->throwError("Vector size out of range 2-4.");
}
@@ -266,7 +265,7 @@ sp<const Element> Element::createVector(sp<RS> rs, RsDataType dt, uint32_t size)
return new Element(id, rs, dt, RS_KIND_USER, false, size);
}
-sp<const Element> Element::createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk) {
+android::RSC::sp<const Element> Element::createPixel(android::RSC::sp<RS> rs, RsDataType dt, RsDataKind dk) {
if (!(dk == RS_KIND_PIXEL_L ||
dk == RS_KIND_PIXEL_A ||
dk == RS_KIND_PIXEL_LA ||
@@ -317,7 +316,7 @@ sp<const Element> Element::createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk)
return new Element(id, rs, dt, dk, true, size);
}
-bool Element::isCompatible(sp<const Element>e) {
+bool Element::isCompatible(android::RSC::sp<const Element>e) {
// Try strict BaseObj equality to start with.
if (this == e.get()) {
return true;
@@ -333,12 +332,12 @@ bool Element::isCompatible(sp<const Element>e) {
(mVectorSize == e->mVectorSize));
}
-Element::Builder::Builder(sp<RS> rs) {
+Element::Builder::Builder(android::RSC::sp<RS> rs) {
mRS = rs;
mSkipPadding = false;
}
-void Element::Builder::add(sp</*const*/ Element>e, android::String8 &name, uint32_t arraySize) {
+void Element::Builder::add(android::RSC::sp</*const*/ Element>e, android::String8 &name, uint32_t arraySize) {
// Skip padding fields after a vector 3 type.
if (mSkipPadding) {
const char *s1 = "#padding_";
@@ -358,12 +357,12 @@ void Element::Builder::add(sp</*const*/ Element>e, android::String8 &name, uint3
mSkipPadding = false;
}
- mElements.add(e);
- mElementNames.add(name);
- mArraySizes.add(arraySize);
+ mElements.push_back(e);
+ mElementNames.push_back(name);
+ mArraySizes.push_back(arraySize);
}
-sp<const Element> Element::Builder::create() {
+android::RSC::sp<const Element> Element::Builder::create() {
size_t fieldCount = mElements.size();
const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
const Element ** elementArray = (const Element **)calloc(fieldCount, sizeof(Element *));
@@ -378,7 +377,7 @@ sp<const Element> Element::Builder::create() {
void *id = RS::dispatch->ElementCreate2(mRS->getContext(),
(RsElement *)elementArray, fieldCount,
nameArray, fieldCount * sizeof(size_t), sizeArray,
- (const uint32_t *)mArraySizes.array(), fieldCount);
+ (const uint32_t *)&mArraySizes[0], fieldCount);
free(nameArray);
diff --git a/cpp/RenderScript.cpp b/cpp/RenderScript.cpp
index c7204e30..18e71178 100644
--- a/cpp/RenderScript.cpp
+++ b/cpp/RenderScript.cpp
@@ -19,7 +19,7 @@
#include <pthread.h>
#include "RenderScript.h"
-#include "rs.h"
+#include "rsCppStructs.h"
#include <dlfcn.h>
diff --git a/cpp/RenderScript.h b/cpp/RenderScript.h
index 9a7a5658..8ed8d0eb 100644
--- a/cpp/RenderScript.h
+++ b/cpp/RenderScript.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_RENDERSCRIPT_H
#define ANDROID_RENDERSCRIPT_H
-#include "rsDefines.h"
#include "rsCppStructs.h"
#ifdef RS_SERVER
diff --git a/cpp/Sampler.cpp b/cpp/Sampler.cpp
index fa6b2fda..a1f46691 100644
--- a/cpp/Sampler.cpp
+++ b/cpp/Sampler.cpp
@@ -15,7 +15,6 @@
*/
#include "RenderScript.h"
-#include <rs.h>
using namespace android;
using namespace RSC;
@@ -58,7 +57,7 @@ sp<Sampler> Sampler::create(sp<RS> rs, RsSamplerValue min, RsSamplerValue mag, R
#define CREATE_SAMPLER(N, MIN, MAG, WRAPS, WRAPT) sp<const Sampler> Sampler::N(sp<RS> rs) { \
if (rs->mSamplers.N == NULL) { \
- rs->mSamplers.N = (create(rs, MIN, MAG, WRAPS, WRAPT, 0.f)).get(); \
+ rs->mSamplers.N = (create(rs, MIN, MAG, WRAPS, WRAPT, 0.f)); \
} \
return rs->mSamplers.N; \
}
diff --git a/cpp/Script.cpp b/cpp/Script.cpp
index 70754d00..9bc55ff3 100644
--- a/cpp/Script.cpp
+++ b/cpp/Script.cpp
@@ -17,7 +17,6 @@
#include <malloc.h>
#include "RenderScript.h"
-#include <rs.h>
using namespace android;
using namespace RSC;
diff --git a/cpp/ScriptC.cpp b/cpp/ScriptC.cpp
index 70d7ba5c..0d653bd6 100644
--- a/cpp/ScriptC.cpp
+++ b/cpp/ScriptC.cpp
@@ -15,7 +15,6 @@
*/
#include "RenderScript.h"
-#include <rs.h>
using namespace android;
using namespace RSC;
diff --git a/cpp/ScriptIntrinsics.cpp b/cpp/ScriptIntrinsics.cpp
index 44c5bb63..76328c43 100644
--- a/cpp/ScriptIntrinsics.cpp
+++ b/cpp/ScriptIntrinsics.cpp
@@ -17,8 +17,6 @@
#include <malloc.h>
#include "RenderScript.h"
-#include <rs.h>
-#include "rsDefines.h"
using namespace android;
using namespace RSC;
@@ -28,9 +26,19 @@ ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e)
mID = RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID());
}
+ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
+ : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
+
+}
+void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
+ Script::forEach(0, ain, aout, NULL, 0);
+}
+void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) {
+ Script::setVar(0, lut);
+}
+
ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
: ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
-
}
void ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) {
@@ -95,6 +103,9 @@ void ScriptIntrinsicBlend::blendSubtract(sp<Allocation> in, sp<Allocation> out)
Script::forEach(35, in, out, NULL, 0);
}
+
+
+
ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
: ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
@@ -108,3 +119,90 @@ void ScriptIntrinsicBlur::blur(sp<Allocation> in, sp<Allocation> out) {
void ScriptIntrinsicBlur::setRadius(float radius) {
Script::setVar(0, &radius, sizeof(float));
}
+
+
+
+ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
+ : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
+
+}
+
+void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
+ Script::forEach(0, in, out, NULL, 0);
+}
+
+
+void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
+ Script::setVar(0, (void*)m, sizeof(float) * 9);
+}
+
+
+void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
+ Script::setVar(0, (void*)m, sizeof(float) * 16);
+}
+
+
+void ScriptIntrinsicColorMatrix::setGreyscale() {
+ float matrix[] = {0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f};
+ setColorMatrix3(matrix);
+}
+
+
+void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
+ float matrix[] = {0.299f,0.587f,0.114f,-0.14713f,-0.28886f,0.436f,0.615f,-0.51499f,-0.10001f};
+ setColorMatrix3(matrix);
+}
+
+
+void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
+ float matrix[] = {1.f,0.f,1.13983f,1.f,-0.39465f,-0.5806f,1.f,2.03211f,0.f};
+ setColorMatrix3(matrix);
+}
+
+ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
+ : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
+
+}
+
+void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
+ Script::setVar(1, in);
+}
+
+void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
+ Script::forEach(0, NULL, out, NULL, 0);
+}
+
+void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
+ Script::setVar(0, (void*)v, sizeof(float) * 9);
+}
+
+ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
+ : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
+
+}
+
+void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
+ Script::setVar(1, in);
+}
+
+void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
+ Script::forEach(0, NULL, out, NULL, 0);
+}
+
+void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
+ Script::setVar(0, (void*)v, sizeof(float) * 25);
+}
+
+/*ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
+ : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e) {
+
+}
+
+void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
+
+}
+
+void ScriptIntrinsicLUT::setLUT(sp<Allocation> lut) {
+
+}*/
+
diff --git a/cpp/Type.cpp b/cpp/Type.cpp
index a8acde49..192dc686 100644
--- a/cpp/Type.cpp
+++ b/cpp/Type.cpp
@@ -17,7 +17,6 @@
#include <malloc.h>
#include <string.h>
-#include <rs.h>
#include "RenderScript.h"
using namespace android;
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index b948c913..b85499c7 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 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.
@@ -17,15 +17,13 @@
#ifndef ANDROID_RSCPPSTRUCTS_H
#define ANDROID_RSCPPSTRUCTS_H
+#include "rsDefines.h"
#include "rsCppUtils.h"
-#ifndef RS_SERVER
-#include "utils/RefBase.h"
-#else
-#include "RefBase.h"
-#endif
-
+#include "util/RefBase.h"
#include "rsDispatch.h"
+#include <vector>
+
// 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
#define RS_CPU_ALLOCATION_ALIGNMENT 16
@@ -45,7 +43,7 @@ class Script;
class ScriptC;
class Sampler;
-class RS : public android::LightRefBase<RS> {
+ class RS : public android::RSC::LightRefBase<RS> {
public:
RS();
@@ -89,97 +87,103 @@ class RS : public android::LightRefBase<RS> {
bool mInit;
struct {
- const Element *U8;
- const Element *I8;
- const Element *U16;
- const Element *I16;
- const Element *U32;
- const Element *I32;
- const Element *U64;
- const Element *I64;
- const Element *F32;
- const Element *F64;
- const Element *BOOLEAN;
-
- const Element *ELEMENT;
- const Element *TYPE;
- const Element *ALLOCATION;
- const Element *SAMPLER;
- const Element *SCRIPT;
- const Element *MESH;
- const Element *PROGRAM_FRAGMENT;
- const Element *PROGRAM_VERTEX;
- const Element *PROGRAM_RASTER;
- const Element *PROGRAM_STORE;
-
- const Element *A_8;
- const Element *RGB_565;
- const Element *RGB_888;
- const Element *RGBA_5551;
- const Element *RGBA_4444;
- const Element *RGBA_8888;
-
- const Element *FLOAT_2;
- const Element *FLOAT_3;
- const Element *FLOAT_4;
-
- const Element *DOUBLE_2;
- const Element *DOUBLE_3;
- const Element *DOUBLE_4;
-
- const Element *UCHAR_2;
- const Element *UCHAR_3;
- const Element *UCHAR_4;
-
- const Element *CHAR_2;
- const Element *CHAR_3;
- const Element *CHAR_4;
-
- const Element *USHORT_2;
- const Element *USHORT_3;
- const Element *USHORT_4;
-
- const Element *SHORT_2;
- const Element *SHORT_3;
- const Element *SHORT_4;
-
- const Element *UINT_2;
- const Element *UINT_3;
- const Element *UINT_4;
-
- const Element *INT_2;
- const Element *INT_3;
- const Element *INT_4;
-
- const Element *ULONG_2;
- const Element *ULONG_3;
- const Element *ULONG_4;
-
- const Element *LONG_2;
- const Element *LONG_3;
- const Element *LONG_4;
-
- const Element *MATRIX_4X4;
- const Element *MATRIX_3X3;
- const Element *MATRIX_2X2;
+ sp<const Element> U8;
+ sp<const Element> I8;
+ sp<const Element> U16;
+ sp<const Element> I16;
+ sp<const Element> U32;
+ sp<const Element> I32;
+ sp<const Element> U64;
+ sp<const Element> I64;
+ sp<const Element> F32;
+ sp<const Element> F64;
+ sp<const Element> BOOLEAN;
+
+ sp<const Element> ELEMENT;
+ sp<const Element> TYPE;
+ sp<const Element> ALLOCATION;
+ sp<const Element> SAMPLER;
+ sp<const Element> SCRIPT;
+ sp<const Element> MESH;
+ sp<const Element> PROGRAM_FRAGMENT;
+ sp<const Element> PROGRAM_VERTEX;
+ sp<const Element> PROGRAM_RASTER;
+ sp<const Element> PROGRAM_STORE;
+
+ sp<const Element> A_8;
+ sp<const Element> RGB_565;
+ sp<const Element> RGB_888;
+ sp<const Element> RGBA_5551;
+ sp<const Element> RGBA_4444;
+ sp<const Element> RGBA_8888;
+
+ sp<const Element> FLOAT_2;
+ sp<const Element> FLOAT_3;
+ sp<const Element> FLOAT_4;
+
+ sp<const Element> DOUBLE_2;
+ sp<const Element> DOUBLE_3;
+ sp<const Element> DOUBLE_4;
+
+ sp<const Element> UCHAR_2;
+ sp<const Element> UCHAR_3;
+ sp<const Element> UCHAR_4;
+
+ sp<const Element> CHAR_2;
+ sp<const Element> CHAR_3;
+ sp<const Element> CHAR_4;
+
+ sp<const Element> USHORT_2;
+ sp<const Element> USHORT_3;
+ sp<const Element> USHORT_4;
+
+ sp<const Element> SHORT_2;
+ sp<const Element> SHORT_3;
+ sp<const Element> SHORT_4;
+
+ sp<const Element> UINT_2;
+ sp<const Element> UINT_3;
+ sp<const Element> UINT_4;
+
+ sp<const Element> INT_2;
+ sp<const Element> INT_3;
+ sp<const Element> INT_4;
+
+ sp<const Element> ULONG_2;
+ sp<const Element> ULONG_3;
+ sp<const Element> ULONG_4;
+
+ sp<const Element> LONG_2;
+ sp<const Element> LONG_3;
+ sp<const Element> LONG_4;
+
+ sp<const Element> MATRIX_4X4;
+ sp<const Element> MATRIX_3X3;
+ sp<const Element> MATRIX_2X2;
} mElements;
struct {
- const Sampler* CLAMP_NEAREST;
- const Sampler* CLAMP_LINEAR;
- const Sampler* CLAMP_LINEAR_MIP_LINEAR;
- const Sampler* WRAP_NEAREST;
- const Sampler* WRAP_LINEAR;
- const Sampler* WRAP_LINEAR_MIP_LINEAR;
- const Sampler* MIRRORED_REPEAT_NEAREST;
- const Sampler* MIRRORED_REPEAT_LINEAR;
- const Sampler* MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
+ sp<const Sampler> CLAMP_NEAREST;
+ sp<const Sampler> CLAMP_LINEAR;
+ sp<const Sampler> CLAMP_LINEAR_MIP_LINEAR;
+ sp<const Sampler> WRAP_NEAREST;
+ sp<const Sampler> WRAP_LINEAR;
+ sp<const Sampler> WRAP_LINEAR_MIP_LINEAR;
+ sp<const Sampler> MIRRORED_REPEAT_NEAREST;
+ sp<const Sampler> MIRRORED_REPEAT_LINEAR;
+ sp<const Sampler> MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
} mSamplers;
friend class Sampler;
friend class Element;
};
-class BaseObj : public android::LightRefBase<BaseObj> {
+class BaseObj : public android::RSC::LightRefBase<BaseObj> {
+public:
+ void * getID() const;
+ virtual ~BaseObj();
+ virtual void updateFromNative();
+ virtual bool equals(sp<const BaseObj> obj);
+
protected:
void *mID;
sp<RS> mRS;
@@ -190,20 +194,14 @@ protected:
static void * getObjID(sp<const BaseObj> o);
-public:
-
- void * getID() const;
- virtual ~BaseObj();
- virtual void updateFromNative();
- virtual bool equals(const BaseObj *obj);
};
class Allocation : public BaseObj {
protected:
- android::sp<const Type> mType;
+ sp<const Type> mType;
uint32_t mUsage;
- android::sp<Allocation> mAdaptedAllocation;
+ sp<Allocation> mAdaptedAllocation;
bool mConstrainedLOD;
bool mConstrainedFace;
@@ -237,7 +235,7 @@ protected:
void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h);
public:
- android::sp<const Type> getType() {
+ sp<const Type> getType() {
return mType;
}
@@ -377,43 +375,44 @@ public:
static sp<const Element> MATRIX_3X3(sp<RS> rs);
static sp<const Element> MATRIX_2X2(sp<RS> rs);
- Element(void *id, sp<RS> rs,
- android::Vector<sp<Element> > &elements,
- android::Vector<android::String8> &elementNames,
- android::Vector<uint32_t> &arraySizes);
- Element(void *id, sp<RS> rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
- Element(sp<RS> rs);
- virtual ~Element();
-
void updateFromNative();
static sp<const Element> createUser(sp<RS> rs, RsDataType dt);
static sp<const Element> createVector(sp<RS> rs, RsDataType dt, uint32_t size);
static sp<const Element> createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk);
bool isCompatible(sp<const Element>e);
+ Element(void *id, sp<RS> rs,
+ std::vector<sp<Element> > &elements,
+ std::vector<android::String8> &elementNames,
+ std::vector<uint32_t> &arraySizes);
+ Element(void *id, sp<RS> rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
+ Element(sp<RS> rs);
+ virtual ~Element();
+
+ protected:
class Builder {
private:
sp<RS> mRS;
- android::Vector<sp<Element> > mElements;
- android::Vector<android::String8> mElementNames;
- android::Vector<uint32_t> mArraySizes;
+ std::vector<sp<Element> > mElements;
+ std::vector<android::String8> mElementNames;
+ std::vector<uint32_t> mArraySizes;
bool mSkipPadding;
public:
Builder(sp<RS> rs);
~Builder();
- void add(sp<Element>, android::String8 &name, uint32_t arraySize = 1);
+ void add(sp<Element> e, android::String8 &name, uint32_t arraySize = 1);
sp<const Element> create();
};
private:
void updateVisibleSubElements();
- android::Vector<sp</*const*/ Element> > mElements;
- android::Vector<android::String8> mElementNames;
- android::Vector<uint32_t> mArraySizes;
- android::Vector<uint32_t> mVisibleElementMap;
- android::Vector<uint32_t> mOffsetInBytes;
+ std::vector<sp<Element> > mElements;
+ std::vector<android::String8> mElementNames;
+ std::vector<uint32_t> mArraySizes;
+ std::vector<uint32_t> mVisibleElementMap;
+ std::vector<uint32_t> mOffsetInBytes;
RsDataType mType;
RsDataKind mKind;
@@ -430,10 +429,9 @@ protected:
public:
FieldPacker(size_t len)
- : mPos(0),
- mLen(len) {
- mData = new unsigned char[len];
- }
+ : mPos(0), mLen(len) {
+ mData = new unsigned char[len];
+ }
virtual ~FieldPacker() {
delete [] mData;
@@ -480,7 +478,7 @@ public:
}
template <typename T>
- void add(T t) {
+ void add(T t) {
align(sizeof(t));
if (mPos + sizeof(t) <= mLen) {
memcpy(&mData[mPos], &t, sizeof(t));
@@ -489,26 +487,26 @@ public:
}
/*
- void add(rs_matrix4x4 m) {
- for (size_t i = 0; i < 16; i++) {
- add(m.m[i]);
- }
- }
-
- void add(rs_matrix3x3 m) {
- for (size_t i = 0; i < 9; i++) {
- add(m.m[i]);
- }
- }
-
- void add(rs_matrix2x2 m) {
- for (size_t i = 0; i < 4; i++) {
- add(m.m[i]);
- }
- }
+ void add(rs_matrix4x4 m) {
+ for (size_t i = 0; i < 16; i++) {
+ add(m.m[i]);
+ }
+ }
+
+ void add(rs_matrix3x3 m) {
+ for (size_t i = 0; i < 9; i++) {
+ add(m.m[i]);
+ }
+ }
+
+ void add(rs_matrix2x2 m) {
+ for (size_t i = 0; i < 4; i++) {
+ add(m.m[i]);
+ }
+ }
*/
- void add(BaseObj* obj) {
+ void add(sp<BaseObj> obj) {
if (obj != NULL) {
add((uint32_t) (uintptr_t) obj->getID());
} else {
@@ -517,6 +515,7 @@ public:
}
};
+
class Type : public BaseObj {
protected:
friend class Allocation;
@@ -663,9 +662,16 @@ class ScriptIntrinsic : public Script {
ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e);
};
+class ScriptIntrinsic3DLUT : public ScriptIntrinsic {
+ public:
+ ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e);
+ void forEach(sp<Allocation> ain, sp<Allocation> aout);
+ void setLUT(sp<Allocation> lut);
+};
+
class ScriptIntrinsicBlend : public ScriptIntrinsic {
public:
- ScriptIntrinsicBlend(sp<RS> rs, sp <const Element> e);
+ ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e);
void blendClear(sp<Allocation> in, sp<Allocation> out);
void blendSrc(sp<Allocation> in, sp<Allocation> out);
void blendDst(sp<Allocation> in, sp<Allocation> out);
@@ -685,11 +691,50 @@ class ScriptIntrinsicBlend : public ScriptIntrinsic {
class ScriptIntrinsicBlur : public ScriptIntrinsic {
public:
- ScriptIntrinsicBlur(sp<RS> rs, sp <const Element> e);
+ ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e);
void blur(sp<Allocation> in, sp<Allocation> out);
void setRadius(float radius);
};
+class ScriptIntrinsicColorMatrix : public ScriptIntrinsic {
+ public:
+ ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e);
+ void forEach(sp<Allocation> in, sp<Allocation> out);
+ void setColorMatrix3(float* m);
+ void setColorMatrix4(float* m);
+ void setGreyscale();
+ void setRGBtoYUV();
+ void setYUVtoRGB();
+};
+
+class ScriptIntrinsicConvolve3x3 : public ScriptIntrinsic {
+ public:
+ ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e);
+ void setInput(sp<Allocation> in);
+ void forEach(sp<Allocation> out);
+ void setCoefficients(float* v);
+};
+
+class ScriptIntrinsicConvolve5x5 : public ScriptIntrinsic {
+ public:
+ ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e);
+ void setInput(sp<Allocation> in);
+ void forEach(sp<Allocation> out);
+ void setCoefficients(float* v);
+};
+
+/*class ScriptIntrinsicLUT : public ScriptIntrinsic {
+ public:
+ ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e);
+ void forEach(sp<Allocation> ain, sp<Allocation> aout);
+ void setLUT(sp<Allocation> lut);
+ };*/
+/*
+class ScriptIntrinsicYuvToRGB : public ScriptIntrinsic {
+
+};
+*/
+
class Sampler : public BaseObj {
private:
Sampler(sp<RS> rs, void* id);
diff --git a/cpp/util/RefBase.h b/cpp/util/RefBase.h
new file mode 100644
index 00000000..eab26ab5
--- /dev/null
+++ b/cpp/util/RefBase.h
@@ -0,0 +1,529 @@
+/*
+ * 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 RS_REF_BASE_H
+#define RS_REF_BASE_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "StrongPointer.h"
+#include "TypeHelpers.h"
+
+// ---------------------------------------------------------------------------
+namespace android{
+namespace RSC {
+
+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 RSC
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // RS_REF_BASE_H
diff --git a/cpp/util/StrongPointer.h b/cpp/util/StrongPointer.h
new file mode 100644
index 00000000..0f68615c
--- /dev/null
+++ b/cpp/util/StrongPointer.h
@@ -0,0 +1,222 @@
+/*
+ * 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 RS_STRONG_POINTER_H
+#define RS_STRONG_POINTER_H
+
+//#include <cutils/atomic.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace RSC {
+
+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 RSC
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // RS_STRONG_POINTER_H
diff --git a/cpp/util/TypeHelpers.h b/cpp/util/TypeHelpers.h
new file mode 100644
index 00000000..33a5201f
--- /dev/null
+++ b/cpp/util/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 RS_TYPE_HELPERS_H
+#define RS_TYPE_HELPERS_H
+
+#include <new>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace RSC {
+
+/*
+ * 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 RS_TRIVIAL_CTOR_TRAIT( T ) \
+ template<> struct trait_trivial_ctor< T > { enum { value = true }; };
+
+#define RS_TRIVIAL_DTOR_TRAIT( T ) \
+ template<> struct trait_trivial_dtor< T > { enum { value = true }; };
+
+#define RS_TRIVIAL_COPY_TRAIT( T ) \
+ template<> struct trait_trivial_copy< T > { enum { value = true }; };
+
+#define RS_TRIVIAL_MOVE_TRAIT( T ) \
+ template<> struct trait_trivial_move< T > { enum { value = true }; };
+
+#define RS_BASIC_TYPES_TRAITS( T ) \
+ RS_TRIVIAL_CTOR_TRAIT( T ) \
+ RS_TRIVIAL_DTOR_TRAIT( T ) \
+ RS_TRIVIAL_COPY_TRAIT( T ) \
+ RS_TRIVIAL_MOVE_TRAIT( T )
+
+// ---------------------------------------------------------------------------
+
+/*
+ * basic types traits
+ */
+
+RS_BASIC_TYPES_TRAITS( void )
+RS_BASIC_TYPES_TRAITS( bool )
+RS_BASIC_TYPES_TRAITS( char )
+RS_BASIC_TYPES_TRAITS( unsigned char )
+RS_BASIC_TYPES_TRAITS( short )
+RS_BASIC_TYPES_TRAITS( unsigned short )
+RS_BASIC_TYPES_TRAITS( int )
+RS_BASIC_TYPES_TRAITS( unsigned int )
+RS_BASIC_TYPES_TRAITS( long )
+RS_BASIC_TYPES_TRAITS( unsigned long )
+RS_BASIC_TYPES_TRAITS( long long )
+RS_BASIC_TYPES_TRAITS( unsigned long long )
+RS_BASIC_TYPES_TRAITS( float )
+RS_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 RS_INT32_HASH(T) \
+ template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
+#define RS_INT64_HASH(T) \
+ template <> inline hash_t hash_type(const T& value) { \
+ return hash_t((value >> 32) ^ value); }
+#define RS_REINTERPRET_HASH(T, R) \
+ template <> inline hash_t hash_type(const T& value) { \
+ return hash_type(*reinterpret_cast<const R*>(&value)); }
+
+RS_INT32_HASH(bool)
+RS_INT32_HASH(int8_t)
+RS_INT32_HASH(uint8_t)
+RS_INT32_HASH(int16_t)
+RS_INT32_HASH(uint16_t)
+RS_INT32_HASH(int32_t)
+RS_INT32_HASH(uint32_t)
+RS_INT64_HASH(int64_t)
+RS_INT64_HASH(uint64_t)
+RS_REINTERPRET_HASH(float, uint32_t)
+RS_REINTERPRET_HASH(double, uint64_t)
+
+template <typename T> inline hash_t hash_type(T* const & value) {
+ return hash_type(uintptr_t(value));
+}
+
+}; // namespace RSC
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // RS_TYPE_HELPERS_H