rsdCore.cpp revision 70415115431f3c52e1da44ba838962ff3b22eb69
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2011 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian#include "rsdCore.h" 18d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian#include "rsdAllocation.h" 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdBcc.h" 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdGL.h" 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdProgramStore.h" 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdProgramRaster.h" 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdProgramVertex.h" 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdProgramFragment.h" 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "rsdMesh.h" 26076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include "rsdSampler.h" 27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include "rsdFrameBuffer.h" 288630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 298630320433bd15aca239522e54e711ef6372ab07Mathias Agopian#include <malloc.h> 308630320433bd15aca239522e54e711ef6372ab07Mathias Agopian#include "rsContext.h" 311b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 321f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include <sys/types.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/resource.h> 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sched.h> 35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <cutils/properties.h> 363e87601170141229d661df93e2f59e1ced73474bMathias Agopian#include <cutils/sched_policy.h> 378630320433bd15aca239522e54e711ef6372ab07Mathias Agopian#include <sys/syscall.h> 388630320433bd15aca239522e54e711ef6372ab07Mathias Agopian#include <string.h> 39a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include <bcc/bcc.h> 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianusing namespace android; 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android::renderscript; 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianstatic void Shutdown(Context *rsc); 4587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianstatic void SetPriority(const Context *rsc, int32_t priority); 4687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianstatic void initForEach(outer_foreach_t* forEachLaunch); 4787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 4887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianstatic RsdHalFunctions FunctionTable = { 4987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian rsdGLInit, 503eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian rsdGLShutdown, 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdGLSetSurface, 5287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian rsdGLSwap, 5387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Shutdown, 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project NULL, 560f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian SetPriority, 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 58a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdScriptInit, 59a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdScriptInvokeFunction, 60a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdScriptInvokeRoot, 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdScriptInvokeForEach, 62d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdScriptInvokeInit, 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdScriptInvokeFreeChildren, 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdScriptSetGlobalVar, 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdScriptSetGlobalBind, 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdScriptSetGlobalObj, 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdScriptDestroy 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }, 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdAllocationInit, 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdAllocationDestroy, 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdAllocationResize, 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdAllocationSyncAll, 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdAllocationMarkDirty, 7682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian rsdAllocationData1D, 77c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian rsdAllocationData2D, 783eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian rsdAllocationData3D, 79a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdAllocationData1D_alloc, 803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian rsdAllocationData2D_alloc, 813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian rsdAllocationData3D_alloc, 823b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian rsdAllocationElementData1D, 833b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian rsdAllocationElementData2D 843b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian }, 851b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 871b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian { 8887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian rsdProgramStoreInit, 8987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian rsdProgramStoreSetActive, 9074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian rsdProgramStoreDestroy 9174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian }, 929c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian 931b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian { 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdProgramRasterInit, 959c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian rsdProgramRasterSetActive, 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdProgramRasterDestroy 970f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian }, 9852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 99d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian { 100d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdProgramVertexInit, 101d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdProgramVertexSetActive, 102d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdProgramVertexDestroy 103d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian }, 104d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 105d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian { 106d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdProgramFragmentInit, 107d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdProgramFragmentSetActive, 108d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdProgramFragmentDestroy 109d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian }, 110d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 111d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian { 112d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdMeshInit, 113d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdMeshDraw, 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsdMeshDestroy 115a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }, 116a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 117a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian { 118a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdSamplerInit, 119a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdSamplerDestroy 120c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian }, 121a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 122d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian { 123a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdFrameBufferInit, 124a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian rsdFrameBufferSetActive, 125d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian rsdFrameBufferDestroy 126a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian }, 127a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 128a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}; 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpthread_key_t rsdgThreadTLSKey = 0; 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t rsdgThreadTLSKeyCount = 0; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER; 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void * HelperThreadProc(void *vrsc) { 1361b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian Context *rsc = static_cast<Context *>(vrsc); 1371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian RsdHal *dc = (RsdHal *)rsc->mHal.drv; 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount); 141d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 14203e407270c7ad76632f982c886d0776bed9e9b4cMathias Agopian //LOGV("RS helperThread starting %p idx=%i", rsc, idx); 143a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 144a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian dc->mWorkers.mLaunchSignals[idx].init(); 145a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian dc->mWorkers.mNativeThreadId[idx] = gettid(); 146a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 147d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct); 1483b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian if (status) { 1493b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian LOGE("pthread_setspecific %i", status); 150d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian } 1513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1523b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian#if 0 1533b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t; 154d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian cpu_set_t cpuset; 155d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian memset(&cpuset, 0, sizeof(cpuset)); 156d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian cpuset.bits[idx / 64] |= 1ULL << (idx % 64); 157a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx], 158d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian sizeof(cpuset), &cpuset); 159d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret)); 160d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian#endif 1611b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian 1621b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian while (!dc->mExit) { 16398a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian dc->mWorkers.mLaunchSignals[idx].wait(); 16498a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian if (dc->mWorkers.mLaunchCallback) { 16587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx); 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_dec(&dc->mWorkers.mRunningCount); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dc->mWorkers.mCompleteSignal.set(); 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 170d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 171 //LOGV("RS helperThread exited %p idx=%i", rsc, idx); 172 return NULL; 173} 174 175void rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) { 176 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 177 178 dc->mWorkers.mLaunchData = data; 179 dc->mWorkers.mLaunchCallback = cbk; 180 android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount); 181 for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) { 182 dc->mWorkers.mLaunchSignals[ct].set(); 183 } 184 while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) { 185 dc->mWorkers.mCompleteSignal.wait(); 186 } 187} 188 189bool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) { 190 rsc->mHal.funcs = FunctionTable; 191 192 RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal)); 193 if (!dc) { 194 LOGE("Calloc for driver hal failed."); 195 return false; 196 } 197 rsc->mHal.drv = dc; 198 199 pthread_mutex_lock(&rsdgInitMutex); 200 if (!rsdgThreadTLSKeyCount) { 201 int status = pthread_key_create(&rsdgThreadTLSKey, NULL); 202 if (status) { 203 LOGE("Failed to init thread tls key."); 204 pthread_mutex_unlock(&rsdgInitMutex); 205 return false; 206 } 207 } 208 rsdgThreadTLSKeyCount++; 209 pthread_mutex_unlock(&rsdgInitMutex); 210 211 initForEach(dc->mForEachLaunch); 212 213 dc->mTlsStruct.mContext = rsc; 214 dc->mTlsStruct.mScript = NULL; 215 int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct); 216 if (status) { 217 LOGE("pthread_setspecific %i", status); 218 } 219 220 221 int cpu = sysconf(_SC_NPROCESSORS_ONLN); 222 LOGV("%p Launching thread(s), CPUs %i", rsc, cpu); 223 if (cpu < 2) cpu = 0; 224 225 dc->mWorkers.mCount = (uint32_t)cpu; 226 dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t)); 227 dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t)); 228 dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount]; 229 dc->mWorkers.mLaunchCallback = NULL; 230 231 dc->mWorkers.mCompleteSignal.init(); 232 233 android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount); 234 android_atomic_release_store(0, &dc->mWorkers.mLaunchCount); 235 236 pthread_attr_t threadAttr; 237 status = pthread_attr_init(&threadAttr); 238 if (status) { 239 LOGE("Failed to init thread attribute."); 240 return false; 241 } 242 243 for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) { 244 status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc); 245 if (status) { 246 dc->mWorkers.mCount = ct; 247 LOGE("Created fewer than expected number of RS threads."); 248 break; 249 } 250 } 251 while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) { 252 usleep(100); 253 } 254 255 pthread_attr_destroy(&threadAttr); 256 return true; 257} 258 259 260void SetPriority(const Context *rsc, int32_t priority) { 261 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 262 for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) { 263 setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority); 264 } 265} 266 267void Shutdown(Context *rsc) { 268 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 269 270 dc->mExit = true; 271 dc->mWorkers.mLaunchData = NULL; 272 dc->mWorkers.mLaunchCallback = NULL; 273 android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount); 274 for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) { 275 dc->mWorkers.mLaunchSignals[ct].set(); 276 } 277 int status; 278 void *res; 279 for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) { 280 status = pthread_join(dc->mWorkers.mThreadId[ct], &res); 281 } 282 rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0); 283 284 // Global structure cleanup. 285 pthread_mutex_lock(&rsdgInitMutex); 286 --rsdgThreadTLSKeyCount; 287 if (!rsdgThreadTLSKeyCount) { 288 pthread_key_delete(rsdgThreadTLSKey); 289 } 290 pthread_mutex_unlock(&rsdgInitMutex); 291 292} 293 294static void rsdForEach17(const void *vRoot, 295 const android::renderscript::RsForEachStubParamStruct *p, 296 uint32_t x1, uint32_t x2, 297 uint32_t instep, uint32_t outstep) { 298 typedef void (*fe)(const void *, uint32_t); 299 (*(fe*)vRoot)(p->in, p->y); 300} 301 302static void rsdForEach18(const void *vRoot, 303 const android::renderscript::RsForEachStubParamStruct *p, 304 uint32_t x1, uint32_t x2, 305 uint32_t instep, uint32_t outstep) { 306 typedef void (*fe)(void *, uint32_t); 307 (*(fe*)vRoot)(p->out, p->y); 308} 309 310static void rsdForEach19(const void *vRoot, 311 const android::renderscript::RsForEachStubParamStruct *p, 312 uint32_t x1, uint32_t x2, 313 uint32_t instep, uint32_t outstep) { 314 typedef void (*fe)(const void *, void *, uint32_t); 315 (*(fe*)vRoot)(p->in, p->out, p->y); 316} 317 318static void rsdForEach21(const void *vRoot, 319 const android::renderscript::RsForEachStubParamStruct *p, 320 uint32_t x1, uint32_t x2, 321 uint32_t instep, uint32_t outstep) { 322 typedef void (*fe)(const void *, const void *, uint32_t); 323 (*(fe*)vRoot)(p->in, p->usr, p->y); 324} 325 326static void rsdForEach22(const void *vRoot, 327 const android::renderscript::RsForEachStubParamStruct *p, 328 uint32_t x1, uint32_t x2, 329 uint32_t instep, uint32_t outstep) { 330 typedef void (*fe)(void *, const void *, uint32_t); 331 (*(fe*)vRoot)(p->out, p->usr, p->y); 332} 333 334static void rsdForEach23(const void *vRoot, 335 const android::renderscript::RsForEachStubParamStruct *p, 336 uint32_t x1, uint32_t x2, 337 uint32_t instep, uint32_t outstep) { 338 typedef void (*fe)(const void *, void *, const void *, uint32_t); 339 (*(fe*)vRoot)(p->in, p->out, p->usr, p->y); 340} 341 342static void rsdForEach25(const void *vRoot, 343 const android::renderscript::RsForEachStubParamStruct *p, 344 uint32_t x1, uint32_t x2, 345 uint32_t instep, uint32_t outstep) { 346 typedef void (*fe)(const void *, uint32_t, uint32_t); 347 const uint8_t *pin = (const uint8_t *)p->in; 348 uint32_t y = p->y; 349 for (uint32_t x = x1; x < x2; x++) { 350 (*(fe*)vRoot)(pin, x, y); 351 pin += instep; 352 } 353} 354 355static void rsdForEach26(const void *vRoot, 356 const android::renderscript::RsForEachStubParamStruct *p, 357 uint32_t x1, uint32_t x2, 358 uint32_t instep, uint32_t outstep) { 359 typedef void (*fe)(void *, uint32_t, uint32_t); 360 uint8_t *pout = (uint8_t *)p->out; 361 uint32_t y = p->y; 362 for (uint32_t x = x1; x < x2; x++) { 363 (*(fe*)vRoot)(pout, x, y); 364 pout += outstep; 365 } 366} 367 368static void rsdForEach27(const void *vRoot, 369 const android::renderscript::RsForEachStubParamStruct *p, 370 uint32_t x1, uint32_t x2, 371 uint32_t instep, uint32_t outstep) { 372 typedef void (*fe)(const void *, void *, uint32_t, uint32_t); 373 uint8_t *pout = (uint8_t *)p->out; 374 const uint8_t *pin = (const uint8_t *)p->in; 375 uint32_t y = p->y; 376 for (uint32_t x = x1; x < x2; x++) { 377 (*(fe*)vRoot)(pin, pout, x, y); 378 pin += instep; 379 pout += outstep; 380 } 381} 382 383static void rsdForEach29(const void *vRoot, 384 const android::renderscript::RsForEachStubParamStruct *p, 385 uint32_t x1, uint32_t x2, 386 uint32_t instep, uint32_t outstep) { 387 typedef void (*fe)(const void *, const void *, uint32_t, uint32_t); 388 const uint8_t *pin = (const uint8_t *)p->in; 389 const void *usr = p->usr; 390 const uint32_t y = p->y; 391 for (uint32_t x = x1; x < x2; x++) { 392 (*(fe*)vRoot)(pin, usr, x, y); 393 pin += instep; 394 } 395} 396 397static void rsdForEach30(const void *vRoot, 398 const android::renderscript::RsForEachStubParamStruct *p, 399 uint32_t x1, uint32_t x2, 400 uint32_t instep, uint32_t outstep) { 401 typedef void (*fe)(void *, const void *, uint32_t, uint32_t); 402 uint8_t *pout = (uint8_t *)p->out; 403 const void *usr = p->usr; 404 const uint32_t y = p->y; 405 for (uint32_t x = x1; x < x2; x++) { 406 (*(fe*)vRoot)(pout, usr, x, y); 407 pout += outstep; 408 } 409} 410 411static void rsdForEach31(const void *vRoot, 412 const android::renderscript::RsForEachStubParamStruct *p, 413 uint32_t x1, uint32_t x2, 414 uint32_t instep, uint32_t outstep) { 415 typedef void (*fe)(const void *, void *, const void *, uint32_t, uint32_t); 416 uint8_t *pout = (uint8_t *)p->out; 417 const uint8_t *pin = (const uint8_t *)p->in; 418 const void *usr = p->usr; 419 const uint32_t y = p->y; 420 for (uint32_t x = x1; x < x2; x++) { 421 (*(fe*)vRoot)(pin, pout, usr, x, y); 422 pin += instep; 423 pout += outstep; 424 } 425} 426 427 428static void initForEach(outer_foreach_t* forEachLaunch) { 429 rsAssert(forEachLaunch); 430 forEachLaunch[0x00] = NULL; 431 forEachLaunch[0x01] = rsdForEach31; // in 432 forEachLaunch[0x02] = rsdForEach30; // out 433 forEachLaunch[0x03] = rsdForEach31; // in, out 434 forEachLaunch[0x04] = NULL; 435 forEachLaunch[0x05] = rsdForEach29; // in, usr 436 forEachLaunch[0x06] = rsdForEach30; // out, usr 437 forEachLaunch[0x07] = rsdForEach31; // in, out, usr 438 forEachLaunch[0x08] = NULL; 439 forEachLaunch[0x09] = rsdForEach25; // in, x 440 forEachLaunch[0x0a] = rsdForEach26; // out, x 441 forEachLaunch[0x0b] = rsdForEach27; // in, out, x 442 forEachLaunch[0x0c] = NULL; 443 forEachLaunch[0x0d] = rsdForEach29; // in, usr, x 444 forEachLaunch[0x0e] = rsdForEach30; // out, usr, x 445 forEachLaunch[0x0f] = rsdForEach31; // in, out, usr, x 446 forEachLaunch[0x10] = NULL; 447 forEachLaunch[0x11] = rsdForEach17; // in y 448 forEachLaunch[0x12] = rsdForEach18; // out, y 449 forEachLaunch[0x13] = rsdForEach19; // in, out, y 450 forEachLaunch[0x14] = NULL; 451 forEachLaunch[0x15] = rsdForEach21; // in, usr, y 452 forEachLaunch[0x16] = rsdForEach22; // out, usr, y 453 forEachLaunch[0x17] = rsdForEach23; // in, out, usr, y 454 forEachLaunch[0x18] = NULL; 455 forEachLaunch[0x19] = rsdForEach25; // in, x, y 456 forEachLaunch[0x1a] = rsdForEach26; // out, x, y 457 forEachLaunch[0x1b] = rsdForEach27; // in, out, x, y 458 forEachLaunch[0x1c] = NULL; 459 forEachLaunch[0x1d] = rsdForEach29; // in, usr, x, y 460 forEachLaunch[0x1e] = rsdForEach30; // out, usr, x, y 461 forEachLaunch[0x1f] = rsdForEach31; // in, out, usr, x, y 462} 463 464