blob: 7bfa81edaa008b58205fb60ba6f06ad5f99bd655 [file] [log] [blame]
Jason Sams326e0dd2009-05-22 14:03:28 -07001/*
2 * Copyright (C) 2009 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"
Mathias Agopian5ae678f2009-06-22 18:01:09 -070020#include <ui/FramebufferNativeWindow.h>
Jason Sams326e0dd2009-05-22 14:03:28 -070021
Jason Sams1aa5a4e2009-06-22 17:15:15 -070022#include <GLES/gl.h>
23#include <GLES/glext.h>
24
Jason Sams326e0dd2009-05-22 14:03:28 -070025using namespace android;
26using namespace android::renderscript;
27
28Context * Context::gCon = NULL;
Jason Samse5769102009-06-19 16:03:18 -070029pthread_key_t Context::gThreadTLSKey = 0;
Jason Sams326e0dd2009-05-22 14:03:28 -070030
31void Context::initEGL()
32{
33 mNumConfigs = -1;
34
35 EGLint s_configAttribs[] = {
36 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
Jason Samsb80dfa72009-07-10 17:32:40 -070037#if 1
38 EGL_RED_SIZE, 8,
39 EGL_GREEN_SIZE, 8,
40 EGL_BLUE_SIZE, 8,
41 EGL_ALPHA_SIZE, 8,
42#else
Jason Sams326e0dd2009-05-22 14:03:28 -070043 EGL_RED_SIZE, 5,
44 EGL_GREEN_SIZE, 6,
45 EGL_BLUE_SIZE, 5,
Jason Samsb80dfa72009-07-10 17:32:40 -070046#endif
Jason Sams326e0dd2009-05-22 14:03:28 -070047 EGL_DEPTH_SIZE, 16,
48 EGL_NONE
49 };
50
Jason Sams326e0dd2009-05-22 14:03:28 -070051 mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
Jason Sams326e0dd2009-05-22 14:03:28 -070052 eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion);
Jason Sams326e0dd2009-05-22 14:03:28 -070053 eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs);
Jason Sams326e0dd2009-05-22 14:03:28 -070054
55 if (mWndSurface) {
Mathias Agopian5ae678f2009-06-22 18:01:09 -070056 mSurface = eglCreateWindowSurface(mDisplay, mConfig, mWndSurface,
Jason Sams326e0dd2009-05-22 14:03:28 -070057 NULL);
58 } else {
59 mSurface = eglCreateWindowSurface(mDisplay, mConfig,
60 android_createDisplaySurface(),
61 NULL);
62 }
63
Jason Sams326e0dd2009-05-22 14:03:28 -070064 mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL);
Jason Samsa44cb292009-06-04 17:58:03 -070065 eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
Jason Sams326e0dd2009-05-22 14:03:28 -070066 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth);
67 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight);
Jason Sams326e0dd2009-05-22 14:03:28 -070068}
69
Jason Samsa0a1b6f2009-06-10 15:04:38 -070070bool Context::runScript(Script *s, uint32_t launchID)
Jason Sams10308932009-06-09 12:15:30 -070071{
72 ObjectBaseRef<ProgramFragment> frag(mFragment);
73 ObjectBaseRef<ProgramVertex> vtx(mVertex);
74 ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
75
Jason Samsa0a1b6f2009-06-10 15:04:38 -070076 bool ret = s->run(this, launchID);
Jason Sams10308932009-06-09 12:15:30 -070077
Jason Samsa0a1b6f2009-06-10 15:04:38 -070078 mFragment.set(frag);
79 mVertex.set(vtx);
80 mFragmentStore.set(store);
Jason Samsc9d43db2009-07-28 12:02:16 -070081 return ret;
Jason Sams10308932009-06-09 12:15:30 -070082}
83
84
Jason Samsa44cb292009-06-04 17:58:03 -070085bool Context::runRootScript()
Jason Sams326e0dd2009-05-22 14:03:28 -070086{
Jason Sams10308932009-06-09 12:15:30 -070087 rsAssert(mRootScript->mEnviroment.mIsRoot);
Jason Sams326e0dd2009-05-22 14:03:28 -070088
Jason Samscfb1d112009-08-05 13:57:03 -070089 //glColor4f(1,1,1,1);
90 //glEnable(GL_LIGHT0);
Jason Sams10308932009-06-09 12:15:30 -070091 glViewport(0, 0, mWidth, mHeight);
Jason Sams326e0dd2009-05-22 14:03:28 -070092
Jason Sams326e0dd2009-05-22 14:03:28 -070093 glDepthMask(GL_TRUE);
94 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
95
Jason Sams928b7342009-06-08 18:50:13 -070096 glClearColor(mRootScript->mEnviroment.mClearColor[0],
97 mRootScript->mEnviroment.mClearColor[1],
98 mRootScript->mEnviroment.mClearColor[2],
99 mRootScript->mEnviroment.mClearColor[3]);
100 glClearDepthf(mRootScript->mEnviroment.mClearDepth);
Jason Sams326e0dd2009-05-22 14:03:28 -0700101 glClear(GL_COLOR_BUFFER_BIT);
102 glClear(GL_DEPTH_BUFFER_BIT);
103
Jason Samscfb1d112009-08-05 13:57:03 -0700104#if RS_LOG_TIMES
105 struct timespec startTime;
106 clock_gettime(CLOCK_MONOTONIC, &startTime);
107#endif
108 bool ret = runScript(mRootScript.get(), 0);
109
110#if RS_LOG_TIMES
111 struct timespec endTime;
112 clock_gettime(CLOCK_MONOTONIC, &endTime);
113
Jason Samsfcd31922009-08-17 18:35:48 -0700114 uint64_t t1 = endTime.tv_nsec + ((uint64_t)endTime.tv_sec * 1000 * 1000 * 1000);
115 uint64_t t2 = startTime.tv_nsec + ((uint64_t)startTime.tv_sec * 1000 * 1000 * 1000);
116 int t3 = (int)((t1 - t2) / 1000 / 1000);
117 LOGE("times %i", t3);
Jason Samscfb1d112009-08-05 13:57:03 -0700118#endif
119
120 return ret;
Jason Sams326e0dd2009-05-22 14:03:28 -0700121}
122
123void Context::setupCheck()
124{
125 if (mFragmentStore.get()) {
Jason Samscfb1d112009-08-05 13:57:03 -0700126 mFragmentStore->setupGL(&mStateFragmentStore);
Jason Sams326e0dd2009-05-22 14:03:28 -0700127 }
128 if (mFragment.get()) {
Jason Samscfb1d112009-08-05 13:57:03 -0700129 mFragment->setupGL(&mStateFragment);
Jason Sams326e0dd2009-05-22 14:03:28 -0700130 }
131 if (mVertex.get()) {
Jason Samscfb1d112009-08-05 13:57:03 -0700132 mVertex->setupGL(&mStateVertex);
Jason Sams326e0dd2009-05-22 14:03:28 -0700133 }
134
135}
136
137
138void * Context::threadProc(void *vrsc)
139{
140 Context *rsc = static_cast<Context *>(vrsc);
141
Jason Sams326e0dd2009-05-22 14:03:28 -0700142 rsc->initEGL();
Jason Sams8ce125b2009-06-17 16:52:59 -0700143
Jason Samse5769102009-06-19 16:03:18 -0700144 ScriptTLSStruct *tlsStruct = new ScriptTLSStruct;
145 if (!tlsStruct) {
146 LOGE("Error allocating tls storage");
147 return NULL;
148 }
149 tlsStruct->mContext = rsc;
150 tlsStruct->mScript = NULL;
151 int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct);
152 if (status) {
153 LOGE("pthread_setspecific %i", status);
154 }
155
Jason Sams8ce125b2009-06-17 16:52:59 -0700156 rsc->mStateVertex.init(rsc, rsc->mWidth, rsc->mHeight);
157 rsc->setVertex(NULL);
158 rsc->mStateFragment.init(rsc, rsc->mWidth, rsc->mHeight);
159 rsc->setFragment(NULL);
160 rsc->mStateFragmentStore.init(rsc, rsc->mWidth, rsc->mHeight);
161 rsc->setFragmentStore(NULL);
162
Jason Sams326e0dd2009-05-22 14:03:28 -0700163 rsc->mRunning = true;
Jason Samsa44cb292009-06-04 17:58:03 -0700164 bool mDraw = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700165 while (!rsc->mExit) {
Jason Samsfcd31922009-08-17 18:35:48 -0700166 mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
Jason Sams732f1c02009-06-18 16:58:42 -0700167 mDraw &= (rsc->mRootScript.get() != NULL);
Jason Sams326e0dd2009-05-22 14:03:28 -0700168
Jason Sams732f1c02009-06-18 16:58:42 -0700169 if (mDraw) {
Jason Samsa44cb292009-06-04 17:58:03 -0700170 mDraw = rsc->runRootScript();
171 eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
Jason Sams326e0dd2009-05-22 14:03:28 -0700172 }
Jason Sams50869382009-08-18 17:07:09 -0700173 rsc->objDestroyOOBRun();
Jason Sams326e0dd2009-05-22 14:03:28 -0700174 }
175
Jason Sams326e0dd2009-05-22 14:03:28 -0700176 glClearColor(0,0,0,0);
177 glClear(GL_COLOR_BUFFER_BIT);
178 eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
179 eglTerminate(rsc->mDisplay);
Jason Sams50869382009-08-18 17:07:09 -0700180 rsc->objDestroyOOBRun();
Jason Sams326e0dd2009-05-22 14:03:28 -0700181 return NULL;
182}
183
184Context::Context(Device *dev, Surface *sur)
185{
Jason Sams326e0dd2009-05-22 14:03:28 -0700186 dev->addContext(this);
187 mDev = dev;
188 mRunning = false;
189 mExit = false;
190
Jason Sams326e0dd2009-05-22 14:03:28 -0700191 // see comment in header
192 gCon = this;
193
Jason Samsa658e902009-06-04 14:35:01 -0700194 int status;
195 pthread_attr_t threadAttr;
196
Jason Samse5769102009-06-19 16:03:18 -0700197 status = pthread_key_create(&gThreadTLSKey, NULL);
198 if (status) {
199 LOGE("Failed to init thread tls key.");
200 return;
201 }
202
Jason Samsa658e902009-06-04 14:35:01 -0700203 status = pthread_attr_init(&threadAttr);
204 if (status) {
205 LOGE("Failed to init thread attribute.");
206 return;
207 }
208
209 sched_param sparam;
210 sparam.sched_priority = ANDROID_PRIORITY_DISPLAY;
211 pthread_attr_setschedparam(&threadAttr, &sparam);
212
Jason Sams992a0b72009-06-23 12:22:47 -0700213 mWndSurface = sur;
214
Jason Sams50869382009-08-18 17:07:09 -0700215 objDestroyOOBInit();
216
Jason Sams992a0b72009-06-23 12:22:47 -0700217 LOGV("RS Launching thread");
Jason Samsa658e902009-06-04 14:35:01 -0700218 status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
Jason Sams326e0dd2009-05-22 14:03:28 -0700219 if (status) {
220 LOGE("Failed to start rs context thread.");
221 }
222
Jason Sams326e0dd2009-05-22 14:03:28 -0700223 while(!mRunning) {
224 sleep(1);
225 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700226
Jason Samsa658e902009-06-04 14:35:01 -0700227 pthread_attr_destroy(&threadAttr);
Jason Sams326e0dd2009-05-22 14:03:28 -0700228}
229
230Context::~Context()
231{
232 mExit = true;
233 void *res;
234
Jason Sams326e0dd2009-05-22 14:03:28 -0700235 int status = pthread_join(mThreadId, &res);
Jason Sams50869382009-08-18 17:07:09 -0700236 objDestroyOOBRun();
Jason Sams326e0dd2009-05-22 14:03:28 -0700237
238 if (mDev) {
239 mDev->removeContext(this);
Jason Samse5769102009-06-19 16:03:18 -0700240 pthread_key_delete(gThreadTLSKey);
Jason Sams326e0dd2009-05-22 14:03:28 -0700241 }
Jason Sams50869382009-08-18 17:07:09 -0700242
243 objDestroyOOBDestroy();
Jason Sams326e0dd2009-05-22 14:03:28 -0700244}
245
246void Context::swapBuffers()
247{
248 eglSwapBuffers(mDisplay, mSurface);
249}
250
251void rsContextSwap(RsContext vrsc)
252{
253 Context *rsc = static_cast<Context *>(vrsc);
254 rsc->swapBuffers();
255}
256
257void Context::setRootScript(Script *s)
258{
259 mRootScript.set(s);
260}
261
262void Context::setFragmentStore(ProgramFragmentStore *pfs)
263{
Jason Sams8ce125b2009-06-17 16:52:59 -0700264 if (pfs == NULL) {
265 mFragmentStore.set(mStateFragmentStore.mDefault);
266 } else {
267 mFragmentStore.set(pfs);
268 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700269}
270
271void Context::setFragment(ProgramFragment *pf)
272{
Jason Sams8ce125b2009-06-17 16:52:59 -0700273 if (pf == NULL) {
274 mFragment.set(mStateFragment.mDefault);
275 } else {
276 mFragment.set(pf);
277 }
Jason Samscfb1d112009-08-05 13:57:03 -0700278}
279
280void Context::allocationCheck(const Allocation *a)
281{
282 mVertex->checkUpdatedAllocation(a);
283 mFragment->checkUpdatedAllocation(a);
284 mFragmentStore->checkUpdatedAllocation(a);
Jason Sams326e0dd2009-05-22 14:03:28 -0700285}
286
287void Context::setVertex(ProgramVertex *pv)
288{
Jason Sams8ce125b2009-06-17 16:52:59 -0700289 if (pv == NULL) {
290 mVertex.set(mStateVertex.mDefault);
291 } else {
292 mVertex.set(pv);
293 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700294}
295
Jason Samsa4a54e42009-06-10 18:39:40 -0700296void Context::assignName(ObjectBase *obj, const char *name, uint32_t len)
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700297{
298 rsAssert(!obj->getName());
Jason Samsa4a54e42009-06-10 18:39:40 -0700299 obj->setName(name, len);
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700300 mNames.add(obj);
301}
302
303void Context::removeName(ObjectBase *obj)
304{
305 for(size_t ct=0; ct < mNames.size(); ct++) {
306 if (obj == mNames[ct]) {
307 mNames.removeAt(ct);
308 return;
309 }
310 }
311}
312
313ObjectBase * Context::lookupName(const char *name) const
314{
315 for(size_t ct=0; ct < mNames.size(); ct++) {
316 if (!strcmp(name, mNames[ct]->getName())) {
317 return mNames[ct];
318 }
319 }
320 return NULL;
321}
322
Jason Samsa4a54e42009-06-10 18:39:40 -0700323void Context::appendNameDefines(String8 *str) const
324{
325 char buf[256];
326 for (size_t ct=0; ct < mNames.size(); ct++) {
327 str->append("#define NAMED_");
328 str->append(mNames[ct]->getName());
329 str->append(" ");
330 sprintf(buf, "%i\n", (int)mNames[ct]);
331 str->append(buf);
332 }
333}
334
Joe Onorato57b79ce2009-08-09 22:57:44 -0700335void Context::appendVarDefines(String8 *str) const
336{
337 char buf[256];
338 for (size_t ct=0; ct < mInt32Defines.size(); ct++) {
339 str->append("#define ");
340 str->append(mInt32Defines.keyAt(ct));
341 str->append(" ");
342 sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct));
343 str->append(buf);
344
345 }
346 for (size_t ct=0; ct < mFloatDefines.size(); ct++) {
347 str->append("#define ");
348 str->append(mFloatDefines.keyAt(ct));
349 str->append(" ");
350 sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct));
351 str->append(buf);
352 }
353}
354
Jason Sams50869382009-08-18 17:07:09 -0700355bool Context::objDestroyOOBInit()
356{
357 int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL);
358 if (status) {
359 LOGE("Context::ObjDestroyOOBInit mutex init failure");
360 return false;
361 }
362 return true;
363}
364
365void Context::objDestroyOOBRun()
366{
367 if (mObjDestroy.mNeedToEmpty) {
368 int status = pthread_mutex_lock(&mObjDestroy.mMutex);
369 if (status) {
370 LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
371 return;
372 }
373
374 for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) {
375 mObjDestroy.mDestroyList[ct]->decRef();
376 }
377 mObjDestroy.mDestroyList.clear();
378 mObjDestroy.mNeedToEmpty = false;
379
380 status = pthread_mutex_unlock(&mObjDestroy.mMutex);
381 if (status) {
382 LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
383 }
384 }
385}
386
387void Context::objDestroyOOBDestroy()
388{
389 rsAssert(!mObjDestroy.mNeedToEmpty);
390 pthread_mutex_destroy(&mObjDestroy.mMutex);
391}
392
393void Context::objDestroyAdd(ObjectBase *obj)
394{
395 int status = pthread_mutex_lock(&mObjDestroy.mMutex);
396 if (status) {
397 LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
398 return;
399 }
400
401 mObjDestroy.mNeedToEmpty = true;
402 mObjDestroy.mDestroyList.add(obj);
403
404 status = pthread_mutex_unlock(&mObjDestroy.mMutex);
405 if (status) {
406 LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
407 }
408}
409
410
Jason Samsa4a54e42009-06-10 18:39:40 -0700411
Jason Sams326e0dd2009-05-22 14:03:28 -0700412///////////////////////////////////////////////////////////////////////////////////////////
Jason Samsa44cb292009-06-04 17:58:03 -0700413//
Jason Sams326e0dd2009-05-22 14:03:28 -0700414
415namespace android {
416namespace renderscript {
417
418
419void rsi_ContextBindRootScript(Context *rsc, RsScript vs)
420{
421 Script *s = static_cast<Script *>(vs);
422 rsc->setRootScript(s);
423}
424
425void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs)
426{
427 Sampler *s = static_cast<Sampler *>(vs);
428
429 if (slot > RS_MAX_SAMPLER_SLOT) {
430 LOGE("Invalid sampler slot");
431 return;
432 }
433
434 s->bindToContext(&rsc->mStateSampler, slot);
435}
436
437void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs)
438{
439 ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs);
440 rsc->setFragmentStore(pfs);
441}
442
443void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf)
444{
445 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
446 rsc->setFragment(pf);
447}
448
449void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
450{
451 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
452 rsc->setVertex(pv);
453}
454
Jason Samsa4a54e42009-06-10 18:39:40 -0700455void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len)
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700456{
457 ObjectBase *ob = static_cast<ObjectBase *>(obj);
Jason Samsa4a54e42009-06-10 18:39:40 -0700458 rsc->assignName(ob, name, len);
Jason Samsa0a1b6f2009-06-10 15:04:38 -0700459}
Jason Sams326e0dd2009-05-22 14:03:28 -0700460
Jason Sams707aaf32009-08-18 14:14:24 -0700461void rsi_ObjDestroy(Context *rsc, void *obj)
462{
463 ObjectBase *ob = static_cast<ObjectBase *>(obj);
464 rsc->removeName(ob);
465 ob->decRef();
466}
467
Joe Onorato57b79ce2009-08-09 22:57:44 -0700468void rsi_ContextSetDefineF(Context *rsc, const char* name, float value)
469{
470 rsc->addInt32Define(name, value);
471}
472
473void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value)
474{
475 rsc->addFloatDefine(name, value);
476}
Jason Sams326e0dd2009-05-22 14:03:28 -0700477
478}
479}
480
481
482RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version)
483{
484 Device * dev = static_cast<Device *>(vdev);
485 Context *rsc = new Context(dev, (Surface *)sur);
486 return rsc;
487}
488
489void rsContextDestroy(RsContext vrsc)
490{
491 Context * rsc = static_cast<Context *>(vrsc);
492 delete rsc;
493}
494
Jason Sams50869382009-08-18 17:07:09 -0700495void rsObjDestroyOOB(RsContext vrsc, void *obj)
496{
497 Context * rsc = static_cast<Context *>(vrsc);
498 rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
499}
500