Home | History | Annotate | Download | only in rs
      1 /*
      2  * Copyright (C) 2009 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 "rsDevice.h"
     18 #include "rsContext.h"
     19 #include "rsThreadIO.h"
     20 #include <ui/FramebufferNativeWindow.h>
     21 #include <ui/EGLUtils.h>
     22 #include <ui/egl/android_natives.h>
     23 
     24 #include <sys/types.h>
     25 #include <sys/resource.h>
     26 
     27 #include <cutils/properties.h>
     28 
     29 #include <GLES/gl.h>
     30 #include <GLES/glext.h>
     31 #include <GLES2/gl2.h>
     32 #include <GLES2/gl2ext.h>
     33 
     34 #include <cutils/sched_policy.h>
     35 
     36 using namespace android;
     37 using namespace android::renderscript;
     38 
     39 pthread_key_t Context::gThreadTLSKey = 0;
     40 uint32_t Context::gThreadTLSKeyCount = 0;
     41 uint32_t Context::gGLContextCount = 0;
     42 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
     43 
     44 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
     45     if (returnVal != EGL_TRUE) {
     46         fprintf(stderr, "%s() returned %d\n", op, returnVal);
     47     }
     48 
     49     for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
     50             = eglGetError()) {
     51         fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
     52                 error);
     53     }
     54 }
     55 
     56 void Context::initEGL(bool useGL2)
     57 {
     58     mEGL.mNumConfigs = -1;
     59     EGLint configAttribs[128];
     60     EGLint *configAttribsPtr = configAttribs;
     61     EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
     62 
     63     memset(configAttribs, 0, sizeof(configAttribs));
     64 
     65     configAttribsPtr[0] = EGL_SURFACE_TYPE;
     66     configAttribsPtr[1] = EGL_WINDOW_BIT;
     67     configAttribsPtr += 2;
     68 
     69     if (useGL2) {
     70         configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
     71         configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
     72         configAttribsPtr += 2;
     73     }
     74 
     75     if (mUseDepth) {
     76         configAttribsPtr[0] = EGL_DEPTH_SIZE;
     77         configAttribsPtr[1] = 16;
     78         configAttribsPtr += 2;
     79     }
     80 
     81     if (mDev->mForceSW) {
     82         configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
     83         configAttribsPtr[1] = EGL_SLOW_CONFIG;
     84         configAttribsPtr += 2;
     85     }
     86 
     87     configAttribsPtr[0] = EGL_NONE;
     88     rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
     89 
     90     LOGV("initEGL start");
     91     mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     92     checkEglError("eglGetDisplay");
     93 
     94     eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion);
     95     checkEglError("eglInitialize");
     96 
     97     status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig);
     98     if (err) {
     99        LOGE("couldn't find an EGLConfig matching the screen format\n");
    100     }
    101     //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
    102 
    103 
    104     if (useGL2) {
    105         mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2);
    106     } else {
    107         mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL);
    108     }
    109     checkEglError("eglCreateContext");
    110     if (mEGL.mContext == EGL_NO_CONTEXT) {
    111         LOGE("eglCreateContext returned EGL_NO_CONTEXT");
    112     }
    113     gGLContextCount++;
    114 }
    115 
    116 void Context::deinitEGL()
    117 {
    118     LOGV("deinitEGL");
    119     setSurface(0, 0, NULL);
    120     eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
    121     checkEglError("eglDestroyContext");
    122 
    123     gGLContextCount--;
    124     if (!gGLContextCount) {
    125         eglTerminate(mEGL.mDisplay);
    126     }
    127 }
    128 
    129 
    130 uint32_t Context::runScript(Script *s, uint32_t launchID)
    131 {
    132     ObjectBaseRef<ProgramFragment> frag(mFragment);
    133     ObjectBaseRef<ProgramVertex> vtx(mVertex);
    134     ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
    135     ObjectBaseRef<ProgramRaster> raster(mRaster);
    136 
    137     uint32_t ret = s->run(this, launchID);
    138 
    139     mFragment.set(frag);
    140     mVertex.set(vtx);
    141     mFragmentStore.set(store);
    142     mRaster.set(raster);
    143     return ret;
    144 }
    145 
    146 void Context::checkError(const char *msg) const
    147 {
    148     GLenum err = glGetError();
    149     if (err != GL_NO_ERROR) {
    150         LOGE("GL Error, 0x%x, from %s", err, msg);
    151     }
    152 }
    153 
    154 uint32_t Context::runRootScript()
    155 {
    156     timerSet(RS_TIMER_CLEAR_SWAP);
    157     rsAssert(mRootScript->mEnviroment.mIsRoot);
    158 
    159     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
    160     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
    161     glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
    162     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    163 
    164     glClearColor(mRootScript->mEnviroment.mClearColor[0],
    165                  mRootScript->mEnviroment.mClearColor[1],
    166                  mRootScript->mEnviroment.mClearColor[2],
    167                  mRootScript->mEnviroment.mClearColor[3]);
    168     if (mUseDepth) {
    169         glDepthMask(GL_TRUE);
    170         glClearDepthf(mRootScript->mEnviroment.mClearDepth);
    171         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    172     } else {
    173         glClear(GL_COLOR_BUFFER_BIT);
    174     }
    175 
    176     timerSet(RS_TIMER_SCRIPT);
    177     mStateFragmentStore.mLast.clear();
    178     uint32_t ret = runScript(mRootScript.get(), 0);
    179 
    180     checkError("runRootScript");
    181     if (mError != RS_ERROR_NONE) {
    182         // If we have an error condition we stop rendering until
    183         // somthing changes that might fix it.
    184         ret = 0;
    185     }
    186     return ret;
    187 }
    188 
    189 uint64_t Context::getTime() const
    190 {
    191     struct timespec t;
    192     clock_gettime(CLOCK_MONOTONIC, &t);
    193     return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
    194 }
    195 
    196 void Context::timerReset()
    197 {
    198     for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) {
    199         mTimers[ct] = 0;
    200     }
    201 }
    202 
    203 void Context::timerInit()
    204 {
    205     mTimeLast = getTime();
    206     mTimeFrame = mTimeLast;
    207     mTimeLastFrame = mTimeLast;
    208     mTimerActive = RS_TIMER_INTERNAL;
    209     timerReset();
    210 }
    211 
    212 void Context::timerFrame()
    213 {
    214     mTimeLastFrame = mTimeFrame;
    215     mTimeFrame = getTime();
    216 }
    217 
    218 void Context::timerSet(Timers tm)
    219 {
    220     uint64_t last = mTimeLast;
    221     mTimeLast = getTime();
    222     mTimers[mTimerActive] += mTimeLast - last;
    223     mTimerActive = tm;
    224 }
    225 
    226 void Context::timerPrint()
    227 {
    228     double total = 0;
    229     for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) {
    230         total += mTimers[ct];
    231     }
    232     uint64_t frame = mTimeFrame - mTimeLastFrame;
    233     mTimeMSLastFrame = frame / 1000000;
    234     mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000;
    235     mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000;
    236 
    237 
    238     if (props.mLogTimes) {
    239         LOGV("RS: Frame (%i),   Script %2.1f (%i),  Clear & Swap %2.1f (%i),  Idle %2.1f (%lli),  Internal %2.1f (%lli)",
    240              mTimeMSLastFrame,
    241              100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
    242              100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
    243              100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
    244              100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000);
    245     }
    246 }
    247 
    248 bool Context::setupCheck()
    249 {
    250     if (checkVersion2_0()) {
    251         if (!mShaderCache.lookup(this, mVertex.get(), mFragment.get())) {
    252             LOGE("Context::setupCheck() 1 fail");
    253             return false;
    254         }
    255 
    256         mFragmentStore->setupGL2(this, &mStateFragmentStore);
    257         mFragment->setupGL2(this, &mStateFragment, &mShaderCache);
    258         mRaster->setupGL2(this, &mStateRaster);
    259         mVertex->setupGL2(this, &mStateVertex, &mShaderCache);
    260 
    261     } else {
    262         mFragmentStore->setupGL(this, &mStateFragmentStore);
    263         mFragment->setupGL(this, &mStateFragment);
    264         mRaster->setupGL(this, &mStateRaster);
    265         mVertex->setupGL(this, &mStateVertex);
    266     }
    267     return true;
    268 }
    269 
    270 static bool getProp(const char *str)
    271 {
    272     char buf[PROPERTY_VALUE_MAX];
    273     property_get(str, buf, "0");
    274     return 0 != strcmp(buf, "0");
    275 }
    276 
    277 void * Context::threadProc(void *vrsc)
    278 {
    279      Context *rsc = static_cast<Context *>(vrsc);
    280      rsc->mNativeThreadId = gettid();
    281 
    282      setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
    283      rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
    284 
    285      rsc->props.mLogTimes = getProp("debug.rs.profile");
    286      rsc->props.mLogScripts = getProp("debug.rs.script");
    287      rsc->props.mLogObjects = getProp("debug.rs.object");
    288      rsc->props.mLogShaders = getProp("debug.rs.shader");
    289 
    290      ScriptTLSStruct *tlsStruct = new ScriptTLSStruct;
    291      if (!tlsStruct) {
    292          LOGE("Error allocating tls storage");
    293          return NULL;
    294      }
    295      tlsStruct->mContext = rsc;
    296      tlsStruct->mScript = NULL;
    297      int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct);
    298      if (status) {
    299          LOGE("pthread_setspecific %i", status);
    300      }
    301 
    302      if (rsc->mIsGraphicsContext) {
    303          rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
    304          rsc->setRaster(NULL);
    305          rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
    306          rsc->setVertex(NULL);
    307          rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
    308          rsc->setFragment(NULL);
    309          rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
    310          rsc->setFragmentStore(NULL);
    311          rsc->mStateVertexArray.init(rsc);
    312      }
    313 
    314      rsc->mRunning = true;
    315      bool mDraw = true;
    316      while (!rsc->mExit) {
    317          mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
    318          mDraw &= (rsc->mRootScript.get() != NULL);
    319          mDraw &= (rsc->mWndSurface != NULL);
    320 
    321          uint32_t targetTime = 0;
    322          if (mDraw && rsc->mIsGraphicsContext) {
    323              targetTime = rsc->runRootScript();
    324              mDraw = targetTime && !rsc->mPaused;
    325              rsc->timerSet(RS_TIMER_CLEAR_SWAP);
    326              eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
    327              rsc->timerFrame();
    328              rsc->timerSet(RS_TIMER_INTERNAL);
    329              rsc->timerPrint();
    330              rsc->timerReset();
    331          }
    332          if (rsc->mObjDestroy.mNeedToEmpty) {
    333              rsc->objDestroyOOBRun();
    334          }
    335          if (rsc->mThreadPriority > 0 && targetTime) {
    336              int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
    337              if (t > 0) {
    338                  usleep(t);
    339              }
    340          }
    341      }
    342 
    343      LOGV("RS Thread exiting");
    344      if (rsc->mIsGraphicsContext) {
    345          rsc->mRaster.clear();
    346          rsc->mFragment.clear();
    347          rsc->mVertex.clear();
    348          rsc->mFragmentStore.clear();
    349          rsc->mRootScript.clear();
    350          rsc->mStateRaster.deinit(rsc);
    351          rsc->mStateVertex.deinit(rsc);
    352          rsc->mStateFragment.deinit(rsc);
    353          rsc->mStateFragmentStore.deinit(rsc);
    354      }
    355      ObjectBase::zeroAllUserRef(rsc);
    356 
    357      rsc->mObjDestroy.mNeedToEmpty = true;
    358      rsc->objDestroyOOBRun();
    359 
    360      if (rsc->mIsGraphicsContext) {
    361          pthread_mutex_lock(&gInitMutex);
    362          rsc->deinitEGL();
    363          pthread_mutex_unlock(&gInitMutex);
    364      }
    365 
    366      LOGV("RS Thread exited");
    367      return NULL;
    368 }
    369 
    370 void Context::setPriority(int32_t p)
    371 {
    372     // Note: If we put this in the proper "background" policy
    373     // the wallpapers can become completly unresponsive at times.
    374     // This is probably not what we want for something the user is actively
    375     // looking at.
    376     mThreadPriority = p;
    377 #if 0
    378     SchedPolicy pol = SP_FOREGROUND;
    379     if (p > 0) {
    380         pol = SP_BACKGROUND;
    381     }
    382     if (!set_sched_policy(mNativeThreadId, pol)) {
    383         // success; reset the priority as well
    384     }
    385 #else
    386         setpriority(PRIO_PROCESS, mNativeThreadId, p);
    387 #endif
    388 }
    389 
    390 Context::Context(Device *dev, bool isGraphics, bool useDepth)
    391 {
    392     pthread_mutex_lock(&gInitMutex);
    393 
    394     dev->addContext(this);
    395     mDev = dev;
    396     mRunning = false;
    397     mExit = false;
    398     mUseDepth = useDepth;
    399     mPaused = false;
    400     mObjHead = NULL;
    401     mError = RS_ERROR_NONE;
    402     mErrorMsg = NULL;
    403 
    404     memset(&mEGL, 0, sizeof(mEGL));
    405     memset(&mGL, 0, sizeof(mGL));
    406     mIsGraphicsContext = isGraphics;
    407 
    408     int status;
    409     pthread_attr_t threadAttr;
    410 
    411     if (!gThreadTLSKeyCount) {
    412         status = pthread_key_create(&gThreadTLSKey, NULL);
    413         if (status) {
    414             LOGE("Failed to init thread tls key.");
    415             pthread_mutex_unlock(&gInitMutex);
    416             return;
    417         }
    418     }
    419     gThreadTLSKeyCount++;
    420     pthread_mutex_unlock(&gInitMutex);
    421 
    422     // Global init done at this point.
    423 
    424     status = pthread_attr_init(&threadAttr);
    425     if (status) {
    426         LOGE("Failed to init thread attribute.");
    427         return;
    428     }
    429 
    430     mWndSurface = NULL;
    431 
    432     objDestroyOOBInit();
    433     timerInit();
    434     timerSet(RS_TIMER_INTERNAL);
    435 
    436     LOGV("RS Launching thread");
    437     status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
    438     if (status) {
    439         LOGE("Failed to start rs context thread.");
    440     }
    441 
    442     while(!mRunning) {
    443         usleep(100);
    444     }
    445 
    446     pthread_attr_destroy(&threadAttr);
    447 }
    448 
    449 Context::~Context()
    450 {
    451     LOGV("Context::~Context");
    452     mExit = true;
    453     mPaused = false;
    454     void *res;
    455 
    456     mIO.shutdown();
    457     int status = pthread_join(mThreadId, &res);
    458     mObjDestroy.mNeedToEmpty = true;
    459     objDestroyOOBRun();
    460 
    461     // Global structure cleanup.
    462     pthread_mutex_lock(&gInitMutex);
    463     if (mDev) {
    464         mDev->removeContext(this);
    465         --gThreadTLSKeyCount;
    466         if (!gThreadTLSKeyCount) {
    467             pthread_key_delete(gThreadTLSKey);
    468         }
    469         mDev = NULL;
    470     }
    471     pthread_mutex_unlock(&gInitMutex);
    472 
    473     objDestroyOOBDestroy();
    474 }
    475 
    476 void Context::setSurface(uint32_t w, uint32_t h, android_native_window_t *sur)
    477 {
    478     rsAssert(mIsGraphicsContext);
    479 
    480     EGLBoolean ret;
    481     if (mEGL.mSurface != NULL) {
    482         ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    483         checkEglError("eglMakeCurrent", ret);
    484 
    485         ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
    486         checkEglError("eglDestroySurface", ret);
    487 
    488         mEGL.mSurface = NULL;
    489         mEGL.mWidth = 0;
    490         mEGL.mHeight = 0;
    491         mWidth = 0;
    492         mHeight = 0;
    493     }
    494 
    495     mWndSurface = sur;
    496     if (mWndSurface != NULL) {
    497         bool first = false;
    498         if (!mEGL.mContext) {
    499             first = true;
    500             pthread_mutex_lock(&gInitMutex);
    501             initEGL(true);
    502             pthread_mutex_unlock(&gInitMutex);
    503         }
    504 
    505         mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
    506         checkEglError("eglCreateWindowSurface");
    507         if (mEGL.mSurface == EGL_NO_SURFACE) {
    508             LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
    509         }
    510 
    511         ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
    512         checkEglError("eglMakeCurrent", ret);
    513 
    514         eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
    515         eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
    516         mWidth = w;
    517         mHeight = h;
    518         mStateVertex.updateSize(this, w, h);
    519 
    520         if ((int)mWidth != mEGL.mWidth || (int)mHeight != mEGL.mHeight) {
    521             LOGE("EGL/Surface mismatch  EGL (%i x %i)  SF (%i x %i)", mEGL.mWidth, mEGL.mHeight, mWidth, mHeight);
    522         }
    523 
    524         if (first) {
    525             mGL.mVersion = glGetString(GL_VERSION);
    526             mGL.mVendor = glGetString(GL_VENDOR);
    527             mGL.mRenderer = glGetString(GL_RENDERER);
    528             mGL.mExtensions = glGetString(GL_EXTENSIONS);
    529 
    530             //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
    531             LOGV("GL Version %s", mGL.mVersion);
    532             //LOGV("GL Vendor %s", mGL.mVendor);
    533             LOGV("GL Renderer %s", mGL.mRenderer);
    534             //LOGV("GL Extensions %s", mGL.mExtensions);
    535 
    536             const char *verptr = NULL;
    537             if (strlen((const char *)mGL.mVersion) > 9) {
    538                 if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) {
    539                     verptr = (const char *)mGL.mVersion + 12;
    540                 }
    541                 if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) {
    542                     verptr = (const char *)mGL.mVersion + 9;
    543                 }
    544             }
    545 
    546             if (!verptr) {
    547                 LOGE("Error, OpenGL ES Lite not supported");
    548             } else {
    549                 sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
    550             }
    551 
    552             glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs);
    553             glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors);
    554             glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits);
    555 
    556             glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors);
    557             glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits);
    558 
    559             glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits);
    560             glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors);
    561 
    562             mGL.OES_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_OES_texture_npot");
    563         }
    564 
    565     }
    566 }
    567 
    568 void Context::pause()
    569 {
    570     rsAssert(mIsGraphicsContext);
    571     mPaused = true;
    572 }
    573 
    574 void Context::resume()
    575 {
    576     rsAssert(mIsGraphicsContext);
    577     mPaused = false;
    578 }
    579 
    580 void Context::setRootScript(Script *s)
    581 {
    582     rsAssert(mIsGraphicsContext);
    583     mRootScript.set(s);
    584 }
    585 
    586 void Context::setFragmentStore(ProgramFragmentStore *pfs)
    587 {
    588     rsAssert(mIsGraphicsContext);
    589     if (pfs == NULL) {
    590         mFragmentStore.set(mStateFragmentStore.mDefault);
    591     } else {
    592         mFragmentStore.set(pfs);
    593     }
    594 }
    595 
    596 void Context::setFragment(ProgramFragment *pf)
    597 {
    598     rsAssert(mIsGraphicsContext);
    599     if (pf == NULL) {
    600         mFragment.set(mStateFragment.mDefault);
    601     } else {
    602         mFragment.set(pf);
    603     }
    604 }
    605 
    606 void Context::setRaster(ProgramRaster *pr)
    607 {
    608     rsAssert(mIsGraphicsContext);
    609     if (pr == NULL) {
    610         mRaster.set(mStateRaster.mDefault);
    611     } else {
    612         mRaster.set(pr);
    613     }
    614 }
    615 
    616 void Context::setVertex(ProgramVertex *pv)
    617 {
    618     rsAssert(mIsGraphicsContext);
    619     if (pv == NULL) {
    620         mVertex.set(mStateVertex.mDefault);
    621     } else {
    622         mVertex.set(pv);
    623     }
    624 }
    625 
    626 void Context::assignName(ObjectBase *obj, const char *name, uint32_t len)
    627 {
    628     rsAssert(!obj->getName());
    629     obj->setName(name, len);
    630     mNames.add(obj);
    631 }
    632 
    633 void Context::removeName(ObjectBase *obj)
    634 {
    635     for(size_t ct=0; ct < mNames.size(); ct++) {
    636         if (obj == mNames[ct]) {
    637             mNames.removeAt(ct);
    638             return;
    639         }
    640     }
    641 }
    642 
    643 ObjectBase * Context::lookupName(const char *name) const
    644 {
    645     for(size_t ct=0; ct < mNames.size(); ct++) {
    646         if (!strcmp(name, mNames[ct]->getName())) {
    647             return mNames[ct];
    648         }
    649     }
    650     return NULL;
    651 }
    652 
    653 void Context::appendNameDefines(String8 *str) const
    654 {
    655     char buf[256];
    656     for (size_t ct=0; ct < mNames.size(); ct++) {
    657         str->append("#define NAMED_");
    658         str->append(mNames[ct]->getName());
    659         str->append(" ");
    660         sprintf(buf, "%i\n", (int)mNames[ct]);
    661         str->append(buf);
    662     }
    663 }
    664 
    665 bool Context::objDestroyOOBInit()
    666 {
    667     int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL);
    668     if (status) {
    669         LOGE("Context::ObjDestroyOOBInit mutex init failure");
    670         return false;
    671     }
    672     return true;
    673 }
    674 
    675 void Context::objDestroyOOBRun()
    676 {
    677     if (mObjDestroy.mNeedToEmpty) {
    678         int status = pthread_mutex_lock(&mObjDestroy.mMutex);
    679         if (status) {
    680             LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
    681             return;
    682         }
    683 
    684         for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) {
    685             mObjDestroy.mDestroyList[ct]->decUserRef();
    686         }
    687         mObjDestroy.mDestroyList.clear();
    688         mObjDestroy.mNeedToEmpty = false;
    689 
    690         status = pthread_mutex_unlock(&mObjDestroy.mMutex);
    691         if (status) {
    692             LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
    693         }
    694     }
    695 }
    696 
    697 void Context::objDestroyOOBDestroy()
    698 {
    699     rsAssert(!mObjDestroy.mNeedToEmpty);
    700     pthread_mutex_destroy(&mObjDestroy.mMutex);
    701 }
    702 
    703 void Context::objDestroyAdd(ObjectBase *obj)
    704 {
    705     int status = pthread_mutex_lock(&mObjDestroy.mMutex);
    706     if (status) {
    707         LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
    708         return;
    709     }
    710 
    711     mObjDestroy.mNeedToEmpty = true;
    712     mObjDestroy.mDestroyList.add(obj);
    713 
    714     status = pthread_mutex_unlock(&mObjDestroy.mMutex);
    715     if (status) {
    716         LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
    717     }
    718 }
    719 
    720 uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait)
    721 {
    722     //LOGE("getMessageToClient %i %i", bufferLen, wait);
    723     if (!wait) {
    724         if (mIO.mToClient.isEmpty()) {
    725             // No message to get and not going to wait for one.
    726             receiveLen = 0;
    727             return 0;
    728         }
    729     }
    730 
    731     //LOGE("getMessageToClient 2 con=%p", this);
    732     uint32_t bytesData = 0;
    733     uint32_t commandID = 0;
    734     const void *d = mIO.mToClient.get(&commandID, &bytesData);
    735     //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
    736 
    737     *receiveLen = bytesData;
    738     if (bufferLen >= bytesData) {
    739         memcpy(data, d, bytesData);
    740         mIO.mToClient.next();
    741         return commandID;
    742     }
    743     return 0;
    744 }
    745 
    746 bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace)
    747 {
    748     //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace);
    749     if (cmdID == 0) {
    750         LOGE("Attempting to send invalid command 0 to client.");
    751         return false;
    752     }
    753     if (!waitForSpace) {
    754         if (mIO.mToClient.getFreeSpace() < len) {
    755             // Not enough room, and not waiting.
    756             return false;
    757         }
    758     }
    759     //LOGE("sendMessageToClient 2");
    760     void *p = mIO.mToClient.reserve(len);
    761     memcpy(p, data, len);
    762     mIO.mToClient.commit(cmdID, len);
    763     //LOGE("sendMessageToClient 3");
    764     return true;
    765 }
    766 
    767 void Context::initToClient()
    768 {
    769     while(!mRunning) {
    770         usleep(100);
    771     }
    772 }
    773 
    774 void Context::deinitToClient()
    775 {
    776     mIO.mToClient.shutdown();
    777 }
    778 
    779 const char * Context::getError(RsError *err)
    780 {
    781     *err = mError;
    782     mError = RS_ERROR_NONE;
    783     if (*err != RS_ERROR_NONE) {
    784         return mErrorMsg;
    785     }
    786     return NULL;
    787 }
    788 
    789 void Context::setError(RsError e, const char *msg)
    790 {
    791     mError = e;
    792     mErrorMsg = msg;
    793 }
    794 
    795 
    796 void Context::dumpDebug() const
    797 {
    798     LOGE("RS Context debug %p", this);
    799     LOGE("RS Context debug");
    800 
    801     LOGE(" EGL ver %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
    802     LOGE(" EGL context %p  surface %p,  w=%i h=%i  Display=%p", mEGL.mContext,
    803          mEGL.mSurface, mEGL.mWidth, mEGL.mHeight, mEGL.mDisplay);
    804     LOGE(" GL vendor: %s", mGL.mVendor);
    805     LOGE(" GL renderer: %s", mGL.mRenderer);
    806     LOGE(" GL Version: %s", mGL.mVersion);
    807     LOGE(" GL Extensions: %s", mGL.mExtensions);
    808     LOGE(" GL int Versions %i %i", mGL.mMajorVersion, mGL.mMinorVersion);
    809     LOGE(" RS width %i, height %i", mWidth, mHeight);
    810     LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused);
    811     LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId);
    812 
    813     LOGV("MAX Textures %i, %i  %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits);
    814     LOGV("MAX Attribs %i", mGL.mMaxVertexAttribs);
    815     LOGV("MAX Uniforms %i, %i", mGL.mMaxVertexUniformVectors, mGL.mMaxFragmentUniformVectors);
    816     LOGV("MAX Varyings %i", mGL.mMaxVaryingVectors);
    817 }
    818 
    819 ///////////////////////////////////////////////////////////////////////////////////////////
    820 //
    821 
    822 namespace android {
    823 namespace renderscript {
    824 
    825 
    826 void rsi_ContextBindRootScript(Context *rsc, RsScript vs)
    827 {
    828     Script *s = static_cast<Script *>(vs);
    829     rsc->setRootScript(s);
    830 }
    831 
    832 void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs)
    833 {
    834     Sampler *s = static_cast<Sampler *>(vs);
    835 
    836     if (slot > RS_MAX_SAMPLER_SLOT) {
    837         LOGE("Invalid sampler slot");
    838         return;
    839     }
    840 
    841     s->bindToContext(&rsc->mStateSampler, slot);
    842 }
    843 
    844 void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs)
    845 {
    846     ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs);
    847     rsc->setFragmentStore(pfs);
    848 }
    849 
    850 void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf)
    851 {
    852     ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
    853     rsc->setFragment(pf);
    854 }
    855 
    856 void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr)
    857 {
    858     ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
    859     rsc->setRaster(pr);
    860 }
    861 
    862 void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
    863 {
    864     ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
    865     rsc->setVertex(pv);
    866 }
    867 
    868 void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len)
    869 {
    870     ObjectBase *ob = static_cast<ObjectBase *>(obj);
    871     rsc->assignName(ob, name, len);
    872 }
    873 
    874 void rsi_ObjDestroy(Context *rsc, void *obj)
    875 {
    876     ObjectBase *ob = static_cast<ObjectBase *>(obj);
    877     rsc->removeName(ob);
    878     ob->decUserRef();
    879 }
    880 
    881 void rsi_ContextPause(Context *rsc)
    882 {
    883     rsc->pause();
    884 }
    885 
    886 void rsi_ContextResume(Context *rsc)
    887 {
    888     rsc->resume();
    889 }
    890 
    891 void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, android_native_window_t *sur)
    892 {
    893     rsc->setSurface(w, h, sur);
    894 }
    895 
    896 void rsi_ContextSetPriority(Context *rsc, int32_t p)
    897 {
    898     rsc->setPriority(p);
    899 }
    900 
    901 void rsi_ContextDump(Context *rsc, int32_t bits)
    902 {
    903     ObjectBase::dumpAll(rsc);
    904 }
    905 
    906 const char * rsi_ContextGetError(Context *rsc, RsError *e)
    907 {
    908     const char *msg = rsc->getError(e);
    909     if (*e != RS_ERROR_NONE) {
    910         LOGE("RS Error %i %s", *e, msg);
    911     }
    912     return msg;
    913 }
    914 
    915 }
    916 }
    917 
    918 
    919 RsContext rsContextCreate(RsDevice vdev, uint32_t version)
    920 {
    921     LOGV("rsContextCreate %p", vdev);
    922     Device * dev = static_cast<Device *>(vdev);
    923     Context *rsc = new Context(dev, false, false);
    924     return rsc;
    925 }
    926 
    927 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, bool useDepth)
    928 {
    929     LOGV("rsContextCreateGL %p, %i", vdev, useDepth);
    930     Device * dev = static_cast<Device *>(vdev);
    931     Context *rsc = new Context(dev, true, useDepth);
    932     return rsc;
    933 }
    934 
    935 void rsContextDestroy(RsContext vrsc)
    936 {
    937     Context * rsc = static_cast<Context *>(vrsc);
    938     delete rsc;
    939 }
    940 
    941 void rsObjDestroyOOB(RsContext vrsc, void *obj)
    942 {
    943     Context * rsc = static_cast<Context *>(vrsc);
    944     rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
    945 }
    946 
    947 uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait)
    948 {
    949     Context * rsc = static_cast<Context *>(vrsc);
    950     return rsc->getMessageToClient(data, receiveLen, bufferLen, wait);
    951 }
    952 
    953 void rsContextInitToClient(RsContext vrsc)
    954 {
    955     Context * rsc = static_cast<Context *>(vrsc);
    956     rsc->initToClient();
    957 }
    958 
    959 void rsContextDeinitToClient(RsContext vrsc)
    960 {
    961     Context * rsc = static_cast<Context *>(vrsc);
    962     rsc->deinitToClient();
    963 }
    964 
    965