|
14 | 14 | #include "ArrayElementAccessor.h"
|
15 | 15 | #include "ObjectManager.h"
|
16 | 16 | #include "include/v8.h"
|
| 17 | +#include "robin_hood.h" |
17 | 18 |
|
18 | 19 | namespace tns {
|
19 | 20 | class CallbackHandlers {
|
@@ -73,6 +74,11 @@ namespace tns {
|
73 | 74 | static void SetJavaField(v8::Isolate *isolate, const v8::Local<v8::Object> &target,
|
74 | 75 | const v8::Local<v8::Value> &value, FieldCallbackData *fieldData);
|
75 | 76 |
|
| 77 | + |
| 78 | + static void RunOnMainThreadCallback(const v8::FunctionCallbackInfo<v8::Value> &args); |
| 79 | + |
| 80 | + static int RunOnMainThreadFdCallback(int fd, int events, void* data); |
| 81 | + |
76 | 82 | static void LogMethodCallback(const v8::FunctionCallbackInfo<v8::Value> &args);
|
77 | 83 |
|
78 | 84 | static void TimeCallback(const v8::FunctionCallbackInfo<v8::Value> &args);
|
@@ -187,6 +193,39 @@ namespace tns {
|
187 | 193 | jstring stackTrace, jstring filename, jint lineno,
|
188 | 194 | jstring threadName);
|
189 | 195 |
|
| 196 | + static void RemoveIsolateEntries(v8::Isolate *isolate); |
| 197 | + |
| 198 | + |
| 199 | + static void PostFrameCallback(const v8::FunctionCallbackInfo<v8::Value> &args); |
| 200 | + |
| 201 | + static void RemoveFrameCallback(const v8::FunctionCallbackInfo<v8::Value> &args); |
| 202 | + |
| 203 | + struct AChoreographer; |
| 204 | + |
| 205 | + |
| 206 | + typedef void (*AChoreographer_frameCallback)(long frameTimeNanos, void* data); |
| 207 | + |
| 208 | + typedef void (*AChoreographer_frameCallback64)(int64_t frameTimeNanos, void* data); |
| 209 | + |
| 210 | + typedef AChoreographer* (*func_AChoreographer_getInstance)(); |
| 211 | + |
| 212 | + typedef void (*func_AChoreographer_postFrameCallback)( |
| 213 | + AChoreographer* choreographer, AChoreographer_frameCallback callback, |
| 214 | + void* data); |
| 215 | + |
| 216 | + typedef void (*func_AChoreographer_postFrameCallback64)( |
| 217 | + AChoreographer* choreographer, AChoreographer_frameCallback64 callback, |
| 218 | + void* data); |
| 219 | + |
| 220 | + typedef void (*func_AChoreographer_postFrameCallbackDelayed)( |
| 221 | + AChoreographer* choreographer, AChoreographer_frameCallback callback, |
| 222 | + void* data, long delayMillis); |
| 223 | + |
| 224 | + typedef void (*func_AChoreographer_postFrameCallbackDelayed64)( |
| 225 | + AChoreographer* choreographer, AChoreographer_frameCallback64 callback, |
| 226 | + void* data, uint32_t delayMillis); |
| 227 | + |
| 228 | + |
190 | 229 | private:
|
191 | 230 | CallbackHandlers() {
|
192 | 231 | }
|
@@ -242,7 +281,82 @@ namespace tns {
|
242 | 281 | jobject _runtime;
|
243 | 282 | };
|
244 | 283 |
|
| 284 | + static void RemoveKey(const uint32_t key); |
| 285 | + |
| 286 | + static _Atomic uint32_t count_; |
| 287 | + |
| 288 | + struct CacheEntry { |
| 289 | + CacheEntry(v8::Isolate* isolate, v8::Persistent<v8::Function>* callback) |
| 290 | + : isolate_(isolate), |
| 291 | + callback_(callback) { |
| 292 | + } |
| 293 | + |
| 294 | + v8::Isolate* isolate_; |
| 295 | + v8::Persistent<v8::Function>* callback_; |
| 296 | + |
| 297 | + }; |
| 298 | + |
| 299 | + static robin_hood::unordered_map<uint32_t, CacheEntry> cache_; |
| 300 | + |
| 301 | + |
| 302 | + static _Atomic uint64_t frameCallbackCount_; |
| 303 | + |
| 304 | + struct FrameCallbackCacheEntry { |
| 305 | + FrameCallbackCacheEntry(v8::Isolate *isolate, v8::Persistent<v8::Function> *callback) |
| 306 | + : isolate_(isolate), |
| 307 | + callback_(callback) { |
| 308 | + } |
| 309 | + |
| 310 | + v8::Isolate *isolate_; |
| 311 | + v8::Persistent<v8::Function> *callback_; |
| 312 | + bool removed; |
| 313 | + uint64_t id; |
| 314 | + |
| 315 | + AChoreographer_frameCallback frameCallback_ = [](long ts, void *data) { |
| 316 | + execute((double)ts, data); |
| 317 | + }; |
| 318 | + |
| 319 | + AChoreographer_frameCallback64 frameCallback64_ = [](int64_t ts, void *data) { |
| 320 | + execute((double)ts, data); |
| 321 | + }; |
| 322 | + |
| 323 | + static void execute(double ts, void *data){ |
| 324 | + if (data != nullptr) { |
| 325 | + auto entry = static_cast<FrameCallbackCacheEntry *>(data); |
| 326 | + if (entry->removed) { |
| 327 | + return; |
| 328 | + } |
| 329 | + v8::Isolate *isolate = entry->isolate_; |
| 330 | + |
| 331 | + v8::Persistent<v8::Function> *poCallback = entry->callback_; |
| 332 | + |
| 333 | + v8::Locker locker(isolate); |
| 334 | + v8::Isolate::Scope isolate_scope(isolate); |
| 335 | + v8::HandleScope handle_scope(isolate); |
| 336 | + auto context = v8::Context::New(isolate); |
| 337 | + v8::Context::Scope context_scope(context); |
| 338 | + |
| 339 | + |
| 340 | + v8::Local<v8::Function> cb = poCallback->Get(isolate); |
| 341 | + v8::Local<v8::Value> result; |
| 342 | + |
| 343 | + v8::Local<v8::Value> args[1] = {v8::Number::New(isolate, ts)}; |
| 344 | + |
| 345 | + if (!cb->Call(context, context->Global(), 1, args).ToLocal(&result)) { |
| 346 | + assert(false); |
| 347 | + } |
| 348 | + |
| 349 | + } |
| 350 | + } |
| 351 | + |
| 352 | + }; |
| 353 | + |
| 354 | + static robin_hood::unordered_map<uint64_t, FrameCallbackCacheEntry> frameCallbackCache_; |
| 355 | + |
| 356 | + static void InitChoreographer(); |
245 | 357 |
|
| 358 | + static void PostCallback(const v8::FunctionCallbackInfo<v8::Value> &args, |
| 359 | + FrameCallbackCacheEntry *entry, v8::Local<v8::Context> context); |
246 | 360 | };
|
247 | 361 | }
|
248 | 362 |
|
|
0 commit comments