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