rsdCore.cpp revision d1f7da6803a1bfc0bf8129a66316cfb8994e7110
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>
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);
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,
58bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
60cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
61bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
624ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines        rsdScriptInvokeFreeChildren,
63bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
64bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalBind,
65bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalObj,
66bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptDestroy
678feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    },
688feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
69eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    {
70eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationInit,
71eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationDestroy,
72eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationResize,
73eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationSyncAll,
74eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationMarkDirty,
7541e373d91a60043afa0f9abd026218b49cbc1201Jason Sams        rsdAllocationInitSurfaceTexture,
767ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationSetSurfaceTexture,
777ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationIoSend,
787ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        rsdAllocationIoReceive,
79eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData1D,
80eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData2D,
81eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData3D,
8274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData1D_alloc,
8374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData2D_alloc,
8474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk        rsdAllocationData3D_alloc,
85eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData1D,
86eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData2D
87eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    },
88eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
898feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
908feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    {
918feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreInit,
928feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreSetActive,
938feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreDestroy
94721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    },
95721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams
96721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    {
97721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterInit,
98721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterSetActive,
99721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterDestroy
100a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
101a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
102a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
103a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexInit,
104a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexSetActive,
105a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexDestroy
106a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
107a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentInit,
110a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentSetActive,
111a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentDestroy
112a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
113a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
114a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
115a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshInit,
116a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDraw,
117a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDestroy
1187f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1197f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk
1207f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    {
1219e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathInitStatic,
1229e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathInitDynamic,
1239e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathDraw,
1249e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams        rsdPathDestroy
1259e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams    },
1269e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams
1279e0afb5a2b3e476c42a373e7cd89cef4a34f8195Jason Sams    {
1287f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerInit,
1297f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerDestroy
1307f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1318feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
132da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    {
133da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferInit,
134da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferSetActive,
135da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferDestroy
136da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    },
137da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk
138bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
139bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
14083c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_key_t rsdgThreadTLSKey = 0;
14183c451a4ef4388e002482e383d488ca9b7b7600dJason Samsuint32_t rsdgThreadTLSKeyCount = 0;
14283c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
143bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
144cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
145cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
146cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
14787fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
148cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
149cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
150cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
151cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
1526598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("RS helperThread starting %p idx=%i", rsc, idx);
153cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
154cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
155cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
156cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
15783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
15883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
159af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("pthread_setspecific %i", status);
16083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
16183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
164cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
165cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
166cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
167cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
168cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
169af12ac6a08651464f8d823add667c706f993b587Steve Block    ALOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
171cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
173cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
174cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
175cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
176cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
178cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
1816598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    //ALOGV("RS helperThread exited %p idx=%i", rsc, idx);
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
184cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
185cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
18687fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
187cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
188cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
189cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
190cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
191cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
192cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
193cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
194cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
195cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
196cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
197cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
198cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
199bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
200bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
201bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
20287fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
2032cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams    if (!dc) {
204af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Calloc for driver hal failed.");
205bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
206bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
207cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
208bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
20983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
21083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
21183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
21283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        if (status) {
213af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("Failed to init thread tls key.");
21483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            pthread_mutex_unlock(&rsdgInitMutex);
21583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            return false;
21683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        }
21783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
21883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    rsdgThreadTLSKeyCount++;
21983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
22083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
22183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mContext = rsc;
22283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mScript = NULL;
22383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
22483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
225af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("pthread_setspecific %i", status);
22683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
22783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
228cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
229cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
2306598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
231d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    if(rsc->props.mDebugMaxThreads && (cpu > (int)rsc->props.mDebugMaxThreads)) {
232d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams        cpu = rsc->props.mDebugMaxThreads;
233d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    }
234d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    if (cpu < 2) {
235d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams        cpu = 0;
236d1f7da6803a1bfc0bf8129a66316cfb8994e7110Jason Sams    }
237cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
238cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
239cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
240cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
241cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
242cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
243cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
244cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
245cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
246cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
247cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
248cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
249cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
250cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
251cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
252af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Failed to init thread attribute.");
253cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
254cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
255cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
256cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
257cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
258cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
259cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
260af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("Created fewer than expected number of RS threads.");
261cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
262cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
263cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
264cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
265cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
266cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
267cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
268cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
269bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
270bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
271bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
273cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
27487fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
275cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
276cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
277cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
2789719bd4a0187c400ba868712612fe66da4635aacJason Sams    if (dc->mHasGraphics) {
2799719bd4a0187c400ba868712612fe66da4635aacJason Sams        rsdGLSetPriority(rsc, priority);
2809719bd4a0187c400ba868712612fe66da4635aacJason Sams    }
281cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
282cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
283cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
28487fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
285cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
286cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
287cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
288cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
289cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
290cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
291cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
292cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
293cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status;
294cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
295cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
296cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
297cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
298cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
29983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
30083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    // Global structure cleanup.
30183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
30283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    --rsdgThreadTLSKeyCount;
30383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
30483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        pthread_key_delete(rsdgThreadTLSKey);
30583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
30683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
30783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
308cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
309cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
310