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