rsdCore.cpp revision 4ee16ffbd9d1d72e1757c9b26715597fdc044117
1bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams/*
24b3de47071d875faaa7d419d050a464b09538797Jason Sams * Copyright (C) 2011 The Android Open Source Project
3bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
4bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * you may not use this file except in compliance with the License.
6bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * You may obtain a copy of the License at
7bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
8bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
10bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Unless required by applicable law or agreed to in writing, software
11bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * See the License for the specific language governing permissions and
14bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * limitations under the License.
15bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams */
16bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
17bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdCore.h"
18eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdAllocation.h"
19bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdBcc.h"
204b3de47071d875faaa7d419d050a464b09538797Jason Sams#include "rsdGL.h"
218feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams#include "rsdProgramStore.h"
22721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams#include "rsdProgramRaster.h"
23a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramVertex.h"
24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramFragment.h"
25a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdMesh.h"
267f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk#include "rsdSampler.h"
27da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk#include "rsdFrameBuffer.h"
28bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
29bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <malloc.h>
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
31bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
32cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/types.h>
33cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/resource.h>
34cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sched.h>
35cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/properties.h>
36cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/sched_policy.h>
37cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/syscall.h>
38cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <string.h>
39b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk#include <bcc/bcc.h>
40cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
41bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android;
42bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android::renderscript;
43bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
44cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void Shutdown(Context *rsc);
45cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void SetPriority(const Context *rsc, int32_t priority);
463815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void initForEach(outer_foreach_t* forEachLaunch);
47cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
48bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstatic RsdHalFunctions FunctionTable = {
494b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLInit,
504b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLShutdown,
514b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSetSurface,
524b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSwap,
534b3de47071d875faaa7d419d050a464b09538797Jason Sams
54cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Shutdown,
55bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    NULL,
56cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    SetPriority,
57bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    {
58bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInit,
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
60bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
61cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
62bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
634ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines        rsdScriptInvokeFreeChildren,
64bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
65bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalBind,
66bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalObj,
67bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptDestroy
688feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    },
698feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
70eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    {
71eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationInit,
72eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationDestroy,
73eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationResize,
74eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationSyncAll,
75eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationMarkDirty,
76eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData1D,
77eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData2D,
78eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData3D,
7974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData1D_alloc,
8074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData2D_alloc,
8174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData3D_alloc,
82eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData1D,
83eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData2D
84eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    },
85eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
868feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
878feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    {
888feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreInit,
898feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreSetActive,
908feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreDestroy
91721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    },
92721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams
93721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    {
94721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterInit,
95721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterSetActive,
96721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterDestroy
97a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
98a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
99a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
100a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexInit,
101a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexSetActive,
102a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexDestroy
103a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
104a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
105a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
106a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentInit,
107a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentSetActive,
108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentDestroy
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
112a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshInit,
113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDraw,
114a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDestroy
1157f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1167f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk
1177f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    {
1187f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerInit,
1197f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerDestroy
1207f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1218feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
122da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    {
123da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferInit,
124da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferSetActive,
125da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferDestroy
126da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    },
127da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk
128bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
129bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
13083c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_key_t rsdgThreadTLSKey = 0;
13183c451a4ef4388e002482e383d488ca9b7b7600dJason Samsuint32_t rsdgThreadTLSKeyCount = 0;
13283c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
133bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
134cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
135cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
136cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
13787fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
138cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
139cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
140cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
141cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
142cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
143cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
144cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
145cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
146cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
14783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
14883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
14983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        LOGE("pthread_setspecific %i", status);
15083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
15183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
152cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
153cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
154cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
155cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
156cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
157cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
158cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
159cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
160cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
161cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
164cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
165cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
166cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
167cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
168cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
169cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
171cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
173cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
174cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
175cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
17687fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
178cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
181cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
184cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
185cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
186cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
187cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
188cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
189bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
190bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
191bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
19287fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
1932cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams    if (!dc) {
1942cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams        LOGE("Calloc for driver hal failed.");
195bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
196bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
197cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
198bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
19983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
20083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
20183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
20283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        if (status) {
20383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            LOGE("Failed to init thread tls key.");
20483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            pthread_mutex_unlock(&rsdgInitMutex);
20583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            return false;
20683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        }
20783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
20883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    rsdgThreadTLSKeyCount++;
20983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
21083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
2113815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    initForEach(dc->mForEachLaunch);
2123815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
21383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mContext = rsc;
21483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mScript = NULL;
21583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
21683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
21783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        LOGE("pthread_setspecific %i", status);
21883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
21983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
220cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
221cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
222cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
223cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (cpu < 2) cpu = 0;
224cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
225cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
226cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
227cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
228cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
229cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
230cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
231cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
232cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
233cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
234cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
235cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
236cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
237cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
238cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
239cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        LOGE("Failed to init thread attribute.");
240cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
241cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
242cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
243cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
244cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
245cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
246cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
247cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            LOGE("Created fewer than expected number of RS threads.");
248cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
249cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
250cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
251cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
252cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
253cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
254cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
255cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
256bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
257bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
258bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
259cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
260cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
26187fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
262cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
263cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
264cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
265cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
266cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
267cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
26887fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
269cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
270cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
271cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
273cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
274cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
275cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
276cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
277cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status;
278cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
279cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
280cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
281cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
282cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
28383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
28483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    // Global structure cleanup.
28583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
28683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    --rsdgThreadTLSKeyCount;
28783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
28883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        pthread_key_delete(rsdgThreadTLSKey);
28983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
29083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
29183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
292cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
293cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
2943815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach17(const void *vRoot,
2953815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
2963815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, uint32_t);
2973815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->y);
2983815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
2993815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3003815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach18(const void *vRoot,
3013815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3023815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(void *, uint32_t);
3033815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->out, p->y);
3043815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3053815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3063815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach19(const void *vRoot,
3073815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3083815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, void *, uint32_t);
3093815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->out, p->y);
3103815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3113815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3123815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach21(const void *vRoot,
3133815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3143815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, const void *, uint32_t);
3153815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->usr, p->y);
3163815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3173815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3183815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach22(const void *vRoot,
3193815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3203815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(void *, const void *, uint32_t);
3213815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->out, p->usr, p->y);
3223815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3233815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3243815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach23(const void *vRoot,
3253815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3263815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, void *, const void *, uint32_t);
3273815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->out, p->usr, p->y);
3283815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3293815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3303815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach25(const void *vRoot,
3313815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3323815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, uint32_t, uint32_t);
3333815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->x, p->y);
3343815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3353815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3363815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach26(const void *vRoot,
3373815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3383815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(void *, uint32_t, uint32_t);
3393815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->out, p->x, p->y);
3403815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3413815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3423815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach27(const void *vRoot,
3433815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3443815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, void *, uint32_t, uint32_t);
3453815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->out, p->x, p->y);
3463815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3473815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3483815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach29(const void *vRoot,
3493815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3503815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, const void *, uint32_t, uint32_t);
3513815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->usr, p->x, p->y);
3523815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3533815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3543815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach30(const void *vRoot,
3553815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3563815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(void *, const void *, uint32_t, uint32_t);
3573815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->out, p->usr, p->x, p->y);
3583815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3593815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3603815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void rsdForEach31(const void *vRoot,
3613815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        const android::renderscript::RsForEachStubParamStruct *p) {
3623815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    typedef void (*fe)(const void *, void *, const void *, uint32_t, uint32_t);
3633815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    (*(fe*)vRoot)(p->in, p->out, p->usr, p->x, p->y);
3643815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
3653815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3663815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
3673815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinesstatic void initForEach(outer_foreach_t* forEachLaunch) {
3683815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    rsAssert(forEachLaunch);
3693815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x00] = NULL;
3703815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x01] = rsdForEach31; // in
3713815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x02] = rsdForEach30; //     out
3723815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x03] = rsdForEach31; // in, out
3733815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x04] = NULL;
3743815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x05] = rsdForEach29;  // in,      usr
3753815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x06] = rsdForEach30; //     out, usr
3763815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x07] = rsdForEach31; // in, out, usr
3773815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x08] = NULL;
3783815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x09] = rsdForEach25; // in,           x
3793815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x0a] = rsdForEach26; //     out,      x
3803815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x0b] = rsdForEach27; // in, out,      x
3813815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x0c] = NULL;
3823815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x0d] = rsdForEach29; // in,      usr, x
3833815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x0e] = rsdForEach30; //     out, usr, x
3843815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x0f] = rsdForEach31; // in, out, usr, x
3853815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x10] = NULL;
3863815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x11] = rsdForEach17; // in               y
3873815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x12] = rsdForEach18; //     out,         y
3883815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x13] = rsdForEach19; // in, out,         y
3893815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x14] = NULL;
3903815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x15] = rsdForEach21; // in,      usr,    y
3913815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x16] = rsdForEach22; //     out, usr,    y
3923815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x17] = rsdForEach23; // in, out, usr,    y
3933815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x18] = NULL;
3943815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x19] = rsdForEach25; // in,           x, y
3953815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x1a] = rsdForEach26; //     out,      x, y
3963815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x1b] = rsdForEach27; // in, out,      x, y
3973815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x1c] = NULL;
3983815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x1d] = rsdForEach29; // in,      usr, x, y
3993815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x1e] = rsdForEach30; //     out, usr, x, y
4003815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    forEachLaunch[0x1f] = rsdForEach31; // in, out, usr, x, y
4013815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines}
402cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
403