• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "rsDevice.h"
18 #include "rsContext.h"
19 #include "rsThreadIO.h"
20 #include <ui/FramebufferNativeWindow.h>
21 
22 #include <sys/types.h>
23 #include <sys/resource.h>
24 #include <sched.h>
25 
26 #include <cutils/properties.h>
27 
28 #include <cutils/sched_policy.h>
29 #include <sys/syscall.h>
30 #include <string.h>
31 
32 using namespace android;
33 using namespace android::renderscript;
34 
35 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
36 pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER;
37 
initGLThread()38 bool Context::initGLThread() {
39     pthread_mutex_lock(&gInitMutex);
40 
41     if (!mHal.funcs.initGraphics(this)) {
42         pthread_mutex_unlock(&gInitMutex);
43         LOGE("%p initGraphics failed", this);
44         return false;
45     }
46 
47     pthread_mutex_unlock(&gInitMutex);
48     return true;
49 }
50 
deinitEGL()51 void Context::deinitEGL() {
52     mHal.funcs.shutdownGraphics(this);
53 }
54 
PushState(Context * con)55 Context::PushState::PushState(Context *con) {
56     mRsc = con;
57     if (con->mIsGraphicsContext) {
58         mFragment.set(con->getProgramFragment());
59         mVertex.set(con->getProgramVertex());
60         mStore.set(con->getProgramStore());
61         mRaster.set(con->getProgramRaster());
62         mFont.set(con->getFont());
63     }
64 }
65 
~PushState()66 Context::PushState::~PushState() {
67     if (mRsc->mIsGraphicsContext) {
68         mRsc->setProgramFragment(mFragment.get());
69         mRsc->setProgramVertex(mVertex.get());
70         mRsc->setProgramStore(mStore.get());
71         mRsc->setProgramRaster(mRaster.get());
72         mRsc->setFont(mFont.get());
73     }
74 }
75 
76 
runScript(Script * s)77 uint32_t Context::runScript(Script *s) {
78     PushState(this);
79 
80     uint32_t ret = s->run(this);
81     return ret;
82 }
83 
runRootScript()84 uint32_t Context::runRootScript() {
85     timerSet(RS_TIMER_SCRIPT);
86     mStateFragmentStore.mLast.clear();
87     watchdog.inRoot = true;
88     uint32_t ret = runScript(mRootScript.get());
89     watchdog.inRoot = false;
90 
91     return ret;
92 }
93 
getTime() const94 uint64_t Context::getTime() const {
95 #ifndef ANDROID_RS_SERIALIZE
96     struct timespec t;
97     clock_gettime(CLOCK_MONOTONIC, &t);
98     return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
99 #else
100     return 0;
101 #endif //ANDROID_RS_SERIALIZE
102 }
103 
timerReset()104 void Context::timerReset() {
105     for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) {
106         mTimers[ct] = 0;
107     }
108 }
109 
timerInit()110 void Context::timerInit() {
111     mTimeLast = getTime();
112     mTimeFrame = mTimeLast;
113     mTimeLastFrame = mTimeLast;
114     mTimerActive = RS_TIMER_INTERNAL;
115     mAverageFPSFrameCount = 0;
116     mAverageFPSStartTime = mTimeLast;
117     mAverageFPS = 0;
118     timerReset();
119 }
120 
timerFrame()121 void Context::timerFrame() {
122     mTimeLastFrame = mTimeFrame;
123     mTimeFrame = getTime();
124     // Update average fps
125     const uint64_t averageFramerateInterval = 1000 * 1000000;
126     mAverageFPSFrameCount ++;
127     uint64_t inverval = mTimeFrame - mAverageFPSStartTime;
128     if (inverval >= averageFramerateInterval) {
129         inverval = inverval / 1000000;
130         mAverageFPS = (mAverageFPSFrameCount * 1000) / inverval;
131         mAverageFPSFrameCount = 0;
132         mAverageFPSStartTime = mTimeFrame;
133     }
134 }
135 
timerSet(Timers tm)136 void Context::timerSet(Timers tm) {
137     uint64_t last = mTimeLast;
138     mTimeLast = getTime();
139     mTimers[mTimerActive] += mTimeLast - last;
140     mTimerActive = tm;
141 }
142 
timerPrint()143 void Context::timerPrint() {
144     double total = 0;
145     for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) {
146         total += mTimers[ct];
147     }
148     uint64_t frame = mTimeFrame - mTimeLastFrame;
149     mTimeMSLastFrame = frame / 1000000;
150     mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000;
151     mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000;
152 
153 
154     if (props.mLogTimes) {
155         LOGV("RS: Frame (%i),   Script %2.1f%% (%i),  Swap %2.1f%% (%i),  Idle %2.1f%% (%lli),  Internal %2.1f%% (%lli), Avg fps: %u",
156              mTimeMSLastFrame,
157              100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
158              100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
159              100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
160              100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000,
161              mAverageFPS);
162     }
163 }
164 
setupCheck()165 bool Context::setupCheck() {
166 
167     mFragmentStore->setup(this, &mStateFragmentStore);
168     mFragment->setup(this, &mStateFragment);
169     mRaster->setup(this, &mStateRaster);
170     mVertex->setup(this, &mStateVertex);
171     mFBOCache.setup(this);
172     return true;
173 }
174 
setupProgramStore()175 void Context::setupProgramStore() {
176     mFragmentStore->setup(this, &mStateFragmentStore);
177 }
178 
getProp(const char * str)179 static bool getProp(const char *str) {
180     char buf[PROPERTY_VALUE_MAX];
181     property_get(str, buf, "0");
182     return 0 != strcmp(buf, "0");
183 }
184 
displayDebugStats()185 void Context::displayDebugStats() {
186     char buffer[128];
187     sprintf(buffer, "Avg fps %u, Frame %i ms, Script %i ms", mAverageFPS, mTimeMSLastFrame, mTimeMSLastScript);
188     float oldR, oldG, oldB, oldA;
189     mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
190     uint32_t bufferLen = strlen(buffer);
191 
192     ObjectBaseRef<Font> lastFont(getFont());
193     setFont(NULL);
194     float shadowCol = 0.1f;
195     mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
196     mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6);
197 
198     mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
199     mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7);
200 
201     setFont(lastFont.get());
202     mStateFont.setFontColor(oldR, oldG, oldB, oldA);
203 }
204 
threadProc(void * vrsc)205 void * Context::threadProc(void *vrsc) {
206     Context *rsc = static_cast<Context *>(vrsc);
207 #ifndef ANDROID_RS_SERIALIZE
208     rsc->mNativeThreadId = gettid();
209     setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
210     rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
211 #endif //ANDROID_RS_SERIALIZE
212     rsc->props.mLogTimes = getProp("debug.rs.profile");
213     rsc->props.mLogScripts = getProp("debug.rs.script");
214     rsc->props.mLogObjects = getProp("debug.rs.object");
215     rsc->props.mLogShaders = getProp("debug.rs.shader");
216     rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes");
217     rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms");
218     rsc->props.mLogVisual = getProp("debug.rs.visual");
219 
220     if (!rsdHalInit(rsc, 0, 0)) {
221         rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed initializing GL");
222         LOGE("Hal init failed");
223         return NULL;
224     }
225     rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);
226 
227     if (rsc->mIsGraphicsContext) {
228         if (!rsc->initGLThread()) {
229             rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
230             return NULL;
231         }
232 
233         rsc->mStateRaster.init(rsc);
234         rsc->setProgramRaster(NULL);
235         rsc->mStateVertex.init(rsc);
236         rsc->setProgramVertex(NULL);
237         rsc->mStateFragment.init(rsc);
238         rsc->setProgramFragment(NULL);
239         rsc->mStateFragmentStore.init(rsc);
240         rsc->setProgramStore(NULL);
241         rsc->mStateFont.init(rsc);
242         rsc->setFont(NULL);
243         rsc->mStateSampler.init(rsc);
244         rsc->mFBOCache.init(rsc);
245     }
246 
247     rsc->mRunning = true;
248     bool mDraw = true;
249     bool doWait = true;
250 
251     uint64_t targetTime = rsc->getTime();
252     while (!rsc->mExit) {
253         uint64_t waitTime = 0;
254         uint64_t now = rsc->getTime();
255         if (!doWait) {
256             if (now < targetTime) {
257                 waitTime = targetTime - now;
258                 doWait = true;
259             }
260         }
261 
262         mDraw |= rsc->mIO.playCoreCommands(rsc, doWait, waitTime);
263         mDraw &= (rsc->mRootScript.get() != NULL);
264         mDraw &= rsc->mHasSurface;
265 
266         if (mDraw && rsc->mIsGraphicsContext) {
267             uint64_t delay = rsc->runRootScript() * 1000000;
268             targetTime = rsc->getTime() + delay;
269             doWait = (delay == 0);
270 
271             if (rsc->props.mLogVisual) {
272                 rsc->displayDebugStats();
273             }
274 
275             mDraw = !rsc->mPaused;
276             rsc->timerSet(RS_TIMER_CLEAR_SWAP);
277             rsc->mHal.funcs.swap(rsc);
278             rsc->timerFrame();
279             rsc->timerSet(RS_TIMER_INTERNAL);
280             rsc->timerPrint();
281             rsc->timerReset();
282         } else {
283             doWait = true;
284         }
285     }
286 
287     LOGV("%p RS Thread exiting", rsc);
288 
289     if (rsc->mIsGraphicsContext) {
290         pthread_mutex_lock(&gInitMutex);
291         rsc->deinitEGL();
292         pthread_mutex_unlock(&gInitMutex);
293     }
294 
295     LOGV("%p RS Thread exited", rsc);
296     return NULL;
297 }
298 
destroyWorkerThreadResources()299 void Context::destroyWorkerThreadResources() {
300     //LOGV("destroyWorkerThreadResources 1");
301     ObjectBase::zeroAllUserRef(this);
302     if (mIsGraphicsContext) {
303          mRaster.clear();
304          mFragment.clear();
305          mVertex.clear();
306          mFragmentStore.clear();
307          mFont.clear();
308          mRootScript.clear();
309          mStateRaster.deinit(this);
310          mStateVertex.deinit(this);
311          mStateFragment.deinit(this);
312          mStateFragmentStore.deinit(this);
313          mStateFont.deinit(this);
314          mStateSampler.deinit(this);
315          mFBOCache.deinit(this);
316     }
317     ObjectBase::freeAllChildren(this);
318     //LOGV("destroyWorkerThreadResources 2");
319     mExit = true;
320 }
321 
printWatchdogInfo(void * ctx)322 void Context::printWatchdogInfo(void *ctx) {
323     Context *rsc = (Context *)ctx;
324     if (rsc->watchdog.command && rsc->watchdog.file) {
325         LOGE("RS watchdog timeout: %i  %s  line %i %s", rsc->watchdog.inRoot,
326              rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
327     } else {
328         LOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot);
329     }
330 }
331 
332 
setPriority(int32_t p)333 void Context::setPriority(int32_t p) {
334     // Note: If we put this in the proper "background" policy
335     // the wallpapers can become completly unresponsive at times.
336     // This is probably not what we want for something the user is actively
337     // looking at.
338     mThreadPriority = p;
339 #if 0
340     SchedPolicy pol = SP_FOREGROUND;
341     if (p > 0) {
342         pol = SP_BACKGROUND;
343     }
344     if (!set_sched_policy(mNativeThreadId, pol)) {
345         // success; reset the priority as well
346     }
347 #else
348     setpriority(PRIO_PROCESS, mNativeThreadId, p);
349 #endif
350 }
351 
Context()352 Context::Context() {
353     mDev = NULL;
354     mRunning = false;
355     mExit = false;
356     mPaused = false;
357     mObjHead = NULL;
358     mError = RS_ERROR_NONE;
359     mTargetSdkVersion = 14;
360     mDPI = 96;
361     mIsContextLite = false;
362 }
363 
createContext(Device * dev,const RsSurfaceConfig * sc)364 Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc) {
365     Context * rsc = new Context();
366 
367     if (!rsc->initContext(dev, sc)) {
368         delete rsc;
369         return NULL;
370     }
371     return rsc;
372 }
373 
createContextLite()374 Context * Context::createContextLite() {
375     Context * rsc = new Context();
376     rsc->mIsContextLite = true;
377     return rsc;
378 }
379 
initContext(Device * dev,const RsSurfaceConfig * sc)380 bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
381     pthread_mutex_lock(&gInitMutex);
382 
383     mIO.init();
384     mIO.setTimoutCallback(printWatchdogInfo, this, 2e9);
385 
386     dev->addContext(this);
387     mDev = dev;
388     if (sc) {
389         mUserSurfaceConfig = *sc;
390     } else {
391         memset(&mUserSurfaceConfig, 0, sizeof(mUserSurfaceConfig));
392     }
393 
394     mIsGraphicsContext = sc != NULL;
395 
396     int status;
397     pthread_attr_t threadAttr;
398 
399     pthread_mutex_unlock(&gInitMutex);
400 
401     // Global init done at this point.
402 
403     status = pthread_attr_init(&threadAttr);
404     if (status) {
405         LOGE("Failed to init thread attribute.");
406         return false;
407     }
408 
409     mHasSurface = false;
410 
411     timerInit();
412     timerSet(RS_TIMER_INTERNAL);
413 
414     status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
415     if (status) {
416         LOGE("Failed to start rs context thread.");
417         return false;
418     }
419     while (!mRunning && (mError == RS_ERROR_NONE)) {
420         usleep(100);
421     }
422 
423     if (mError != RS_ERROR_NONE) {
424         LOGE("Errors during thread init");
425         return false;
426     }
427 
428     pthread_attr_destroy(&threadAttr);
429     return true;
430 }
431 
~Context()432 Context::~Context() {
433     LOGV("%p Context::~Context", this);
434 
435     if (!mIsContextLite) {
436         mIO.coreFlush();
437         rsAssert(mExit);
438         mExit = true;
439         mPaused = false;
440         void *res;
441 
442         mIO.shutdown();
443         int status = pthread_join(mThreadId, &res);
444 
445         if (mHal.funcs.shutdownDriver) {
446             mHal.funcs.shutdownDriver(this);
447         }
448 
449         // Global structure cleanup.
450         pthread_mutex_lock(&gInitMutex);
451         if (mDev) {
452             mDev->removeContext(this);
453             mDev = NULL;
454         }
455         pthread_mutex_unlock(&gInitMutex);
456     }
457     LOGV("%p Context::~Context done", this);
458 }
459 
setSurface(uint32_t w,uint32_t h,RsNativeWindow sur)460 void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
461     rsAssert(mIsGraphicsContext);
462     mHal.funcs.setSurface(this, w, h, sur);
463 
464     mHasSurface = sur != NULL;
465     mWidth = w;
466     mHeight = h;
467 
468     if (mWidth && mHeight) {
469         mStateVertex.updateSize(this);
470         mFBOCache.updateSize();
471     }
472 }
473 
pause()474 void Context::pause() {
475     rsAssert(mIsGraphicsContext);
476     mPaused = true;
477 }
478 
resume()479 void Context::resume() {
480     rsAssert(mIsGraphicsContext);
481     mPaused = false;
482 }
483 
setRootScript(Script * s)484 void Context::setRootScript(Script *s) {
485     rsAssert(mIsGraphicsContext);
486     mRootScript.set(s);
487 }
488 
setProgramStore(ProgramStore * pfs)489 void Context::setProgramStore(ProgramStore *pfs) {
490     rsAssert(mIsGraphicsContext);
491     if (pfs == NULL) {
492         mFragmentStore.set(mStateFragmentStore.mDefault);
493     } else {
494         mFragmentStore.set(pfs);
495     }
496 }
497 
setProgramFragment(ProgramFragment * pf)498 void Context::setProgramFragment(ProgramFragment *pf) {
499     rsAssert(mIsGraphicsContext);
500     if (pf == NULL) {
501         mFragment.set(mStateFragment.mDefault);
502     } else {
503         mFragment.set(pf);
504     }
505 }
506 
setProgramRaster(ProgramRaster * pr)507 void Context::setProgramRaster(ProgramRaster *pr) {
508     rsAssert(mIsGraphicsContext);
509     if (pr == NULL) {
510         mRaster.set(mStateRaster.mDefault);
511     } else {
512         mRaster.set(pr);
513     }
514 }
515 
setProgramVertex(ProgramVertex * pv)516 void Context::setProgramVertex(ProgramVertex *pv) {
517     rsAssert(mIsGraphicsContext);
518     if (pv == NULL) {
519         mVertex.set(mStateVertex.mDefault);
520     } else {
521         mVertex.set(pv);
522     }
523 }
524 
setFont(Font * f)525 void Context::setFont(Font *f) {
526     rsAssert(mIsGraphicsContext);
527     if (f == NULL) {
528         mFont.set(mStateFont.mDefault);
529     } else {
530         mFont.set(f);
531     }
532 }
533 
assignName(ObjectBase * obj,const char * name,uint32_t len)534 void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) {
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     for (size_t ct=0; ct < mNames.size(); ct++) {
542         if (obj == mNames[ct]) {
543             mNames.removeAt(ct);
544             return;
545         }
546     }
547 }
548 
peekMessageToClient(size_t * receiveLen,uint32_t * subID)549 RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID) {
550     return (RsMessageToClientType)mIO.getClientHeader(receiveLen, subID);
551 }
552 
getMessageToClient(void * data,size_t * receiveLen,uint32_t * subID,size_t bufferLen)553 RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen) {
554     return (RsMessageToClientType)mIO.getClientPayload(data, receiveLen, subID, bufferLen);
555 }
556 
sendMessageToClient(const void * data,RsMessageToClientType cmdID,uint32_t subID,size_t len,bool waitForSpace) const557 bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID,
558                                   uint32_t subID, size_t len, bool waitForSpace) const {
559 
560     return mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
561 }
562 
initToClient()563 void Context::initToClient() {
564     while (!mRunning) {
565         usleep(100);
566     }
567 }
568 
deinitToClient()569 void Context::deinitToClient() {
570     mIO.clientShutdown();
571 }
572 
setError(RsError e,const char * msg) const573 void Context::setError(RsError e, const char *msg) const {
574     mError = e;
575     sendMessageToClient(msg, RS_MESSAGE_TO_CLIENT_ERROR, e, strlen(msg) + 1, true);
576 }
577 
578 
dumpDebug() const579 void Context::dumpDebug() const {
580     LOGE("RS Context debug %p", this);
581     LOGE("RS Context debug");
582 
583     LOGE(" RS width %i, height %i", mWidth, mHeight);
584     LOGE(" RS running %i, exit %i, paused %i", mRunning, mExit, mPaused);
585     LOGE(" RS pThreadID %li, nativeThreadID %i", (long int)mThreadId, mNativeThreadId);
586 }
587 
588 ///////////////////////////////////////////////////////////////////////////////////////////
589 //
590 
591 namespace android {
592 namespace renderscript {
593 
rsi_ContextFinish(Context * rsc)594 void rsi_ContextFinish(Context *rsc) {
595 }
596 
rsi_ContextBindRootScript(Context * rsc,RsScript vs)597 void rsi_ContextBindRootScript(Context *rsc, RsScript vs) {
598     Script *s = static_cast<Script *>(vs);
599     rsc->setRootScript(s);
600 }
601 
rsi_ContextBindSampler(Context * rsc,uint32_t slot,RsSampler vs)602 void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) {
603     Sampler *s = static_cast<Sampler *>(vs);
604 
605     if (slot > RS_MAX_SAMPLER_SLOT) {
606         LOGE("Invalid sampler slot");
607         return;
608     }
609 
610     s->bindToContext(&rsc->mStateSampler, slot);
611 }
612 
rsi_ContextBindProgramStore(Context * rsc,RsProgramStore vpfs)613 void rsi_ContextBindProgramStore(Context *rsc, RsProgramStore vpfs) {
614     ProgramStore *pfs = static_cast<ProgramStore *>(vpfs);
615     rsc->setProgramStore(pfs);
616 }
617 
rsi_ContextBindProgramFragment(Context * rsc,RsProgramFragment vpf)618 void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) {
619     ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
620     rsc->setProgramFragment(pf);
621 }
622 
rsi_ContextBindProgramRaster(Context * rsc,RsProgramRaster vpr)623 void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) {
624     ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
625     rsc->setProgramRaster(pr);
626 }
627 
rsi_ContextBindProgramVertex(Context * rsc,RsProgramVertex vpv)628 void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) {
629     ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
630     rsc->setProgramVertex(pv);
631 }
632 
rsi_ContextBindFont(Context * rsc,RsFont vfont)633 void rsi_ContextBindFont(Context *rsc, RsFont vfont) {
634     Font *font = static_cast<Font *>(vfont);
635     rsc->setFont(font);
636 }
637 
rsi_AssignName(Context * rsc,RsObjectBase obj,const char * name,size_t name_length)638 void rsi_AssignName(Context *rsc, RsObjectBase obj, const char *name, size_t name_length) {
639     ObjectBase *ob = static_cast<ObjectBase *>(obj);
640     rsc->assignName(ob, name, name_length);
641 }
642 
rsi_ObjDestroy(Context * rsc,void * optr)643 void rsi_ObjDestroy(Context *rsc, void *optr) {
644     ObjectBase *ob = static_cast<ObjectBase *>(optr);
645     rsc->removeName(ob);
646     ob->decUserRef();
647 }
648 
rsi_ContextPause(Context * rsc)649 void rsi_ContextPause(Context *rsc) {
650     rsc->pause();
651 }
652 
rsi_ContextResume(Context * rsc)653 void rsi_ContextResume(Context *rsc) {
654     rsc->resume();
655 }
656 
rsi_ContextSetSurface(Context * rsc,uint32_t w,uint32_t h,RsNativeWindow sur)657 void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
658     rsc->setSurface(w, h, sur);
659 }
660 
rsi_ContextSetPriority(Context * rsc,int32_t p)661 void rsi_ContextSetPriority(Context *rsc, int32_t p) {
662     rsc->setPriority(p);
663 }
664 
rsi_ContextDump(Context * rsc,int32_t bits)665 void rsi_ContextDump(Context *rsc, int32_t bits) {
666     ObjectBase::dumpAll(rsc);
667 }
668 
rsi_ContextDestroyWorker(Context * rsc)669 void rsi_ContextDestroyWorker(Context *rsc) {
670     rsc->destroyWorkerThreadResources();
671 }
672 
rsi_ContextDestroy(Context * rsc)673 void rsi_ContextDestroy(Context *rsc) {
674     LOGV("%p rsContextDestroy", rsc);
675     rsContextDestroyWorker(rsc);
676     delete rsc;
677     LOGV("%p rsContextDestroy done", rsc);
678 }
679 
680 
rsi_ContextPeekMessage(Context * rsc,size_t * receiveLen,size_t receiveLen_length,uint32_t * subID,size_t subID_length)681 RsMessageToClientType rsi_ContextPeekMessage(Context *rsc,
682                                            size_t * receiveLen, size_t receiveLen_length,
683                                            uint32_t * subID, size_t subID_length) {
684     return rsc->peekMessageToClient(receiveLen, subID);
685 }
686 
rsi_ContextGetMessage(Context * rsc,void * data,size_t data_length,size_t * receiveLen,size_t receiveLen_length,uint32_t * subID,size_t subID_length)687 RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length,
688                                           size_t * receiveLen, size_t receiveLen_length,
689                                           uint32_t * subID, size_t subID_length) {
690     rsAssert(subID_length == sizeof(uint32_t));
691     rsAssert(receiveLen_length == sizeof(size_t));
692     return rsc->getMessageToClient(data, receiveLen, subID, data_length);
693 }
694 
rsi_ContextInitToClient(Context * rsc)695 void rsi_ContextInitToClient(Context *rsc) {
696     rsc->initToClient();
697 }
698 
rsi_ContextDeinitToClient(Context * rsc)699 void rsi_ContextDeinitToClient(Context *rsc) {
700     rsc->deinitToClient();
701 }
702 
703 }
704 }
705 
rsContextCreate(RsDevice vdev,uint32_t version,uint32_t sdkVersion)706 RsContext rsContextCreate(RsDevice vdev, uint32_t version,
707                           uint32_t sdkVersion) {
708     LOGV("rsContextCreate dev=%p", vdev);
709     Device * dev = static_cast<Device *>(vdev);
710     Context *rsc = Context::createContext(dev, NULL);
711     if (rsc) {
712         rsc->setTargetSdkVersion(sdkVersion);
713     }
714     return rsc;
715 }
716 
rsContextCreateGL(RsDevice vdev,uint32_t version,uint32_t sdkVersion,RsSurfaceConfig sc,uint32_t dpi)717 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
718                             uint32_t sdkVersion, RsSurfaceConfig sc,
719                             uint32_t dpi) {
720     LOGV("rsContextCreateGL dev=%p", vdev);
721     Device * dev = static_cast<Device *>(vdev);
722     Context *rsc = Context::createContext(dev, &sc);
723     if (rsc) {
724         rsc->setTargetSdkVersion(sdkVersion);
725         rsc->setDPI(dpi);
726     }
727     LOGV("%p rsContextCreateGL ret", rsc);
728     return rsc;
729 }
730 
731 // Only to be called at a3d load time, before object is visible to user
732 // not thread safe
rsaGetName(RsContext con,void * obj,const char ** name)733 void rsaGetName(RsContext con, void * obj, const char **name) {
734     ObjectBase *ob = static_cast<ObjectBase *>(obj);
735     (*name) = ob->getName();
736 }
737