diff options
| author | 2009-11-15 12:06:20 -0800 | |
|---|---|---|
| committer | 2009-11-15 12:06:23 -0800 | |
| commit | 478de466ce0504b9af639c3338b883893670a8e8 (patch) | |
| tree | 61aba455baf06a4821a65b82d1115929619b49bd /libs/rs/rsContext.cpp | |
| parent | 2b63ff51d5202eb2b458e937d4b65b326238733e (diff) | |
| parent | 9db3d07b9620b4269ab33f78604a36327e536ce1 (diff) | |
merge from eclair
Diffstat (limited to 'libs/rs/rsContext.cpp')
| -rw-r--r-- | libs/rs/rsContext.cpp | 815 |
1 files changed, 815 insertions, 0 deletions
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp new file mode 100644 index 000000000000..3e4cc36bc36a --- /dev/null +++ b/libs/rs/rsContext.cpp @@ -0,0 +1,815 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rsDevice.h" +#include "rsContext.h" +#include "rsThreadIO.h" +#include <ui/FramebufferNativeWindow.h> +#include <ui/EGLUtils.h> + +#include <cutils/properties.h> + +#include <GLES/gl.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + +pthread_key_t Context::gThreadTLSKey = 0; +uint32_t Context::gThreadTLSKeyCount = 0; +uint32_t Context::gGLContextCount = 0; +pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER; + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +void Context::initEGL() +{ + mEGL.mNumConfigs = -1; + EGLint configAttribs[128]; + EGLint *configAttribsPtr = configAttribs; + + memset(configAttribs, 0, sizeof(configAttribs)); + + configAttribsPtr[0] = EGL_SURFACE_TYPE; + configAttribsPtr[1] = EGL_WINDOW_BIT; + configAttribsPtr += 2; + + if (mUseDepth) { + configAttribsPtr[0] = EGL_DEPTH_SIZE; + configAttribsPtr[1] = 16; + configAttribsPtr += 2; + } + + if (mDev->mForceSW) { + configAttribsPtr[0] = EGL_CONFIG_CAVEAT; + configAttribsPtr[1] = EGL_SLOW_CONFIG; + configAttribsPtr += 2; + } + + configAttribsPtr[0] = EGL_NONE; + rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint)))); + + LOGV("initEGL start"); + mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + + eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion); + checkEglError("eglInitialize"); + + status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig); + if (err) { + LOGE("couldn't find an EGLConfig matching the screen format\n"); + } + //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs); + + + mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL); + checkEglError("eglCreateContext"); + if (mEGL.mContext == EGL_NO_CONTEXT) { + LOGE("eglCreateContext returned EGL_NO_CONTEXT"); + } + gGLContextCount++; + + if (mWndSurface) { + setSurface(mWndSurface); + } else { + setSurface((Surface *)android_createDisplaySurface()); + } + + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); + + + mGL.mVersion = glGetString(GL_VERSION); + mGL.mVendor = glGetString(GL_VENDOR); + mGL.mRenderer = glGetString(GL_RENDERER); + mGL.mExtensions = glGetString(GL_EXTENSIONS); + + LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); + LOGV("GL Version %s", mGL.mVersion); + LOGV("GL Vendor %s", mGL.mVendor); + LOGV("GL Renderer %s", mGL.mRenderer); + LOGV("GL Extensions %s", mGL.mExtensions); + + if ((strlen((const char *)mGL.mVersion) < 12) || memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { + LOGE("Error, OpenGL ES Lite not supported"); + } else { + sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); + } +} + +void Context::deinitEGL() +{ + setSurface(NULL); + eglDestroyContext(mEGL.mDisplay, mEGL.mContext); + checkEglError("eglDestroyContext"); + + gGLContextCount--; + if (!gGLContextCount) { + eglTerminate(mEGL.mDisplay); + } +} + + +bool Context::runScript(Script *s, uint32_t launchID) +{ + ObjectBaseRef<ProgramFragment> frag(mFragment); + ObjectBaseRef<ProgramVertex> vtx(mVertex); + ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore); + ObjectBaseRef<ProgramRaster> raster(mRaster); + + bool ret = s->run(this, launchID); + + mFragment.set(frag); + mVertex.set(vtx); + mFragmentStore.set(store); + mRaster.set(raster); + return ret; +} + + +bool Context::runRootScript() +{ + if (props.mLogTimes) { + timerSet(RS_TIMER_CLEAR_SWAP); + } + rsAssert(mRootScript->mEnviroment.mIsRoot); + + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); + glViewport(0, 0, mEGL.mWidth, mEGL.mHeight); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glClearColor(mRootScript->mEnviroment.mClearColor[0], + mRootScript->mEnviroment.mClearColor[1], + mRootScript->mEnviroment.mClearColor[2], + mRootScript->mEnviroment.mClearColor[3]); + if (mUseDepth) { + glDepthMask(GL_TRUE); + glClearDepthf(mRootScript->mEnviroment.mClearDepth); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } else { + glClear(GL_COLOR_BUFFER_BIT); + } + + if (this->props.mLogTimes) { + timerSet(RS_TIMER_SCRIPT); + } + mStateFragmentStore.mLast.clear(); + bool ret = runScript(mRootScript.get(), 0); + + GLenum err = glGetError(); + if (err != GL_NO_ERROR) { + LOGE("Pending GL Error, 0x%x", err); + } + + return ret; +} + +uint64_t Context::getTime() const +{ + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); +} + +void Context::timerReset() +{ + for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) { + mTimers[ct] = 0; + } +} + +void Context::timerInit() +{ + mTimeLast = getTime(); + mTimeFrame = mTimeLast; + mTimeLastFrame = mTimeLast; + mTimerActive = RS_TIMER_INTERNAL; + timerReset(); +} + +void Context::timerFrame() +{ + mTimeLastFrame = mTimeFrame; + mTimeFrame = getTime(); +} + +void Context::timerSet(Timers tm) +{ + uint64_t last = mTimeLast; + mTimeLast = getTime(); + mTimers[mTimerActive] += mTimeLast - last; + mTimerActive = tm; +} + +void Context::timerPrint() +{ + double total = 0; + for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) { + total += mTimers[ct]; + } + uint64_t frame = mTimeFrame - mTimeLastFrame; + + LOGV("RS: Frame (%lli), Script %2.1f (%lli), Clear & Swap %2.1f (%lli), Idle %2.1f (%lli), Internal %2.1f (%lli)", + frame / 1000000, + 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimers[RS_TIMER_SCRIPT] / 1000000, + 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimers[RS_TIMER_CLEAR_SWAP] / 1000000, + 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000, + 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000); +} + +void Context::setupCheck() +{ + mFragmentStore->setupGL(this, &mStateFragmentStore); + mFragment->setupGL(this, &mStateFragment); + mRaster->setupGL(this, &mStateRaster); + mVertex->setupGL(this, &mStateVertex); +} + +static bool getProp(const char *str) +{ + char buf[PROPERTY_VALUE_MAX]; + property_get(str, buf, "0"); + return 0 != strcmp(buf, "0"); +} + +void * Context::threadProc(void *vrsc) +{ + Context *rsc = static_cast<Context *>(vrsc); + + rsc->props.mLogTimes = getProp("debug.rs.profile"); + rsc->props.mLogScripts = getProp("debug.rs.script"); + rsc->props.mLogObjects = getProp("debug.rs.objects"); + + pthread_mutex_lock(&gInitMutex); + rsc->initEGL(); + pthread_mutex_unlock(&gInitMutex); + + ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; + if (!tlsStruct) { + LOGE("Error allocating tls storage"); + return NULL; + } + tlsStruct->mContext = rsc; + tlsStruct->mScript = NULL; + int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct); + if (status) { + LOGE("pthread_setspecific %i", status); + } + + rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); + rsc->setRaster(NULL); + rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); + rsc->setVertex(NULL); + rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); + rsc->setFragment(NULL); + rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); + rsc->setFragmentStore(NULL); + + rsc->mRunning = true; + bool mDraw = true; + while (!rsc->mExit) { + mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw); + mDraw &= (rsc->mRootScript.get() != NULL); + mDraw &= (rsc->mWndSurface != NULL); + + if (mDraw) { + mDraw = rsc->runRootScript() && !rsc->mPaused; + if (rsc->props.mLogTimes) { + rsc->timerSet(RS_TIMER_CLEAR_SWAP); + } + eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); + if (rsc->props.mLogTimes) { + rsc->timerFrame(); + rsc->timerSet(RS_TIMER_INTERNAL); + rsc->timerPrint(); + rsc->timerReset(); + } + } + if (rsc->mObjDestroy.mNeedToEmpty) { + rsc->objDestroyOOBRun(); + } + } + + LOGV("RS Thread exiting"); + rsc->mRaster.clear(); + rsc->mFragment.clear(); + rsc->mVertex.clear(); + rsc->mFragmentStore.clear(); + rsc->mRootScript.clear(); + rsc->mStateRaster.deinit(rsc); + rsc->mStateVertex.deinit(rsc); + rsc->mStateFragment.deinit(rsc); + rsc->mStateFragmentStore.deinit(rsc); + ObjectBase::zeroAllUserRef(rsc); + + rsc->mObjDestroy.mNeedToEmpty = true; + rsc->objDestroyOOBRun(); + + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); + + pthread_mutex_lock(&gInitMutex); + rsc->deinitEGL(); + pthread_mutex_unlock(&gInitMutex); + + LOGV("RS Thread exited"); + return NULL; +} + +Context::Context(Device *dev, Surface *sur, bool useDepth) +{ + pthread_mutex_lock(&gInitMutex); + + dev->addContext(this); + mDev = dev; + mRunning = false; + mExit = false; + mUseDepth = useDepth; + mPaused = false; + mObjHead = NULL; + + int status; + pthread_attr_t threadAttr; + + if (!gThreadTLSKeyCount) { + status = pthread_key_create(&gThreadTLSKey, NULL); + if (status) { + LOGE("Failed to init thread tls key."); + pthread_mutex_unlock(&gInitMutex); + return; + } + } + gThreadTLSKeyCount++; + pthread_mutex_unlock(&gInitMutex); + + // Global init done at this point. + + status = pthread_attr_init(&threadAttr); + if (status) { + LOGE("Failed to init thread attribute."); + return; + } + + sched_param sparam; + sparam.sched_priority = ANDROID_PRIORITY_DISPLAY; + pthread_attr_setschedparam(&threadAttr, &sparam); + + mWndSurface = sur; + + objDestroyOOBInit(); + timerInit(); + timerSet(RS_TIMER_INTERNAL); + + LOGV("RS Launching thread"); + status = pthread_create(&mThreadId, &threadAttr, threadProc, this); + if (status) { + LOGE("Failed to start rs context thread."); + } + + while(!mRunning) { + usleep(100); + } + + pthread_attr_destroy(&threadAttr); +} + +Context::~Context() +{ + LOGV("Context::~Context"); + mExit = true; + mPaused = false; + void *res; + + mIO.shutdown(); + int status = pthread_join(mThreadId, &res); + mObjDestroy.mNeedToEmpty = true; + objDestroyOOBRun(); + + // Global structure cleanup. + pthread_mutex_lock(&gInitMutex); + if (mDev) { + mDev->removeContext(this); + --gThreadTLSKeyCount; + if (!gThreadTLSKeyCount) { + pthread_key_delete(gThreadTLSKey); + } + mDev = NULL; + } + pthread_mutex_unlock(&gInitMutex); + + objDestroyOOBDestroy(); +} + +void Context::setSurface(Surface *sur) +{ + EGLBoolean ret; + if (mEGL.mSurface != NULL) { + ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + checkEglError("eglMakeCurrent", ret); + + ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface); + checkEglError("eglDestroySurface", ret); + + mEGL.mSurface = NULL; + } + + mWndSurface = sur; + if (mWndSurface != NULL) { + mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL); + checkEglError("eglCreateWindowSurface"); + if (mEGL.mSurface == EGL_NO_SURFACE) { + LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE"); + } + + ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext); + checkEglError("eglMakeCurrent", ret); + } +} + +void Context::pause() +{ + mPaused = true; +} + +void Context::resume() +{ + mPaused = false; +} + +void Context::setRootScript(Script *s) +{ + mRootScript.set(s); +} + +void Context::setFragmentStore(ProgramFragmentStore *pfs) +{ + if (pfs == NULL) { + mFragmentStore.set(mStateFragmentStore.mDefault); + } else { + mFragmentStore.set(pfs); + } +} + +void Context::setFragment(ProgramFragment *pf) +{ + if (pf == NULL) { + mFragment.set(mStateFragment.mDefault); + } else { + mFragment.set(pf); + } +} + +void Context::setRaster(ProgramRaster *pr) +{ + if (pr == NULL) { + mRaster.set(mStateRaster.mDefault); + } else { + mRaster.set(pr); + } +} + +void Context::allocationCheck(const Allocation *a) +{ + mVertex->checkUpdatedAllocation(a); + mFragment->checkUpdatedAllocation(a); + mFragmentStore->checkUpdatedAllocation(a); +} + +void Context::setVertex(ProgramVertex *pv) +{ + if (pv == NULL) { + mVertex.set(mStateVertex.mDefault); + } else { + mVertex.set(pv); + } + mVertex->forceDirty(); +} + +void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) +{ + rsAssert(!obj->getName()); + obj->setName(name, len); + mNames.add(obj); +} + +void Context::removeName(ObjectBase *obj) +{ + for(size_t ct=0; ct < mNames.size(); ct++) { + if (obj == mNames[ct]) { + mNames.removeAt(ct); + return; + } + } +} + +ObjectBase * Context::lookupName(const char *name) const +{ + for(size_t ct=0; ct < mNames.size(); ct++) { + if (!strcmp(name, mNames[ct]->getName())) { + return mNames[ct]; + } + } + return NULL; +} + +void Context::appendNameDefines(String8 *str) const +{ + char buf[256]; + for (size_t ct=0; ct < mNames.size(); ct++) { + str->append("#define NAMED_"); + str->append(mNames[ct]->getName()); + str->append(" "); + sprintf(buf, "%i\n", (int)mNames[ct]); + str->append(buf); + } +} + +void Context::appendVarDefines(String8 *str) const +{ + char buf[256]; + for (size_t ct=0; ct < mInt32Defines.size(); ct++) { + str->append("#define "); + str->append(mInt32Defines.keyAt(ct)); + str->append(" "); + sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct)); + str->append(buf); + + } + for (size_t ct=0; ct < mFloatDefines.size(); ct++) { + str->append("#define "); + str->append(mFloatDefines.keyAt(ct)); + str->append(" "); + sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct)); + str->append(buf); + } +} + +bool Context::objDestroyOOBInit() +{ + int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL); + if (status) { + LOGE("Context::ObjDestroyOOBInit mutex init failure"); + return false; + } + return true; +} + +void Context::objDestroyOOBRun() +{ + if (mObjDestroy.mNeedToEmpty) { + int status = pthread_mutex_lock(&mObjDestroy.mMutex); + if (status) { + LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status); + return; + } + + for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) { + mObjDestroy.mDestroyList[ct]->decUserRef(); + } + mObjDestroy.mDestroyList.clear(); + mObjDestroy.mNeedToEmpty = false; + + status = pthread_mutex_unlock(&mObjDestroy.mMutex); + if (status) { + LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status); + } + } +} + +void Context::objDestroyOOBDestroy() +{ + rsAssert(!mObjDestroy.mNeedToEmpty); + pthread_mutex_destroy(&mObjDestroy.mMutex); +} + +void Context::objDestroyAdd(ObjectBase *obj) +{ + int status = pthread_mutex_lock(&mObjDestroy.mMutex); + if (status) { + LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status); + return; + } + + mObjDestroy.mNeedToEmpty = true; + mObjDestroy.mDestroyList.add(obj); + + status = pthread_mutex_unlock(&mObjDestroy.mMutex); + if (status) { + LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status); + } +} + +uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait) +{ + //LOGE("getMessageToClient %i %i", bufferLen, wait); + if (!wait) { + if (mIO.mToClient.isEmpty()) { + // No message to get and not going to wait for one. + receiveLen = 0; + return 0; + } + } + + //LOGE("getMessageToClient 2 con=%p", this); + uint32_t bytesData = 0; + uint32_t commandID = 0; + const void *d = mIO.mToClient.get(&commandID, &bytesData); + //LOGE("getMessageToClient 3 %i %i", commandID, bytesData); + + *receiveLen = bytesData; + if (bufferLen >= bytesData) { + memcpy(data, d, bytesData); + mIO.mToClient.next(); + return commandID; + } + return 0; +} + +bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace) +{ + //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace); + if (cmdID == 0) { + LOGE("Attempting to send invalid command 0 to client."); + return false; + } + if (!waitForSpace) { + if (mIO.mToClient.getFreeSpace() < len) { + // Not enough room, and not waiting. + return false; + } + } + //LOGE("sendMessageToClient 2"); + void *p = mIO.mToClient.reserve(len); + memcpy(p, data, len); + mIO.mToClient.commit(cmdID, len); + //LOGE("sendMessageToClient 3"); + return true; +} + +void Context::initToClient() +{ + while(!mRunning) { + usleep(100); + } +} + +void Context::deinitToClient() +{ + mIO.mToClient.shutdown(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// + +namespace android { +namespace renderscript { + + +void rsi_ContextBindRootScript(Context *rsc, RsScript vs) +{ + Script *s = static_cast<Script *>(vs); + rsc->setRootScript(s); +} + +void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) +{ + Sampler *s = static_cast<Sampler *>(vs); + + if (slot > RS_MAX_SAMPLER_SLOT) { + LOGE("Invalid sampler slot"); + return; + } + + s->bindToContext(&rsc->mStateSampler, slot); +} + +void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs) +{ + ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs); + rsc->setFragmentStore(pfs); +} + +void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) +{ + ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); + rsc->setFragment(pf); +} + +void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) +{ + ProgramRaster *pr = static_cast<ProgramRaster *>(vpr); + rsc->setRaster(pr); +} + +void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) +{ + ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); + rsc->setVertex(pv); +} + +void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len) +{ + ObjectBase *ob = static_cast<ObjectBase *>(obj); + rsc->assignName(ob, name, len); +} + +void rsi_ObjDestroy(Context *rsc, void *obj) +{ + ObjectBase *ob = static_cast<ObjectBase *>(obj); + rsc->removeName(ob); + ob->decUserRef(); +} + +void rsi_ContextSetDefineF(Context *rsc, const char* name, float value) +{ + rsc->addInt32Define(name, value); +} + +void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value) +{ + rsc->addFloatDefine(name, value); +} + +void rsi_ContextPause(Context *rsc) +{ + rsc->pause(); +} + +void rsi_ContextResume(Context *rsc) +{ + rsc->resume(); +} + +void rsi_ContextSetSurface(Context *rsc, void *sur) +{ + rsc->setSurface((Surface *)sur); +} + +} +} + + +RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version, bool useDepth) +{ + Device * dev = static_cast<Device *>(vdev); + Context *rsc = new Context(dev, (Surface *)sur, useDepth); + return rsc; +} + +void rsContextDestroy(RsContext vrsc) +{ + Context * rsc = static_cast<Context *>(vrsc); + delete rsc; +} + +void rsObjDestroyOOB(RsContext vrsc, void *obj) +{ + Context * rsc = static_cast<Context *>(vrsc); + rsc->objDestroyAdd(static_cast<ObjectBase *>(obj)); +} + +uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait) +{ + Context * rsc = static_cast<Context *>(vrsc); + return rsc->getMessageToClient(data, receiveLen, bufferLen, wait); +} + +void rsContextInitToClient(RsContext vrsc) +{ + Context * rsc = static_cast<Context *>(vrsc); + rsc->initToClient(); +} + +void rsContextDeinitToClient(RsContext vrsc) +{ + Context * rsc = static_cast<Context *>(vrsc); + rsc->deinitToClient(); +} + |