1 /*
2  * Copyright (C) 2012 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 RSD_CPU_CORE_H
18 #define RSD_CPU_CORE_H
19 
20 #include "rsd_cpu.h"
21 #include "rsSignal.h"
22 #include "rsContext.h"
23 #include "rsCppUtils.h"
24 #include "rsElement.h"
25 #include "rsScriptC.h"
26 #include "rsCpuCoreRuntime.h"
27 
28 namespace bcc {
29     class BCCContext;
30     class RSCompilerDriver;
31     class RSExecutable;
32 }
33 
34 namespace android {
35 namespace renderscript {
36 
37 // Whether the CPU we're running on supports SIMD instructions
38 extern bool gArchUseSIMD;
39 
40 typedef void (* InvokeFunc_t)(void);
41 typedef void (* ForEachFunc_t)(void);
42 typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
43 
44 class RsdCpuScriptImpl;
45 class RsdCpuReferenceImpl;
46 
47 struct ScriptTLSStruct {
48     android::renderscript::Context * mContext;
49     const android::renderscript::Script * mScript;
50     RsdCpuScriptImpl *mImpl;
51 };
52 
53 struct MTLaunchStruct {
54     RsExpandKernelDriverInfo fep;
55 
56     RsdCpuReferenceImpl *rsc;
57     RsdCpuScriptImpl *script;
58 
59     ForEachFunc_t kernel;
60     uint32_t sig;
61     const Allocation * ains[RS_KERNEL_INPUT_LIMIT];
62     Allocation * aout[RS_KERNEL_INPUT_LIMIT];
63 
64     uint32_t mSliceSize;
65     volatile int mSliceNum;
66     bool isThreadable;
67 
68     RsLaunchDimensions start;
69     RsLaunchDimensions end;
70 };
71 
72 class RsdCpuReferenceImpl : public RsdCpuReference {
73 public:
74     ~RsdCpuReferenceImpl() override;
75     RsdCpuReferenceImpl(Context *);
76 
77     void lockMutex();
78     void unlockMutex();
79 
80     bool init(uint32_t version_major, uint32_t version_minor, sym_lookup_t, script_lookup_t);
81     void setPriority(int32_t priority) override;
82     virtual void launchThreads(WorkerCallback_t cbk, void *data);
83     static void * helperThreadProc(void *vrsc);
84     RsdCpuScriptImpl * setTLS(RsdCpuScriptImpl *sc);
85 
getContext()86     Context * getContext() {return mRSC;}
getThreadCount()87     uint32_t getThreadCount() const {
88         return mWorkers.mCount + 1;
89     }
90 
91     void launchThreads(const Allocation** ains, uint32_t inLen, Allocation* aout,
92                        const RsScriptCall* sc, MTLaunchStruct* mtls);
93 
94     CpuScript * createScript(const ScriptC *s, char const *resName, char const *cacheDir,
95                              uint8_t const *bitcode, size_t bitcodeSize, uint32_t flags) override;
96     CpuScript * createIntrinsic(const Script *s, RsScriptIntrinsicID iid, Element *e) override;
97     void* createScriptGroup(const ScriptGroupBase *sg) override;
98 
99     const RsdCpuReference::CpuSymbol *symLookup(const char *);
100 
lookupScript(const Script * s)101     RsdCpuReference::CpuScript * lookupScript(const Script *s) {
102         return mScriptLookupFn(mRSC, s);
103     }
104 
setLinkRuntimeCallback(bcc::RSLinkRuntimeCallback pLinkRuntimeCallback)105     void setLinkRuntimeCallback(
106             bcc::RSLinkRuntimeCallback pLinkRuntimeCallback) {
107         mLinkRuntimeCallback = pLinkRuntimeCallback;
108     }
getLinkRuntimeCallback()109     bcc::RSLinkRuntimeCallback getLinkRuntimeCallback() {
110         return mLinkRuntimeCallback;
111     }
112 
setSelectRTCallback(RSSelectRTCallback pSelectRTCallback)113     void setSelectRTCallback(RSSelectRTCallback pSelectRTCallback) {
114         mSelectRTCallback = pSelectRTCallback;
115     }
getSelectRTCallback()116     RSSelectRTCallback getSelectRTCallback() {
117         return mSelectRTCallback;
118     }
119 
120 #ifndef RS_COMPATIBILITY_LIB
setSetupCompilerCallback(RSSetupCompilerCallback pSetupCompilerCallback)121     void setSetupCompilerCallback(RSSetupCompilerCallback pSetupCompilerCallback) override {
122         mSetupCompilerCallback = pSetupCompilerCallback;
123     }
getSetupCompilerCallback()124     RSSetupCompilerCallback getSetupCompilerCallback() const override {
125         return mSetupCompilerCallback;
126     }
127 #endif
128 
setBccPluginName(const char * name)129     virtual void setBccPluginName(const char *name) {
130         mBccPluginName.setTo(name);
131     }
getBccPluginName()132     virtual const char *getBccPluginName() const {
133         return mBccPluginName.string();
134     }
getInForEach()135     bool getInForEach() override { return mInForEach; }
136 
137     // Set to true if we should embed global variable information in the code.
setEmbedGlobalInfo(bool v)138     void setEmbedGlobalInfo(bool v) override {
139         mEmbedGlobalInfo = v;
140     }
141 
142     // Returns true if we should embed global variable information in the code.
getEmbedGlobalInfo()143     bool getEmbedGlobalInfo() const override {
144         return mEmbedGlobalInfo;
145     }
146 
147     // Set to true if we should skip constant (immutable) global variables when
148     // potentially embedding information about globals.
setEmbedGlobalInfoSkipConstant(bool v)149     void setEmbedGlobalInfoSkipConstant(bool v) override {
150         mEmbedGlobalInfoSkipConstant = v;
151     }
152 
153     // Returns true if we should skip constant (immutable) global variables when
154     // potentially embedding information about globals.
getEmbedGlobalInfoSkipConstant()155     bool getEmbedGlobalInfoSkipConstant() const override {
156         return mEmbedGlobalInfoSkipConstant;
157     }
158 
159 protected:
160     Context *mRSC;
161     uint32_t version_major;
162     uint32_t version_minor;
163     //bool mHasGraphics;
164     bool mInForEach;
165 
166     struct Workers {
167         volatile int mRunningCount;
168         volatile int mLaunchCount;
169         uint32_t mCount;
170         pthread_t *mThreadId;
171         pid_t *mNativeThreadId;
172         Signal mCompleteSignal;
173         Signal *mLaunchSignals;
174         WorkerCallback_t mLaunchCallback;
175         void *mLaunchData;
176     };
177     Workers mWorkers;
178     bool mExit;
179     sym_lookup_t mSymLookupFn;
180     script_lookup_t mScriptLookupFn;
181 
182     ScriptTLSStruct mTlsStruct;
183 
184     bcc::RSLinkRuntimeCallback mLinkRuntimeCallback;
185     RSSelectRTCallback mSelectRTCallback;
186     RSSetupCompilerCallback mSetupCompilerCallback;
187     String8 mBccPluginName;
188 
189     // Specifies whether we should embed global variable information in the
190     // code via special RS variables that can be examined later by the driver.
191     // Defaults to true.
192     bool mEmbedGlobalInfo;
193 
194     // Specifies whether we should skip constant (immutable) global variables
195     // when potentially embedding information about globals.
196     // Defaults to true.
197     bool mEmbedGlobalInfoSkipConstant;
198 };
199 
200 
201 }
202 }
203 
204 #endif
205