1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/views/SkEvent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,508 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkEvent.h" 1.14 + 1.15 +void SkEvent::initialize(const char* type, size_t typeLen, 1.16 + SkEventSinkID targetID) { 1.17 + fType = NULL; 1.18 + setType(type, typeLen); 1.19 + f32 = 0; 1.20 + fTargetID = targetID; 1.21 + fTargetProc = NULL; 1.22 +#ifdef SK_DEBUG 1.23 + fTime = 0; 1.24 + fNextEvent = NULL; 1.25 +#endif 1.26 +} 1.27 + 1.28 +SkEvent::SkEvent() 1.29 +{ 1.30 + initialize("", 0, 0); 1.31 +} 1.32 + 1.33 +SkEvent::SkEvent(const SkEvent& src) 1.34 +{ 1.35 + *this = src; 1.36 + if (((size_t) fType & 1) == 0) 1.37 + setType(src.fType); 1.38 +} 1.39 + 1.40 +SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID) 1.41 +{ 1.42 + initialize(type.c_str(), type.size(), targetID); 1.43 +} 1.44 + 1.45 +SkEvent::SkEvent(const char type[], SkEventSinkID targetID) 1.46 +{ 1.47 + SkASSERT(type); 1.48 + initialize(type, strlen(type), targetID); 1.49 +} 1.50 + 1.51 +SkEvent::~SkEvent() 1.52 +{ 1.53 + if (((size_t) fType & 1) == 0) 1.54 + sk_free((void*) fType); 1.55 +} 1.56 + 1.57 +static size_t makeCharArray(char* buffer, size_t compact) 1.58 +{ 1.59 + size_t bits = (size_t) compact >> 1; 1.60 + memcpy(buffer, &bits, sizeof(compact)); 1.61 + buffer[sizeof(compact)] = 0; 1.62 + return strlen(buffer); 1.63 +} 1.64 + 1.65 +void SkEvent::getType(SkString* str) const 1.66 +{ 1.67 + if (str) 1.68 + { 1.69 + if ((size_t) fType & 1) // not a pointer 1.70 + { 1.71 + char chars[sizeof(size_t) + 1]; 1.72 + size_t len = makeCharArray(chars, (size_t) fType); 1.73 + str->set(chars, len); 1.74 + } 1.75 + else 1.76 + str->set(fType); 1.77 + } 1.78 +} 1.79 + 1.80 +bool SkEvent::isType(const SkString& str) const 1.81 +{ 1.82 + return this->isType(str.c_str(), str.size()); 1.83 +} 1.84 + 1.85 +bool SkEvent::isType(const char type[], size_t typeLen) const 1.86 +{ 1.87 + if (typeLen == 0) 1.88 + typeLen = strlen(type); 1.89 + if ((size_t) fType & 1) { // not a pointer 1.90 + char chars[sizeof(size_t) + 1]; 1.91 + size_t len = makeCharArray(chars, (size_t) fType); 1.92 + return len == typeLen && strncmp(chars, type, typeLen) == 0; 1.93 + } 1.94 + return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0; 1.95 +} 1.96 + 1.97 +void SkEvent::setType(const char type[], size_t typeLen) 1.98 +{ 1.99 + if (typeLen == 0) 1.100 + typeLen = strlen(type); 1.101 + if (typeLen <= sizeof(fType)) { 1.102 + size_t slot = 0; 1.103 + memcpy(&slot, type, typeLen); 1.104 + if (slot << 1 >> 1 != slot) 1.105 + goto useCharStar; 1.106 + slot <<= 1; 1.107 + slot |= 1; 1.108 + fType = (char*) slot; 1.109 + } else { 1.110 +useCharStar: 1.111 + fType = (char*) sk_malloc_throw(typeLen + 1); 1.112 + SkASSERT(((size_t) fType & 1) == 0); 1.113 + memcpy(fType, type, typeLen); 1.114 + fType[typeLen] = 0; 1.115 + } 1.116 +} 1.117 + 1.118 +void SkEvent::setType(const SkString& type) 1.119 +{ 1.120 + setType(type.c_str()); 1.121 +} 1.122 + 1.123 +//////////////////////////////////////////////////////////////////////////// 1.124 + 1.125 +#include "SkParse.h" 1.126 + 1.127 +void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node) 1.128 +{ 1.129 + const char* name = dom.findAttr(node, "type"); 1.130 + if (name) 1.131 + this->setType(name); 1.132 + 1.133 + const char* value; 1.134 + if ((value = dom.findAttr(node, "fast32")) != NULL) 1.135 + { 1.136 + int32_t n; 1.137 + if (SkParse::FindS32(value, &n)) 1.138 + this->setFast32(n); 1.139 + } 1.140 + 1.141 + for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node)) 1.142 + { 1.143 + if (strcmp(dom.getName(node), "data")) 1.144 + { 1.145 + SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));) 1.146 + continue; 1.147 + } 1.148 + 1.149 + name = dom.findAttr(node, "name"); 1.150 + if (name == NULL) 1.151 + { 1.152 + SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");) 1.153 + continue; 1.154 + } 1.155 + 1.156 + if ((value = dom.findAttr(node, "s32")) != NULL) 1.157 + { 1.158 + int32_t n; 1.159 + if (SkParse::FindS32(value, &n)) 1.160 + this->setS32(name, n); 1.161 + } 1.162 + else if ((value = dom.findAttr(node, "scalar")) != NULL) 1.163 + { 1.164 + SkScalar x; 1.165 + if (SkParse::FindScalar(value, &x)) 1.166 + this->setScalar(name, x); 1.167 + } 1.168 + else if ((value = dom.findAttr(node, "string")) != NULL) 1.169 + this->setString(name, value); 1.170 +#ifdef SK_DEBUG 1.171 + else 1.172 + { 1.173 + SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name); 1.174 + } 1.175 +#endif 1.176 + } 1.177 +} 1.178 + 1.179 +#ifdef SK_DEBUG 1.180 + 1.181 + #ifndef SkScalarToFloat 1.182 + #define SkScalarToFloat(x) ((x) / 65536.f) 1.183 + #endif 1.184 + 1.185 + void SkEvent::dump(const char title[]) 1.186 + { 1.187 + if (title) 1.188 + SkDebugf("%s ", title); 1.189 + 1.190 + SkString etype; 1.191 + this->getType(&etype); 1.192 + SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32()); 1.193 + 1.194 + const SkMetaData& md = this->getMetaData(); 1.195 + SkMetaData::Iter iter(md); 1.196 + SkMetaData::Type mtype; 1.197 + int count; 1.198 + const char* name; 1.199 + 1.200 + while ((name = iter.next(&mtype, &count)) != NULL) 1.201 + { 1.202 + SkASSERT(count > 0); 1.203 + 1.204 + SkDebugf(" <%s>=", name); 1.205 + switch (mtype) { 1.206 + case SkMetaData::kS32_Type: // vector version??? 1.207 + { 1.208 + int32_t value; 1.209 + md.findS32(name, &value); 1.210 + SkDebugf("%d ", value); 1.211 + } 1.212 + break; 1.213 + case SkMetaData::kScalar_Type: 1.214 + { 1.215 + const SkScalar* values = md.findScalars(name, &count, NULL); 1.216 + SkDebugf("%f", SkScalarToFloat(values[0])); 1.217 + for (int i = 1; i < count; i++) 1.218 + SkDebugf(", %f", SkScalarToFloat(values[i])); 1.219 + SkDebugf(" "); 1.220 + } 1.221 + break; 1.222 + case SkMetaData::kString_Type: 1.223 + { 1.224 + const char* value = md.findString(name); 1.225 + SkASSERT(value); 1.226 + SkDebugf("<%s> ", value); 1.227 + } 1.228 + break; 1.229 + case SkMetaData::kPtr_Type: // vector version??? 1.230 + { 1.231 + void* value; 1.232 + md.findPtr(name, &value); 1.233 + SkDebugf("%p ", value); 1.234 + } 1.235 + break; 1.236 + case SkMetaData::kBool_Type: // vector version??? 1.237 + { 1.238 + bool value; 1.239 + md.findBool(name, &value); 1.240 + SkDebugf("%s ", value ? "true" : "false"); 1.241 + } 1.242 + break; 1.243 + default: 1.244 + SkDEBUGFAIL("unknown metadata type returned from iterator"); 1.245 + break; 1.246 + } 1.247 + } 1.248 + SkDebugf("\n"); 1.249 + } 1.250 +#endif 1.251 + 1.252 +/////////////////////////////////////////////////////////////////////////////////////// 1.253 + 1.254 +#ifdef SK_DEBUG 1.255 +// #define SK_TRACE_EVENTSx 1.256 +#endif 1.257 + 1.258 +#ifdef SK_TRACE_EVENTS 1.259 + static void event_log(const char s[]) 1.260 + { 1.261 + SkDEBUGF(("%s\n", s)); 1.262 + } 1.263 + 1.264 + #define EVENT_LOG(s) event_log(s) 1.265 + #define EVENT_LOGN(s, n) do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0) 1.266 +#else 1.267 + #define EVENT_LOG(s) 1.268 + #define EVENT_LOGN(s, n) 1.269 +#endif 1.270 + 1.271 +#include "SkThread.h" 1.272 +#include "SkTime.h" 1.273 + 1.274 +class SkEvent_Globals { 1.275 +public: 1.276 + SkEvent_Globals() { 1.277 + fEventQHead = NULL; 1.278 + fEventQTail = NULL; 1.279 + fDelayQHead = NULL; 1.280 + SkDEBUGCODE(fEventCounter = 0;) 1.281 + } 1.282 + 1.283 + SkMutex fEventMutex; 1.284 + SkEvent* fEventQHead, *fEventQTail; 1.285 + SkEvent* fDelayQHead; 1.286 + SkDEBUGCODE(int fEventCounter;) 1.287 +}; 1.288 + 1.289 +static SkEvent_Globals& getGlobals() { 1.290 + // leak this, so we don't incure any shutdown perf hit 1.291 + static SkEvent_Globals* gGlobals = new SkEvent_Globals; 1.292 + return *gGlobals; 1.293 +} 1.294 + 1.295 +/////////////////////////////////////////////////////////////////////////////// 1.296 + 1.297 +void SkEvent::postDelay(SkMSec delay) { 1.298 + if (!fTargetID && !fTargetProc) { 1.299 + delete this; 1.300 + return; 1.301 + } 1.302 + 1.303 + if (delay) { 1.304 + this->postTime(SkTime::GetMSecs() + delay); 1.305 + return; 1.306 + } 1.307 + 1.308 + SkEvent_Globals& globals = getGlobals(); 1.309 + 1.310 + globals.fEventMutex.acquire(); 1.311 + bool wasEmpty = SkEvent::Enqueue(this); 1.312 + globals.fEventMutex.release(); 1.313 + 1.314 + // call outside of us holding the mutex 1.315 + if (wasEmpty) { 1.316 + SkEvent::SignalNonEmptyQueue(); 1.317 + } 1.318 +} 1.319 + 1.320 +void SkEvent::postTime(SkMSec time) { 1.321 + if (!fTargetID && !fTargetProc) { 1.322 + delete this; 1.323 + return; 1.324 + } 1.325 + 1.326 + SkEvent_Globals& globals = getGlobals(); 1.327 + 1.328 + globals.fEventMutex.acquire(); 1.329 + SkMSec queueDelay = SkEvent::EnqueueTime(this, time); 1.330 + globals.fEventMutex.release(); 1.331 + 1.332 + // call outside of us holding the mutex 1.333 + if ((int32_t)queueDelay != ~0) { 1.334 + SkEvent::SignalQueueTimer(queueDelay); 1.335 + } 1.336 +} 1.337 + 1.338 +bool SkEvent::Enqueue(SkEvent* evt) { 1.339 + SkEvent_Globals& globals = getGlobals(); 1.340 + // gEventMutex acquired by caller 1.341 + 1.342 + SkASSERT(evt); 1.343 + 1.344 + bool wasEmpty = globals.fEventQHead == NULL; 1.345 + 1.346 + if (globals.fEventQTail) 1.347 + globals.fEventQTail->fNextEvent = evt; 1.348 + globals.fEventQTail = evt; 1.349 + if (globals.fEventQHead == NULL) 1.350 + globals.fEventQHead = evt; 1.351 + evt->fNextEvent = NULL; 1.352 + 1.353 + SkDEBUGCODE(++globals.fEventCounter); 1.354 + 1.355 + return wasEmpty; 1.356 +} 1.357 + 1.358 +SkEvent* SkEvent::Dequeue() { 1.359 + SkEvent_Globals& globals = getGlobals(); 1.360 + globals.fEventMutex.acquire(); 1.361 + 1.362 + SkEvent* evt = globals.fEventQHead; 1.363 + if (evt) { 1.364 + SkDEBUGCODE(--globals.fEventCounter); 1.365 + 1.366 + globals.fEventQHead = evt->fNextEvent; 1.367 + if (globals.fEventQHead == NULL) { 1.368 + globals.fEventQTail = NULL; 1.369 + } 1.370 + } 1.371 + globals.fEventMutex.release(); 1.372 + 1.373 + return evt; 1.374 +} 1.375 + 1.376 +bool SkEvent::QHasEvents() { 1.377 + SkEvent_Globals& globals = getGlobals(); 1.378 + 1.379 + // this is not thread accurate, need a semaphore for that 1.380 + return globals.fEventQHead != NULL; 1.381 +} 1.382 + 1.383 +#ifdef SK_TRACE_EVENTS 1.384 + static int gDelayDepth; 1.385 +#endif 1.386 + 1.387 +SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) { 1.388 + SkEvent_Globals& globals = getGlobals(); 1.389 + // gEventMutex acquired by caller 1.390 + 1.391 + SkEvent* curr = globals.fDelayQHead; 1.392 + SkEvent* prev = NULL; 1.393 + 1.394 + while (curr) { 1.395 + if (SkMSec_LT(time, curr->fTime)) { 1.396 + break; 1.397 + } 1.398 + prev = curr; 1.399 + curr = curr->fNextEvent; 1.400 + } 1.401 + 1.402 + evt->fTime = time; 1.403 + evt->fNextEvent = curr; 1.404 + if (prev == NULL) { 1.405 + globals.fDelayQHead = evt; 1.406 + } else { 1.407 + prev->fNextEvent = evt; 1.408 + } 1.409 + 1.410 + SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs(); 1.411 + if ((int32_t)delay <= 0) { 1.412 + delay = 1; 1.413 + } 1.414 + return delay; 1.415 +} 1.416 + 1.417 +/////////////////////////////////////////////////////////////////////////////// 1.418 + 1.419 +#include "SkEventSink.h" 1.420 + 1.421 +bool SkEvent::ProcessEvent() { 1.422 + SkEvent* evt = SkEvent::Dequeue(); 1.423 + SkAutoTDelete<SkEvent> autoDelete(evt); 1.424 + bool again = false; 1.425 + 1.426 + EVENT_LOGN("ProcessEvent", (int32_t)evt); 1.427 + 1.428 + if (evt) { 1.429 + (void)SkEventSink::DoEvent(*evt); 1.430 + again = SkEvent::QHasEvents(); 1.431 + } 1.432 + return again; 1.433 +} 1.434 + 1.435 +void SkEvent::ServiceQueueTimer() 1.436 +{ 1.437 + SkEvent_Globals& globals = getGlobals(); 1.438 + 1.439 + globals.fEventMutex.acquire(); 1.440 + 1.441 + bool wasEmpty = false; 1.442 + SkMSec now = SkTime::GetMSecs(); 1.443 + SkEvent* evt = globals.fDelayQHead; 1.444 + 1.445 + while (evt) 1.446 + { 1.447 + if (SkMSec_LT(now, evt->fTime)) 1.448 + break; 1.449 + 1.450 +#ifdef SK_TRACE_EVENTS 1.451 + --gDelayDepth; 1.452 + SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth); 1.453 + const char* idStr = evt->findString("id"); 1.454 + if (idStr) 1.455 + SkDebugf(" (%s)", idStr); 1.456 + SkDebugf("\n"); 1.457 +#endif 1.458 + 1.459 + SkEvent* next = evt->fNextEvent; 1.460 + if (SkEvent::Enqueue(evt)) 1.461 + wasEmpty = true; 1.462 + evt = next; 1.463 + } 1.464 + globals.fDelayQHead = evt; 1.465 + 1.466 + SkMSec time = evt ? evt->fTime - now : 0; 1.467 + 1.468 + globals.fEventMutex.release(); 1.469 + 1.470 + if (wasEmpty) 1.471 + SkEvent::SignalNonEmptyQueue(); 1.472 + 1.473 + SkEvent::SignalQueueTimer(time); 1.474 +} 1.475 + 1.476 +int SkEvent::CountEventsOnQueue() { 1.477 + SkEvent_Globals& globals = getGlobals(); 1.478 + globals.fEventMutex.acquire(); 1.479 + 1.480 + int count = 0; 1.481 + const SkEvent* evt = globals.fEventQHead; 1.482 + while (evt) { 1.483 + count += 1; 1.484 + evt = evt->fNextEvent; 1.485 + } 1.486 + globals.fEventMutex.release(); 1.487 + 1.488 + return count; 1.489 +} 1.490 + 1.491 +/////////////////////////////////////////////////////////////////////////////// 1.492 + 1.493 +void SkEvent::Init() {} 1.494 + 1.495 +void SkEvent::Term() { 1.496 + SkEvent_Globals& globals = getGlobals(); 1.497 + 1.498 + SkEvent* evt = globals.fEventQHead; 1.499 + while (evt) { 1.500 + SkEvent* next = evt->fNextEvent; 1.501 + delete evt; 1.502 + evt = next; 1.503 + } 1.504 + 1.505 + evt = globals.fDelayQHead; 1.506 + while (evt) { 1.507 + SkEvent* next = evt->fNextEvent; 1.508 + delete evt; 1.509 + evt = next; 1.510 + } 1.511 +}