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