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