1e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams/* 2803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams * Copyright (C) 2011 The Android Open Source Project 3e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * 4e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * you may not use this file except in compliance with the License. 6e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * You may obtain a copy of the License at 7e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * 8e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 9e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * 10e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * Unless required by applicable law or agreed to in writing, software 11e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * See the License for the specific language governing permissions and 14e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * limitations under the License. 15e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams */ 16e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 17e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include "rsdCore.h" 187e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams#include "rsdAllocation.h" 19e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include "rsdBcc.h" 20803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams#include "rsdGL.h" 2148f505657adba4d9156856e7d5593f23af5d5d5aJason Sams#include "rsdProgramStore.h" 22331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams#include "rsdProgramRaster.h" 234a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk#include "rsdProgramVertex.h" 244a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk#include "rsdProgramFragment.h" 254a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk#include "rsdMesh.h" 26438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk#include "rsdSampler.h" 272f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk#include "rsdFrameBuffer.h" 28e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 29e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include <malloc.h> 30e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include "rsContext.h" 31e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 3255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sys/types.h> 3355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sys/resource.h> 3455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sched.h> 3555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <cutils/properties.h> 3655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <cutils/sched_policy.h> 3755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sys/syscall.h> 3855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <string.h> 3917a8a1939d4cbc74de54954c67f3dd61882420aaAlex Sakhartchouk#include <bcc/bcc.h> 4055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 41e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsusing namespace android; 42e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsusing namespace android::renderscript; 43e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 4455d2a25402319380c62a97f3f84b57e2977448d1Jason Samsstatic void Shutdown(Context *rsc); 4555d2a25402319380c62a97f3f84b57e2977448d1Jason Samsstatic void SetPriority(const Context *rsc, int32_t priority); 461222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void initForEach(outer_foreach_t* forEachLaunch); 4755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 48e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsstatic RsdHalFunctions FunctionTable = { 49803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams rsdGLInit, 50803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams rsdGLShutdown, 51803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams rsdGLSetSurface, 52803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams rsdGLSwap, 53803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams 5455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams Shutdown, 55e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams NULL, 5655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams SetPriority, 57e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams { 58e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptInit, 59e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptInvokeFunction, 60e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptInvokeRoot, 6155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams rsdScriptInvokeForEach, 62e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptInvokeInit, 63514f9790fdf180ca3c58e508cbd36c520fa7be08Stephen Hines rsdScriptInvokeFreeChildren, 64e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptSetGlobalVar, 65e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptSetGlobalBind, 66e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptSetGlobalObj, 67e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsdScriptDestroy 6848f505657adba4d9156856e7d5593f23af5d5d5aJason Sams }, 6948f505657adba4d9156856e7d5593f23af5d5d5aJason Sams 707e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams { 717e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationInit, 727e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationDestroy, 737e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationResize, 747e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationSyncAll, 757e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationMarkDirty, 767e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationData1D, 777e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationData2D, 787e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationData3D, 79304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk rsdAllocationData1D_alloc, 80304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk rsdAllocationData2D_alloc, 81304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk rsdAllocationData3D_alloc, 827e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationElementData1D, 837e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams rsdAllocationElementData2D 847e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams }, 857e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams 8648f505657adba4d9156856e7d5593f23af5d5d5aJason Sams 8748f505657adba4d9156856e7d5593f23af5d5d5aJason Sams { 8848f505657adba4d9156856e7d5593f23af5d5d5aJason Sams rsdProgramStoreInit, 8948f505657adba4d9156856e7d5593f23af5d5d5aJason Sams rsdProgramStoreSetActive, 9048f505657adba4d9156856e7d5593f23af5d5d5aJason Sams rsdProgramStoreDestroy 91331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams }, 92331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams 93331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams { 94331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams rsdProgramRasterInit, 95331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams rsdProgramRasterSetActive, 96331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams rsdProgramRasterDestroy 974a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk }, 984a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk 994a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk { 1004a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdProgramVertexInit, 1014a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdProgramVertexSetActive, 1024a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdProgramVertexDestroy 1034a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk }, 1044a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk 1054a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk { 1064a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdProgramFragmentInit, 1074a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdProgramFragmentSetActive, 1084a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdProgramFragmentDestroy 1094a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk }, 1104a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk 1114a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk { 1124a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdMeshInit, 1134a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdMeshDraw, 1144a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk rsdMeshDestroy 115438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk }, 116438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk 117438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk { 118438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk rsdSamplerInit, 119438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk rsdSamplerDestroy 120438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk }, 12148f505657adba4d9156856e7d5593f23af5d5d5aJason Sams 1222f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk { 1232f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk rsdFrameBufferInit, 1242f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk rsdFrameBufferSetActive, 1252f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk rsdFrameBufferDestroy 1262f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk }, 1272f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk 128e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams}; 129e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 130be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Samspthread_key_t rsdgThreadTLSKey = 0; 131be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Samsuint32_t rsdgThreadTLSKeyCount = 0; 132be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER; 133e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 13455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 13555d2a25402319380c62a97f3f84b57e2977448d1Jason Samsstatic void * HelperThreadProc(void *vrsc) { 13655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams Context *rsc = static_cast<Context *>(vrsc); 137fcf7231249822ff4dae852f1de1f799756689f91Jason Sams RsdHal *dc = (RsdHal *)rsc->mHal.drv; 13855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 13955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 14055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount); 14155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 14255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams //LOGV("RS helperThread starting %p idx=%i", rsc, idx); 14355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 14455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchSignals[idx].init(); 14555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mNativeThreadId[idx] = gettid(); 14655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 147be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct); 148be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams if (status) { 149be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams LOGE("pthread_setspecific %i", status); 150be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams } 151be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams 15255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#if 0 15355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t; 15455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams cpu_set_t cpuset; 15555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams memset(&cpuset, 0, sizeof(cpuset)); 15655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams cpuset.bits[idx / 64] |= 1ULL << (idx % 64); 15755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx], 15855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams sizeof(cpuset), &cpuset); 15955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret)); 16055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#endif 16155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 16255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams while (!dc->mExit) { 16355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchSignals[idx].wait(); 16455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams if (dc->mWorkers.mLaunchCallback) { 16555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx); 16655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 16755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams android_atomic_dec(&dc->mWorkers.mRunningCount); 16855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mCompleteSignal.set(); 16955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 17055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 17155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams //LOGV("RS helperThread exited %p idx=%i", rsc, idx); 17255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams return NULL; 17355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams} 17455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 17555d2a25402319380c62a97f3f84b57e2977448d1Jason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) { 176fcf7231249822ff4dae852f1de1f799756689f91Jason Sams RsdHal *dc = (RsdHal *)rsc->mHal.drv; 17755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 17855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchData = data; 17955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchCallback = cbk; 18055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount); 18155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) { 18255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchSignals[ct].set(); 18355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 18455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) { 18555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mCompleteSignal.wait(); 18655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 18755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams} 18855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 189e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) { 190e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams rsc->mHal.funcs = FunctionTable; 191e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 192fcf7231249822ff4dae852f1de1f799756689f91Jason Sams RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal)); 19380e29cf5c45e378bd28a1b061bb70d8ce02846aeJason Sams if (!dc) { 19480e29cf5c45e378bd28a1b061bb70d8ce02846aeJason Sams LOGE("Calloc for driver hal failed."); 195e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams return false; 196e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams } 19755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams rsc->mHal.drv = dc; 198e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 199be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams pthread_mutex_lock(&rsdgInitMutex); 200be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams if (!rsdgThreadTLSKeyCount) { 201be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams int status = pthread_key_create(&rsdgThreadTLSKey, NULL); 202be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams if (status) { 203be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams LOGE("Failed to init thread tls key."); 204be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams pthread_mutex_unlock(&rsdgInitMutex); 205be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams return false; 206be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams } 207be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams } 208be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams rsdgThreadTLSKeyCount++; 209be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams pthread_mutex_unlock(&rsdgInitMutex); 210be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams 2111222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines initForEach(dc->mForEachLaunch); 2121222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 213be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams dc->mTlsStruct.mContext = rsc; 214be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams dc->mTlsStruct.mScript = NULL; 215be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct); 216be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams if (status) { 217be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams LOGE("pthread_setspecific %i", status); 218be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams } 219be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams 22055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 22155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams int cpu = sysconf(_SC_NPROCESSORS_ONLN); 2228410b14c85b5a0c7fcaa095b61feca96fb36d528Jason Sams LOGV("%p Launching thread(s), CPUs %i", rsc, cpu); 22355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams if (cpu < 2) cpu = 0; 22455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 22555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mCount = (uint32_t)cpu; 22655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t)); 22755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t)); 22855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount]; 22955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchCallback = NULL; 23055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 23155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mCompleteSignal.init(); 23255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 23355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount); 23455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams android_atomic_release_store(0, &dc->mWorkers.mLaunchCount); 23555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 23655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams pthread_attr_t threadAttr; 23755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams status = pthread_attr_init(&threadAttr); 23855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams if (status) { 23955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams LOGE("Failed to init thread attribute."); 24055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams return false; 24155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 24255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 24355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) { 24455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc); 24555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams if (status) { 24655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mCount = ct; 24755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams LOGE("Created fewer than expected number of RS threads."); 24855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams break; 24955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 25055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 25155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) { 25255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams usleep(100); 25355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 25455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 25555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams pthread_attr_destroy(&threadAttr); 256e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams return true; 257e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams} 258e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams 25955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 26055d2a25402319380c62a97f3f84b57e2977448d1Jason Samsvoid SetPriority(const Context *rsc, int32_t priority) { 261fcf7231249822ff4dae852f1de1f799756689f91Jason Sams RsdHal *dc = (RsdHal *)rsc->mHal.drv; 26255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) { 26355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority); 26455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 26555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams} 26655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 26755d2a25402319380c62a97f3f84b57e2977448d1Jason Samsvoid Shutdown(Context *rsc) { 268fcf7231249822ff4dae852f1de1f799756689f91Jason Sams RsdHal *dc = (RsdHal *)rsc->mHal.drv; 26955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 27055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mExit = true; 27155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchData = NULL; 27255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchCallback = NULL; 27355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount); 27455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) { 27555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams dc->mWorkers.mLaunchSignals[ct].set(); 27655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 27755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams int status; 27855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams void *res; 27955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) { 28055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams status = pthread_join(dc->mWorkers.mThreadId[ct], &res); 28155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams } 28255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0); 283be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams 284be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams // Global structure cleanup. 285be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams pthread_mutex_lock(&rsdgInitMutex); 286be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams --rsdgThreadTLSKeyCount; 287be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams if (!rsdgThreadTLSKeyCount) { 288be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams pthread_key_delete(rsdgThreadTLSKey); 289be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams } 290be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams pthread_mutex_unlock(&rsdgInitMutex); 291be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams 29255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams} 29355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 2941222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach17(const void *vRoot, 295aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 296aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 297aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 2981222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, uint32_t); 2991222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines (*(fe*)vRoot)(p->in, p->y); 3001222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3011222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3021222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach18(const void *vRoot, 303aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 304aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 305aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3061222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(void *, uint32_t); 3071222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines (*(fe*)vRoot)(p->out, p->y); 3081222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3091222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3101222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach19(const void *vRoot, 311aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 312aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 313aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3141222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, void *, uint32_t); 3151222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines (*(fe*)vRoot)(p->in, p->out, p->y); 3161222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3171222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3181222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach21(const void *vRoot, 319aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 320aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 321aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3221222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, const void *, uint32_t); 3231222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines (*(fe*)vRoot)(p->in, p->usr, p->y); 3241222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3251222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3261222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach22(const void *vRoot, 327aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 328aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 329aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3301222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(void *, const void *, uint32_t); 3311222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines (*(fe*)vRoot)(p->out, p->usr, p->y); 3321222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3331222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3341222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach23(const void *vRoot, 335aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 336aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 337aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3381222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, void *, const void *, uint32_t); 3391222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines (*(fe*)vRoot)(p->in, p->out, p->usr, p->y); 3401222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3411222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3421222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach25(const void *vRoot, 343aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 344aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 345aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3461222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, uint32_t, uint32_t); 347aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint8_t *pin = (const uint8_t *)p->in; 348aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t y = p->y; 349aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams for (uint32_t x = x1; x < x2; x++) { 350aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams (*(fe*)vRoot)(pin, x, y); 351aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pin += instep; 352aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams } 3531222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3541222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3551222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach26(const void *vRoot, 356aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 357aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 358aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3591222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(void *, uint32_t, uint32_t); 360aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint8_t *pout = (uint8_t *)p->out; 361aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t y = p->y; 362aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams for (uint32_t x = x1; x < x2; x++) { 363aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams (*(fe*)vRoot)(pout, x, y); 364aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pout += outstep; 365aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams } 3661222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3671222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3681222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach27(const void *vRoot, 369aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 370aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 371aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3721222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, void *, uint32_t, uint32_t); 373aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint8_t *pout = (uint8_t *)p->out; 374aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint8_t *pin = (const uint8_t *)p->in; 375aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t y = p->y; 376aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams for (uint32_t x = x1; x < x2; x++) { 377aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams (*(fe*)vRoot)(pin, pout, x, y); 378aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pin += instep; 379aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pout += outstep; 380aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams } 3811222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3821222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3831222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach29(const void *vRoot, 384aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 385aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 386aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 3871222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, const void *, uint32_t, uint32_t); 388aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint8_t *pin = (const uint8_t *)p->in; 389aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const void *usr = p->usr; 390aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint32_t y = p->y; 391aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams for (uint32_t x = x1; x < x2; x++) { 392aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams (*(fe*)vRoot)(pin, usr, x, y); 393aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pin += instep; 394aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams } 3951222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 3961222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 3971222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach30(const void *vRoot, 398aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 399aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 400aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 4011222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(void *, const void *, uint32_t, uint32_t); 402aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint8_t *pout = (uint8_t *)p->out; 403aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const void *usr = p->usr; 404aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint32_t y = p->y; 405aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams for (uint32_t x = x1; x < x2; x++) { 406aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams (*(fe*)vRoot)(pout, usr, x, y); 407aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pout += outstep; 408aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams } 4091222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 4101222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 4111222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach31(const void *vRoot, 412aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const android::renderscript::RsForEachStubParamStruct *p, 413aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t x1, uint32_t x2, 414aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint32_t instep, uint32_t outstep) { 4151222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines typedef void (*fe)(const void *, void *, const void *, uint32_t, uint32_t); 416aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams uint8_t *pout = (uint8_t *)p->out; 417aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint8_t *pin = (const uint8_t *)p->in; 418aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const void *usr = p->usr; 419aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams const uint32_t y = p->y; 420aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams for (uint32_t x = x1; x < x2; x++) { 421aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams (*(fe*)vRoot)(pin, pout, usr, x, y); 422aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pin += instep; 423aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams pout += outstep; 424aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams } 4251222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 4261222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 4271222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines 4281222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void initForEach(outer_foreach_t* forEachLaunch) { 4291222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines rsAssert(forEachLaunch); 4301222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x00] = NULL; 4311222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x01] = rsdForEach31; // in 4321222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x02] = rsdForEach30; // out 4331222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x03] = rsdForEach31; // in, out 4341222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x04] = NULL; 4351222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x05] = rsdForEach29; // in, usr 4361222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x06] = rsdForEach30; // out, usr 4371222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x07] = rsdForEach31; // in, out, usr 4381222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x08] = NULL; 4391222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x09] = rsdForEach25; // in, x 4401222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x0a] = rsdForEach26; // out, x 4411222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x0b] = rsdForEach27; // in, out, x 4421222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x0c] = NULL; 4431222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x0d] = rsdForEach29; // in, usr, x 4441222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x0e] = rsdForEach30; // out, usr, x 4451222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x0f] = rsdForEach31; // in, out, usr, x 4461222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x10] = NULL; 4471222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x11] = rsdForEach17; // in y 4481222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x12] = rsdForEach18; // out, y 4491222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x13] = rsdForEach19; // in, out, y 4501222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x14] = NULL; 4511222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x15] = rsdForEach21; // in, usr, y 4521222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x16] = rsdForEach22; // out, usr, y 4531222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x17] = rsdForEach23; // in, out, usr, y 4541222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x18] = NULL; 4551222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x19] = rsdForEach25; // in, x, y 4561222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x1a] = rsdForEach26; // out, x, y 4571222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x1b] = rsdForEach27; // in, out, x, y 4581222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x1c] = NULL; 4591222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x1d] = rsdForEach29; // in, usr, x, y 4601222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x1e] = rsdForEach30; // out, usr, x, y 4611222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines forEachLaunch[0x1f] = rsdForEach31; // in, out, usr, x, y 4621222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines} 46355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams 464