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.
39struct 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.
53static 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.
58static 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.
64static 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
70class GlobalObjGuard {
71  public:
72    GlobalObjGuard() {
73        globalObjAlive = true;
74    }
75
76    ~GlobalObjGuard() {
77        globalObjAlive = false;
78    }
79};
80static 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.
84extern "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
93extern "C" RsDevice rsDeviceCreate()
94{
95    return (void *) 1;
96}
97extern "C" void rsDeviceDestroy(RsDevice dev)
98{
99}
100extern "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 */
110extern "C" int gDebuggerPresent = 0;
111
112namespace{
113// Use reflection to query the default cache dir.
114std::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
149extern "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
194extern "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
209extern "C" void rsContextFinish (RsContext ctxWrapper)
210{
211    RS_DISPATCH(ctxWrapper, ContextFinish);
212}
213
214extern "C" void rsContextDump (RsContext ctxWrapper, int32_t bits)
215{
216    RS_DISPATCH(ctxWrapper, ContextDump, bits);
217}
218
219extern "C" void rsContextSetPriority (RsContext ctxWrapper, int32_t priority)
220{
221    RS_DISPATCH(ctxWrapper, ContextSetPriority, priority);
222}
223
224extern "C" void rsContextDestroyWorker (RsContext ctxWrapper)
225{
226}
227
228extern "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
237extern "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
246extern "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
251extern "C" void rsContextInitToClient (RsContext ctxWrapper)
252{
253    RS_DISPATCH(ctxWrapper, ContextInitToClient);
254}
255
256extern "C" void rsContextDeinitToClient (RsContext ctxWrapper)
257{
258    RS_DISPATCH(ctxWrapper, ContextDeinitToClient);
259}
260
261extern "C" void rsContextSetCacheDir (RsContext ctxWrapper, const char * cacheDir, size_t cacheDir_length)
262{
263    RS_DISPATCH(ctxWrapper, ContextSetCacheDir, cacheDir, cacheDir_length);
264}
265
266extern "C" void rsaContextSetNativeLibDir(RsContext ctxWrapper, char *libDir, size_t length)
267{
268}
269
270// BaseObject
271
272extern "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
277extern "C" void rsaGetName(RsContext ctxWrapper, void * obj, const char **name)
278{
279    RS_DISPATCH(ctxWrapper, GetName, obj, name);
280}
281
282extern "C" void rsObjDestroy (RsContext ctxWrapper, RsAsyncVoidPtr objPtr)
283{
284    RS_DISPATCH(ctxWrapper, ObjDestroy, objPtr);
285}
286
287// Element
288
289extern "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
295extern "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
305extern "C" void rsaElementGetNativeData(RsContext ctxWrapper, RsElement elem, uint32_t *elemData, uint32_t elemDataSize)
306{
307    RS_DISPATCH(ctxWrapper, ElementGetNativeData, elem, elemData, elemDataSize);
308}
309
310extern "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
318extern "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
324extern "C" RsType rsTypeCreate2 (RsContext ctxWrapper, const RsTypeCreateParams * dat, size_t dat_length)
325{
326    return nullptr;
327}
328
329extern "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
337extern "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
343extern "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
349extern "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
355extern "C" RsAllocation rsAllocationAdapterCreate (RsContext ctxWrapper, RsType vtype, RsAllocation baseAlloc)
356{
357    return RS_DISPATCH(ctxWrapper, AllocationAdapterCreate, vtype, baseAlloc);
358}
359
360extern "C" const void * rsaAllocationGetType(RsContext ctxWrapper, RsAllocation va)
361{
362    return RS_DISPATCH(ctxWrapper, AllocationGetType, va);
363}
364
365extern "C" RsNativeWindow rsAllocationGetSurface (RsContext ctxWrapper, RsAllocation alloc)
366{
367    return RS_DISPATCH(ctxWrapper, AllocationGetSurface, alloc);
368}
369
370extern "C" void rsAllocationSetupBufferQueue (RsContext ctxWrapper, RsAllocation alloc, uint32_t numAlloc)
371{
372    RS_DISPATCH(ctxWrapper, AllocationSetupBufferQueue, alloc, numAlloc);
373}
374
375extern "C" void rsAllocationShareBufferQueue (RsContext ctxWrapper, RsAllocation alloc1, RsAllocation alloc2)
376{
377    RS_DISPATCH(ctxWrapper, AllocationShareBufferQueue, alloc1, alloc2);
378}
379
380extern "C" void rsAllocationSetSurface (RsContext ctxWrapper, RsAllocation alloc, RsNativeWindow sur)
381{
382    RS_DISPATCH(ctxWrapper, AllocationSetSurface, alloc, sur);
383}
384
385extern "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
391extern "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
396extern "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
402extern "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
408extern "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
414extern "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
420extern "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
427extern "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
434extern "C" void rsAllocationGenerateMipmaps (RsContext ctxWrapper, RsAllocation va)
435{
436    RS_DISPATCH(ctxWrapper, AllocationGenerateMipmaps, va);
437}
438
439extern "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
444extern "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
450extern "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
456extern "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
463extern "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
470extern "C" void rsAllocationSyncAll (RsContext ctxWrapper, RsAllocation va, RsAllocationUsageType src)
471{
472    RS_DISPATCH(ctxWrapper, AllocationSyncAll, va, src);
473}
474
475extern "C" void rsAllocationResize1D (RsContext ctxWrapper, RsAllocation va, uint32_t dimX)
476{
477    RS_DISPATCH(ctxWrapper, AllocationResize1D, va, dimX);
478}
479
480extern "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
493extern "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
507extern "C" void rsAllocationIoSend (RsContext ctxWrapper, RsAllocation alloc)
508{
509    RS_DISPATCH(ctxWrapper, AllocationIoSend, alloc);
510}
511
512extern "C" int64_t rsAllocationIoReceive (RsContext ctxWrapper, RsAllocation alloc)
513{
514    return RS_DISPATCH(ctxWrapper, AllocationIoReceive, alloc);
515}
516
517// ScriptGroup
518
519extern "C" void rsScriptGroupExecute (RsContext ctxWrapper, RsScriptGroup group)
520{
521    RS_DISPATCH(ctxWrapper, ScriptGroupExecute, group);
522}
523
524extern "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
534extern "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
547extern "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
560extern "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
566extern "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
572extern "C" RsScriptKernelID rsScriptKernelIDCreate (RsContext ctxWrapper, RsScript sid, int slot, int sig)
573{
574    return RS_DISPATCH(ctxWrapper, ScriptKernelIDCreate, sid, slot, sig);
575}
576
577extern "C" RsScriptFieldID rsScriptFieldIDCreate (RsContext ctxWrapper, RsScript sid, int slot)
578{
579    return RS_DISPATCH(ctxWrapper, ScriptFieldIDCreate, sid, slot);
580}
581
582extern "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
594extern "C" void rsScriptGroupSetOutput (RsContext ctxWrapper, RsScriptGroup group,
595                                        RsScriptKernelID kernel, RsAllocation alloc)
596{
597    RS_DISPATCH(ctxWrapper, ScriptGroupSetOutput, group, kernel, alloc);
598}
599
600extern "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
608extern "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
617extern "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
624extern "C" RsScript rsScriptIntrinsicCreate (RsContext ctxWrapper, uint32_t id, RsElement eid)
625{
626    return RS_DISPATCH(ctxWrapper, ScriptIntrinsicCreate, id, eid);
627}
628
629extern "C" void rsScriptBindAllocation (RsContext ctxWrapper, RsScript vtm, RsAllocation va, uint32_t slot)
630{
631    RS_DISPATCH(ctxWrapper, ScriptBindAllocation, vtm, va, slot);
632}
633
634extern "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
639extern "C" RsScriptInvokeID rsScriptInvokeIDCreate (RsContext ctxWrapper, RsScript s, uint32_t slot)
640{
641    return RS_DISPATCH(ctxWrapper, ScriptInvokeIDCreate, s, slot);
642}
643
644extern "C" void rsScriptInvoke (RsContext ctxWrapper, RsScript s, uint32_t slot)
645{
646    RS_DISPATCH(ctxWrapper, ScriptInvoke, s, slot);
647}
648
649extern "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
654extern "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
662extern "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
670extern "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
677extern "C" void rsScriptSetVarI (RsContext ctxWrapper, RsScript s, uint32_t slot, int value)
678{
679    RS_DISPATCH(ctxWrapper, ScriptSetVarI, s, slot, value);
680}
681
682extern "C" void rsScriptSetVarObj (RsContext ctxWrapper, RsScript s, uint32_t slot, RsObjectBase value)
683{
684    RS_DISPATCH(ctxWrapper, ScriptSetVarObj, s, slot, value);
685}
686
687extern "C" void rsScriptSetVarJ (RsContext ctxWrapper, RsScript s, uint32_t slot, int64_t value)
688{
689    RS_DISPATCH(ctxWrapper, ScriptSetVarJ, s, slot, value);
690}
691
692extern "C" void rsScriptSetVarF (RsContext ctxWrapper, RsScript s, uint32_t slot, float value)
693{
694    RS_DISPATCH(ctxWrapper, ScriptSetVarF, s, slot, value);
695}
696
697extern "C" void rsScriptSetVarD (RsContext ctxWrapper, RsScript s, uint32_t slot, double value)
698{
699    RS_DISPATCH(ctxWrapper, ScriptSetVarD, s, slot, value);
700}
701
702extern "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
708extern "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
714extern "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
725RsContext 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
745extern "C" void rsContextBindProgramStore (RsContext ctxWrapper, RsProgramStore pgm)
746{
747    RS_DISPATCH(ctxWrapper, ContextBindProgramStore, pgm);
748}
749
750extern "C" void rsContextBindProgramFragment (RsContext ctxWrapper, RsProgramFragment pgm)
751{
752    RS_DISPATCH(ctxWrapper, ContextBindProgramFragment, pgm);
753}
754
755extern "C" void rsContextBindProgramVertex (RsContext ctxWrapper, RsProgramVertex pgm)
756{
757    RS_DISPATCH(ctxWrapper, ContextBindProgramVertex, pgm);
758}
759
760extern "C" void rsContextBindProgramRaster (RsContext ctxWrapper, RsProgramRaster pgm)
761{
762    RS_DISPATCH(ctxWrapper, ContextBindProgramRaster, pgm);
763}
764
765extern "C" void rsContextBindFont (RsContext ctxWrapper, RsFont pgm)
766{
767    RS_DISPATCH(ctxWrapper, ContextBindFont, pgm);
768}
769
770extern "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
776extern "C" void rsContextBindRootScript (RsContext ctxWrapper, RsScript sampler)
777{
778    RS_DISPATCH(ctxWrapper, ContextBindRootScript, sampler);
779}
780
781extern "C" void rsContextPause (RsContext ctxWrapper)
782{
783    RS_DISPATCH(ctxWrapper, ContextPause);
784}
785
786extern "C" void rsContextResume (RsContext ctxWrapper)
787{
788    RS_DISPATCH(ctxWrapper, ContextResume);
789}
790
791extern "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
804extern "C" RsProgramRaster rsProgramRasterCreate (RsContext ctxWrapper, bool pointSprite, RsCullMode cull)
805{
806    return RS_DISPATCH(ctxWrapper, ProgramRasterCreate, pointSprite, cull);
807}
808
809extern "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
821extern "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
833extern "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
839extern "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
846extern "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
853extern "C" void rsProgramBindConstants (RsContext ctxWrapper, RsProgram vp, uint32_t slot, RsAllocation constants)
854{
855    RS_DISPATCH(ctxWrapper, ProgramBindConstants, vp, slot, constants);
856}
857
858extern "C" void rsProgramBindTexture (RsContext ctxWrapper, RsProgramFragment pf, uint32_t slot, RsAllocation a)
859{
860    RS_DISPATCH(ctxWrapper, ProgramBindTexture, pf, slot,a);
861}
862
863extern "C" void rsProgramBindSampler (RsContext ctxWrapper, RsProgramFragment pf, uint32_t slot, RsSampler s)
864{
865    RS_DISPATCH(ctxWrapper, ProgramBindSampler, pf, slot, s);
866}
867
868RsObjectBase rsaFileA3DGetEntryByIndex(RsContext ctxWrapper, uint32_t index, RsFile file)
869{
870    return RS_DISPATCH(ctxWrapper, FileA3DGetEntryByIndex, index, file);
871}
872
873RsFile rsaFileA3DCreateFromMemory(RsContext ctxWrapper, const void *data, uint32_t len)
874{
875    return RS_DISPATCH(ctxWrapper, FileA3DCreateFromMemory, data, len);
876}
877
878RsFile rsaFileA3DCreateFromAsset(RsContext ctxWrapper, void *_asset)
879{
880    return RS_DISPATCH(ctxWrapper, FileA3DCreateFromAsset, _asset);
881}
882
883RsFile rsaFileA3DCreateFromFile(RsContext ctxWrapper, const char *path)
884{
885    return RS_DISPATCH(ctxWrapper, FileA3DCreateFromFile, path);
886}
887
888void rsaFileA3DGetNumIndexEntries(RsContext ctxWrapper, int32_t *numEntries, RsFile file)
889{
890    RS_DISPATCH(ctxWrapper, FileA3DGetNumIndexEntries, numEntries, file);
891}
892
893void rsaFileA3DGetIndexEntries(RsContext ctxWrapper, RsFileIndexEntry *fileEntries, uint32_t numEntries, RsFile file)
894{
895    RS_DISPATCH(ctxWrapper, FileA3DGetIndexEntries, fileEntries, numEntries, file);
896}
897
898void rsaMeshGetVertexBufferCount(RsContext ctxWrapper, RsMesh mv, int32_t *numVtx)
899{
900    RS_DISPATCH(ctxWrapper, MeshGetVertexBufferCount, mv, numVtx);
901}
902
903void rsaMeshGetIndexCount(RsContext ctxWrapper, RsMesh mv, int32_t *numIdx)
904{
905    RS_DISPATCH(ctxWrapper, MeshGetIndexCount, mv, numIdx);
906}
907
908void rsaMeshGetVertices(RsContext ctxWrapper, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount)
909{
910    RS_DISPATCH(ctxWrapper, MeshGetVertices, mv, vtxData, vtxDataCount);
911}
912
913void 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