1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9 #include "SkDOM.h" 10 #include "SkEvent.h" 11 12 void SkEvent::initialize(const char* type, size_t typeLen, 13 SkEventSinkID targetID) { 14 fType = nullptr; 15 setType(type, typeLen); 16 f32 = 0; 17 fTargetID = targetID; 18 fTargetProc = nullptr; 19 #ifdef SK_DEBUG 20 fTime = 0; 21 fNextEvent = nullptr; 22 #endif 23 } 24 25 SkEvent::SkEvent() 26 { 27 initialize("", 0, 0); 28 } 29 30 SkEvent::SkEvent(const SkEvent& src) 31 { 32 *this = src; 33 if (((size_t) fType & 1) == 0) 34 setType(src.fType); 35 } 36 37 SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID) 38 { 39 initialize(type.c_str(), type.size(), targetID); 40 } 41 42 SkEvent::SkEvent(const char type[], SkEventSinkID targetID) 43 { 44 SkASSERT(type); 45 initialize(type, strlen(type), targetID); 46 } 47 48 SkEvent::~SkEvent() 49 { 50 if (((size_t) fType & 1) == 0) 51 sk_free((void*) fType); 52 } 53 54 static size_t makeCharArray(char* buffer, size_t compact) 55 { 56 size_t bits = (size_t) compact >> 1; 57 memcpy(buffer, &bits, sizeof(compact)); 58 buffer[sizeof(compact)] = 0; 59 return strlen(buffer); 60 } 61 62 void SkEvent::getType(SkString* str) const 63 { 64 if (str) 65 { 66 if ((size_t) fType & 1) // not a pointer 67 { 68 char chars[sizeof(size_t) + 1]; 69 size_t len = makeCharArray(chars, (size_t) fType); 70 str->set(chars, len); 71 } 72 else 73 str->set(fType); 74 } 75 } 76 77 bool SkEvent::isType(const SkString& str) const 78 { 79 return this->isType(str.c_str(), str.size()); 80 } 81 82 bool SkEvent::isType(const char type[], size_t typeLen) const 83 { 84 if (typeLen == 0) 85 typeLen = strlen(type); 86 if ((size_t) fType & 1) { // not a pointer 87 char chars[sizeof(size_t) + 1]; 88 size_t len = makeCharArray(chars, (size_t) fType); 89 return len == typeLen && strncmp(chars, type, typeLen) == 0; 90 } 91 return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0; 92 } 93 94 void SkEvent::setType(const char type[], size_t typeLen) 95 { 96 if (typeLen == 0) 97 typeLen = strlen(type); 98 if (typeLen <= sizeof(fType)) { 99 size_t slot = 0; 100 memcpy(&slot, type, typeLen); 101 if (slot << 1 >> 1 != slot) 102 goto useCharStar; 103 slot <<= 1; 104 slot |= 1; 105 fType = (char*) slot; 106 } else { 107 useCharStar: 108 fType = (char*) sk_malloc_throw(typeLen + 1); 109 SkASSERT(((size_t) fType & 1) == 0); 110 memcpy(fType, type, typeLen); 111 fType[typeLen] = 0; 112 } 113 } 114 115 void SkEvent::setType(const SkString& type) 116 { 117 setType(type.c_str()); 118 } 119 120 //////////////////////////////////////////////////////////////////////////// 121 122 #include "SkParse.h" 123 124 void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node) 125 { 126 const char* name = dom.findAttr(node, "type"); 127 if (name) 128 this->setType(name); 129 130 const char* value; 131 if ((value = dom.findAttr(node, "fast32")) != nullptr) 132 { 133 int32_t n; 134 if (SkParse::FindS32(value, &n)) 135 this->setFast32(n); 136 } 137 138 for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node)) 139 { 140 if (strcmp(dom.getName(node), "data")) 141 { 142 SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));) 143 continue; 144 } 145 146 name = dom.findAttr(node, "name"); 147 if (name == nullptr) 148 { 149 SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");) 150 continue; 151 } 152 153 if ((value = dom.findAttr(node, "s32")) != nullptr) 154 { 155 int32_t n; 156 if (SkParse::FindS32(value, &n)) 157 this->setS32(name, n); 158 } 159 else if ((value = dom.findAttr(node, "scalar")) != nullptr) 160 { 161 SkScalar x; 162 if (SkParse::FindScalar(value, &x)) 163 this->setScalar(name, x); 164 } 165 else if ((value = dom.findAttr(node, "string")) != nullptr) 166 this->setString(name, value); 167 #ifdef SK_DEBUG 168 else 169 { 170 SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name); 171 } 172 #endif 173 } 174 } 175 176 #ifdef SK_DEBUG 177 178 #ifndef SkScalarToFloat 179 #define SkScalarToFloat(x) ((x) / 65536.f) 180 #endif 181 182 void SkEvent::dump(const char title[]) 183 { 184 if (title) 185 SkDebugf("%s ", title); 186 187 SkString etype; 188 this->getType(&etype); 189 SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32()); 190 191 const SkMetaData& md = this->getMetaData(); 192 SkMetaData::Iter iter(md); 193 SkMetaData::Type mtype; 194 int count; 195 const char* name; 196 197 while ((name = iter.next(&mtype, &count)) != nullptr) 198 { 199 SkASSERT(count > 0); 200 201 SkDebugf(" <%s>=", name); 202 switch (mtype) { 203 case SkMetaData::kS32_Type: // vector version??? 204 { 205 int32_t value; 206 md.findS32(name, &value); 207 SkDebugf("%d ", value); 208 } 209 break; 210 case SkMetaData::kScalar_Type: 211 { 212 const SkScalar* values = md.findScalars(name, &count, nullptr); 213 SkDebugf("%f", SkScalarToFloat(values[0])); 214 for (int i = 1; i < count; i++) 215 SkDebugf(", %f", SkScalarToFloat(values[i])); 216 SkDebugf(" "); 217 } 218 break; 219 case SkMetaData::kString_Type: 220 { 221 const char* value = md.findString(name); 222 SkASSERT(value); 223 SkDebugf("<%s> ", value); 224 } 225 break; 226 case SkMetaData::kPtr_Type: // vector version??? 227 { 228 void* value; 229 md.findPtr(name, &value); 230 SkDebugf("%p ", value); 231 } 232 break; 233 case SkMetaData::kBool_Type: // vector version??? 234 { 235 bool value; 236 md.findBool(name, &value); 237 SkDebugf("%s ", value ? "true" : "false"); 238 } 239 break; 240 default: 241 SkDEBUGFAIL("unknown metadata type returned from iterator"); 242 break; 243 } 244 } 245 SkDebugf("\n"); 246 } 247 #endif 248 249 /////////////////////////////////////////////////////////////////////////////////////// 250 251 #ifdef SK_DEBUG 252 // #define SK_TRACE_EVENTSx 253 #endif 254 255 #ifdef SK_TRACE_EVENTS 256 static void event_log(const char s[]) 257 { 258 SkDEBUGF(("%s\n", s)); 259 } 260 261 #define EVENT_LOG(s) event_log(s) 262 #define EVENT_LOGN(s, n) do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0) 263 #else 264 #define EVENT_LOG(s) 265 #define EVENT_LOGN(s, n) 266 #endif 267 268 #include "SkMutex.h" 269 #include "SkTime.h" 270 271 class SkEvent_Globals { 272 public: 273 SkEvent_Globals() { 274 fEventQHead = nullptr; 275 fEventQTail = nullptr; 276 fDelayQHead = nullptr; 277 SkDEBUGCODE(fEventCounter = 0;) 278 } 279 280 SkMutex fEventMutex; 281 SkEvent* fEventQHead, *fEventQTail; 282 SkEvent* fDelayQHead; 283 SkDEBUGCODE(int fEventCounter;) 284 }; 285 286 static SkEvent_Globals& getGlobals() { 287 // leak this, so we don't incure any shutdown perf hit 288 static SkEvent_Globals* gGlobals = new SkEvent_Globals; 289 return *gGlobals; 290 } 291 292 /////////////////////////////////////////////////////////////////////////////// 293 294 void SkEvent::postDelay(SkMSec delay) { 295 if (!fTargetID && !fTargetProc) { 296 delete this; 297 return; 298 } 299 300 if (delay) { 301 this->postTime(GetMSecsSinceStartup() + delay); 302 return; 303 } 304 305 SkEvent_Globals& globals = getGlobals(); 306 307 globals.fEventMutex.acquire(); 308 bool wasEmpty = SkEvent::Enqueue(this); 309 globals.fEventMutex.release(); 310 311 // call outside of us holding the mutex 312 if (wasEmpty) { 313 SkEvent::SignalNonEmptyQueue(); 314 } 315 } 316 317 void SkEvent::postTime(SkMSec time) { 318 if (!fTargetID && !fTargetProc) { 319 delete this; 320 return; 321 } 322 323 SkEvent_Globals& globals = getGlobals(); 324 325 globals.fEventMutex.acquire(); 326 SkMSec queueDelay = SkEvent::EnqueueTime(this, time); 327 globals.fEventMutex.release(); 328 329 // call outside of us holding the mutex 330 if ((int32_t)queueDelay != ~0) { 331 SkEvent::SignalQueueTimer(queueDelay); 332 } 333 } 334 335 bool SkEvent::Enqueue(SkEvent* evt) { 336 SkEvent_Globals& globals = getGlobals(); 337 // gEventMutex acquired by caller 338 339 SkASSERT(evt); 340 341 bool wasEmpty = globals.fEventQHead == nullptr; 342 343 if (globals.fEventQTail) 344 globals.fEventQTail->fNextEvent = evt; 345 globals.fEventQTail = evt; 346 if (globals.fEventQHead == nullptr) 347 globals.fEventQHead = evt; 348 evt->fNextEvent = nullptr; 349 350 SkDEBUGCODE(++globals.fEventCounter); 351 352 return wasEmpty; 353 } 354 355 SkEvent* SkEvent::Dequeue() { 356 SkEvent_Globals& globals = getGlobals(); 357 globals.fEventMutex.acquire(); 358 359 SkEvent* evt = globals.fEventQHead; 360 if (evt) { 361 SkDEBUGCODE(--globals.fEventCounter); 362 363 globals.fEventQHead = evt->fNextEvent; 364 if (globals.fEventQHead == nullptr) { 365 globals.fEventQTail = nullptr; 366 } 367 } 368 globals.fEventMutex.release(); 369 370 return evt; 371 } 372 373 bool SkEvent::QHasEvents() { 374 SkEvent_Globals& globals = getGlobals(); 375 376 // this is not thread accurate, need a semaphore for that 377 return globals.fEventQHead != nullptr; 378 } 379 380 #ifdef SK_TRACE_EVENTS 381 static int gDelayDepth; 382 #endif 383 384 SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) { 385 SkEvent_Globals& globals = getGlobals(); 386 // gEventMutex acquired by caller 387 388 SkEvent* curr = globals.fDelayQHead; 389 SkEvent* prev = nullptr; 390 391 while (curr) { 392 if (SkMSec_LT(time, curr->fTime)) { 393 break; 394 } 395 prev = curr; 396 curr = curr->fNextEvent; 397 } 398 399 evt->fTime = time; 400 evt->fNextEvent = curr; 401 if (prev == nullptr) { 402 globals.fDelayQHead = evt; 403 } else { 404 prev->fNextEvent = evt; 405 } 406 407 SkMSec delay = globals.fDelayQHead->fTime - GetMSecsSinceStartup(); 408 if ((int32_t)delay <= 0) { 409 delay = 1; 410 } 411 return delay; 412 } 413 414 /////////////////////////////////////////////////////////////////////////////// 415 416 #include "SkEventSink.h" 417 418 bool SkEvent::ProcessEvent() { 419 std::unique_ptr<SkEvent> evt(SkEvent::Dequeue()); 420 bool again = false; 421 422 EVENT_LOGN("ProcessEvent", (int32_t)evt); 423 424 if (evt) { 425 (void)SkEventSink::DoEvent(*evt); 426 again = SkEvent::QHasEvents(); 427 } 428 return again; 429 } 430 431 void SkEvent::ServiceQueueTimer() 432 { 433 SkEvent_Globals& globals = getGlobals(); 434 435 globals.fEventMutex.acquire(); 436 437 bool wasEmpty = false; 438 SkMSec now = GetMSecsSinceStartup(); 439 SkEvent* evt = globals.fDelayQHead; 440 441 while (evt) 442 { 443 if (SkMSec_LT(now, evt->fTime)) 444 break; 445 446 #ifdef SK_TRACE_EVENTS 447 --gDelayDepth; 448 SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth); 449 const char* idStr = evt->findString("id"); 450 if (idStr) 451 SkDebugf(" (%s)", idStr); 452 SkDebugf("\n"); 453 #endif 454 455 SkEvent* next = evt->fNextEvent; 456 if (SkEvent::Enqueue(evt)) 457 wasEmpty = true; 458 evt = next; 459 } 460 globals.fDelayQHead = evt; 461 462 SkMSec time = evt ? evt->fTime - now : 0; 463 464 globals.fEventMutex.release(); 465 466 if (wasEmpty) 467 SkEvent::SignalNonEmptyQueue(); 468 469 SkEvent::SignalQueueTimer(time); 470 } 471 472 int SkEvent::CountEventsOnQueue() { 473 SkEvent_Globals& globals = getGlobals(); 474 globals.fEventMutex.acquire(); 475 476 int count = 0; 477 const SkEvent* evt = globals.fEventQHead; 478 while (evt) { 479 count += 1; 480 evt = evt->fNextEvent; 481 } 482 globals.fEventMutex.release(); 483 484 return count; 485 } 486 487 SkMSec SkEvent::GetMSecsSinceStartup() { 488 static const double kEpoch = SkTime::GetMSecs(); 489 return static_cast<SkMSec>(SkTime::GetMSecs() - kEpoch); 490 } 491 492 /////////////////////////////////////////////////////////////////////////////// 493 494 void SkEvent::Init() {} 495 496 void SkEvent::Term() { 497 SkEvent_Globals& globals = getGlobals(); 498 499 SkEvent* evt = globals.fEventQHead; 500 while (evt) { 501 SkEvent* next = evt->fNextEvent; 502 delete evt; 503 evt = next; 504 } 505 506 evt = globals.fDelayQHead; 507 while (evt) { 508 SkEvent* next = evt->fNextEvent; 509 delete evt; 510 evt = next; 511 } 512 } 513