rsdCore.cpp revision 414a46166126da6864258bd25ff183f9a3c6261d
1bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams/*
2ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines * Copyright (C) 2011-2012 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"
219e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams#include "rsdPath.h"
228feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams#include "rsdProgramStore.h"
23721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams#include "rsdProgramRaster.h"
24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramVertex.h"
25a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramFragment.h"
26a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdMesh.h"
277f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk#include "rsdSampler.h"
28da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk#include "rsdFrameBuffer.h"
29bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <malloc.h>
31bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
32bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
33cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/types.h>
34cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/resource.h>
35cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sched.h>
36cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/properties.h>
37cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/syscall.h>
38cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <string.h>
39cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
40bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android;
41bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android::renderscript;
42bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
43cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void Shutdown(Context *rsc);
44cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void SetPriority(const Context *rsc, int32_t priority);
45cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
46bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstatic RsdHalFunctions FunctionTable = {
474b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLInit,
484b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLShutdown,
494b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSetSurface,
504b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSwap,
514b3de47071d875faaa7d419d050a464b09538797Jason Sams
52cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Shutdown,
53bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    NULL,
54cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    SetPriority,
55bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    {
56bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInit,
578eaba4fee0c7b5325742c87187622fdff51d5effJason Sams        rsdInitIntrinsic,
58bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
60cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
61bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
624ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines        rsdScriptInvokeFreeChildren,
63bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
642980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        rsdScriptSetGlobalVarWithElemDims,
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,
7641e373d91a60043afa0f9abd026218b49cbc1201Jason Sams        rsdAllocationInitSurfaceTexture,
777ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationSetSurfaceTexture,
787ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationIoSend,
797ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationIoReceive,
80eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData1D,
81eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData2D,
82eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData3D,
83807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationRead1D,
84807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationRead2D,
85807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationRead3D,
86807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationLock1D,
87807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationUnlock1D,
8874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData1D_alloc,
8974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData2D_alloc,
9074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData3D_alloc,
91eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData1D,
9261a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsdAllocationElementData2D,
9361a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsdAllocationGenerateMipmaps
94eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    },
95eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
968feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
978feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    {
988feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreInit,
998feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreSetActive,
1008feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreDestroy
101721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    },
102721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams
103721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    {
104721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterInit,
105721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterSetActive,
106721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterDestroy
107a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexInit,
111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexSetActive,
112a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexDestroy
113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
114a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
115a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
116a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentInit,
117a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentSetActive,
118a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentDestroy
119a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
120a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
121a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
122a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshInit,
123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDraw,
124a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDestroy
1257f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1267f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk
1277f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    {
1289e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathInitStatic,
1299e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathInitDynamic,
1309e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathDraw,
1319e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathDestroy
1329e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams    },
1339e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams
1349e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams    {
1357f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerInit,
1367f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerDestroy
1377f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1388feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
139da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    {
140da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferInit,
141da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferSetActive,
142da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferDestroy
143da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    },
144da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk
145bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
146bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
14783c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_key_t rsdgThreadTLSKey = 0;
14883c451a4ef4388e002482e383d488ca9b7b7600dJason Samsuint32_t rsdgThreadTLSKeyCount = 0;
14983c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
150bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
151cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
152cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
153cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
15487fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
155cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
156cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
157cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
158cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
1596598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("RS helperThread starting %p idx=%i", rsc, idx);
160cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
161cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
16483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
16583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
166af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("pthread_setspecific %i", status);
16783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
16883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
169cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
171cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
173cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
174cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
175cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
176af12ac6a08651464f8d823add667c706f993b587Steve Block    ALOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
178cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
181cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
184cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
185cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
186cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
187cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
1886598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("RS helperThread exited %p idx=%i", rsc, idx);
189cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
190cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
191cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
192cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
19387fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
194cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
195cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
196cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
197cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
198cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
199cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
200cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
201cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
202cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
203cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
204cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
205cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
206414a46166126da6864258bd25ff183f9a3c6261dStephen Hinesextern "C" bool rsdHalInit(RsContext c, uint32_t version_major,
207414a46166126da6864258bd25ff183f9a3c6261dStephen Hines                           uint32_t version_minor) {
208414a46166126da6864258bd25ff183f9a3c6261dStephen Hines    Context *rsc = (Context*) c;
209bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
210bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
21187fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
2122cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams    if (!dc) {
213af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Calloc for driver hal failed.");
214bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
215bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
216cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
217bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
21883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
21983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
22083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
22183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        if (status) {
222af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("Failed to init thread tls key.");
22383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            pthread_mutex_unlock(&rsdgInitMutex);
22483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            return false;
22583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        }
22683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
22783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    rsdgThreadTLSKeyCount++;
22883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
22983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
23083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mContext = rsc;
23183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mScript = NULL;
23283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
23383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
234af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("pthread_setspecific %i", status);
23583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
23683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
237cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
238cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
239abd6d04992e4b7c903ed2c1278d744e73ac74334Jason Sams    if(rsc->props.mDebugMaxThreads) {
240d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams        cpu = rsc->props.mDebugMaxThreads;
241d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    }
242d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    if (cpu < 2) {
243d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams        cpu = 0;
244d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    }
2453522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
246cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
247cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
248cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
249cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
250cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
251cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
252cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
253cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
254cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
255cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
256cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
257cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
258cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
259cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
260cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
261af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Failed to init thread attribute.");
262cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
263cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
264cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
265cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
266cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
267cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
268cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
269af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("Created fewer than expected number of RS threads.");
270cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
271cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
273cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
274cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
275cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
276cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
277cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
278bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
279bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
280bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
281cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
282cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
28387fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
284cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
285cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
286cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
2879719bd4a0187c400ba868712612fe66da4635aacJason Sams    if (dc->mHasGraphics) {
2889719bd4a0187c400ba868712612fe66da4635aacJason Sams        rsdGLSetPriority(rsc, priority);
2899719bd4a0187c400ba868712612fe66da4635aacJason Sams    }
290cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
291cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
292cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
29387fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
294cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
295cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
296cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
297cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
298cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
299cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
300cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
301cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
302cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
303cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
304d2d868f98f235a0b6cecda7cbdef36c7d5c3d4afJean-Baptiste Queru        pthread_join(dc->mWorkers.mThreadId[ct], &res);
305cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
306cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
30783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
30883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    // Global structure cleanup.
30983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
31083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    --rsdgThreadTLSKeyCount;
31183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
31283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        pthread_key_delete(rsdgThreadTLSKey);
31383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
31483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
31583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
316cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
317cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
318