Home | History | Annotate | Download | only in rs
      1 #include "rsClosure.h"
      2 
      3 #include "cpu_ref/rsCpuCore.h"
      4 #include "rsContext.h" // XXX: necessary to avoid compiler error on rsScript.h below
      5 #include "rsScript.h"
      6 #include "rsType.h"
      7 
      8 namespace android {
      9 namespace renderscript {
     10 
     11 RsClosure rsi_ClosureCreate(Context* context, RsScriptKernelID kernelID,
     12                             RsAllocation returnValue,
     13                             RsScriptFieldID* fieldIDs, size_t fieldIDs_length,
     14                             const int64_t* values, size_t values_length,
     15                             const int* sizes, size_t sizes_length,
     16                             RsClosure* depClosures, size_t depClosures_length,
     17                             RsScriptFieldID* depFieldIDs,
     18                             size_t depFieldIDs_length) {
     19     rsAssert(fieldIDs_length == values_length && values_length == sizes_length &&
     20              sizes_length == depClosures_length &&
     21              depClosures_length == depFieldIDs_length);
     22 
     23     Closure* c = new Closure(
     24         context, (const ScriptKernelID*)kernelID, (Allocation*)returnValue,
     25         fieldIDs_length, (const ScriptFieldID**)fieldIDs, values,
     26         sizes, (const Closure**)depClosures,
     27         (const ScriptFieldID**)depFieldIDs);
     28     c->incUserRef();
     29     return static_cast<RsClosure>(c);
     30 }
     31 
     32 RsClosure rsi_InvokeClosureCreate(Context* context, RsScriptInvokeID invokeID,
     33                                   const void* params, const size_t paramLength,
     34                                   const RsScriptFieldID* fieldIDs, const size_t fieldIDs_length,
     35                                   const int64_t* values, const size_t values_length,
     36                                   const int* sizes, const size_t sizes_length) {
     37     rsAssert(fieldIDs_length == values_length && values_length == sizes_length);
     38     Closure* c = new Closure(
     39         context, (const ScriptInvokeID*)invokeID, params, paramLength,
     40         fieldIDs_length, (const ScriptFieldID**)fieldIDs, values,
     41         sizes);
     42     c->incUserRef();
     43     return static_cast<RsClosure>(c);
     44 }
     45 
     46 void rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index,
     47                        uintptr_t value, int size) {
     48     ((Closure*)closure)->setArg(index, (const void*)value, size);
     49 }
     50 
     51 void rsi_ClosureSetGlobal(Context* rsc, RsClosure closure,
     52                           RsScriptFieldID fieldID, int64_t value,
     53                           int size) {
     54     ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID,
     55                                    value, size);
     56 }
     57 
     58 Closure::Closure(Context* context,
     59                  const ScriptKernelID* kernelID,
     60                  Allocation* returnValue,
     61                  const int numValues,
     62                  const ScriptFieldID** fieldIDs,
     63                  const int64_t* values,
     64                  const int* sizes,
     65                  const Closure** depClosures,
     66                  const ScriptFieldID** depFieldIDs) :
     67     ObjectBase(context), mContext(context), mFunctionID((IDBase*)kernelID),
     68     mIsKernel(true), mReturnValue(returnValue), mParams(nullptr),
     69     mParamLength(0) {
     70     size_t i;
     71 
     72     for (i = 0; i < (size_t)numValues && fieldIDs[i] == nullptr; i++);
     73 
     74     mNumArg = i;
     75     mArgs = new const void*[mNumArg];
     76     for (size_t j = 0; j < mNumArg; j++) {
     77         mArgs[j] = (const void*)values[j];
     78     }
     79 
     80     for (; i < (size_t)numValues; i++) {
     81         rsAssert(fieldIDs[i] != nullptr);
     82         mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
     83     }
     84 
     85     for (i = 0; i < mNumArg; i++) {
     86         const Closure* dep = depClosures[i];
     87         if (dep != nullptr) {
     88             auto mapping = mArgDeps[dep];
     89             if (mapping == nullptr) {
     90                 mapping = new Map<int, ObjectBaseRef<ScriptFieldID>>();
     91                 mArgDeps[dep] = mapping;
     92             }
     93             (*mapping)[i].set(const_cast<ScriptFieldID*>(depFieldIDs[i]));
     94         }
     95     }
     96 
     97     for (; i < (size_t)numValues; i++) {
     98         const Closure* dep = depClosures[i];
     99         if (dep != nullptr) {
    100             auto mapping = mGlobalDeps[dep];
    101             if (mapping == nullptr) {
    102                 mapping = new Map<const ScriptFieldID*,
    103                                   ObjectBaseRef<ScriptFieldID>>();
    104                 mGlobalDeps[dep] = mapping;
    105             }
    106             fieldIDs[i]->incSysRef();
    107             (*mapping)[fieldIDs[i]].set(const_cast<ScriptFieldID*>(depFieldIDs[i]));
    108         }
    109     }
    110 }
    111 
    112 Closure::Closure(Context* context, const ScriptInvokeID* invokeID,
    113                  const void* params, const size_t paramLength,
    114                  const size_t numValues, const ScriptFieldID** fieldIDs,
    115                  const int64_t* values, const int* sizes) :
    116     ObjectBase(context), mContext(context), mFunctionID((IDBase*)invokeID), mIsKernel(false),
    117     mArgs(nullptr), mNumArg(0),
    118     mReturnValue(nullptr), mParamLength(paramLength) {
    119     mParams = new uint8_t[mParamLength];
    120     memcpy(mParams, params, mParamLength);
    121     for (size_t i = 0; i < numValues; i++) {
    122         mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
    123     }
    124 }
    125 
    126 Closure::~Closure() {
    127     for (const auto& p : mArgDeps) {
    128         auto map = p.second;
    129         delete p.second;
    130     }
    131 
    132     for (const auto& p : mGlobalDeps) {
    133         auto map = p.second;
    134         for (const auto& p1 : *map) {
    135             p1.first->decSysRef();
    136         }
    137         delete p.second;
    138     }
    139 
    140     delete[] mArgs;
    141     delete[] mParams;
    142 }
    143 
    144 void Closure::setArg(const uint32_t index, const void* value, const int size) {
    145     mArgs[index] = value;
    146 }
    147 
    148 void Closure::setGlobal(const ScriptFieldID* fieldID, const int64_t value,
    149                         const int size) {
    150     mGlobals[fieldID] = make_pair(value, size);
    151 }
    152 
    153 }  // namespace renderscript
    154 }  // namespace android
    155