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             mGL.GL_IMG_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_IMG_texture_npot");
    576         }
    577 
    578     }
    579 }
    580 
    581 void Context::pause()
    582 {
    583     rsAssert(mIsGraphicsContext);
    584     mPaused = true;
    585 }
    586 
    587 void Context::resume()
    588 {
    589     rsAssert(mIsGraphicsContext);
    590     mPaused = false;
    591 }
    592 
    593 void Context::setRootScript(Script *s)
    594 {
    595     rsAssert(mIsGraphicsContext);
    596     mRootScript.set(s);
    597 }
    598 
    599 void Context::setFragmentStore(ProgramFragmentStore *pfs)
    600 {
    601     rsAssert(mIsGraphicsContext);
    602     if (pfs == NULL) {
    603         mFragmentStore.set(mStateFragmentStore.mDefault);
    604     } else {
    605         mFragmentStore.set(pfs);
    606     }
    607 }
    608 
    609 void Context::setFragment(ProgramFragment *pf)
    610 {
    611     rsAssert(mIsGraphicsContext);
    612     if (pf == NULL) {
    613         mFragment.set(mStateFragment.mDefault);
    614     } else {
    615         mFragment.set(pf);
    616     }
    617 }
    618 
    619 void Context::setRaster(ProgramRaster *pr)
    620 {
    621     rsAssert(mIsGraphicsContext);
    622     if (pr == NULL) {
    623         mRaster.set(mStateRaster.mDefault);
    624     } else {
    625         mRaster.set(pr);
    626     }
    627 }
    628 
    629 void Context::setVertex(ProgramVertex *pv)
    630 {
    631     rsAssert(mIsGraphicsContext);
    632     if (pv == NULL) {
    633         mVertex.set(mStateVertex.mDefault);
    634     } else {
    635         mVertex.set(pv);
    636     }
    637 }
    638 
    639 void Context::assignName(ObjectBase *obj, const char *name, uint32_t len)
    640 {
    641     rsAssert(!obj->getName());
    642     obj->setName(name, len);
    643     mNames.add(obj);
    644 }
    645 
    646 void Context::removeName(ObjectBase *obj)
    647 {
    648     for(size_t ct=0; ct < mNames.size(); ct++) {
    649         if (obj == mNames[ct]) {
    650             mNames.removeAt(ct);
    651             return;
    652         }
    653     }
    654 }
    655 
    656 ObjectBase * Context::lookupName(const char *name) const
    657 {
    658     for(size_t ct=0; ct < mNames.size(); ct++) {
    659         if (!strcmp(name, mNames[ct]->getName())) {
    660             return mNames[ct];
    661         }
    662     }
    663     return NULL;
    664 }
    665 
    666 void Context::appendNameDefines(String8 *str) const
    667 {
    668     char buf[256];
    669     for (size_t ct=0; ct < mNames.size(); ct++) {
    670         str->append("#define NAMED_");
    671         str->append(mNames[ct]->getName());
    672         str->append(" ");
    673         sprintf(buf, "%i\n", (int)mNames[ct]);
    674         str->append(buf);
    675     }
    676 }
    677 
    678 bool Context::objDestroyOOBInit()
    679 {
    680     int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL);
    681     if (status) {
    682         LOGE("Context::ObjDestroyOOBInit mutex init failure");
    683         return false;
    684     }
    685     return true;
    686 }
    687 
    688 void Context::objDestroyOOBRun()
    689 {
    690     if (mObjDestroy.mNeedToEmpty) {
    691         int status = pthread_mutex_lock(&mObjDestroy.mMutex);
    692         if (status) {
    693             LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
    694             return;
    695         }
    696 
    697         for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) {
    698             mObjDestroy.mDestroyList[ct]->decUserRef();
    699         }
    700         mObjDestroy.mDestroyList.clear();
    701         mObjDestroy.mNeedToEmpty = false;
    702 
    703         status = pthread_mutex_unlock(&mObjDestroy.mMutex);
    704         if (status) {
    705             LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
    706         }
    707     }
    708 }
    709 
    710 void Context::objDestroyOOBDestroy()
    711 {
    712     rsAssert(!mObjDestroy.mNeedToEmpty);
    713     pthread_mutex_destroy(&mObjDestroy.mMutex);
    714 }
    715 
    716 void Context::objDestroyAdd(ObjectBase *obj)
    717 {
    718     int status = pthread_mutex_lock(&mObjDestroy.mMutex);
    719     if (status) {
    720         LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
    721         return;
    722     }
    723 
    724     mObjDestroy.mNeedToEmpty = true;
    725     mObjDestroy.mDestroyList.add(obj);
    726 
    727     status = pthread_mutex_unlock(&mObjDestroy.mMutex);
    728     if (status) {
    729         LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
    730     }
    731 }
    732 
    733 uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait)
    734 {
    735     //LOGE("getMessageToClient %i %i", bufferLen, wait);
    736     if (!wait) {
    737         if (mIO.mToClient.isEmpty()) {
    738             // No message to get and not going to wait for one.
    739             receiveLen = 0;
    740             return 0;
    741         }
    742     }
    743 
    744     //LOGE("getMessageToClient 2 con=%p", this);
    745     uint32_t bytesData = 0;
    746     uint32_t commandID = 0;
    747     const void *d = mIO.mToClient.get(&commandID, &bytesData);
    748     //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
    749 
    750     *receiveLen = bytesData;
    751     if (bufferLen >= bytesData) {
    752         memcpy(data, d, bytesData);
    753         mIO.mToClient.next();
    754         return commandID;
    755     }
    756     return 0;
    757 }
    758 
    759 bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace)
    760 {
    761     //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace);
    762     if (cmdID == 0) {
    763         LOGE("Attempting to send invalid command 0 to client.");
    764         return false;
    765     }
    766     if (!waitForSpace) {
    767         if (mIO.mToClient.getFreeSpace() < len) {
    768             // Not enough room, and not waiting.
    769             return false;
    770         }
    771     }
    772     //LOGE("sendMessageToClient 2");
    773     void *p = mIO.mToClient.reserve(len);
    774     memcpy(p, data, len);
    775     mIO.mToClient.commit(cmdID, len);
    776     //LOGE("sendMessageToClient 3");
    777     return true;
    778 }
    779 
    780 void Context::initToClient()
    781 {
    782     while(!mRunning) {
    783         usleep(100);
    784     }
    785 }
    786 
    787 void Context::deinitToClient()
    788 {
    789     mIO.mToClient.shutdown();
    790 }
    791 
    792 const char * Context::getError(RsError *err)
    793 {
    794     *err = mError;
    795     mError = RS_ERROR_NONE;
    796     if (*err != RS_ERROR_NONE) {
    797         return mErrorMsg;
    798     }
    799     return NULL;
    800 }
    801 
    802 void Context::setError(RsError e, const char *msg)
    803 {
    804     mError = e;
    805     mErrorMsg = msg;
    806 }
    807 
    808 
    809 void Context::dumpDebug() const
    810 {
    811     LOGE("RS Context debug %p", this);
    812     LOGE("RS Context debug");
    813 
    814     LOGE(" EGL ver %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
    815     LOGE(" EGL context %p  surface %p,  w=%i h=%i  Display=%p", mEGL.mContext,
    816          mEGL.mSurface, mEGL.mWidth, mEGL.mHeight, mEGL.mDisplay);
    817     LOGE(" GL vendor: %s", mGL.mVendor);
    818     LOGE(" GL renderer: %s", mGL.mRenderer);
    819     LOGE(" GL Version: %s", mGL.mVersion);
    820     LOGE(" GL Extensions: %s", mGL.mExtensions);
    821     LOGE(" GL int Versions %i %i", mGL.mMajorVersion, mGL.mMinorVersion);
    822     LOGE(" RS width %i, height %i", mWidth, mHeight);
    823     LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused);
    824     LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId);
    825 
    826     LOGV("MAX Textures %i, %i  %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits);
    827     LOGV("MAX Attribs %i", mGL.mMaxVertexAttribs);
    828     LOGV("MAX Uniforms %i, %i", mGL.mMaxVertexUniformVectors, mGL.mMaxFragmentUniformVectors);
    829     LOGV("MAX Varyings %i", mGL.mMaxVaryingVectors);
    830 }
    831 
    832 ///////////////////////////////////////////////////////////////////////////////////////////
    833 //
    834 
    835 namespace android {
    836 namespace renderscript {
    837 
    838 
    839 void rsi_ContextBindRootScript(Context *rsc, RsScript vs)
    840 {
    841     Script *s = static_cast<Script *>(vs);
    842     rsc->setRootScript(s);
    843 }
    844 
    845 void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs)
    846 {
    847     Sampler *s = static_cast<Sampler *>(vs);
    848 
    849     if (slot > RS_MAX_SAMPLER_SLOT) {
    850         LOGE("Invalid sampler slot");
    851         return;
    852     }
    853 
    854     s->bindToContext(&rsc->mStateSampler, slot);
    855 }
    856 
    857 void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs)
    858 {
    859     ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs);
    860     rsc->setFragmentStore(pfs);
    861 }
    862 
    863 void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf)
    864 {
    865     ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
    866     rsc->setFragment(pf);
    867 }
    868 
    869 void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr)
    870 {
    871     ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
    872     rsc->setRaster(pr);
    873 }
    874 
    875 void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
    876 {
    877     ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
    878     rsc->setVertex(pv);
    879 }
    880 
    881 void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len)
    882 {
    883     ObjectBase *ob = static_cast<ObjectBase *>(obj);
    884     rsc->assignName(ob, name, len);
    885 }
    886 
    887 void rsi_ObjDestroy(Context *rsc, void *obj)
    888 {
    889     ObjectBase *ob = static_cast<ObjectBase *>(obj);
    890     rsc->removeName(ob);
    891     ob->decUserRef();
    892 }
    893 
    894 void rsi_ContextPause(Context *rsc)
    895 {
    896     rsc->pause();
    897 }
    898 
    899 void rsi_ContextResume(Context *rsc)
    900 {
    901     rsc->resume();
    902 }
    903 
    904 void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, ANativeWindow *sur)
    905 {
    906     rsc->setSurface(w, h, sur);
    907 }
    908 
    909 void rsi_ContextSetPriority(Context *rsc, int32_t p)
    910 {
    911     rsc->setPriority(p);
    912 }
    913 
    914 void rsi_ContextDump(Context *rsc, int32_t bits)
    915 {
    916     ObjectBase::dumpAll(rsc);
    917 }
    918 
    919 const char * rsi_ContextGetError(Context *rsc, RsError *e)
    920 {
    921     const char *msg = rsc->getError(e);
    922     if (*e != RS_ERROR_NONE) {
    923         LOGE("RS Error %i %s", *e, msg);
    924     }
    925     return msg;
    926 }
    927 
    928 }
    929 }
    930 
    931 
    932 RsContext rsContextCreate(RsDevice vdev, uint32_t version)
    933 {
    934     LOGV("rsContextCreate %p", vdev);
    935     Device * dev = static_cast<Device *>(vdev);
    936     Context *rsc = new Context(dev, false, false);
    937     return rsc;
    938 }
    939 
    940 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, bool useDepth)
    941 {
    942     LOGV("rsContextCreateGL %p, %i", vdev, useDepth);
    943     Device * dev = static_cast<Device *>(vdev);
    944     Context *rsc = new Context(dev, true, useDepth);
    945     return rsc;
    946 }
    947 
    948 void rsContextDestroy(RsContext vrsc)
    949 {
    950     Context * rsc = static_cast<Context *>(vrsc);
    951     delete rsc;
    952 }
    953 
    954 void rsObjDestroyOOB(RsContext vrsc, void *obj)
    955 {
    956     Context * rsc = static_cast<Context *>(vrsc);
    957     rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
    958 }
    959 
    960 uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait)
    961 {
    962     Context * rsc = static_cast<Context *>(vrsc);
    963     return rsc->getMessageToClient(data, receiveLen, bufferLen, wait);
    964 }
    965 
    966 void rsContextInitToClient(RsContext vrsc)
    967 {
    968     Context * rsc = static_cast<Context *>(vrsc);
    969     rsc->initToClient();
    970 }
    971 
    972 void rsContextDeinitToClient(RsContext vrsc)
    973 {
    974     Context * rsc = static_cast<Context *>(vrsc);
    975     rsc->deinitToClient();
    976 }
    977 
    978