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"
28dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams#include "rsdScriptGroup.h"
29da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk#include "rsdFrameBuffer.h"
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
31bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <malloc.h>
32bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
33bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
34cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/types.h>
35cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/resource.h>
36cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sched.h>
37cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/properties.h>
38cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/syscall.h>
39cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <string.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);
46cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
47bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstatic RsdHalFunctions FunctionTable = {
484b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLInit,
494b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLShutdown,
504b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSetSurface,
514b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSwap,
524b3de47071d875faaa7d419d050a464b09538797Jason Sams
53cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Shutdown,
54bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    NULL,
55cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    SetPriority,
56bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    {
57bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInit,
588eaba4fee0c7b5325742c87187622fdff51d5effJason Sams        rsdInitIntrinsic,
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
60bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
61cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
62bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
634ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines        rsdScriptInvokeFreeChildren,
64bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
652980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        rsdScriptSetGlobalVarWithElemDims,
66bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalBind,
67bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalObj,
68bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptDestroy
698feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    },
708feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
71eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    {
72eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationInit,
73eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationDestroy,
74eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationResize,
75eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationSyncAll,
76eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationMarkDirty,
7741e373d91a60043afa0f9abd026218b49cbc1201Jason Sams        rsdAllocationInitSurfaceTexture,
787ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationSetSurfaceTexture,
797ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationIoSend,
807ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationIoReceive,
81eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData1D,
82eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData2D,
83eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData3D,
84807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationRead1D,
85807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationRead2D,
86807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationRead3D,
87807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationLock1D,
88807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        rsdAllocationUnlock1D,
8974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData1D_alloc,
9074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData2D_alloc,
9174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData3D_alloc,
92eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData1D,
9361a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsdAllocationElementData2D,
9461a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsdAllocationGenerateMipmaps
95eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    },
96eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
978feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
988feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    {
998feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreInit,
1008feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreSetActive,
1018feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreDestroy
102721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    },
103721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams
104721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    {
105721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterInit,
106721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterSetActive,
107721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterDestroy
108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexInit,
112a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexSetActive,
113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexDestroy
114a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
115a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
116a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
117a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentInit,
118a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentSetActive,
119a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentDestroy
120a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
121a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
122a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
123a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshInit,
124a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDraw,
125a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDestroy
1267f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1277f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk
1287f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    {
1299e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathInitStatic,
1309e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathInitDynamic,
1319e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathDraw,
1329e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathDestroy
1339e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams    },
1349e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams
1359e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams    {
1367f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerInit,
1377f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerDestroy
1387f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1398feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
140da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    {
141da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferInit,
142da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferSetActive,
143da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferDestroy
144da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    },
145da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk
146dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams    {
147dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams        rsdScriptGroupInit,
148dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams        rsdScriptGroupSetInput,
149dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams        rsdScriptGroupSetOutput,
150dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams        rsdScriptGroupExecute,
151dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams        rsdScriptGroupDestroy
152dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams    }
153dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams
154dbe66d6783c1e53cd1572de0ef6ef6fdf6f76f48Jason Sams
155bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
156bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
15783c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_key_t rsdgThreadTLSKey = 0;
15883c451a4ef4388e002482e383d488ca9b7b7600dJason Samsuint32_t rsdgThreadTLSKeyCount = 0;
15983c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
160bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
161cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
16487fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
165cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
166cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
167cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
168cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
1696598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("RS helperThread starting %p idx=%i", rsc, idx);
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
171cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
173cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
17483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
17583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
176af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("pthread_setspecific %i", status);
17783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
17883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
181cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
184cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
185cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
186af12ac6a08651464f8d823add667c706f993b587Steve Block    ALOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
187cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
188cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
189cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
190cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
191cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
192c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams            // idx +1 is used because the calling thread is always worker 0.
193c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams            dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx+1);
194cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
195cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
196cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
197cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
198cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
1996598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("RS helperThread exited %p idx=%i", rsc, idx);
200cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
201cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
202cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
203cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
20487fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
205cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
206cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
207cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
208cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
209cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
210cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
211cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
212c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams
213c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams    // We use the calling thread as one of the workers so we can start without
214c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams    // the delay of the thread wakeup.
215c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams    if (dc->mWorkers.mLaunchCallback) {
216c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams       dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, 0);
217c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams    }
218c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams
219cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
220cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
221cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
222cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
223cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
224414a46166126da6864258bd25ff183f9a3c6261dStephen Hinesextern "C" bool rsdHalInit(RsContext c, uint32_t version_major,
225414a46166126da6864258bd25ff183f9a3c6261dStephen Hines                           uint32_t version_minor) {
226414a46166126da6864258bd25ff183f9a3c6261dStephen Hines    Context *rsc = (Context*) c;
227bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
228bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
22987fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
2302cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams    if (!dc) {
231af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Calloc for driver hal failed.");
232bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
233bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
234cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
235bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
23683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
23783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
23883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
23983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        if (status) {
240af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("Failed to init thread tls key.");
24183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            pthread_mutex_unlock(&rsdgInitMutex);
24283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            return false;
24383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        }
24483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
24583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    rsdgThreadTLSKeyCount++;
24683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
24783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
24883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mContext = rsc;
24983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mScript = NULL;
25083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
25183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
252af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("pthread_setspecific %i", status);
25383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
25483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
255cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
256cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
257abd6d04992e4b7c903ed2c1278d744e73ac74334Jason Sams    if(rsc->props.mDebugMaxThreads) {
258d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams        cpu = rsc->props.mDebugMaxThreads;
259d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    }
260d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    if (cpu < 2) {
261cef5fe99666296748cd274eb71a04b573b031393Stephen Hines        dc->mWorkers.mCount = 0;
262cef5fe99666296748cd274eb71a04b573b031393Stephen Hines        return true;
263d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    }
2643522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
265cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
266c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams    // Subtract one from the cpu count because we also use the command thread as a worker.
267c5b34c6ff0f1c2a25c45af932e1d7a7b494a34b0Jason Sams    dc->mWorkers.mCount = (uint32_t)(cpu - 1);
268cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
269cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
270cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
271cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
273cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
274cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
275cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
276cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
277cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
278cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
279cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
280cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
281af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Failed to init thread attribute.");
282cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
283cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
284cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
285cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
286cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
287cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
288cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
289af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("Created fewer than expected number of RS threads.");
290cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
291cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
292cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
293cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
294cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
295cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
296cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
297cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
298bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
299bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
300bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
301cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
302cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
30387fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
304cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
305cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
306cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
3079719bd4a0187c400ba868712612fe66da4635aacJason Sams    if (dc->mHasGraphics) {
3089719bd4a0187c400ba868712612fe66da4635aacJason Sams        rsdGLSetPriority(rsc, priority);
3099719bd4a0187c400ba868712612fe66da4635aacJason Sams    }
310cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
311cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
312cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
31387fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
314cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
315cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
316cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
317cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
318cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
319cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
320cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
321cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
322cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
323cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
324d2d868f98f235a0b6cecda7cbdef36c7d5c3d4afJean-Baptiste Queru        pthread_join(dc->mWorkers.mThreadId[ct], &res);
325cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
326cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
32783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
32883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    // Global structure cleanup.
32983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
33083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    --rsdgThreadTLSKeyCount;
33183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
33283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        pthread_key_delete(rsdgThreadTLSKey);
33383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
33483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
33583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
336cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
337cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
338