diff options
author | Tim Murray <timmurray@google.com> | 2013-07-29 14:30:02 -0700 |
---|---|---|
committer | Tim Murray <timmurray@google.com> | 2013-08-01 14:14:07 -0700 |
commit | 89daad6bae798779e57f252e9da4fe4e62337124 (patch) | |
tree | c55735f278a67b2fe5b74b42581cbfae9c99846c /cpp | |
parent | dcfaa3c0bf151da7be31463bb3fa4e2b4aea6b8c (diff) | |
download | rs-89daad6bae798779e57f252e9da4fe4e62337124.tar.gz |
Add basic support for intrinsics. Move sp<> into RScpp.
Change-Id: I74cdee7069a624ded5091d53db3a4b8ce9894033
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/Allocation.cpp | 54 | ||||
-rw-r--r-- | cpp/Android.mk | 61 | ||||
-rw-r--r-- | cpp/BaseObj.cpp | 7 | ||||
-rw-r--r-- | cpp/Element.cpp | 49 | ||||
-rw-r--r-- | cpp/RenderScript.cpp | 2 | ||||
-rw-r--r-- | cpp/RenderScript.h | 1 | ||||
-rw-r--r-- | cpp/Sampler.cpp | 3 | ||||
-rw-r--r-- | cpp/Script.cpp | 1 | ||||
-rw-r--r-- | cpp/ScriptC.cpp | 1 | ||||
-rw-r--r-- | cpp/ScriptIntrinsics.cpp | 104 | ||||
-rw-r--r-- | cpp/Type.cpp | 1 | ||||
-rw-r--r-- | cpp/rsCppStructs.h | 329 | ||||
-rw-r--r-- | cpp/util/RefBase.h | 529 | ||||
-rw-r--r-- | cpp/util/StrongPointer.h | 222 | ||||
-rw-r--r-- | cpp/util/TypeHelpers.h | 302 |
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 |