• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
initialize(const char * type,size_t typeLen)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 
SkEvent()32 SkEvent::SkEvent()
33 {
34     initialize("", 0);
35 }
36 
SkEvent(const SkEvent & src)37 SkEvent::SkEvent(const SkEvent& src)
38 {
39     *this = src;
40     if (((size_t) fType & 1) == 0)
41         setType(src.fType);
42 }
43 
SkEvent(const SkString & type)44 SkEvent::SkEvent(const SkString& type)
45 {
46     initialize(type.c_str(), type.size());
47 }
48 
SkEvent(const char type[])49 SkEvent::SkEvent(const char type[])
50 {
51     SkASSERT(type);
52     initialize(type, strlen(type));
53 }
54 
~SkEvent()55 SkEvent::~SkEvent()
56 {
57     if (((size_t) fType & 1) == 0)
58         sk_free((void*) fType);
59 }
60 
makeCharArray(char * buffer,size_t compact)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 
getType(SkString * str) const83 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 
isType(const SkString & str) const98 bool SkEvent::isType(const SkString& str) const
99 {
100     return this->isType(str.c_str(), str.size());
101 }
102 
isType(const char type[],size_t typeLen) const103 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 
setType(const char type[],size_t typeLen)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 
setType(const SkString & type)136 void SkEvent::setType(const SkString& type)
137 {
138     setType(type.c_str());
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////
142 
143 #include "SkParse.h"
144 
inflate(const SkDOM & dom,const SkDOM::Node * node)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 
dump(const char title[])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
event_log(const char s[])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 
create_globals()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 
Post(SkEvent * evt,SkEventSinkID sinkID,SkMSec delay)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 
PostTime(SkEvent * evt,SkEventSinkID sinkID,SkMSec time)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 
Enqueue(SkEvent * evt)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 
Dequeue(SkEventSinkID * sinkID)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 
QHasEvents()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 
EnqueueTime(SkEvent * evt,SkMSec time)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 
ProcessEvent()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 
ServiceQueueTimer()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 
Init()541 void SkEvent::Init()
542 {
543 }
544 
Term()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