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