Home | History | Annotate | Download | only in rs
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "rsApiStubs.h"
     18 #include "rsHidlAdaptation.h"
     19 #include "rsFallbackAdaptation.h"
     20 #include "cpp/rsDispatch.h"
     21 
     22 #include <log/log.h>
     23 #include <dlfcn.h>
     24 
     25 #include <mutex>
     26 #include <map>
     27 
     28 #undef LOG_TAG
     29 #define LOG_TAG "RenderScript"
     30 
     31 // TODO: Figure out how to use different declared types for the two interfaces
     32 //       to avoid the confusion. Currently, RsContext is used as the API type for
     33 //       both the client interface and the dispatch table interface, but at the
     34 //       client interface it's really RsContextWrapper* instead.
     35 // TODO: Figure out how to better design class hierarchy for all these Contexts.
     36 // RsContextWrapper wraps the RsContext and corresponding dispatchTable pointer.
     37 // The wrapper object is created during ContextCreate, and the address of the
     38 // object is returned to Java / C++, instead of the RsContext handle.
     39 // The wrapper object is destroyed during ContextDestroy to release the memory.
     40 struct RsContextWrapper {
     41     RsContext context;
     42     const dispatchTable* dispatch;
     43 };
     44 
     45 #define RS_DISPATCH(opaqueWrapper, func, ...) \
     46     [&]() { \
     47       const RsContextWrapper *wrapper = reinterpret_cast<RsContextWrapper *>(opaqueWrapper); \
     48       RsContext context = wrapper->context; \
     49       return wrapper->dispatch->func(context, ##__VA_ARGS__); \
     50     }()
     51 
     52 
     53 // contextMap maps RsContext to the corresponding RsContextWrapper pointer.
     54 static std::map<RsContext, RsContextWrapper* > contextMap;
     55 
     56 // contextMapMutex is used to protect concurrent access of the contextMap.
     57 // std::mutex is safe for pthreads on Android. Since other threading model
     58 // supported on Android are built on top of pthread, std::mutex is safe for them.
     59 static std::mutex contextMapMutex;
     60 
     61 // globalObjAlive is a global flag indicating whether the global objects,
     62 // contextMap & contextMapMutex, are still alive.
     63 // For the protected functions during application teardown, this
     64 // flag will be checked before accessing the global objects.
     65 static bool globalObjAlive;
     66 
     67 // GlobalObjGuard manipulates the globalObjAlive flag during construction and
     68 // destruction. If the guard object is destroyed, globalObjAlive will be set
     69 // to false, which will make the protected functions NO-OP.
     70 // https://goto.google.com/rs-static-destructor
     71 class GlobalObjGuard {
     72   public:
     73     GlobalObjGuard() {
     74         globalObjAlive = true;
     75     }
     76 
     77     ~GlobalObjGuard() {
     78         globalObjAlive = false;
     79     }
     80 };
     81 static GlobalObjGuard guard;
     82 
     83 // API to find high-level context (RsContextWrapper) given a low level context.
     84 // This API is only intended to be used by RenderScript debugger.
     85 extern "C" RsContext rsDebugGetHighLevelContext(RsContext context) {
     86     std::unique_lock<std::mutex> lock(contextMapMutex);
     87     return contextMap.at(context);
     88 }
     89 
     90 // Device
     91 // These API stubs are kept here to maintain backward compatibility,
     92 // but they are not actually doing anything.
     93 
     94 extern "C" RsDevice rsDeviceCreate()
     95 {
     96     return (void *) 1;
     97 }
     98 extern "C" void rsDeviceDestroy(RsDevice dev)
     99 {
    100 }
    101 extern "C" void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value)
    102 {
    103 }
    104 
    105 /*
    106  * This global will be found by the debugger and will have its value flipped.
    107  * It's independent of the Context class to allow the debugger to do the above
    108  * without knowing the type makeup. This allows the debugger to be attached at
    109  * an earlier stage.
    110  */
    111 extern "C" int gDebuggerPresent = 0;
    112 
    113 namespace{
    114 // Check if the calling process is a vendor process or not.
    115 static bool isVendorProcess() {
    116     char path[PATH_MAX];
    117     ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
    118     if (path_len == -1) {
    119         return false;
    120     }
    121     // Vendor process will return "/vendor/*"
    122     static const char vendor_path[] = "/vendor/";
    123     return !strncmp(path, vendor_path, sizeof(vendor_path)-1);
    124 }
    125 
    126 typedef const char* (*QueryCacheDirFnPtr)();
    127 // Dynamically load the queryCacheDir function pointer, so that for vendor
    128 // processes, libandroid_runtime.so will not be loaded.
    129 static QueryCacheDirFnPtr loadQueryCacheFnPtr() {
    130     QueryCacheDirFnPtr queryCacheDir = nullptr;
    131     void* handle = dlopen("libRSCacheDir.so", RTLD_LAZY | RTLD_LOCAL);
    132     if (!handle ||
    133         !(queryCacheDir = (QueryCacheDirFnPtr)dlsym(handle, "rsQueryCacheDir"))) {
    134         ALOGW("Not able to query cache dir: %s", dlerror());
    135     }
    136     return queryCacheDir;
    137 }
    138 } // anonymous namespace
    139 
    140 // Context
    141 extern "C" RsContext rsContextCreate(RsDevice vdev, uint32_t version, uint32_t sdkVersion,
    142                                      RsContextType ct, uint32_t flags)
    143 {
    144     if (!globalObjAlive) {
    145         ALOGE("rsContextCreate is not allowed during process teardown.");
    146         return nullptr;
    147     }
    148 
    149     RsContext context;
    150     RsContextWrapper *ctxWrapper;
    151 
    152     if (flags & RS_CONTEXT_LOW_LATENCY) {
    153         // Use CPU path for LOW_LATENCY context.
    154         RsFallbackAdaptation& instance = RsFallbackAdaptation::GetInstance();
    155         context = instance.GetEntryFuncs()->ContextCreate(vdev, version, sdkVersion, ct, flags);
    156         ctxWrapper = new RsContextWrapper{context, instance.GetEntryFuncs()};
    157     } else {
    158         RsHidlAdaptation& instance = RsHidlAdaptation::GetInstance();
    159         context = instance.GetEntryFuncs()->ContextCreate(vdev, version, sdkVersion, ct, flags);
    160         ctxWrapper = new RsContextWrapper{context, instance.GetEntryFuncs()};
    161 
    162         // Use function local static variables to ensure thread safety.
    163         static QueryCacheDirFnPtr queryCacheDir = isVendorProcess() ? nullptr : loadQueryCacheFnPtr();
    164         if (queryCacheDir) {
    165             static std::string defaultCacheDir = std::string(queryCacheDir());
    166             if (defaultCacheDir.size() > 0) {
    167                 ALOGD("Setting cache dir: %s", defaultCacheDir.c_str());
    168                 rsContextSetCacheDir(ctxWrapper,
    169                                  defaultCacheDir.c_str(),
    170                                  defaultCacheDir.size());
    171             }
    172         }
    173     }
    174 
    175     // Wait for debugger to attach if RS_CONTEXT_WAIT_FOR_ATTACH flag set.
    176     if (flags & RS_CONTEXT_WAIT_FOR_ATTACH) {
    177         while (!gDebuggerPresent) {
    178             sleep(0);
    179         }
    180     }
    181 
    182     // Lock contextMap when adding new entries.
    183     std::unique_lock<std::mutex> lock(contextMapMutex);
    184     contextMap.insert(std::make_pair(context, ctxWrapper));
    185 
    186     return (RsContext) ctxWrapper;
    187 }
    188 
    189 extern "C" void rsContextDestroy (RsContext ctxWrapper)
    190 {
    191     if (!globalObjAlive) {
    192         return;
    193     }
    194 
    195     RS_DISPATCH(ctxWrapper, ContextDestroy);
    196 
    197     // Lock contextMap when deleting an existing entry.
    198     std::unique_lock<std::mutex> lock(contextMapMutex);
    199     contextMap.erase(reinterpret_cast< RsContextWrapper* >(ctxWrapper)->context);
    200 
    201     delete (RsContextWrapper *)ctxWrapper;
    202 }
    203 
    204 extern "C" void rsContextFinish (RsContext ctxWrapper)
    205 {
    206     RS_DISPATCH(ctxWrapper, ContextFinish);
    207 }
    208 
    209 extern "C" void rsContextDump (RsContext ctxWrapper, int32_t bits)
    210 {
    211     RS_DISPATCH(ctxWrapper, ContextDump, bits);
    212 }
    213 
    214 extern "C" void rsContextSetPriority (RsContext ctxWrapper, int32_t priority)
    215 {
    216     RS_DISPATCH(ctxWrapper, ContextSetPriority, priority);
    217 }
    218 
    219 extern "C" void rsContextDestroyWorker (RsContext ctxWrapper)
    220 {
    221 }
    222 
    223 extern "C" RsMessageToClientType rsContextGetMessage (RsContext ctxWrapper, void * data, size_t data_length,
    224                                                       size_t * receiveLen, size_t receiveLen_length,
    225                                                       uint32_t * usrID, size_t usrID_length)
    226 {
    227     return RS_DISPATCH(ctxWrapper, ContextGetMessage, data, data_length,
    228                                        receiveLen, receiveLen_length,
    229                                        usrID, usrID_length);
    230 }
    231 
    232 extern "C" RsMessageToClientType rsContextPeekMessage (RsContext ctxWrapper,
    233                                                        size_t * receiveLen, size_t receiveLen_length,
    234                                                        uint32_t * usrID, size_t usrID_length)
    235 {
    236     return RS_DISPATCH(ctxWrapper, ContextPeekMessage,
    237                        receiveLen, receiveLen_length,
    238                        usrID, usrID_length);
    239 }
    240 
    241 extern "C" void rsContextSendMessage (RsContext ctxWrapper, uint32_t id, const uint8_t * data, size_t data_length)
    242 {
    243     RS_DISPATCH(ctxWrapper, ContextSendMessage, id, data, data_length);
    244 }
    245 
    246 extern "C" void rsContextInitToClient (RsContext ctxWrapper)
    247 {
    248     RS_DISPATCH(ctxWrapper, ContextInitToClient);
    249 }
    250 
    251 extern "C" void rsContextDeinitToClient (RsContext ctxWrapper)
    252 {
    253     RS_DISPATCH(ctxWrapper, ContextDeinitToClient);
    254 }
    255 
    256 extern "C" void rsContextSetCacheDir (RsContext ctxWrapper, const char * cacheDir, size_t cacheDir_length)
    257 {
    258     RS_DISPATCH(ctxWrapper, ContextSetCacheDir, cacheDir, cacheDir_length);
    259 }
    260 
    261 extern "C" void rsaContextSetNativeLibDir(RsContext ctxWrapper, char *libDir, size_t length)
    262 {
    263 }
    264 
    265 // BaseObject
    266 
    267 extern "C" void rsAssignName (RsContext ctxWrapper, RsObjectBase obj, const char * name, size_t name_length)
    268 {
    269     RS_DISPATCH(ctxWrapper, AssignName, obj, name, name_length);
    270 }
    271 
    272 extern "C" void rsaGetName(RsContext ctxWrapper, void * obj, const char **name)
    273 {
    274     RS_DISPATCH(ctxWrapper, GetName, obj, name);
    275 }
    276 
    277 extern "C" void rsObjDestroy (RsContext ctxWrapper, RsAsyncVoidPtr objPtr)
    278 {
    279     RS_DISPATCH(ctxWrapper, ObjDestroy, objPtr);
    280 }
    281 
    282 // Element
    283 
    284 extern "C" RsElement rsElementCreate (RsContext ctxWrapper, RsDataType mType, RsDataKind mKind,
    285                                       bool mNormalized, uint32_t mVectorSize)
    286 {
    287     return RS_DISPATCH(ctxWrapper, ElementCreate, mType, mKind, mNormalized, mVectorSize);
    288 }
    289 
    290 extern "C" RsElement rsElementCreate2 (RsContext ctxWrapper, const RsElement * elements, size_t elements_length,
    291                                        const char ** names, size_t names_length_length, const size_t * names_length,
    292                                        const uint32_t * arraySize, size_t arraySize_length)
    293 {
    294     return RS_DISPATCH(ctxWrapper, ElementCreate2,
    295                        elements, elements_length,
    296                        names, names_length_length, names_length,
    297                        arraySize, arraySize_length);
    298 }
    299 
    300 extern "C" void rsaElementGetNativeData(RsContext ctxWrapper, RsElement elem, uint32_t *elemData, uint32_t elemDataSize)
    301 {
    302     RS_DISPATCH(ctxWrapper, ElementGetNativeData, elem, elemData, elemDataSize);
    303 }
    304 
    305 extern "C" void rsaElementGetSubElements(RsContext ctxWrapper, RsElement elem, uintptr_t *ids, const char **names,
    306                                          size_t *arraySizes, uint32_t dataSize)
    307 {
    308     RS_DISPATCH(ctxWrapper, ElementGetSubElements, elem, ids, names, arraySizes, dataSize);
    309 }
    310 
    311 // Type
    312 
    313 extern "C" RsType rsTypeCreate (RsContext ctxWrapper, RsElement e, uint32_t dimX, uint32_t dimY, uint32_t dimZ,
    314                                 bool mipmaps, bool faces, uint32_t yuv)
    315 {
    316     return RS_DISPATCH(ctxWrapper, TypeCreate, e, dimX, dimY, dimZ, mipmaps, faces, yuv);
    317 }
    318 
    319 extern "C" RsType rsTypeCreate2 (RsContext ctxWrapper, const RsTypeCreateParams * dat, size_t dat_length)
    320 {
    321     return nullptr;
    322 }
    323 
    324 extern "C" void rsaTypeGetNativeData(RsContext ctxWrapper, RsType type, uintptr_t *typeData, uint32_t typeDataSize)
    325 {
    326     RS_DISPATCH(ctxWrapper, TypeGetNativeData, type, typeData, typeDataSize);
    327 }
    328 
    329 
    330 // Allocation
    331 
    332 extern "C" RsAllocation rsAllocationCreateTyped (RsContext ctxWrapper, RsType vtype, RsAllocationMipmapControl mipmaps,
    333                                                  uint32_t usages, uintptr_t ptr)
    334 {
    335     return RS_DISPATCH(ctxWrapper, AllocationCreateTyped, vtype, mipmaps, usages, ptr);
    336 }
    337 
    338 extern "C" RsAllocation rsAllocationCreateFromBitmap (RsContext ctxWrapper, RsType vtype, RsAllocationMipmapControl mipmaps,
    339                                                       const void * data, size_t data_length, uint32_t usages)
    340 {
    341     return RS_DISPATCH(ctxWrapper, AllocationCreateFromBitmap, vtype, mipmaps, data, data_length, usages);
    342 }
    343 
    344 extern "C" RsAllocation rsAllocationCubeCreateFromBitmap (RsContext ctxWrapper, RsType vtype, RsAllocationMipmapControl mipmaps,
    345                                                           const void * data, size_t data_length, uint32_t usages)
    346 {
    347     return RS_DISPATCH(ctxWrapper, AllocationCubeCreateFromBitmap, vtype, mipmaps, data, data_length, usages);
    348 }
    349 
    350 extern "C" RsAllocation rsAllocationAdapterCreate (RsContext ctxWrapper, RsType vtype, RsAllocation baseAlloc)
    351 {
    352     return RS_DISPATCH(ctxWrapper, AllocationAdapterCreate, vtype, baseAlloc);
    353 }
    354 
    355 extern "C" const void * rsaAllocationGetType(RsContext ctxWrapper, RsAllocation va)
    356 {
    357     return RS_DISPATCH(ctxWrapper, AllocationGetType, va);
    358 }
    359 
    360 extern "C" RsNativeWindow rsAllocationGetSurface (RsContext ctxWrapper, RsAllocation alloc)
    361 {
    362     return RS_DISPATCH(ctxWrapper, AllocationGetSurface, alloc);
    363 }
    364 
    365 extern "C" void rsAllocationSetupBufferQueue (RsContext ctxWrapper, RsAllocation alloc, uint32_t numAlloc)
    366 {
    367     RS_DISPATCH(ctxWrapper, AllocationSetupBufferQueue, alloc, numAlloc);
    368 }
    369 
    370 extern "C" void rsAllocationShareBufferQueue (RsContext ctxWrapper, RsAllocation alloc1, RsAllocation alloc2)
    371 {
    372     RS_DISPATCH(ctxWrapper, AllocationShareBufferQueue, alloc1, alloc2);
    373 }
    374 
    375 extern "C" void rsAllocationSetSurface (RsContext ctxWrapper, RsAllocation alloc, RsNativeWindow sur)
    376 {
    377     RS_DISPATCH(ctxWrapper, AllocationSetSurface, alloc, sur);
    378 }
    379 
    380 extern "C" void rsAllocationAdapterOffset (RsContext ctxWrapper, RsAllocation alloc,
    381                                            const uint32_t * offsets, size_t offsets_length)
    382 {
    383     RS_DISPATCH(ctxWrapper, AllocationAdapterOffset, alloc, offsets, offsets_length);
    384 }
    385 
    386 extern "C" void rsAllocationCopyToBitmap (RsContext ctxWrapper, RsAllocation alloc, void * data, size_t data_length)
    387 {
    388     RS_DISPATCH(ctxWrapper, AllocationCopyToBitmap, alloc, data, data_length);
    389 }
    390 
    391 extern "C" void * rsAllocationGetPointer (RsContext ctxWrapper, RsAllocation va, uint32_t lod, RsAllocationCubemapFace face,
    392                                           uint32_t z, uint32_t array, size_t * stride, size_t stride_length)
    393 {
    394     return RS_DISPATCH(ctxWrapper, AllocationGetPointer, va, lod, face, z, array, stride, stride_length);
    395 }
    396 
    397 extern "C" void rsAllocation1DData (RsContext ctxWrapper, RsAllocation va, uint32_t xoff, uint32_t lod, uint32_t count,
    398                                     const void * data, size_t data_length)
    399 {
    400     RS_DISPATCH(ctxWrapper, Allocation1DData, va, xoff, lod, count, data, data_length);
    401 }
    402 
    403 extern "C" void rsAllocation1DElementData (RsContext ctxWrapper, RsAllocation va, uint32_t x, uint32_t lod,
    404                                            const void * data, size_t data_length, size_t comp_offset)
    405 {
    406     RS_DISPATCH(ctxWrapper, Allocation1DElementData, va, x, lod, data, data_length, comp_offset);
    407 }
    408 
    409 extern "C" void rsAllocationElementData (RsContext ctxWrapper, RsAllocation va, uint32_t x, uint32_t y, uint32_t z,
    410                                          uint32_t lod, const void * data, size_t data_length, size_t comp_offset)
    411 {
    412     RS_DISPATCH(ctxWrapper, AllocationElementData, va, x, y, z, lod, data, data_length, comp_offset);
    413 }
    414 
    415 extern "C" void rsAllocation2DData (RsContext ctxWrapper, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod,
    416                                     RsAllocationCubemapFace face, uint32_t w, uint32_t h,
    417                                     const void * data, size_t data_length, size_t stride)
    418 {
    419     RS_DISPATCH(ctxWrapper, Allocation2DData, va, xoff, yoff, lod, face, w, h, data, data_length, stride);
    420 }
    421 
    422 extern "C" void rsAllocation3DData (RsContext ctxWrapper, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff,
    423                                     uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
    424                                     const void * data, size_t data_length, size_t stride)
    425 {
    426     RS_DISPATCH(ctxWrapper, Allocation3DData, va, xoff, yoff, zoff, lod, w, h, d, data, data_length, stride);
    427 }
    428 
    429 extern "C" void rsAllocationGenerateMipmaps (RsContext ctxWrapper, RsAllocation va)
    430 {
    431     RS_DISPATCH(ctxWrapper, AllocationGenerateMipmaps, va);
    432 }
    433 
    434 extern "C" void rsAllocationRead (RsContext ctxWrapper, RsAllocation va, void * data, size_t data_length)
    435 {
    436     RS_DISPATCH(ctxWrapper, AllocationRead, va, data, data_length);
    437 }
    438 
    439 extern "C" void rsAllocation1DRead (RsContext ctxWrapper, RsAllocation va, uint32_t xoff, uint32_t lod, uint32_t count,
    440                                     void * data, size_t data_length)
    441 {
    442     RS_DISPATCH(ctxWrapper, Allocation1DRead, va, xoff, lod, count, data, data_length);
    443 }
    444 
    445 extern "C" void rsAllocationElementRead (RsContext ctxWrapper, RsAllocation va, uint32_t x, uint32_t y, uint32_t z,
    446                                          uint32_t lod, void * data, size_t data_length, size_t comp_offset)
    447 {
    448     RS_DISPATCH(ctxWrapper, AllocationElementRead, va, x, y, z, lod, data, data_length, comp_offset);
    449 }
    450 
    451 extern "C" void rsAllocation2DRead (RsContext ctxWrapper, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod,
    452                                     RsAllocationCubemapFace face, uint32_t w, uint32_t h,
    453                                     void * data, size_t data_length, size_t stride)
    454 {
    455     RS_DISPATCH(ctxWrapper, Allocation2DRead, va, xoff, yoff, lod, face, w, h, data, data_length, stride);
    456 }
    457 
    458 extern "C" void rsAllocation3DRead (RsContext ctxWrapper, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff,
    459                                     uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
    460                                     void * data, size_t data_length, size_t stride)
    461 {
    462     RS_DISPATCH(ctxWrapper, Allocation3DRead, va, xoff, yoff, zoff, lod, w, h, d, data, data_length, stride);
    463 }
    464 
    465 extern "C" void rsAllocationSyncAll (RsContext ctxWrapper, RsAllocation va, RsAllocationUsageType src)
    466 {
    467     RS_DISPATCH(ctxWrapper, AllocationSyncAll, va, src);
    468 }
    469 
    470 extern "C" void rsAllocationResize1D (RsContext ctxWrapper, RsAllocation va, uint32_t dimX)
    471 {
    472     RS_DISPATCH(ctxWrapper, AllocationResize1D, va, dimX);
    473 }
    474 
    475 extern "C" void rsAllocationCopy2DRange (RsContext ctxWrapper,
    476                                          RsAllocation dest,
    477                                          uint32_t destXoff, uint32_t destYoff,
    478                                          uint32_t destMip, uint32_t destFace,
    479                                          uint32_t width, uint32_t height,
    480                                          RsAllocation src,
    481                                          uint32_t srcXoff, uint32_t srcYoff,
    482                                          uint32_t srcMip, uint32_t srcFace)
    483 {
    484     RS_DISPATCH(ctxWrapper, AllocationCopy2DRange, dest, destXoff, destYoff, destMip, destFace,
    485                                     width, height, src, srcXoff, srcYoff, srcMip, srcFace);
    486 }
    487 
    488 extern "C" void rsAllocationCopy3DRange (RsContext ctxWrapper,
    489                                          RsAllocation dest,
    490                                          uint32_t destXoff, uint32_t destYoff, uint32_t destZoff,
    491                                          uint32_t destMip,
    492                                          uint32_t width, uint32_t height, uint32_t depth,
    493                                          RsAllocation src,
    494                                          uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
    495                                          uint32_t srcMip)
    496 {
    497     RS_DISPATCH(ctxWrapper, AllocationCopy3DRange,
    498                 dest, destXoff, destYoff, destZoff, destMip,
    499                 width, height, depth, src, srcXoff, srcYoff, srcZoff, srcMip);
    500 }
    501 
    502 extern "C" void rsAllocationIoSend (RsContext ctxWrapper, RsAllocation alloc)
    503 {
    504     RS_DISPATCH(ctxWrapper, AllocationIoSend, alloc);
    505 }
    506 
    507 extern "C" int64_t rsAllocationIoReceive (RsContext ctxWrapper, RsAllocation alloc)
    508 {
    509     return RS_DISPATCH(ctxWrapper, AllocationIoReceive, alloc);
    510 }
    511 
    512 // ScriptGroup
    513 
    514 extern "C" void rsScriptGroupExecute (RsContext ctxWrapper, RsScriptGroup group)
    515 {
    516     RS_DISPATCH(ctxWrapper, ScriptGroupExecute, group);
    517 }
    518 
    519 extern "C" RsScriptGroup2 rsScriptGroup2Create (RsContext ctxWrapper, const char * name, size_t name_length,
    520                                                 const char * cacheDir, size_t cacheDir_length,
    521                                                 RsClosure * closures, size_t closures_length)
    522 {
    523     return RS_DISPATCH(ctxWrapper, ScriptGroup2Create,
    524                        name, name_length,
    525                        cacheDir, cacheDir_length,
    526                        closures, closures_length);
    527 }
    528 
    529 extern "C" RsClosure rsClosureCreate (RsContext ctxWrapper, RsScriptKernelID kernelID, RsAllocation returnValue,
    530                                       RsScriptFieldID * fieldIDs, size_t fieldIDs_length,
    531                                       const int64_t * values, size_t values_length,
    532                                       const int * sizes, size_t sizes_length,
    533                                       RsClosure * depClosures, size_t depClosures_length,
    534                                       RsScriptFieldID * depFieldIDs, size_t depFieldIDs_length)
    535 {
    536     return RS_DISPATCH(ctxWrapper, ClosureCreate, kernelID, returnValue, fieldIDs, fieldIDs_length,
    537                                    const_cast<int64_t *>(values), values_length,
    538                                    const_cast<int *>(sizes), sizes_length,
    539                                    depClosures, depClosures_length, depFieldIDs, depFieldIDs_length);
    540 }
    541 
    542 extern "C" RsClosure rsInvokeClosureCreate (RsContext ctxWrapper, RsScriptInvokeID invokeID,
    543                                             const void * params, size_t params_length,
    544                                             const RsScriptFieldID * fieldIDs, size_t fieldIDs_length,
    545                                             const int64_t * values, size_t values_length,
    546                                             const int * sizes, size_t sizes_length)
    547 {
    548     return RS_DISPATCH(ctxWrapper, InvokeClosureCreate, invokeID,
    549                        params, params_length,
    550                        fieldIDs, fieldIDs_length,
    551                        values, values_length,
    552                        sizes, sizes_length);
    553 }
    554 
    555 extern "C" void rsClosureSetArg (RsContext ctxWrapper, RsClosure closureID, uint32_t index,
    556                                  uintptr_t value, int valueSize)
    557 {
    558     RS_DISPATCH(ctxWrapper, ClosureSetArg, closureID, index, value, valueSize);
    559 }
    560 
    561 extern "C" void rsClosureSetGlobal (RsContext ctxWrapper, RsClosure closureID, RsScriptFieldID fieldID,
    562                                     int64_t value, int valueSize)
    563 {
    564     RS_DISPATCH(ctxWrapper, ClosureSetGlobal, closureID, fieldID, value, valueSize);
    565 }
    566 
    567 extern "C" RsScriptKernelID rsScriptKernelIDCreate (RsContext ctxWrapper, RsScript sid, int slot, int sig)
    568 {
    569     return RS_DISPATCH(ctxWrapper, ScriptKernelIDCreate, sid, slot, sig);
    570 }
    571 
    572 extern "C" RsScriptFieldID rsScriptFieldIDCreate (RsContext ctxWrapper, RsScript sid, int slot)
    573 {
    574     return RS_DISPATCH(ctxWrapper, ScriptFieldIDCreate, sid, slot);
    575 }
    576 
    577 extern "C" RsScriptGroup rsScriptGroupCreate (RsContext ctxWrapper, RsScriptKernelID * kernels, size_t kernels_length,
    578                                               RsScriptKernelID * src, size_t src_length,
    579                                               RsScriptKernelID * dstK, size_t dstK_length,
    580                                               RsScriptFieldID * dstF, size_t dstF_length,
    581                                               const RsType * type, size_t type_length)
    582 {
    583     return RS_DISPATCH(ctxWrapper, ScriptGroupCreate,
    584                        kernels, kernels_length,
    585                        src, src_length, dstK, dstK_length,
    586                        dstF, dstF_length, type, type_length);
    587 }
    588 
    589 extern "C" void rsScriptGroupSetOutput (RsContext ctxWrapper, RsScriptGroup group,
    590                                         RsScriptKernelID kernel, RsAllocation alloc)
    591 {
    592     RS_DISPATCH(ctxWrapper, ScriptGroupSetOutput, group, kernel, alloc);
    593 }
    594 
    595 extern "C" void rsScriptGroupSetInput (RsContext ctxWrapper, RsScriptGroup group,
    596                                        RsScriptKernelID kernel, RsAllocation alloc)
    597 {
    598     RS_DISPATCH(ctxWrapper, ScriptGroupSetInput, group, kernel, alloc);
    599 }
    600 
    601 
    602 // Sampler
    603 extern "C" RsSampler rsSamplerCreate (RsContext ctxWrapper, RsSamplerValue magFilter, RsSamplerValue minFilter,
    604                                       RsSamplerValue wrapS, RsSamplerValue wrapT, RsSamplerValue wrapR,
    605                                       float mAniso)
    606 {
    607     return RS_DISPATCH(ctxWrapper, SamplerCreate, magFilter, minFilter, wrapS, wrapT, wrapR, mAniso);
    608 }
    609 
    610 // Script
    611 
    612 extern "C" RsScript rsScriptCCreate (RsContext ctxWrapper, const char * resName, size_t resName_length,
    613                                      const char * cacheDir, size_t cacheDir_length,
    614                                      const char * text, size_t text_length)
    615 {
    616     return RS_DISPATCH(ctxWrapper, ScriptCCreate, resName, resName_length, cacheDir, cacheDir_length, text, text_length);
    617 }
    618 
    619 extern "C" RsScript rsScriptIntrinsicCreate (RsContext ctxWrapper, uint32_t id, RsElement eid)
    620 {
    621     return RS_DISPATCH(ctxWrapper, ScriptIntrinsicCreate, id, eid);
    622 }
    623 
    624 extern "C" void rsScriptBindAllocation (RsContext ctxWrapper, RsScript vtm, RsAllocation va, uint32_t slot)
    625 {
    626     RS_DISPATCH(ctxWrapper, ScriptBindAllocation, vtm, va, slot);
    627 }
    628 
    629 extern "C" void rsScriptSetTimeZone (RsContext ctxWrapper, RsScript s, const char * timeZone, size_t timeZone_length)
    630 {
    631     RS_DISPATCH(ctxWrapper, ScriptSetTimeZone, s, timeZone, timeZone_length);
    632 }
    633 
    634 extern "C" RsScriptInvokeID rsScriptInvokeIDCreate (RsContext ctxWrapper, RsScript s, uint32_t slot)
    635 {
    636     return RS_DISPATCH(ctxWrapper, ScriptInvokeIDCreate, s, slot);
    637 }
    638 
    639 extern "C" void rsScriptInvoke (RsContext ctxWrapper, RsScript s, uint32_t slot)
    640 {
    641     RS_DISPATCH(ctxWrapper, ScriptInvoke, s, slot);
    642 }
    643 
    644 extern "C" void rsScriptInvokeV (RsContext ctxWrapper, RsScript s, uint32_t slot, const void * data, size_t data_length)
    645 {
    646     RS_DISPATCH(ctxWrapper, ScriptInvokeV, s, slot, data, data_length);
    647 }
    648 
    649 extern "C" void rsScriptForEach (RsContext ctxWrapper, RsScript s, uint32_t slot,
    650                                  RsAllocation ain, RsAllocation aout,
    651                                  const void * usr, size_t usr_length,
    652                                  const RsScriptCall * sc, size_t sc_length)
    653 {
    654     RS_DISPATCH(ctxWrapper, ScriptForEach, s, slot, ain, aout, usr, usr_length, sc, sc_length);
    655 }
    656 
    657 extern "C" void rsScriptForEachMulti (RsContext ctxWrapper, RsScript s, uint32_t slot,
    658                                       RsAllocation * ains, size_t ains_length, RsAllocation aout,
    659                                       const void * usr, size_t usr_length,
    660                                       const RsScriptCall * sc, size_t sc_length)
    661 {
    662     RS_DISPATCH(ctxWrapper, ScriptForEachMulti, s, slot, ains, ains_length, aout, usr, usr_length, sc, sc_length);
    663 }
    664 
    665 extern "C" void rsScriptReduce (RsContext ctxWrapper, RsScript s, uint32_t slot,
    666                                 RsAllocation * ains, size_t ains_length, RsAllocation aout,
    667                                 const RsScriptCall * sc, size_t sc_length)
    668 {
    669     RS_DISPATCH(ctxWrapper, ScriptReduce, s, slot, ains, ains_length, aout, sc, sc_length);
    670 }
    671 
    672 extern "C" void rsScriptSetVarI (RsContext ctxWrapper, RsScript s, uint32_t slot, int value)
    673 {
    674     RS_DISPATCH(ctxWrapper, ScriptSetVarI, s, slot, value);
    675 }
    676 
    677 extern "C" void rsScriptSetVarObj (RsContext ctxWrapper, RsScript s, uint32_t slot, RsObjectBase value)
    678 {
    679     RS_DISPATCH(ctxWrapper, ScriptSetVarObj, s, slot, value);
    680 }
    681 
    682 extern "C" void rsScriptSetVarJ (RsContext ctxWrapper, RsScript s, uint32_t slot, int64_t value)
    683 {
    684     RS_DISPATCH(ctxWrapper, ScriptSetVarJ, s, slot, value);
    685 }
    686 
    687 extern "C" void rsScriptSetVarF (RsContext ctxWrapper, RsScript s, uint32_t slot, float value)
    688 {
    689     RS_DISPATCH(ctxWrapper, ScriptSetVarF, s, slot, value);
    690 }
    691 
    692 extern "C" void rsScriptSetVarD (RsContext ctxWrapper, RsScript s, uint32_t slot, double value)
    693 {
    694     RS_DISPATCH(ctxWrapper, ScriptSetVarD, s, slot, value);
    695 }
    696 
    697 extern "C" void rsScriptSetVarV (RsContext ctxWrapper, RsScript s, uint32_t slot,
    698                                  const void * data, size_t data_length)
    699 {
    700     RS_DISPATCH(ctxWrapper, ScriptSetVarV, s, slot, data, data_length);
    701 }
    702 
    703 extern "C" void rsScriptGetVarV (RsContext ctxWrapper, RsScript s, uint32_t slot,
    704                                  void * data, size_t data_length)
    705 {
    706     RS_DISPATCH(ctxWrapper, ScriptGetVarV, s, slot, data, data_length);
    707 }
    708 
    709 extern "C" void rsScriptSetVarVE (RsContext ctxWrapper, RsScript s, uint32_t slot,
    710                                   const void * data, size_t data_length,
    711                                   RsElement e, const uint32_t * dims, size_t dims_length)
    712 {
    713     RS_DISPATCH(ctxWrapper, ScriptSetVarVE, s, slot, data, data_length, e, dims, dims_length);
    714 }
    715 
    716 
    717 // Graphics
    718 /* The following API are deprecated. */
    719 
    720 extern "C" RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, uint32_t sdkVersion,
    721                                        RsSurfaceConfig sc, uint32_t dpi)
    722 {
    723     if (!globalObjAlive) {
    724         ALOGE("rsContextCreateGL is not allowed during process teardown.");
    725         return nullptr;
    726     }
    727 
    728     RsFallbackAdaptation& instance = RsFallbackAdaptation::GetInstance();
    729     RsContext context = instance.GetEntryFuncs()->ContextCreateGL(vdev, version, sdkVersion, sc, dpi);
    730 
    731     RsContextWrapper *ctxWrapper = new RsContextWrapper{context, instance.GetEntryFuncs()};
    732 
    733     // Lock contextMap when adding new entries.
    734     std::unique_lock<std::mutex> lock(contextMapMutex);
    735     contextMap.insert(std::make_pair(context, ctxWrapper));
    736 
    737     return (RsContext) ctxWrapper;
    738 }
    739 
    740 extern "C" void rsContextBindProgramStore (RsContext ctxWrapper, RsProgramStore pgm)
    741 {
    742     RS_DISPATCH(ctxWrapper, ContextBindProgramStore, pgm);
    743 }
    744 
    745 extern "C" void rsContextBindProgramFragment (RsContext ctxWrapper, RsProgramFragment pgm)
    746 {
    747     RS_DISPATCH(ctxWrapper, ContextBindProgramFragment, pgm);
    748 }
    749 
    750 extern "C" void rsContextBindProgramVertex (RsContext ctxWrapper, RsProgramVertex pgm)
    751 {
    752     RS_DISPATCH(ctxWrapper, ContextBindProgramVertex, pgm);
    753 }
    754 
    755 extern "C" void rsContextBindProgramRaster (RsContext ctxWrapper, RsProgramRaster pgm)
    756 {
    757     RS_DISPATCH(ctxWrapper, ContextBindProgramRaster, pgm);
    758 }
    759 
    760 extern "C" void rsContextBindFont (RsContext ctxWrapper, RsFont pgm)
    761 {
    762     RS_DISPATCH(ctxWrapper, ContextBindFont, pgm);
    763 }
    764 
    765 extern "C" void rsContextSetSurface (RsContext ctxWrapper, uint32_t width, uint32_t height,
    766                                      RsNativeWindow sur)
    767 {
    768     RS_DISPATCH(ctxWrapper, ContextSetSurface, width, height, sur);
    769 }
    770 
    771 extern "C" void rsContextBindRootScript (RsContext ctxWrapper, RsScript sampler)
    772 {
    773     RS_DISPATCH(ctxWrapper, ContextBindRootScript, sampler);
    774 }
    775 
    776 extern "C" void rsContextPause (RsContext ctxWrapper)
    777 {
    778     RS_DISPATCH(ctxWrapper, ContextPause);
    779 }
    780 
    781 extern "C" void rsContextResume (RsContext ctxWrapper)
    782 {
    783     RS_DISPATCH(ctxWrapper, ContextResume);
    784 }
    785 
    786 extern "C" RsProgramStore rsProgramStoreCreate (RsContext ctxWrapper,
    787                                                 bool colorMaskR, bool colorMaskG,
    788                                                 bool colorMaskB, bool colorMaskA,
    789                                                 bool depthMask, bool ditherEnable,
    790                                                 RsBlendSrcFunc srcFunc,
    791                                                 RsBlendDstFunc destFunc,
    792                                                 RsDepthFunc depthFunc)
    793 {
    794     return RS_DISPATCH(ctxWrapper, ProgramStoreCreate,
    795                        colorMaskR, colorMaskG, colorMaskB, colorMaskA,
    796                        depthMask, ditherEnable, srcFunc, destFunc, depthFunc);
    797 }
    798 
    799 extern "C" RsProgramRaster rsProgramRasterCreate (RsContext ctxWrapper, bool pointSprite, RsCullMode cull)
    800 {
    801     return RS_DISPATCH(ctxWrapper, ProgramRasterCreate, pointSprite, cull);
    802 }
    803 
    804 extern "C" RsProgramFragment rsProgramFragmentCreate (RsContext ctxWrapper,
    805                                                       const char * shaderText, size_t shaderText_length,
    806                                                       const char ** textureNames, size_t textureNames_length_length,
    807                                                       const size_t * textureNames_length,
    808                                                       const uintptr_t * params, size_t params_length)
    809 {
    810     return RS_DISPATCH(ctxWrapper, ProgramFragmentCreate,
    811                        shaderText, shaderText_length,
    812                        textureNames, textureNames_length_length, textureNames_length,
    813                        params, params_length);
    814 }
    815 
    816 extern "C" RsProgramVertex rsProgramVertexCreate (RsContext ctxWrapper,
    817                                                   const char * shaderText, size_t shaderText_length,
    818                                                   const char ** textureNames, size_t textureNames_length_length,
    819                                                   const size_t * textureNames_length,
    820                                                   const uintptr_t * params, size_t params_length)
    821 {
    822     return RS_DISPATCH(ctxWrapper, ProgramVertexCreate,
    823                        shaderText, shaderText_length,
    824                        textureNames, textureNames_length_length, textureNames_length,
    825                        params, params_length);
    826 }
    827 
    828 extern "C" RsFont rsFontCreateFromFile (RsContext ctxWrapper, const char * name, size_t name_length,
    829                                         float fontSize, uint32_t dpi)
    830 {
    831     return RS_DISPATCH(ctxWrapper, FontCreateFromFile, name, name_length, fontSize, dpi);
    832 }
    833 
    834 extern "C" RsFont rsFontCreateFromMemory (RsContext ctxWrapper, const char * name, size_t name_length,
    835                                           float fontSize, uint32_t dpi,
    836                                           const void * data, size_t data_length)
    837 {
    838     return RS_DISPATCH(ctxWrapper, FontCreateFromMemory, name, name_length, fontSize, dpi, data, data_length);
    839 }
    840 
    841 extern "C" RsMesh rsMeshCreate (RsContext ctxWrapper, RsAllocation * vtx, size_t vtx_length,
    842                                 RsAllocation * idx, size_t idx_length,
    843                                 uint32_t * primType, size_t primType_length)
    844 {
    845     return RS_DISPATCH(ctxWrapper, MeshCreate, vtx, vtx_length, idx, idx_length, primType, primType_length);
    846 }
    847 
    848 extern "C" void rsProgramBindConstants (RsContext ctxWrapper, RsProgram vp, uint32_t slot, RsAllocation constants)
    849 {
    850     RS_DISPATCH(ctxWrapper, ProgramBindConstants, vp, slot, constants);
    851 }
    852 
    853 extern "C" void rsProgramBindTexture (RsContext ctxWrapper, RsProgramFragment pf, uint32_t slot, RsAllocation a)
    854 {
    855     RS_DISPATCH(ctxWrapper, ProgramBindTexture, pf, slot,a);
    856 }
    857 
    858 extern "C" void rsProgramBindSampler (RsContext ctxWrapper, RsProgramFragment pf, uint32_t slot, RsSampler s)
    859 {
    860     RS_DISPATCH(ctxWrapper, ProgramBindSampler, pf, slot, s);
    861 }
    862 
    863 extern "C" RsObjectBase rsaFileA3DGetEntryByIndex(RsContext ctxWrapper, uint32_t index, RsFile file)
    864 {
    865     return RS_DISPATCH(ctxWrapper, FileA3DGetEntryByIndex, index, file);
    866 }
    867 
    868 extern "C" RsFile rsaFileA3DCreateFromMemory(RsContext ctxWrapper, const void *data, uint32_t len)
    869 {
    870     return RS_DISPATCH(ctxWrapper, FileA3DCreateFromMemory, data, len);
    871 }
    872 
    873 extern "C" RsFile rsaFileA3DCreateFromAsset(RsContext ctxWrapper, void *_asset)
    874 {
    875     return RS_DISPATCH(ctxWrapper, FileA3DCreateFromAsset, _asset);
    876 }
    877 
    878 extern "C" RsFile rsaFileA3DCreateFromFile(RsContext ctxWrapper, const char *path)
    879 {
    880     return RS_DISPATCH(ctxWrapper, FileA3DCreateFromFile, path);
    881 }
    882 
    883 extern "C"  void rsaFileA3DGetNumIndexEntries(RsContext ctxWrapper, int32_t *numEntries, RsFile file)
    884 {
    885     RS_DISPATCH(ctxWrapper, FileA3DGetNumIndexEntries, numEntries, file);
    886 }
    887 
    888 extern "C" void rsaFileA3DGetIndexEntries(RsContext ctxWrapper, RsFileIndexEntry *fileEntries, uint32_t numEntries, RsFile file)
    889 {
    890     RS_DISPATCH(ctxWrapper, FileA3DGetIndexEntries, fileEntries, numEntries, file);
    891 }
    892 
    893 extern "C" void rsaMeshGetVertexBufferCount(RsContext ctxWrapper, RsMesh mv, int32_t *numVtx)
    894 {
    895     RS_DISPATCH(ctxWrapper, MeshGetVertexBufferCount, mv, numVtx);
    896 }
    897 
    898 extern "C" void rsaMeshGetIndexCount(RsContext ctxWrapper, RsMesh mv, int32_t *numIdx)
    899 {
    900     RS_DISPATCH(ctxWrapper, MeshGetIndexCount, mv, numIdx);
    901 }
    902 
    903 extern "C" void rsaMeshGetVertices(RsContext ctxWrapper, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount)
    904 {
    905     RS_DISPATCH(ctxWrapper, MeshGetVertices, mv, vtxData, vtxDataCount);
    906 }
    907 
    908 extern "C" void rsaMeshGetIndices(RsContext ctxWrapper, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount)
    909 {
    910     RS_DISPATCH(ctxWrapper, MeshGetIndices, mv, va, primType, idxDataCount);
    911 }
    912