Home | History | Annotate | Download | only in views
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkEvent.h"
     11 
     12 void SkEvent::initialize(const char* type, size_t typeLen,
     13                          SkEventSinkID targetID) {
     14     fType = NULL;
     15     setType(type, typeLen);
     16     f32 = 0;
     17     fTargetID = targetID;
     18     fTargetProc = NULL;
     19 #ifdef SK_DEBUG
     20     fTime = 0;
     21     fNextEvent = NULL;
     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")) != NULL)
    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 == NULL)
    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")) != NULL)
    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")) != NULL)
    160         {
    161             SkScalar x;
    162             if (SkParse::FindScalar(value, &x))
    163                 this->setScalar(name, x);
    164         }
    165         else if ((value = dom.findAttr(node, "string")) != NULL)
    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)) != NULL)
    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, NULL);
    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 "SkThread.h"
    269 #include "SkTime.h"
    270 
    271 class SkEvent_Globals {
    272 public:
    273     SkEvent_Globals() {
    274         fEventQHead = NULL;
    275         fEventQTail = NULL;
    276         fDelayQHead = NULL;
    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(SkTime::GetMSecs() + 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 == NULL;
    342 
    343     if (globals.fEventQTail)
    344         globals.fEventQTail->fNextEvent = evt;
    345     globals.fEventQTail = evt;
    346     if (globals.fEventQHead == NULL)
    347         globals.fEventQHead = evt;
    348     evt->fNextEvent = NULL;
    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 == NULL) {
    365             globals.fEventQTail = NULL;
    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 != NULL;
    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 = NULL;
    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 == NULL) {
    402         globals.fDelayQHead = evt;
    403     } else {
    404         prev->fNextEvent = evt;
    405     }
    406 
    407     SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs();
    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     SkEvent*                evt = SkEvent::Dequeue();
    420     SkAutoTDelete<SkEvent>  autoDelete(evt);
    421     bool                    again = false;
    422 
    423     EVENT_LOGN("ProcessEvent", (int32_t)evt);
    424 
    425     if (evt) {
    426         (void)SkEventSink::DoEvent(*evt);
    427         again = SkEvent::QHasEvents();
    428     }
    429     return again;
    430 }
    431 
    432 void SkEvent::ServiceQueueTimer()
    433 {
    434     SkEvent_Globals& globals = getGlobals();
    435 
    436     globals.fEventMutex.acquire();
    437 
    438     bool        wasEmpty = false;
    439     SkMSec      now = SkTime::GetMSecs();
    440     SkEvent*    evt = globals.fDelayQHead;
    441 
    442     while (evt)
    443     {
    444         if (SkMSec_LT(now, evt->fTime))
    445             break;
    446 
    447 #ifdef SK_TRACE_EVENTS
    448         --gDelayDepth;
    449         SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth);
    450         const char* idStr = evt->findString("id");
    451         if (idStr)
    452             SkDebugf(" (%s)", idStr);
    453         SkDebugf("\n");
    454 #endif
    455 
    456         SkEvent* next = evt->fNextEvent;
    457         if (SkEvent::Enqueue(evt))
    458             wasEmpty = true;
    459         evt = next;
    460     }
    461     globals.fDelayQHead = evt;
    462 
    463     SkMSec time = evt ? evt->fTime - now : 0;
    464 
    465     globals.fEventMutex.release();
    466 
    467     if (wasEmpty)
    468         SkEvent::SignalNonEmptyQueue();
    469 
    470     SkEvent::SignalQueueTimer(time);
    471 }
    472 
    473 int SkEvent::CountEventsOnQueue() {
    474     SkEvent_Globals& globals = getGlobals();
    475     globals.fEventMutex.acquire();
    476 
    477     int count = 0;
    478     const SkEvent* evt = globals.fEventQHead;
    479     while (evt) {
    480         count += 1;
    481         evt = evt->fNextEvent;
    482     }
    483     globals.fEventMutex.release();
    484 
    485     return count;
    486 }
    487 
    488 ///////////////////////////////////////////////////////////////////////////////
    489 
    490 void SkEvent::Init() {}
    491 
    492 void SkEvent::Term() {
    493     SkEvent_Globals& globals = getGlobals();
    494 
    495     SkEvent* evt = globals.fEventQHead;
    496     while (evt) {
    497         SkEvent* next = evt->fNextEvent;
    498         delete evt;
    499         evt = next;
    500     }
    501 
    502     evt = globals.fDelayQHead;
    503     while (evt) {
    504         SkEvent* next = evt->fNextEvent;
    505         delete evt;
    506         evt = next;
    507     }
    508 }
    509