rsContext.cpp revision a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216
1/*
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"
20
21
22using namespace android;
23using namespace android::renderscript;
24
25Context * Context::gCon = NULL;
26
27void Context::initEGL()
28{
29    mNumConfigs = -1;
30
31    EGLint s_configAttribs[] = {
32         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
33         EGL_RED_SIZE,       5,
34         EGL_GREEN_SIZE,     6,
35         EGL_BLUE_SIZE,      5,
36         EGL_DEPTH_SIZE,     16,
37         EGL_NONE
38     };
39
40     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
41     eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion);
42     eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs);
43
44     if (mWndSurface) {
45         mSurface = eglCreateWindowSurface(mDisplay, mConfig,
46                 new EGLNativeWindowSurface(mWndSurface),
47                 NULL);
48     } else {
49         mSurface = eglCreateWindowSurface(mDisplay, mConfig,
50                 android_createDisplaySurface(),
51                 NULL);
52     }
53
54     mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL);
55     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
56     eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth);
57     eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight);
58}
59
60bool Context::runScript(Script *s, uint32_t launchID)
61{
62    ObjectBaseRef<ProgramFragment> frag(mFragment);
63    ObjectBaseRef<ProgramVertex> vtx(mVertex);
64    ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
65
66    bool ret = s->run(this, launchID);
67
68    mFragment.set(frag);
69    mVertex.set(vtx);
70    mFragmentStore.set(store);
71    return true;
72
73}
74
75
76bool Context::runRootScript()
77{
78    rsAssert(mRootScript->mEnviroment.mIsRoot);
79
80    glColor4f(1,1,1,1);
81    glEnable(GL_LIGHT0);
82    glViewport(0, 0, mWidth, mHeight);
83
84    if(mRootScript->mEnviroment.mIsOrtho) {
85        glMatrixMode(GL_PROJECTION);
86        glLoadIdentity();
87        glOrthof(0, mWidth,  mHeight, 0,  0, 1);
88        glMatrixMode(GL_MODELVIEW);
89    } else {
90        float aspectH = ((float)mWidth) / mHeight;
91        glMatrixMode(GL_PROJECTION);
92        glLoadIdentity();
93        glFrustumf(-1, 1,  -aspectH, aspectH,  1, 100);
94        glRotatef(-90, 0,0,1);
95        glTranslatef(0,  0,  -3);
96        glMatrixMode(GL_MODELVIEW);
97    }
98
99    glMatrixMode(GL_MODELVIEW);
100    glLoadIdentity();
101
102    glDepthMask(GL_TRUE);
103    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
104
105    glClearColor(mRootScript->mEnviroment.mClearColor[0],
106                 mRootScript->mEnviroment.mClearColor[1],
107                 mRootScript->mEnviroment.mClearColor[2],
108                 mRootScript->mEnviroment.mClearColor[3]);
109    glClearDepthf(mRootScript->mEnviroment.mClearDepth);
110    glClear(GL_COLOR_BUFFER_BIT);
111    glClear(GL_DEPTH_BUFFER_BIT);
112
113    return runScript(mRootScript.get(), 0);
114}
115
116void Context::setupCheck()
117{
118    if (mFragmentStore.get()) {
119        mFragmentStore->setupGL();
120    }
121    if (mFragment.get()) {
122        mFragment->setupGL();
123    }
124    if (mVertex.get()) {
125        mVertex->setupGL();
126    }
127
128}
129
130
131void * Context::threadProc(void *vrsc)
132{
133     Context *rsc = static_cast<Context *>(vrsc);
134
135     gIO = new ThreadIO();
136     rsc->mServerCommands.init(128);
137     rsc->mServerReturns.init(128);
138
139     rsc->initEGL();
140     rsc->mRunning = true;
141     bool mDraw = true;
142     while (!rsc->mExit) {
143         mDraw |= gIO->playCoreCommands(rsc);
144
145         if (!mDraw || !rsc->mRootScript.get()) {
146             usleep(10000);
147             continue;
148         }
149
150         if (rsc->mRootScript.get()) {
151             mDraw = rsc->runRootScript();
152             eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
153         }
154     }
155
156     glClearColor(0,0,0,0);
157     glClear(GL_COLOR_BUFFER_BIT);
158     eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
159     eglTerminate(rsc->mDisplay);
160     return NULL;
161}
162
163Context::Context(Device *dev, Surface *sur)
164{
165    dev->addContext(this);
166    mDev = dev;
167    mRunning = false;
168    mExit = false;
169
170    mServerCommands.init(256);
171    mServerReturns.init(256);
172
173    // see comment in header
174    gCon = this;
175
176    int status;
177    pthread_attr_t threadAttr;
178
179    status = pthread_attr_init(&threadAttr);
180    if (status) {
181        LOGE("Failed to init thread attribute.");
182        return;
183    }
184
185    sched_param sparam;
186    sparam.sched_priority = ANDROID_PRIORITY_DISPLAY;
187    pthread_attr_setschedparam(&threadAttr, &sparam);
188
189    LOGE("RS Launching thread");
190    status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
191    if (status) {
192        LOGE("Failed to start rs context thread.");
193    }
194
195    mWndSurface = sur;
196    while(!mRunning) {
197        sleep(1);
198    }
199
200    pthread_attr_destroy(&threadAttr);
201}
202
203Context::~Context()
204{
205    mExit = true;
206    void *res;
207
208    int status = pthread_join(mThreadId, &res);
209
210    if (mDev) {
211        mDev->removeContext(this);
212    }
213}
214
215void Context::swapBuffers()
216{
217    eglSwapBuffers(mDisplay, mSurface);
218}
219
220void rsContextSwap(RsContext vrsc)
221{
222    Context *rsc = static_cast<Context *>(vrsc);
223    rsc->swapBuffers();
224}
225
226void Context::setRootScript(Script *s)
227{
228    mRootScript.set(s);
229}
230
231void Context::setFragmentStore(ProgramFragmentStore *pfs)
232{
233    mFragmentStore.set(pfs);
234    pfs->setupGL();
235}
236
237void Context::setFragment(ProgramFragment *pf)
238{
239    mFragment.set(pf);
240    pf->setupGL();
241}
242
243void Context::setVertex(ProgramVertex *pv)
244{
245    mVertex.set(pv);
246    pv->setupGL();
247}
248
249void Context::assignName(ObjectBase *obj, const char *name)
250{
251    rsAssert(!obj->getName());
252    obj->setName(name);
253    mNames.add(obj);
254}
255
256void Context::removeName(ObjectBase *obj)
257{
258    for(size_t ct=0; ct < mNames.size(); ct++) {
259        if (obj == mNames[ct]) {
260            mNames.removeAt(ct);
261            return;
262        }
263    }
264}
265
266ObjectBase * Context::lookupName(const char *name) const
267{
268    for(size_t ct=0; ct < mNames.size(); ct++) {
269        if (!strcmp(name, mNames[ct]->getName())) {
270            return mNames[ct];
271        }
272    }
273    return NULL;
274}
275
276///////////////////////////////////////////////////////////////////////////////////////////
277//
278
279namespace android {
280namespace renderscript {
281
282
283void rsi_ContextBindRootScript(Context *rsc, RsScript vs)
284{
285    Script *s = static_cast<Script *>(vs);
286    rsc->setRootScript(s);
287}
288
289void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs)
290{
291    Sampler *s = static_cast<Sampler *>(vs);
292
293    if (slot > RS_MAX_SAMPLER_SLOT) {
294        LOGE("Invalid sampler slot");
295        return;
296    }
297
298    s->bindToContext(&rsc->mStateSampler, slot);
299}
300
301void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs)
302{
303    ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs);
304    rsc->setFragmentStore(pfs);
305}
306
307void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf)
308{
309    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
310    rsc->setFragment(pf);
311}
312
313void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
314{
315    ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
316    rsc->setVertex(pv);
317}
318
319void rsi_AssignName(Context *rsc, void * obj, const char *name)
320{
321    ObjectBase *ob = static_cast<ObjectBase *>(obj);
322    rsc->assignName(ob, name);
323}
324
325
326}
327}
328
329
330RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version)
331{
332    Device * dev = static_cast<Device *>(vdev);
333    Context *rsc = new Context(dev, (Surface *)sur);
334    return rsc;
335}
336
337void rsContextDestroy(RsContext vrsc)
338{
339    Context * rsc = static_cast<Context *>(vrsc);
340    delete rsc;
341}
342
343