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