rsContext.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  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. #include "rs.h"
  17. #include "rsDevice.h"
  18. #include "rsContext.h"
  19. #include "rsThreadIO.h"
  20. #include "rsgApiStructs.h"
  21. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  22. #include "rsMesh.h"
  23. #endif
  24. #include <sys/types.h>
  25. #include <sys/resource.h>
  26. #include <sched.h>
  27. #include <sys/syscall.h>
  28. #include <string.h>
  29. #include <dlfcn.h>
  30. #include <inttypes.h>
  31. #include <unistd.h>
  32. #ifdef RS_COMPATIBILITY_LIB
  33. #include "rsCompatibilityLib.h"
  34. #endif
  35. namespace android {
  36. namespace renderscript {
  37. pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
  38. pthread_mutex_t Context::gMessageMutex = PTHREAD_MUTEX_INITIALIZER;
  39. pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER;
  40. bool Context::initGLThread() {
  41. pthread_mutex_lock(&gInitMutex);
  42. int32_t ret = mHal.funcs.initGraphics(this);
  43. if (ret < 0) {
  44. pthread_mutex_unlock(&gInitMutex);
  45. ALOGE("%p initGraphics failed", this);
  46. return false;
  47. }
  48. mSyncFd = ret;
  49. pthread_mutex_unlock(&gInitMutex);
  50. return true;
  51. }
  52. void Context::deinitEGL() {
  53. #ifndef RS_COMPATIBILITY_LIB
  54. mHal.funcs.shutdownGraphics(this);
  55. #endif
  56. }
  57. Context::PushState::PushState(Context *con) {
  58. mRsc = con;
  59. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  60. if (con->mIsGraphicsContext) {
  61. mFragment.set(con->getProgramFragment());
  62. mVertex.set(con->getProgramVertex());
  63. mStore.set(con->getProgramStore());
  64. mRaster.set(con->getProgramRaster());
  65. mFont.set(con->getFont());
  66. }
  67. #endif
  68. }
  69. Context::PushState::~PushState() {
  70. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  71. if (mRsc->mIsGraphicsContext) {
  72. mRsc->setProgramFragment(mFragment.get());
  73. mRsc->setProgramVertex(mVertex.get());
  74. mRsc->setProgramStore(mStore.get());
  75. mRsc->setProgramRaster(mRaster.get());
  76. mRsc->setFont(mFont.get());
  77. }
  78. #endif
  79. }
  80. uint32_t Context::runScript(Script *s) {
  81. PushState ps(this);
  82. uint32_t ret = s->run(this);
  83. return ret;
  84. }
  85. uint32_t Context::runRootScript() {
  86. timerSet(RS_TIMER_SCRIPT);
  87. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  88. mStateFragmentStore.mLast.clear();
  89. #endif
  90. watchdog.inRoot = true;
  91. uint32_t ret = runScript(mRootScript.get());
  92. watchdog.inRoot = false;
  93. return ret;
  94. }
  95. uint64_t Context::getTime() const {
  96. struct timespec t;
  97. clock_gettime(CLOCK_MONOTONIC, &t);
  98. return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
  99. }
  100. void Context::timerReset() {
  101. for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) {
  102. mTimers[ct] = 0;
  103. }
  104. }
  105. void Context::timerInit() {
  106. mTimeLast = getTime();
  107. mTimeFrame = mTimeLast;
  108. mTimeLastFrame = mTimeLast;
  109. mTimerActive = RS_TIMER_INTERNAL;
  110. mAverageFPSFrameCount = 0;
  111. mAverageFPSStartTime = mTimeLast;
  112. mAverageFPS = 0;
  113. timerReset();
  114. }
  115. void Context::timerFrame() {
  116. mTimeLastFrame = mTimeFrame;
  117. mTimeFrame = getTime();
  118. // Update average fps
  119. const uint64_t averageFramerateInterval = 1000 * 1000000;
  120. mAverageFPSFrameCount ++;
  121. uint64_t inverval = mTimeFrame - mAverageFPSStartTime;
  122. if (inverval >= averageFramerateInterval) {
  123. inverval = inverval / 1000000;
  124. mAverageFPS = (mAverageFPSFrameCount * 1000) / inverval;
  125. mAverageFPSFrameCount = 0;
  126. mAverageFPSStartTime = mTimeFrame;
  127. }
  128. }
  129. void Context::timerSet(Timers tm) {
  130. uint64_t last = mTimeLast;
  131. mTimeLast = getTime();
  132. mTimers[mTimerActive] += mTimeLast - last;
  133. mTimerActive = tm;
  134. }
  135. void Context::timerPrint() {
  136. double total = 0;
  137. for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) {
  138. total += mTimers[ct];
  139. }
  140. uint64_t frame = mTimeFrame - mTimeLastFrame;
  141. mTimeMSLastFrame = frame / 1000000;
  142. mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000;
  143. mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000;
  144. if (props.mLogTimes) {
  145. ALOGV("RS: Frame (%i), Script %2.1f%% (%i), Swap %2.1f%% (%i), Idle %2.1f%% (%" PRIi64 "), "
  146. "Internal %2.1f%% (%" PRIi64 "), Avg fps: %u",
  147. mTimeMSLastFrame,
  148. 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
  149. 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
  150. 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
  151. 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000,
  152. mAverageFPS);
  153. }
  154. }
  155. bool Context::setupCheck() {
  156. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  157. mFragmentStore->setup(this, &mStateFragmentStore);
  158. mFragment->setup(this, &mStateFragment);
  159. mRaster->setup(this, &mStateRaster);
  160. mVertex->setup(this, &mStateVertex);
  161. mFBOCache.setup(this);
  162. #endif
  163. return true;
  164. }
  165. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  166. void Context::setupProgramStore() {
  167. mFragmentStore->setup(this, &mStateFragmentStore);
  168. }
  169. #endif
  170. static uint32_t getProp(const char *str) {
  171. #ifdef __ANDROID__
  172. char buf[PROP_VALUE_MAX];
  173. property_get(str, buf, "0");
  174. return atoi(buf);
  175. #else
  176. return 0;
  177. #endif
  178. }
  179. void Context::displayDebugStats() {
  180. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  181. char buffer[128];
  182. snprintf(buffer, sizeof(buffer), "Avg fps %u, Frame %i ms, Script %i ms",
  183. mAverageFPS, mTimeMSLastFrame, mTimeMSLastScript);
  184. float oldR, oldG, oldB, oldA;
  185. mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
  186. uint32_t bufferLen = strlen(buffer);
  187. ObjectBaseRef<Font> lastFont(getFont());
  188. setFont(nullptr);
  189. float shadowCol = 0.1f;
  190. mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
  191. mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6);
  192. mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
  193. mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7);
  194. setFont(lastFont.get());
  195. mStateFont.setFontColor(oldR, oldG, oldB, oldA);
  196. #endif
  197. }
  198. void * Context::threadProc(void *vrsc) {
  199. Context *rsc = static_cast<Context *>(vrsc);
  200. rsc->mNativeThreadId = gettid();
  201. rsc->props.mLogTimes = getProp("debug.rs.profile") != 0;
  202. rsc->props.mLogScripts = getProp("debug.rs.script") != 0;
  203. rsc->props.mLogShaders = getProp("debug.rs.shader") != 0;
  204. rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0;
  205. rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0;
  206. rsc->props.mLogVisual = getProp("debug.rs.visual") != 0;
  207. rsc->props.mLogReduce = getProp("debug.rs.reduce");
  208. rsc->props.mDebugReduceSplitAccum = getProp("debug.rs.reduce-split-accum") != 0;
  209. rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads");
  210. if (getProp("debug.rs.debug") != 0) {
  211. ALOGD("Forcing debug context due to debug.rs.debug.");
  212. rsc->mContextType = RS_CONTEXT_TYPE_DEBUG;
  213. rsc->mForceCpu = true;
  214. }
  215. bool forceRSoV = getProp("debug.rs.rsov") != 0;
  216. if (forceRSoV) {
  217. ALOGD("Force the use of RSoV driver");
  218. rsc->mForceRSoV = true;
  219. }
  220. bool forceCpu = getProp("debug.rs.default-CPU-driver") != 0;
  221. if (forceCpu) {
  222. ALOGD("Skipping hardware driver and loading default CPU driver");
  223. rsc->mForceCpu = true;
  224. }
  225. rsc->mForceCpu |= rsc->mIsGraphicsContext;
  226. if (!rsc->loadDriver(rsc->mForceCpu, rsc->mForceRSoV)) {
  227. rsc->setError(RS_ERROR_DRIVER, "Failed loading driver");
  228. return nullptr;
  229. }
  230. if (!rsc->isSynchronous()) {
  231. // Due to legacy we default to normal_graphics
  232. // setPriority will make the adjustments as needed.
  233. rsc->setPriority(RS_THREAD_PRIORITY_NORMAL_GRAPHICS);
  234. }
  235. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  236. if (rsc->mIsGraphicsContext) {
  237. if (!rsc->initGLThread()) {
  238. rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
  239. return nullptr;
  240. }
  241. rsc->mStateRaster.init(rsc);
  242. rsc->setProgramRaster(nullptr);
  243. rsc->mStateVertex.init(rsc);
  244. rsc->setProgramVertex(nullptr);
  245. rsc->mStateFragment.init(rsc);
  246. rsc->setProgramFragment(nullptr);
  247. rsc->mStateFragmentStore.init(rsc);
  248. rsc->setProgramStore(nullptr);
  249. rsc->mStateFont.init(rsc);
  250. rsc->setFont(nullptr);
  251. rsc->mStateSampler.init(rsc);
  252. rsc->mFBOCache.init(rsc);
  253. }
  254. #endif
  255. rsc->mRunning = true;
  256. if (rsc->isSynchronous()) {
  257. return nullptr;
  258. }
  259. if (!rsc->mIsGraphicsContext) {
  260. while (!rsc->mExit) {
  261. rsc->mIO.playCoreCommands(rsc, -1);
  262. }
  263. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  264. } else {
  265. // The number of millisecond to wait between successive calls to the
  266. // root function. The special value 0 means that root should not be
  267. // called again until something external changes.
  268. // See compile/slang/README.rst and search for "The function **root**"
  269. // for more details.
  270. int whenToCallAgain = 0;
  271. while (!rsc->mExit) {
  272. rsc->timerSet(RS_TIMER_IDLE);
  273. // While it's tempting to simply have if(whenToCallAgain > 0)
  274. // usleep(whentoCallAgain * 1000), doing it this way emulates
  275. // more closely what the original code did.
  276. if (whenToCallAgain > 16) {
  277. usleep((whenToCallAgain - 16) * 1000);
  278. }
  279. if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused || whenToCallAgain == 0) {
  280. rsc->mIO.playCoreCommands(rsc, -1);
  281. } else {
  282. rsc->mIO.playCoreCommands(rsc, rsc->mSyncFd);
  283. }
  284. if (rsc->mRootScript.get() && rsc->mHasSurface && !rsc->mPaused) {
  285. whenToCallAgain = rsc->runRootScript();
  286. if (rsc->props.mLogVisual) {
  287. rsc->displayDebugStats();
  288. }
  289. rsc->timerSet(RS_TIMER_CLEAR_SWAP);
  290. rsc->mHal.funcs.swap(rsc);
  291. rsc->timerFrame();
  292. rsc->timerSet(RS_TIMER_INTERNAL);
  293. rsc->timerPrint();
  294. rsc->timerReset();
  295. }
  296. }
  297. #endif
  298. }
  299. //ALOGV("%p RS Thread exiting", rsc);
  300. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  301. if (rsc->mIsGraphicsContext) {
  302. pthread_mutex_lock(&gInitMutex);
  303. rsc->deinitEGL();
  304. pthread_mutex_unlock(&gInitMutex);
  305. }
  306. #endif
  307. //ALOGV("%p RS Thread exited", rsc);
  308. return nullptr;
  309. }
  310. void Context::destroyWorkerThreadResources() {
  311. //ALOGV("destroyWorkerThreadResources 1");
  312. ObjectBase::zeroAllUserRef(this);
  313. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  314. if (mIsGraphicsContext) {
  315. mRaster.clear();
  316. mFragment.clear();
  317. mVertex.clear();
  318. mFragmentStore.clear();
  319. mFont.clear();
  320. mRootScript.clear();
  321. mStateRaster.deinit(this);
  322. mStateVertex.deinit(this);
  323. mStateFragment.deinit(this);
  324. mStateFragmentStore.deinit(this);
  325. mStateFont.deinit(this);
  326. mStateSampler.deinit(this);
  327. mFBOCache.deinit(this);
  328. }
  329. #endif
  330. ObjectBase::freeAllChildren(this);
  331. mExit = true;
  332. //ALOGV("destroyWorkerThreadResources 2");
  333. }
  334. void Context::printWatchdogInfo(void *ctx) {
  335. Context *rsc = (Context *)ctx;
  336. if (rsc->watchdog.command && rsc->watchdog.file) {
  337. ALOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot,
  338. rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
  339. } else {
  340. ALOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot);
  341. }
  342. }
  343. void Context::setPriority(int32_t p) {
  344. switch (p) {
  345. // The public API will always send NORMAL_GRAPHICS
  346. // for normal, we adjust here
  347. case RS_THREAD_PRIORITY_NORMAL_GRAPHICS:
  348. if (!mIsGraphicsContext) {
  349. if (mHal.flags & RS_CONTEXT_LOW_LATENCY) {
  350. p = RS_THREAD_PRIORITY_LOW_LATENCY;
  351. } else {
  352. p = RS_THREAD_PRIORITY_NORMAL;
  353. }
  354. }
  355. break;
  356. case RS_THREAD_PRIORITY_LOW:
  357. break;
  358. }
  359. // Note: If we put this in the proper "background" policy
  360. // the wallpapers can become completly unresponsive at times.
  361. // This is probably not what we want for something the user is actively
  362. // looking at.
  363. mThreadPriority = p;
  364. setpriority(PRIO_PROCESS, mNativeThreadId, p);
  365. mHal.funcs.setPriority(this, mThreadPriority);
  366. }
  367. Context::Context() {
  368. mDev = nullptr;
  369. mRunning = false;
  370. mExit = false;
  371. mPaused = false;
  372. mObjHead = nullptr;
  373. mError = RS_ERROR_NONE;
  374. mTargetSdkVersion = 14;
  375. mDPI = 96;
  376. mIsContextLite = false;
  377. memset(&watchdog, 0, sizeof(watchdog));
  378. memset(&mHal, 0, sizeof(mHal));
  379. mForceCpu = false;
  380. mForceRSoV = false;
  381. mContextType = RS_CONTEXT_TYPE_NORMAL;
  382. mOptLevel = 3;
  383. mSynchronous = false;
  384. mFatalErrorOccured = false;
  385. memset(mCacheDir, 0, sizeof(mCacheDir));
  386. #ifdef RS_COMPATIBILITY_LIB
  387. memset(nativeLibDir, 0, sizeof(nativeLibDir));
  388. #endif
  389. }
  390. void Context::setCacheDir(const char * cacheDir_arg, uint32_t length) {
  391. if (length <= PATH_MAX) {
  392. memcpy(mCacheDir, cacheDir_arg, length);
  393. mCacheDir[length] = 0;
  394. hasSetCacheDir = true;
  395. } else {
  396. setError(RS_ERROR_BAD_VALUE, "Invalid path");
  397. }
  398. }
  399. Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc,
  400. RsContextType ct, uint32_t flags,
  401. const char* vendorDriverName) {
  402. Context * rsc = new Context();
  403. if (flags & RS_CONTEXT_LOW_LATENCY) {
  404. rsc->mForceCpu = true;
  405. }
  406. if (flags & RS_CONTEXT_SYNCHRONOUS) {
  407. rsc->mSynchronous = true;
  408. }
  409. rsc->mContextType = ct;
  410. rsc->mHal.flags = flags;
  411. rsc->mVendorDriverName = vendorDriverName;
  412. if (!rsc->initContext(dev, sc)) {
  413. delete rsc;
  414. return nullptr;
  415. }
  416. return rsc;
  417. }
  418. Context * Context::createContextLite() {
  419. Context * rsc = new Context();
  420. rsc->mIsContextLite = true;
  421. return rsc;
  422. }
  423. bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
  424. pthread_mutex_lock(&gInitMutex);
  425. if (!mIO.init()) {
  426. ALOGE("Failed initializing IO Fifo");
  427. pthread_mutex_unlock(&gInitMutex);
  428. return false;
  429. }
  430. mIO.setTimeoutCallback(printWatchdogInfo, this, 2e9);
  431. if (sc) {
  432. mUserSurfaceConfig = *sc;
  433. } else {
  434. memset(&mUserSurfaceConfig, 0, sizeof(mUserSurfaceConfig));
  435. }
  436. mIsGraphicsContext = sc != nullptr;
  437. int status;
  438. pthread_attr_t threadAttr;
  439. pthread_mutex_unlock(&gInitMutex);
  440. // Global init done at this point.
  441. status = pthread_attr_init(&threadAttr);
  442. if (status) {
  443. ALOGE("Failed to init thread attribute.");
  444. return false;
  445. }
  446. mHasSurface = false;
  447. mDriverName = NULL;
  448. timerInit();
  449. timerSet(RS_TIMER_INTERNAL);
  450. if (mSynchronous) {
  451. threadProc(this);
  452. if (mError != RS_ERROR_NONE) {
  453. ALOGE("Errors during thread init (sync mode)");
  454. return false;
  455. }
  456. } else {
  457. status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
  458. if (status) {
  459. ALOGE("Failed to start rs context thread.");
  460. return false;
  461. }
  462. while (!mRunning && (mError == RS_ERROR_NONE)) {
  463. usleep(100);
  464. }
  465. if (mError != RS_ERROR_NONE) {
  466. ALOGE("Errors during thread init");
  467. return false;
  468. }
  469. pthread_attr_destroy(&threadAttr);
  470. }
  471. return true;
  472. }
  473. Context::~Context() {
  474. if (!mIsContextLite) {
  475. mPaused = false;
  476. void *res;
  477. mIO.shutdown();
  478. if (!mSynchronous && mRunning) {
  479. // Only try to join a pthread when:
  480. // 1. The Context is asynchronous.
  481. // 2. pthread successfully created and running.
  482. pthread_join(mThreadId, &res);
  483. }
  484. rsAssert(mExit);
  485. if (mHal.funcs.shutdownDriver && mHal.drv) {
  486. mHal.funcs.shutdownDriver(this);
  487. }
  488. }
  489. }
  490. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  491. void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
  492. rsAssert(mIsGraphicsContext);
  493. mHal.funcs.setSurface(this, w, h, sur);
  494. mHasSurface = sur != nullptr;
  495. mWidth = w;
  496. mHeight = h;
  497. if (mWidth && mHeight) {
  498. mStateVertex.updateSize(this);
  499. mFBOCache.updateSize();
  500. }
  501. }
  502. uint32_t Context::getCurrentSurfaceWidth() const {
  503. for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
  504. if (mFBOCache.mHal.state.colorTargets[i] != nullptr) {
  505. return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimX();
  506. }
  507. }
  508. if (mFBOCache.mHal.state.depthTarget != nullptr) {
  509. return mFBOCache.mHal.state.depthTarget->getType()->getDimX();
  510. }
  511. return mWidth;
  512. }
  513. uint32_t Context::getCurrentSurfaceHeight() const {
  514. for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
  515. if (mFBOCache.mHal.state.colorTargets[i] != nullptr) {
  516. return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimY();
  517. }
  518. }
  519. if (mFBOCache.mHal.state.depthTarget != nullptr) {
  520. return mFBOCache.mHal.state.depthTarget->getType()->getDimY();
  521. }
  522. return mHeight;
  523. }
  524. void Context::pause() {
  525. rsAssert(mIsGraphicsContext);
  526. mPaused = true;
  527. }
  528. void Context::resume() {
  529. rsAssert(mIsGraphicsContext);
  530. mPaused = false;
  531. }
  532. void Context::setRootScript(Script *s) {
  533. rsAssert(mIsGraphicsContext);
  534. mRootScript.set(s);
  535. }
  536. void Context::setProgramStore(ProgramStore *pfs) {
  537. rsAssert(mIsGraphicsContext);
  538. if (pfs == nullptr) {
  539. mFragmentStore.set(mStateFragmentStore.mDefault);
  540. } else {
  541. mFragmentStore.set(pfs);
  542. }
  543. }
  544. void Context::setProgramFragment(ProgramFragment *pf) {
  545. rsAssert(mIsGraphicsContext);
  546. if (pf == nullptr) {
  547. mFragment.set(mStateFragment.mDefault);
  548. } else {
  549. mFragment.set(pf);
  550. }
  551. }
  552. void Context::setProgramRaster(ProgramRaster *pr) {
  553. rsAssert(mIsGraphicsContext);
  554. if (pr == nullptr) {
  555. mRaster.set(mStateRaster.mDefault);
  556. } else {
  557. mRaster.set(pr);
  558. }
  559. }
  560. void Context::setProgramVertex(ProgramVertex *pv) {
  561. rsAssert(mIsGraphicsContext);
  562. if (pv == nullptr) {
  563. mVertex.set(mStateVertex.mDefault);
  564. } else {
  565. mVertex.set(pv);
  566. }
  567. }
  568. void Context::setFont(Font *f) {
  569. rsAssert(mIsGraphicsContext);
  570. if (f == nullptr) {
  571. mFont.set(mStateFont.mDefault);
  572. } else {
  573. mFont.set(f);
  574. }
  575. }
  576. #endif
  577. void Context::finish() {
  578. if (mHal.funcs.finish) {
  579. mHal.funcs.finish(this);
  580. }
  581. }
  582. void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) {
  583. rsAssert(!obj->getName());
  584. obj->setName(name, len);
  585. mNames.push_back(obj);
  586. }
  587. void Context::removeName(ObjectBase *obj) {
  588. for (size_t ct=0; ct < mNames.size(); ct++) {
  589. if (obj == mNames[ct]) {
  590. mNames.erase(mNames.begin() + ct);
  591. return;
  592. }
  593. }
  594. }
  595. RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID) {
  596. return (RsMessageToClientType)mIO.getClientHeader(receiveLen, subID);
  597. }
  598. RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen) {
  599. return (RsMessageToClientType)mIO.getClientPayload(data, receiveLen, subID, bufferLen);
  600. }
  601. bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID,
  602. uint32_t subID, size_t len, bool waitForSpace) const {
  603. pthread_mutex_lock(&gMessageMutex);
  604. bool ret = mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
  605. pthread_mutex_unlock(&gMessageMutex);
  606. return ret;
  607. }
  608. void Context::initToClient() {
  609. while (!mRunning) {
  610. usleep(100);
  611. }
  612. }
  613. void Context::deinitToClient() {
  614. mIO.clientShutdown();
  615. }
  616. void Context::setError(RsError e, const char *msg) const {
  617. mError = e;
  618. if (mError >= RS_ERROR_FATAL_DEBUG) {
  619. // If a FATAL error occurred, set the flag to indicate the process
  620. // will be goign down
  621. mFatalErrorOccured = true;
  622. }
  623. sendMessageToClient(msg, RS_MESSAGE_TO_CLIENT_ERROR, e, strlen(msg) + 1, true);
  624. }
  625. void Context::dumpDebug() const {
  626. ALOGE("RS Context debug %p", this);
  627. ALOGE("RS Context debug");
  628. ALOGE(" RS width %i, height %i", mWidth, mHeight);
  629. ALOGE(" RS running %i, exit %i, paused %i", mRunning, mExit, mPaused);
  630. ALOGE(" RS pThreadID %li, nativeThreadID %i", (long int)mThreadId, mNativeThreadId);
  631. }
  632. ///////////////////////////////////////////////////////////////////////////////////////////
  633. //
  634. void rsi_ContextFinish(Context *rsc) {
  635. rsc->finish();
  636. }
  637. void rsi_ContextBindRootScript(Context *rsc, RsScript vs) {
  638. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  639. Script *s = static_cast<Script *>(vs);
  640. rsc->setRootScript(s);
  641. #endif
  642. }
  643. void rsi_ContextSetCacheDir(Context *rsc, const char *cacheDir, size_t cacheDir_length) {
  644. rsc->setCacheDir(cacheDir, cacheDir_length);
  645. }
  646. void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) {
  647. Sampler *s = static_cast<Sampler *>(vs);
  648. if (slot > RS_MAX_SAMPLER_SLOT) {
  649. ALOGE("Invalid sampler slot");
  650. return;
  651. }
  652. s->bindToContext(&rsc->mStateSampler, slot);
  653. }
  654. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  655. void rsi_ContextBindProgramStore(Context *rsc, RsProgramStore vpfs) {
  656. ProgramStore *pfs = static_cast<ProgramStore *>(vpfs);
  657. rsc->setProgramStore(pfs);
  658. }
  659. void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) {
  660. ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
  661. rsc->setProgramFragment(pf);
  662. }
  663. void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) {
  664. ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
  665. rsc->setProgramRaster(pr);
  666. }
  667. void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) {
  668. ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
  669. rsc->setProgramVertex(pv);
  670. }
  671. void rsi_ContextBindFont(Context *rsc, RsFont vfont) {
  672. Font *font = static_cast<Font *>(vfont);
  673. rsc->setFont(font);
  674. }
  675. #endif
  676. void rsi_AssignName(Context *rsc, RsObjectBase obj, const char *name, size_t name_length) {
  677. ObjectBase *ob = static_cast<ObjectBase *>(obj);
  678. rsc->assignName(ob, name, name_length);
  679. }
  680. void rsi_ObjDestroy(Context *rsc, void *optr) {
  681. ObjectBase *ob = static_cast<ObjectBase *>(optr);
  682. rsc->removeName(ob);
  683. ob->decUserRef();
  684. }
  685. #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB)
  686. void rsi_ContextPause(Context *rsc) {
  687. rsc->pause();
  688. }
  689. void rsi_ContextResume(Context *rsc) {
  690. rsc->resume();
  691. }
  692. void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
  693. rsc->setSurface(w, h, sur);
  694. }
  695. #endif
  696. void rsi_ContextSetPriority(Context *rsc, int32_t p) {
  697. rsc->setPriority(p);
  698. }
  699. void rsi_ContextDump(Context *rsc, int32_t bits) {
  700. ObjectBase::dumpAll(rsc);
  701. }
  702. void rsi_ContextDestroyWorker(Context *rsc) {
  703. rsc->destroyWorkerThreadResources();
  704. }
  705. void rsi_ContextDestroy(Context *rsc) {
  706. //ALOGE("%p rsContextDestroy", rsc);
  707. rsc->destroyWorkerThreadResources();
  708. delete rsc;
  709. //ALOGV("%p rsContextDestroy done", rsc);
  710. }
  711. RsMessageToClientType rsi_ContextPeekMessage(Context *rsc,
  712. size_t * receiveLen, size_t receiveLen_length,
  713. uint32_t * subID, size_t subID_length) {
  714. return rsc->peekMessageToClient(receiveLen, subID);
  715. }
  716. RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length,
  717. size_t * receiveLen, size_t receiveLen_length,
  718. uint32_t * subID, size_t subID_length) {
  719. rsAssert(subID_length == sizeof(uint32_t));
  720. rsAssert(receiveLen_length == sizeof(size_t));
  721. return rsc->getMessageToClient(data, receiveLen, subID, data_length);
  722. }
  723. void rsi_ContextInitToClient(Context *rsc) {
  724. rsc->initToClient();
  725. }
  726. void rsi_ContextDeinitToClient(Context *rsc) {
  727. rsc->deinitToClient();
  728. }
  729. void rsi_ContextSendMessage(Context *rsc, uint32_t id, const uint8_t *data, size_t len) {
  730. rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, id, len, true);
  731. }
  732. // implementation of handcode LF_ObjDestroy
  733. // required so nObjDestroy can be run from finalizer without blocking
  734. void LF_ObjDestroy_handcode(const Context *rsc, RsAsyncVoidPtr objPtr) {
  735. if (((Context *)rsc)->isSynchronous()) {
  736. rsi_ObjDestroy((Context *)rsc, objPtr);
  737. return;
  738. }
  739. // struct has two parts:
  740. // RsPlaybackRemoteHeader (cmdID and bytes)
  741. // RS_CMD_ObjDestroy (ptr)
  742. struct destroyCmd {
  743. uint32_t cmdID;
  744. uint32_t bytes;
  745. RsAsyncVoidPtr ptr;
  746. };
  747. destroyCmd cmd;
  748. cmd.cmdID = RS_CMD_ID_ObjDestroy;
  749. cmd.bytes = sizeof(RsAsyncVoidPtr);
  750. cmd.ptr = objPtr;
  751. ThreadIO *io = &((Context *)rsc)->mIO;
  752. io->coreWrite((void*)&cmd, sizeof(destroyCmd));
  753. }
  754. } // namespace renderscript
  755. } // namespace android