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 "rs.h"
18 #include "rsDevice.h"
19 #include "rsContext.h"
20 #include "rsThreadIO.h"
21
22 #ifndef RS_COMPATIBILITY_LIB
23 #include "rsMesh.h"
24 #include <ui/FramebufferNativeWindow.h>
25 #include <gui/DisplayEventReceiver.h>
26 #endif
27
28 #include <sys/types.h>
29 #include <sys/resource.h>
30 #include <sched.h>
31
32 #include <sys/syscall.h>
33 #include <string.h>
34 #include <dlfcn.h>
35
36 #ifndef RS_SERVER
37 #include <cutils/properties.h>
38 #endif
39
40 #ifdef RS_SERVER
41 // Android exposes gettid(), standard Linux does not
gettid()42 static pid_t gettid() {
43 return syscall(SYS_gettid);
44 }
45 #endif
46
47 using namespace android;
48 using namespace android::renderscript;
49
50 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
51 pthread_mutex_t Context::gMessageMutex = PTHREAD_MUTEX_INITIALIZER;
52 pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER;
53
initGLThread()54 bool Context::initGLThread() {
55 pthread_mutex_lock(&gInitMutex);
56
57 if (!mHal.funcs.initGraphics(this)) {
58 pthread_mutex_unlock(&gInitMutex);
59 ALOGE("%p initGraphics failed", this);
60 return false;
61 }
62
63 pthread_mutex_unlock(&gInitMutex);
64 return true;
65 }
66
deinitEGL()67 void Context::deinitEGL() {
68 #ifndef RS_COMPATIBILITY_LIB
69 mHal.funcs.shutdownGraphics(this);
70 #endif
71 }
72
PushState(Context * con)73 Context::PushState::PushState(Context *con) {
74 mRsc = con;
75 #ifndef RS_COMPATIBILITY_LIB
76 if (con->mIsGraphicsContext) {
77 mFragment.set(con->getProgramFragment());
78 mVertex.set(con->getProgramVertex());
79 mStore.set(con->getProgramStore());
80 mRaster.set(con->getProgramRaster());
81 mFont.set(con->getFont());
82 }
83 #endif
84 }
85
~PushState()86 Context::PushState::~PushState() {
87 #ifndef RS_COMPATIBILITY_LIB
88 if (mRsc->mIsGraphicsContext) {
89 mRsc->setProgramFragment(mFragment.get());
90 mRsc->setProgramVertex(mVertex.get());
91 mRsc->setProgramStore(mStore.get());
92 mRsc->setProgramRaster(mRaster.get());
93 mRsc->setFont(mFont.get());
94 }
95 #endif
96 }
97
98
runScript(Script * s)99 uint32_t Context::runScript(Script *s) {
100 PushState ps(this);
101
102 uint32_t ret = s->run(this);
103 return ret;
104 }
105
runRootScript()106 uint32_t Context::runRootScript() {
107 timerSet(RS_TIMER_SCRIPT);
108 #ifndef RS_COMPATIBILITY_LIB
109 mStateFragmentStore.mLast.clear();
110 #endif
111 watchdog.inRoot = true;
112 uint32_t ret = runScript(mRootScript.get());
113 watchdog.inRoot = false;
114
115 return ret;
116 }
117
getTime() const118 uint64_t Context::getTime() const {
119 #ifndef ANDROID_RS_SERIALIZE
120 struct timespec t;
121 clock_gettime(CLOCK_MONOTONIC, &t);
122 return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
123 #else
124 return 0;
125 #endif //ANDROID_RS_SERIALIZE
126 }
127
timerReset()128 void Context::timerReset() {
129 for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) {
130 mTimers[ct] = 0;
131 }
132 }
133
timerInit()134 void Context::timerInit() {
135 mTimeLast = getTime();
136 mTimeFrame = mTimeLast;
137 mTimeLastFrame = mTimeLast;
138 mTimerActive = RS_TIMER_INTERNAL;
139 mAverageFPSFrameCount = 0;
140 mAverageFPSStartTime = mTimeLast;
141 mAverageFPS = 0;
142 timerReset();
143 }
144
timerFrame()145 void Context::timerFrame() {
146 mTimeLastFrame = mTimeFrame;
147 mTimeFrame = getTime();
148 // Update average fps
149 const uint64_t averageFramerateInterval = 1000 * 1000000;
150 mAverageFPSFrameCount ++;
151 uint64_t inverval = mTimeFrame - mAverageFPSStartTime;
152 if (inverval >= averageFramerateInterval) {
153 inverval = inverval / 1000000;
154 mAverageFPS = (mAverageFPSFrameCount * 1000) / inverval;
155 mAverageFPSFrameCount = 0;
156 mAverageFPSStartTime = mTimeFrame;
157 }
158 }
159
timerSet(Timers tm)160 void Context::timerSet(Timers tm) {
161 uint64_t last = mTimeLast;
162 mTimeLast = getTime();
163 mTimers[mTimerActive] += mTimeLast - last;
164 mTimerActive = tm;
165 }
166
timerPrint()167 void Context::timerPrint() {
168 double total = 0;
169 for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) {
170 total += mTimers[ct];
171 }
172 uint64_t frame = mTimeFrame - mTimeLastFrame;
173 mTimeMSLastFrame = frame / 1000000;
174 mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000;
175 mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000;
176
177
178 if (props.mLogTimes) {
179 ALOGV("RS: Frame (%i), Script %2.1f%% (%i), Swap %2.1f%% (%i), Idle %2.1f%% (%lli), Internal %2.1f%% (%lli), Avg fps: %u",
180 mTimeMSLastFrame,
181 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
182 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
183 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
184 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000,
185 mAverageFPS);
186 }
187 }
188
setupCheck()189 bool Context::setupCheck() {
190 #ifndef RS_COMPATIBILITY_LIB
191 mFragmentStore->setup(this, &mStateFragmentStore);
192 mFragment->setup(this, &mStateFragment);
193 mRaster->setup(this, &mStateRaster);
194 mVertex->setup(this, &mStateVertex);
195 mFBOCache.setup(this);
196 #endif
197 return true;
198 }
199
200 #ifndef RS_COMPATIBILITY_LIB
setupProgramStore()201 void Context::setupProgramStore() {
202 mFragmentStore->setup(this, &mStateFragmentStore);
203 }
204 #endif
205
getProp(const char * str)206 static uint32_t getProp(const char *str) {
207 #ifndef RS_SERVER
208 char buf[PROPERTY_VALUE_MAX];
209 property_get(str, buf, "0");
210 return atoi(buf);
211 #else
212 return 0;
213 #endif
214 }
215
displayDebugStats()216 void Context::displayDebugStats() {
217 #ifndef RS_COMPATIBILITY_LIB
218 char buffer[128];
219 sprintf(buffer, "Avg fps %u, Frame %i ms, Script %i ms", mAverageFPS, mTimeMSLastFrame, mTimeMSLastScript);
220 float oldR, oldG, oldB, oldA;
221 mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
222 uint32_t bufferLen = strlen(buffer);
223
224 ObjectBaseRef<Font> lastFont(getFont());
225 setFont(NULL);
226 float shadowCol = 0.1f;
227 mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
228 mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6);
229
230 mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
231 mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7);
232
233 setFont(lastFont.get());
234 mStateFont.setFontColor(oldR, oldG, oldB, oldA);
235 #endif
236 }
237
loadRuntime(const char * filename,Context * rsc)238 bool Context::loadRuntime(const char* filename, Context* rsc) {
239
240 // TODO: store the driverSO somewhere so we can dlclose later
241 void *driverSO = NULL;
242
243 driverSO = dlopen(filename, RTLD_LAZY);
244 if (driverSO == NULL) {
245 ALOGE("Failed loading RS driver: %s", dlerror());
246 return false;
247 }
248
249 // Need to call dlerror() to clear buffer before using it for dlsym().
250 (void) dlerror();
251 typedef bool (*HalSig)(Context*, uint32_t, uint32_t);
252 HalSig halInit = (HalSig) dlsym(driverSO, "rsdHalInit");
253
254 // If we can't find the C variant, we go looking for the C++ version.
255 if (halInit == NULL) {
256 ALOGW("Falling back to find C++ rsdHalInit: %s", dlerror());
257 halInit = (HalSig) dlsym(driverSO,
258 "_Z10rsdHalInitPN7android12renderscript7ContextEjj");
259 }
260
261 if (halInit == NULL) {
262 dlclose(driverSO);
263 ALOGE("Failed to find rsdHalInit: %s", dlerror());
264 return false;
265 }
266
267 if (!(*halInit)(rsc, 0, 0)) {
268 dlclose(driverSO);
269 ALOGE("Hal init failed");
270 return false;
271 }
272
273 //validate HAL struct
274
275
276 return true;
277 }
278
279 extern "C" bool rsdHalInit(RsContext c, uint32_t version_major, uint32_t version_minor);
280
threadProc(void * vrsc)281 void * Context::threadProc(void *vrsc) {
282 Context *rsc = static_cast<Context *>(vrsc);
283 #ifndef ANDROID_RS_SERIALIZE
284 rsc->mNativeThreadId = gettid();
285 #ifndef RS_COMPATIBILITY_LIB
286 if (!rsc->isSynchronous()) {
287 setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
288 }
289 rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
290 #else
291 if (!rsc->isSynchronous()) {
292 setpriority(PRIO_PROCESS, rsc->mNativeThreadId, -4);
293 }
294 rsc->mThreadPriority = -4;
295 #endif
296 #endif //ANDROID_RS_SERIALIZE
297 rsc->props.mLogTimes = getProp("debug.rs.profile") != 0;
298 rsc->props.mLogScripts = getProp("debug.rs.script") != 0;
299 rsc->props.mLogObjects = getProp("debug.rs.object") != 0;
300 rsc->props.mLogShaders = getProp("debug.rs.shader") != 0;
301 rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0;
302 rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0;
303 rsc->props.mLogVisual = getProp("debug.rs.visual") != 0;
304 rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads");
305
306 bool loadDefault = true;
307
308 // Provide a mechanism for dropping in a different RS driver.
309 #ifndef RS_COMPATIBILITY_LIB
310 #ifdef OVERRIDE_RS_DRIVER
311 #define XSTR(S) #S
312 #define STR(S) XSTR(S)
313 #define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER)
314
315 if (getProp("debug.rs.default-CPU-driver") != 0) {
316 ALOGE("Skipping override driver and loading default CPU driver");
317 } else if (rsc->mForceCpu) {
318 ALOGV("Application requested CPU execution");
319 } else if (rsc->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
320 ALOGV("Application requested debug context");
321 } else {
322 if (loadRuntime(OVERRIDE_RS_DRIVER_STRING, rsc)) {
323 ALOGE("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING);
324 loadDefault = false;
325 } else {
326 ALOGE("Failed to load runtime %s, loading default", OVERRIDE_RS_DRIVER_STRING);
327 }
328 }
329
330 #undef XSTR
331 #undef STR
332 #endif // OVERRIDE_RS_DRIVER
333
334 if (loadDefault) {
335 if (!loadRuntime("libRSDriver.so", rsc)) {
336 ALOGE("Failed to load default runtime!");
337 rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed loading RS driver");
338 return NULL;
339 }
340 }
341 #else // RS_COMPATIBILITY_LIB
342 if (rsdHalInit(rsc, 0, 0) != true) {
343 return NULL;
344 }
345 #endif
346
347
348 rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);
349
350 #ifndef RS_COMPATIBILITY_LIB
351 if (rsc->mIsGraphicsContext) {
352 if (!rsc->initGLThread()) {
353 rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
354 return NULL;
355 }
356
357 rsc->mStateRaster.init(rsc);
358 rsc->setProgramRaster(NULL);
359 rsc->mStateVertex.init(rsc);
360 rsc->setProgramVertex(NULL);
361 rsc->mStateFragment.init(rsc);
362 rsc->setProgramFragment(NULL);
363 rsc->mStateFragmentStore.init(rsc);
364 rsc->setProgramStore(NULL);
365 rsc->mStateFont.init(rsc);
366 rsc->setFont(NULL);
367 rsc->mStateSampler.init(rsc);
368 rsc->mFBOCache.init(rsc);
369 }
370 #endif
371
372 rsc->mRunning = true;
373
374 if (rsc->isSynchronous()) {
375 return NULL;
376 }
377
378 if (!rsc->mIsGraphicsContext) {
379 while (!rsc->mExit) {
380 rsc->mIO.playCoreCommands(rsc, -1);
381 }
382 #ifndef RS_COMPATIBILITY_LIB
383 } else {
384 #ifndef ANDROID_RS_SERIALIZE
385 DisplayEventReceiver displayEvent;
386 DisplayEventReceiver::Event eventBuffer[1];
387 #endif
388 int vsyncRate = 0;
389 int targetRate = 0;
390
391 bool drawOnce = false;
392 while (!rsc->mExit) {
393 rsc->timerSet(RS_TIMER_IDLE);
394
395 #ifndef ANDROID_RS_SERIALIZE
396 if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) {
397 targetRate = 0;
398 }
399
400 if (vsyncRate != targetRate) {
401 displayEvent.setVsyncRate(targetRate);
402 vsyncRate = targetRate;
403 }
404 if (targetRate) {
405 drawOnce |= rsc->mIO.playCoreCommands(rsc, displayEvent.getFd());
406 while (displayEvent.getEvents(eventBuffer, 1) != 0) {
407 //ALOGE("vs2 time past %lld", (rsc->getTime() - eventBuffer[0].header.timestamp) / 1000000);
408 }
409 } else
410 #endif
411 {
412 drawOnce |= rsc->mIO.playCoreCommands(rsc, -1);
413 }
414
415 if ((rsc->mRootScript.get() != NULL) && rsc->mHasSurface &&
416 (targetRate || drawOnce) && !rsc->mPaused) {
417
418 drawOnce = false;
419 targetRate = ((rsc->runRootScript() + 15) / 16);
420
421 if (rsc->props.mLogVisual) {
422 rsc->displayDebugStats();
423 }
424
425 rsc->timerSet(RS_TIMER_CLEAR_SWAP);
426 rsc->mHal.funcs.swap(rsc);
427 rsc->timerFrame();
428 rsc->timerSet(RS_TIMER_INTERNAL);
429 rsc->timerPrint();
430 rsc->timerReset();
431 }
432 }
433 #endif
434 }
435
436 //ALOGV("%p RS Thread exiting", rsc);
437
438 #ifndef RS_COMPATIBILITY_LIB
439 if (rsc->mIsGraphicsContext) {
440 pthread_mutex_lock(&gInitMutex);
441 rsc->deinitEGL();
442 pthread_mutex_unlock(&gInitMutex);
443 }
444 #endif
445
446 //ALOGV("%p RS Thread exited", rsc);
447 return NULL;
448 }
449
destroyWorkerThreadResources()450 void Context::destroyWorkerThreadResources() {
451 //ALOGV("destroyWorkerThreadResources 1");
452 ObjectBase::zeroAllUserRef(this);
453 #ifndef RS_COMPATIBILITY_LIB
454 if (mIsGraphicsContext) {
455 mRaster.clear();
456 mFragment.clear();
457 mVertex.clear();
458 mFragmentStore.clear();
459 mFont.clear();
460 mRootScript.clear();
461 mStateRaster.deinit(this);
462 mStateVertex.deinit(this);
463 mStateFragment.deinit(this);
464 mStateFragmentStore.deinit(this);
465 mStateFont.deinit(this);
466 mStateSampler.deinit(this);
467 mFBOCache.deinit(this);
468 }
469 #endif
470 ObjectBase::freeAllChildren(this);
471 mExit = true;
472 //ALOGV("destroyWorkerThreadResources 2");
473 }
474
printWatchdogInfo(void * ctx)475 void Context::printWatchdogInfo(void *ctx) {
476 Context *rsc = (Context *)ctx;
477 if (rsc->watchdog.command && rsc->watchdog.file) {
478 ALOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot,
479 rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
480 } else {
481 ALOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot);
482 }
483 }
484
485
setPriority(int32_t p)486 void Context::setPriority(int32_t p) {
487 // Note: If we put this in the proper "background" policy
488 // the wallpapers can become completly unresponsive at times.
489 // This is probably not what we want for something the user is actively
490 // looking at.
491 mThreadPriority = p;
492 setpriority(PRIO_PROCESS, mNativeThreadId, p);
493 mHal.funcs.setPriority(this, mThreadPriority);
494 }
495
Context()496 Context::Context() {
497 mDev = NULL;
498 mRunning = false;
499 mExit = false;
500 mPaused = false;
501 mObjHead = NULL;
502 mError = RS_ERROR_NONE;
503 mTargetSdkVersion = 14;
504 mDPI = 96;
505 mIsContextLite = false;
506 memset(&watchdog, 0, sizeof(watchdog));
507 mForceCpu = false;
508 mContextType = RS_CONTEXT_TYPE_NORMAL;
509 mSynchronous = false;
510 }
511
createContext(Device * dev,const RsSurfaceConfig * sc,RsContextType ct,bool forceCpu,bool synchronous)512 Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc,
513 RsContextType ct, bool forceCpu,
514 bool synchronous) {
515 Context * rsc = new Context();
516
517 rsc->mForceCpu = forceCpu;
518 rsc->mSynchronous = synchronous;
519 rsc->mContextType = ct;
520
521 if (!rsc->initContext(dev, sc)) {
522 delete rsc;
523 return NULL;
524 }
525 return rsc;
526 }
527
createContextLite()528 Context * Context::createContextLite() {
529 Context * rsc = new Context();
530 rsc->mIsContextLite = true;
531 return rsc;
532 }
533
initContext(Device * dev,const RsSurfaceConfig * sc)534 bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
535 pthread_mutex_lock(&gInitMutex);
536
537 mIO.init();
538 mIO.setTimeoutCallback(printWatchdogInfo, this, 2e9);
539
540 dev->addContext(this);
541 mDev = dev;
542 if (sc) {
543 mUserSurfaceConfig = *sc;
544 } else {
545 memset(&mUserSurfaceConfig, 0, sizeof(mUserSurfaceConfig));
546 }
547
548 mIsGraphicsContext = sc != NULL;
549
550 int status;
551 pthread_attr_t threadAttr;
552
553 pthread_mutex_unlock(&gInitMutex);
554
555 // Global init done at this point.
556
557 status = pthread_attr_init(&threadAttr);
558 if (status) {
559 ALOGE("Failed to init thread attribute.");
560 return false;
561 }
562
563 mHasSurface = false;
564
565 timerInit();
566 timerSet(RS_TIMER_INTERNAL);
567 if (mSynchronous) {
568 threadProc(this);
569 } else {
570 status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
571 if (status) {
572 ALOGE("Failed to start rs context thread.");
573 return false;
574 }
575 while (!mRunning && (mError == RS_ERROR_NONE)) {
576 usleep(100);
577 }
578
579 if (mError != RS_ERROR_NONE) {
580 ALOGE("Errors during thread init");
581 return false;
582 }
583
584 pthread_attr_destroy(&threadAttr);
585 }
586 return true;
587 }
588
~Context()589 Context::~Context() {
590 //ALOGV("%p Context::~Context", this);
591
592 if (!mIsContextLite) {
593 mPaused = false;
594 void *res;
595
596 mIO.shutdown();
597 int status = pthread_join(mThreadId, &res);
598 rsAssert(mExit);
599
600 if (mHal.funcs.shutdownDriver) {
601 mHal.funcs.shutdownDriver(this);
602 }
603
604 // Global structure cleanup.
605 pthread_mutex_lock(&gInitMutex);
606 if (mDev) {
607 mDev->removeContext(this);
608 mDev = NULL;
609 }
610 pthread_mutex_unlock(&gInitMutex);
611 }
612 //ALOGV("%p Context::~Context done", this);
613 }
614
615 #ifndef RS_COMPATIBILITY_LIB
setSurface(uint32_t w,uint32_t h,RsNativeWindow sur)616 void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
617 rsAssert(mIsGraphicsContext);
618 mHal.funcs.setSurface(this, w, h, sur);
619
620 mHasSurface = sur != NULL;
621 mWidth = w;
622 mHeight = h;
623
624 if (mWidth && mHeight) {
625 mStateVertex.updateSize(this);
626 mFBOCache.updateSize();
627 }
628 }
629
getCurrentSurfaceWidth() const630 uint32_t Context::getCurrentSurfaceWidth() const {
631 for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
632 if (mFBOCache.mHal.state.colorTargets[i] != NULL) {
633 return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimX();
634 }
635 }
636 if (mFBOCache.mHal.state.depthTarget != NULL) {
637 return mFBOCache.mHal.state.depthTarget->getType()->getDimX();
638 }
639 return mWidth;
640 }
641
getCurrentSurfaceHeight() const642 uint32_t Context::getCurrentSurfaceHeight() const {
643 for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
644 if (mFBOCache.mHal.state.colorTargets[i] != NULL) {
645 return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimY();
646 }
647 }
648 if (mFBOCache.mHal.state.depthTarget != NULL) {
649 return mFBOCache.mHal.state.depthTarget->getType()->getDimY();
650 }
651 return mHeight;
652 }
653
pause()654 void Context::pause() {
655 rsAssert(mIsGraphicsContext);
656 mPaused = true;
657 }
658
resume()659 void Context::resume() {
660 rsAssert(mIsGraphicsContext);
661 mPaused = false;
662 }
663
setRootScript(Script * s)664 void Context::setRootScript(Script *s) {
665 rsAssert(mIsGraphicsContext);
666 mRootScript.set(s);
667 }
668
setProgramStore(ProgramStore * pfs)669 void Context::setProgramStore(ProgramStore *pfs) {
670 rsAssert(mIsGraphicsContext);
671 if (pfs == NULL) {
672 mFragmentStore.set(mStateFragmentStore.mDefault);
673 } else {
674 mFragmentStore.set(pfs);
675 }
676 }
677
setProgramFragment(ProgramFragment * pf)678 void Context::setProgramFragment(ProgramFragment *pf) {
679 rsAssert(mIsGraphicsContext);
680 if (pf == NULL) {
681 mFragment.set(mStateFragment.mDefault);
682 } else {
683 mFragment.set(pf);
684 }
685 }
686
setProgramRaster(ProgramRaster * pr)687 void Context::setProgramRaster(ProgramRaster *pr) {
688 rsAssert(mIsGraphicsContext);
689 if (pr == NULL) {
690 mRaster.set(mStateRaster.mDefault);
691 } else {
692 mRaster.set(pr);
693 }
694 }
695
setProgramVertex(ProgramVertex * pv)696 void Context::setProgramVertex(ProgramVertex *pv) {
697 rsAssert(mIsGraphicsContext);
698 if (pv == NULL) {
699 mVertex.set(mStateVertex.mDefault);
700 } else {
701 mVertex.set(pv);
702 }
703 }
704
setFont(Font * f)705 void Context::setFont(Font *f) {
706 rsAssert(mIsGraphicsContext);
707 if (f == NULL) {
708 mFont.set(mStateFont.mDefault);
709 } else {
710 mFont.set(f);
711 }
712 }
713 #endif
714
assignName(ObjectBase * obj,const char * name,uint32_t len)715 void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) {
716 rsAssert(!obj->getName());
717 obj->setName(name, len);
718 mNames.add(obj);
719 }
720
removeName(ObjectBase * obj)721 void Context::removeName(ObjectBase *obj) {
722 for (size_t ct=0; ct < mNames.size(); ct++) {
723 if (obj == mNames[ct]) {
724 mNames.removeAt(ct);
725 return;
726 }
727 }
728 }
729
peekMessageToClient(size_t * receiveLen,uint32_t * subID)730 RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID) {
731 return (RsMessageToClientType)mIO.getClientHeader(receiveLen, subID);
732 }
733
getMessageToClient(void * data,size_t * receiveLen,uint32_t * subID,size_t bufferLen)734 RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen) {
735 return (RsMessageToClientType)mIO.getClientPayload(data, receiveLen, subID, bufferLen);
736 }
737
sendMessageToClient(const void * data,RsMessageToClientType cmdID,uint32_t subID,size_t len,bool waitForSpace) const738 bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID,
739 uint32_t subID, size_t len, bool waitForSpace) const {
740
741 pthread_mutex_lock(&gMessageMutex);
742 bool ret = mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
743 pthread_mutex_unlock(&gMessageMutex);
744 return ret;
745 }
746
initToClient()747 void Context::initToClient() {
748 while (!mRunning) {
749 usleep(100);
750 }
751 }
752
deinitToClient()753 void Context::deinitToClient() {
754 mIO.clientShutdown();
755 }
756
setError(RsError e,const char * msg) const757 void Context::setError(RsError e, const char *msg) const {
758 mError = e;
759 sendMessageToClient(msg, RS_MESSAGE_TO_CLIENT_ERROR, e, strlen(msg) + 1, true);
760 }
761
762
dumpDebug() const763 void Context::dumpDebug() const {
764 ALOGE("RS Context debug %p", this);
765 ALOGE("RS Context debug");
766
767 ALOGE(" RS width %i, height %i", mWidth, mHeight);
768 ALOGE(" RS running %i, exit %i, paused %i", mRunning, mExit, mPaused);
769 ALOGE(" RS pThreadID %li, nativeThreadID %i", (long int)mThreadId, mNativeThreadId);
770 }
771
772 ///////////////////////////////////////////////////////////////////////////////////////////
773 //
774
775 namespace android {
776 namespace renderscript {
777
rsi_ContextFinish(Context * rsc)778 void rsi_ContextFinish(Context *rsc) {
779 }
780
rsi_ContextBindRootScript(Context * rsc,RsScript vs)781 void rsi_ContextBindRootScript(Context *rsc, RsScript vs) {
782 #ifndef RS_COMPATIBILITY_LIB
783 Script *s = static_cast<Script *>(vs);
784 rsc->setRootScript(s);
785 #endif
786 }
787
rsi_ContextBindSampler(Context * rsc,uint32_t slot,RsSampler vs)788 void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) {
789 Sampler *s = static_cast<Sampler *>(vs);
790
791 if (slot > RS_MAX_SAMPLER_SLOT) {
792 ALOGE("Invalid sampler slot");
793 return;
794 }
795
796 s->bindToContext(&rsc->mStateSampler, slot);
797 }
798
799 #ifndef RS_COMPATIBILITY_LIB
rsi_ContextBindProgramStore(Context * rsc,RsProgramStore vpfs)800 void rsi_ContextBindProgramStore(Context *rsc, RsProgramStore vpfs) {
801 ProgramStore *pfs = static_cast<ProgramStore *>(vpfs);
802 rsc->setProgramStore(pfs);
803 }
804
rsi_ContextBindProgramFragment(Context * rsc,RsProgramFragment vpf)805 void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) {
806 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
807 rsc->setProgramFragment(pf);
808 }
809
rsi_ContextBindProgramRaster(Context * rsc,RsProgramRaster vpr)810 void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) {
811 ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
812 rsc->setProgramRaster(pr);
813 }
814
rsi_ContextBindProgramVertex(Context * rsc,RsProgramVertex vpv)815 void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) {
816 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
817 rsc->setProgramVertex(pv);
818 }
819
rsi_ContextBindFont(Context * rsc,RsFont vfont)820 void rsi_ContextBindFont(Context *rsc, RsFont vfont) {
821 Font *font = static_cast<Font *>(vfont);
822 rsc->setFont(font);
823 }
824 #endif
825
rsi_AssignName(Context * rsc,RsObjectBase obj,const char * name,size_t name_length)826 void rsi_AssignName(Context *rsc, RsObjectBase obj, const char *name, size_t name_length) {
827 ObjectBase *ob = static_cast<ObjectBase *>(obj);
828 rsc->assignName(ob, name, name_length);
829 }
830
rsi_ObjDestroy(Context * rsc,void * optr)831 void rsi_ObjDestroy(Context *rsc, void *optr) {
832 ObjectBase *ob = static_cast<ObjectBase *>(optr);
833 rsc->removeName(ob);
834 ob->decUserRef();
835 }
836
837 #ifndef RS_COMPATIBILITY_LIB
rsi_ContextPause(Context * rsc)838 void rsi_ContextPause(Context *rsc) {
839 rsc->pause();
840 }
841
rsi_ContextResume(Context * rsc)842 void rsi_ContextResume(Context *rsc) {
843 rsc->resume();
844 }
845
rsi_ContextSetSurface(Context * rsc,uint32_t w,uint32_t h,RsNativeWindow sur)846 void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
847 rsc->setSurface(w, h, sur);
848 }
849 #endif
850
rsi_ContextSetPriority(Context * rsc,int32_t p)851 void rsi_ContextSetPriority(Context *rsc, int32_t p) {
852 rsc->setPriority(p);
853 }
854
rsi_ContextDump(Context * rsc,int32_t bits)855 void rsi_ContextDump(Context *rsc, int32_t bits) {
856 ObjectBase::dumpAll(rsc);
857 }
858
rsi_ContextDestroyWorker(Context * rsc)859 void rsi_ContextDestroyWorker(Context *rsc) {
860 rsc->destroyWorkerThreadResources();
861 }
862
rsi_ContextDestroy(Context * rsc)863 void rsi_ContextDestroy(Context *rsc) {
864 //ALOGV("%p rsContextDestroy", rsc);
865 rsContextDestroyWorker(rsc);
866 delete rsc;
867 //ALOGV("%p rsContextDestroy done", rsc);
868 }
869
870
rsi_ContextPeekMessage(Context * rsc,size_t * receiveLen,size_t receiveLen_length,uint32_t * subID,size_t subID_length)871 RsMessageToClientType rsi_ContextPeekMessage(Context *rsc,
872 size_t * receiveLen, size_t receiveLen_length,
873 uint32_t * subID, size_t subID_length) {
874 return rsc->peekMessageToClient(receiveLen, subID);
875 }
876
rsi_ContextGetMessage(Context * rsc,void * data,size_t data_length,size_t * receiveLen,size_t receiveLen_length,uint32_t * subID,size_t subID_length)877 RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length,
878 size_t * receiveLen, size_t receiveLen_length,
879 uint32_t * subID, size_t subID_length) {
880 rsAssert(subID_length == sizeof(uint32_t));
881 rsAssert(receiveLen_length == sizeof(size_t));
882 return rsc->getMessageToClient(data, receiveLen, subID, data_length);
883 }
884
rsi_ContextInitToClient(Context * rsc)885 void rsi_ContextInitToClient(Context *rsc) {
886 rsc->initToClient();
887 }
888
rsi_ContextDeinitToClient(Context * rsc)889 void rsi_ContextDeinitToClient(Context *rsc) {
890 rsc->deinitToClient();
891 }
892
rsi_ContextSendMessage(Context * rsc,uint32_t id,const uint8_t * data,size_t len)893 void rsi_ContextSendMessage(Context *rsc, uint32_t id, const uint8_t *data, size_t len) {
894 rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, id, len, true);
895 }
896
897 }
898 }
899
rsContextCreate(RsDevice vdev,uint32_t version,uint32_t sdkVersion,RsContextType ct,bool forceCpu,bool synchronous)900 RsContext rsContextCreate(RsDevice vdev, uint32_t version, uint32_t sdkVersion,
901 RsContextType ct, bool forceCpu, bool synchronous) {
902 //ALOGV("rsContextCreate dev=%p", vdev);
903 Device * dev = static_cast<Device *>(vdev);
904 Context *rsc = Context::createContext(dev, NULL, ct, forceCpu, synchronous);
905 if (rsc) {
906 rsc->setTargetSdkVersion(sdkVersion);
907 }
908 return rsc;
909 }
910
911 #ifndef RS_COMPATIBILITY_LIB
rsContextCreateGL(RsDevice vdev,uint32_t version,uint32_t sdkVersion,RsSurfaceConfig sc,uint32_t dpi)912 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
913 uint32_t sdkVersion, RsSurfaceConfig sc,
914 uint32_t dpi) {
915 //ALOGV("rsContextCreateGL dev=%p", vdev);
916 Device * dev = static_cast<Device *>(vdev);
917 Context *rsc = Context::createContext(dev, &sc);
918 if (rsc) {
919 rsc->setTargetSdkVersion(sdkVersion);
920 rsc->setDPI(dpi);
921 }
922 //ALOGV("%p rsContextCreateGL ret", rsc);
923 return rsc;
924 }
925 #endif
926
927 // Only to be called at a3d load time, before object is visible to user
928 // not thread safe
rsaGetName(RsContext con,void * obj,const char ** name)929 void rsaGetName(RsContext con, void * obj, const char **name) {
930 ObjectBase *ob = static_cast<ObjectBase *>(obj);
931 (*name) = ob->getName();
932 }
933