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 #ifndef ANDROID_RS_CONTEXT_H
18 #define ANDROID_RS_CONTEXT_H
19 
20 #include "rsUtils.h"
21 #include "rs_hal.h"
22 #include <string.h>
23 
24 #include "rsThreadIO.h"
25 #include "rsScriptC.h"
26 #include "rsScriptGroup.h"
27 #include "rsSampler.h"
28 
29 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
30 #define ATRACE_TAG ATRACE_TAG_RS
31 #include "utils/Trace.h"
32 #else
33 #define ATRACE_ENABLED(...) false
34 #define ATRACE_NAME(...)
35 #define ATRACE_CALL(...)
36 #endif
37 
38 #ifndef RS_COMPATIBILITY_LIB
39 #include "rsFont.h"
40 #include "rsProgramFragment.h"
41 #include "rsProgramStore.h"
42 #include "rsProgramRaster.h"
43 #include "rsProgramVertex.h"
44 #include "rsFBOCache.h"
45 
46 #endif
47 
48 /*
49  * This global will be found by the debugger and will have its value flipped.
50  * It's independent of the Context class to allow the debugger to do the above
51  * without knowing the type makeup. This allows the debugger to be attached at
52  * an earlier stage.
53 */
54 extern "C" int gDebuggerPresent;
55 
56 // ---------------------------------------------------------------------------
57 namespace android {
58 
59 namespace renderscript {
60 
61 class Device;
62 
63 #if 0
64 #define CHECK_OBJ(o) { \
65     GET_TLS(); \
66     if (!ObjectBase::isValid(rsc, (const ObjectBase *)o)) {  \
67         ALOGE("Bad object %p at %s, %i", o, __FILE__, __LINE__);  \
68     } \
69 }
70 #define CHECK_OBJ_OR_NULL(o) { \
71     GET_TLS(); \
72     if (o && !ObjectBase::isValid(rsc, (const ObjectBase *)o)) {  \
73         ALOGE("Bad object %p at %s, %i", o, __FILE__, __LINE__);  \
74     } \
75 }
76 #else
77 #define CHECK_OBJ(o)
78 #define CHECK_OBJ_OR_NULL(o)
79 #endif
80 
81 
82 
83 class Context {
84 public:
85     struct Hal {
86         void * drv;
87 
88         RsdHalFunctions funcs;
89         uint32_t flags;
90     };
91     Hal mHal;
92 
93     static Context * createContext(Device *, const RsSurfaceConfig *sc,
94             RsContextType ct = RS_CONTEXT_TYPE_NORMAL,
95             uint32_t flags = 0);
96     static Context * createContextLite();
97     ~Context();
98 
99     static pthread_mutex_t gMessageMutex;
100     static pthread_mutex_t gInitMutex;
101     // Library mutex (for providing thread-safe calls from the runtime)
102     static pthread_mutex_t gLibMutex;
103 
104     class PushState {
105     public:
106         PushState(Context *);
107         ~PushState();
108 
109     private:
110 #ifndef RS_COMPATIBILITY_LIB
111         ObjectBaseRef<ProgramFragment> mFragment;
112         ObjectBaseRef<ProgramVertex> mVertex;
113         ObjectBaseRef<ProgramStore> mStore;
114         ObjectBaseRef<ProgramRaster> mRaster;
115         ObjectBaseRef<Font> mFont;
116 #endif
117         Context *mRsc;
118     };
119 
120     RsSurfaceConfig mUserSurfaceConfig;
121 
122     ElementState mStateElement;
123     TypeState mStateType;
124     SamplerState mStateSampler;
125 
isSynchronous()126     bool isSynchronous() {return mSynchronous;}
127     bool setupCheck();
128 
129 #ifndef RS_COMPATIBILITY_LIB
130     FBOCache mFBOCache;
131     ProgramFragmentState mStateFragment;
132     ProgramStoreState mStateFragmentStore;
133     ProgramRasterState mStateRaster;
134     ProgramVertexState mStateVertex;
135     FontState mStateFont;
136 
137 
138     void swapBuffers();
139     void setRootScript(Script *);
140     void setProgramRaster(ProgramRaster *);
141     void setProgramVertex(ProgramVertex *);
142     void setProgramFragment(ProgramFragment *);
143     void setProgramStore(ProgramStore *);
144     void setFont(Font *);
145 
146     void updateSurface(void *sur);
147 
getProgramFragment()148     ProgramFragment * getProgramFragment() {return mFragment.get();}
getProgramStore()149     ProgramStore * getProgramStore() {return mFragmentStore.get();}
getProgramRaster()150     ProgramRaster * getProgramRaster() {return mRaster.get();}
getProgramVertex()151     ProgramVertex * getProgramVertex() {return mVertex.get();}
getFont()152     Font * getFont() {return mFont.get();}
153 
154     void setupProgramStore();
155 
156     void pause();
157     void resume();
158     void setSurface(uint32_t w, uint32_t h, RsNativeWindow sur);
159 #endif
160     void finish();
161 
162     void setPriority(int32_t p);
163     void destroyWorkerThreadResources();
164 
165     void assignName(ObjectBase *obj, const char *name, uint32_t len);
166     void removeName(ObjectBase *obj);
167 
168     RsMessageToClientType peekMessageToClient(size_t *receiveLen, uint32_t *subID);
169     RsMessageToClientType getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen);
170     bool sendMessageToClient(const void *data, RsMessageToClientType cmdID, uint32_t subID, size_t len, bool waitForSpace) const;
171     uint32_t runScript(Script *s);
172 
173     void initToClient();
174     void deinitToClient();
175 
176 #ifndef RS_COMPATIBILITY_LIB
getDefaultProgramFragment()177     ProgramFragment * getDefaultProgramFragment() const {
178         return mStateFragment.mDefault.get();
179     }
getDefaultProgramVertex()180     ProgramVertex * getDefaultProgramVertex() const {
181         return mStateVertex.mDefault.get();
182     }
getDefaultProgramStore()183     ProgramStore * getDefaultProgramStore() const {
184         return mStateFragmentStore.mDefault.get();
185     }
getDefaultProgramRaster()186     ProgramRaster * getDefaultProgramRaster() const {
187         return mStateRaster.mDefault.get();
188     }
getDefaultFont()189     Font* getDefaultFont() const {
190         return mStateFont.mDefault.get();
191     }
192 
getWidth()193     uint32_t getWidth() const {return mWidth;}
getHeight()194     uint32_t getHeight() const {return mHeight;}
195 
196     uint32_t getCurrentSurfaceWidth() const;
197     uint32_t getCurrentSurfaceHeight() const;
198 
setWatchdogGL(const char * cmd,uint32_t line,const char * file)199     void setWatchdogGL(const char *cmd, uint32_t line, const char *file) const {
200         watchdog.command = cmd;
201         watchdog.file = file;
202         watchdog.line = line;
203     }
204 #endif
205 
206     mutable ThreadIO mIO;
207 
208     // Timers
209     enum Timers {
210         RS_TIMER_IDLE,
211         RS_TIMER_INTERNAL,
212         RS_TIMER_SCRIPT,
213         RS_TIMER_CLEAR_SWAP,
214         _RS_TIMER_TOTAL
215     };
216     uint64_t getTime() const;
217     void timerInit();
218     void timerReset();
219     void timerSet(Timers);
220     void timerPrint();
221     void timerFrame();
222 
223     struct {
224         bool mLogTimes;
225         bool mLogScripts;
226         bool mLogShaders;
227         bool mLogShadersAttr;
228         bool mLogShadersUniforms;
229         bool mLogVisual;
230         uint32_t mLogReduce;
231         bool mDebugReduceSplitAccum;
232         uint32_t mDebugMaxThreads;
233     } props;
234 
235     mutable struct {
236         bool inRoot;
237         const char *command;
238         const char *file;
239         uint32_t line;
240     } watchdog;
241     static void printWatchdogInfo(void *ctx);
242 
243     void dumpDebug() const;
244     void setError(RsError e, const char *msg = nullptr) const;
245 
246     mutable const ObjectBase * mObjHead;
247 
getDPI()248     uint32_t getDPI() const {return mDPI;}
setDPI(uint32_t dpi)249     void setDPI(uint32_t dpi) {mDPI = dpi;}
250 
getTargetSdkVersion()251     uint32_t getTargetSdkVersion() const {return mTargetSdkVersion;}
setTargetSdkVersion(uint32_t sdkVer)252     void setTargetSdkVersion(uint32_t sdkVer) {mTargetSdkVersion = sdkVer;}
253 
getContextType()254     RsContextType getContextType() const { return mContextType; }
setContextType(RsContextType ct)255     void setContextType(RsContextType ct) { mContextType = ct; }
256 
257     // Check for Fatal errors
258     // Should be used to prevent work from being launched
259     // which could take the process down.  Maximizes the chance
260     // the process lives long enough to get the error to the developer
hadFatalError()261     bool hadFatalError() {return mFatalErrorOccured;}
262 
getOptLevel()263     uint32_t getOptLevel() const { return mOptLevel; }
setOptLevel(uint32_t optLevel)264     void setOptLevel(uint32_t optLevel) { mOptLevel = optLevel; }
265 
266     Device *mDev;
267 
268 #ifdef RS_COMPATIBILITY_LIB
setNativeLibDir(const char * libDir,uint32_t length)269     void setNativeLibDir(const char * libDir, uint32_t length) {
270         if (!hasSetNativeLibDir) {
271             if (length <= PATH_MAX) {
272                 memcpy(nativeLibDir, libDir, length);
273                 nativeLibDir[length] = 0;
274                 hasSetNativeLibDir = true;
275             } else {
276                 setError(RS_ERROR_BAD_VALUE, "Invalid path");
277             }
278         }
279     }
getNativeLibDir()280     const char * getNativeLibDir() {
281         return nativeLibDir;
282     }
283 #endif
284 
285     void setCacheDir(const char * cacheDir_arg, uint32_t length);
getCacheDir()286     const char * getCacheDir() {
287         if (hasSetCacheDir) {
288             return mCacheDir;
289         }
290         return nullptr;
291     }
292 
293     // Returns the actual loaded driver's name (like "libRSDriver.so").
getDriverName()294     const char * getDriverName() {
295         return mDriverName;
296     }
297 
298     // Set a new driver name, should be called from within
299     // rsdHalInit in order to alter default behaviour.
setDriverName(const char * name)300     void setDriverName(const char * name) {
301         if (!mDriverName) {
302             mDriverName = name;
303         }
304     }
305 
306 
307 protected:
308 
309     uint32_t mTargetSdkVersion;
310     uint32_t mDPI;
311     uint32_t mWidth;
312     uint32_t mHeight;
313     int32_t mThreadPriority;
314     bool mIsGraphicsContext;
315 
316     bool mForceCpu;
317 
318     RsContextType mContextType;
319     uint32_t mOptLevel;
320 
321     bool mRunning;
322     bool mExit;
323     bool mPaused;
324     mutable bool mFatalErrorOccured;
325     mutable RsError mError;
326 
327 
328     pthread_t mThreadId;
329     pid_t mNativeThreadId;
330 
331     ObjectBaseRef<Script> mRootScript;
332 #ifndef RS_COMPATIBILITY_LIB
333     ObjectBaseRef<ProgramFragment> mFragment;
334     ObjectBaseRef<ProgramVertex> mVertex;
335     ObjectBaseRef<ProgramStore> mFragmentStore;
336     ObjectBaseRef<ProgramRaster> mRaster;
337     ObjectBaseRef<Font> mFont;
338 #endif
339 
340     void displayDebugStats();
341 
342 private:
343     Context();
344     bool initContext(Device *, const RsSurfaceConfig *sc);
345     void waitForDebugger();
346     bool mSynchronous;
347     bool initGLThread();
348     void deinitEGL();
349 
350     uint32_t runRootScript();
351 
352     bool loadRuntime(const char* filename);
353     bool loadDriver(bool forceDefault);
354     static void * threadProc(void *);
355     static void * helperThreadProc(void *);
356 
357     bool mHasSurface;
358     bool mIsContextLite;
359 
360     // This holds the name of the driver (like "libRSDriver.so").
361     // Since this is always just a static string, we don't have to
362     // allocate, copy, or free any memory here.
363     const char* mDriverName;
364 
365     Vector<ObjectBase *> mNames;
366 
367     uint64_t mTimers[_RS_TIMER_TOTAL];
368     Timers mTimerActive;
369     uint64_t mTimeLast;
370     uint64_t mTimeFrame;
371     uint64_t mTimeLastFrame;
372     uint32_t mTimeMSLastFrame;
373     uint32_t mTimeMSLastScript;
374     uint32_t mTimeMSLastSwap;
375     uint32_t mAverageFPSFrameCount;
376     uint64_t mAverageFPSStartTime;
377     uint32_t mAverageFPS;
378 #ifdef RS_COMPATIBILITY_LIB
379     bool hasSetNativeLibDir = false;
380     char nativeLibDir[PATH_MAX+1];
381 #endif
382     bool hasSetCacheDir = false;
383     char mCacheDir[PATH_MAX+1];
384 };
385 
386 void LF_ObjDestroy_handcode(const Context *rsc, RsAsyncVoidPtr objPtr);
387 
388 } // renderscript
389 } // android
390 #endif
391