blob: 7b658c839a4577c117dc4d9db7c86f9688ac7c30 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008
9#include "SkEvent.h"
10
reed@google.com87fac4a2011-08-04 13:50:17 +000011void SkEvent::initialize(const char* type, size_t typeLen,
12 SkEventSinkID targetID) {
halcanary96fcdcc2015-08-27 07:41:13 -070013 fType = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +000014 setType(type, typeLen);
15 f32 = 0;
reed@google.com87fac4a2011-08-04 13:50:17 +000016 fTargetID = targetID;
halcanary96fcdcc2015-08-27 07:41:13 -070017 fTargetProc = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +000018#ifdef SK_DEBUG
reed@android.com8a1c16f2008-12-17 15:59:43 +000019 fTime = 0;
halcanary96fcdcc2015-08-27 07:41:13 -070020 fNextEvent = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +000021#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000022}
23
24SkEvent::SkEvent()
25{
reed@google.com87fac4a2011-08-04 13:50:17 +000026 initialize("", 0, 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +000027}
28
29SkEvent::SkEvent(const SkEvent& src)
30{
31 *this = src;
32 if (((size_t) fType & 1) == 0)
33 setType(src.fType);
34}
35
reed@google.com87fac4a2011-08-04 13:50:17 +000036SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID)
reed@android.com8a1c16f2008-12-17 15:59:43 +000037{
reed@google.com87fac4a2011-08-04 13:50:17 +000038 initialize(type.c_str(), type.size(), targetID);
reed@android.com8a1c16f2008-12-17 15:59:43 +000039}
40
reed@google.com87fac4a2011-08-04 13:50:17 +000041SkEvent::SkEvent(const char type[], SkEventSinkID targetID)
reed@android.com8a1c16f2008-12-17 15:59:43 +000042{
43 SkASSERT(type);
reed@google.com87fac4a2011-08-04 13:50:17 +000044 initialize(type, strlen(type), targetID);
reed@android.com8a1c16f2008-12-17 15:59:43 +000045}
46
47SkEvent::~SkEvent()
48{
49 if (((size_t) fType & 1) == 0)
50 sk_free((void*) fType);
51}
52
53static size_t makeCharArray(char* buffer, size_t compact)
54{
55 size_t bits = (size_t) compact >> 1;
56 memcpy(buffer, &bits, sizeof(compact));
57 buffer[sizeof(compact)] = 0;
58 return strlen(buffer);
59}
60
rmistry@google.comd6176b02012-08-23 18:14:13 +000061void SkEvent::getType(SkString* str) const
62{
63 if (str)
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 {
65 if ((size_t) fType & 1) // not a pointer
66 {
67 char chars[sizeof(size_t) + 1];
68 size_t len = makeCharArray(chars, (size_t) fType);
69 str->set(chars, len);
70 }
71 else
72 str->set(fType);
73 }
74}
75
rmistry@google.comd6176b02012-08-23 18:14:13 +000076bool SkEvent::isType(const SkString& str) const
reed@android.com8a1c16f2008-12-17 15:59:43 +000077{
rmistry@google.comd6176b02012-08-23 18:14:13 +000078 return this->isType(str.c_str(), str.size());
reed@android.com8a1c16f2008-12-17 15:59:43 +000079}
80
rmistry@google.comd6176b02012-08-23 18:14:13 +000081bool SkEvent::isType(const char type[], size_t typeLen) const
82{
reed@android.com8a1c16f2008-12-17 15:59:43 +000083 if (typeLen == 0)
84 typeLen = strlen(type);
85 if ((size_t) fType & 1) { // not a pointer
86 char chars[sizeof(size_t) + 1];
87 size_t len = makeCharArray(chars, (size_t) fType);
88 return len == typeLen && strncmp(chars, type, typeLen) == 0;
89 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000090 return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0;
reed@android.com8a1c16f2008-12-17 15:59:43 +000091}
92
93void SkEvent::setType(const char type[], size_t typeLen)
94{
95 if (typeLen == 0)
96 typeLen = strlen(type);
97 if (typeLen <= sizeof(fType)) {
98 size_t slot = 0;
99 memcpy(&slot, type, typeLen);
100 if (slot << 1 >> 1 != slot)
101 goto useCharStar;
102 slot <<= 1;
103 slot |= 1;
104 fType = (char*) slot;
105 } else {
106useCharStar:
107 fType = (char*) sk_malloc_throw(typeLen + 1);
108 SkASSERT(((size_t) fType & 1) == 0);
109 memcpy(fType, type, typeLen);
110 fType[typeLen] = 0;
111 }
112}
113
114void SkEvent::setType(const SkString& type)
115{
116 setType(type.c_str());
117}
118
119////////////////////////////////////////////////////////////////////////////
120
121#include "SkParse.h"
122
123void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node)
124{
125 const char* name = dom.findAttr(node, "type");
126 if (name)
127 this->setType(name);
128
129 const char* value;
halcanary96fcdcc2015-08-27 07:41:13 -0700130 if ((value = dom.findAttr(node, "fast32")) != nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000131 {
132 int32_t n;
133 if (SkParse::FindS32(value, &n))
134 this->setFast32(n);
135 }
136
137 for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node))
138 {
139 if (strcmp(dom.getName(node), "data"))
140 {
141 SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));)
142 continue;
143 }
144
145 name = dom.findAttr(node, "name");
halcanary96fcdcc2015-08-27 07:41:13 -0700146 if (name == nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000147 {
148 SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");)
149 continue;
150 }
151
halcanary96fcdcc2015-08-27 07:41:13 -0700152 if ((value = dom.findAttr(node, "s32")) != nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000153 {
154 int32_t n;
155 if (SkParse::FindS32(value, &n))
156 this->setS32(name, n);
157 }
halcanary96fcdcc2015-08-27 07:41:13 -0700158 else if ((value = dom.findAttr(node, "scalar")) != nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159 {
160 SkScalar x;
161 if (SkParse::FindScalar(value, &x))
162 this->setScalar(name, x);
163 }
halcanary96fcdcc2015-08-27 07:41:13 -0700164 else if ((value = dom.findAttr(node, "string")) != nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000165 this->setString(name, value);
166#ifdef SK_DEBUG
167 else
168 {
169 SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name);
170 }
171#endif
172 }
173}
174
175#ifdef SK_DEBUG
176
177 #ifndef SkScalarToFloat
178 #define SkScalarToFloat(x) ((x) / 65536.f)
179 #endif
180
181 void SkEvent::dump(const char title[])
182 {
183 if (title)
184 SkDebugf("%s ", title);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000185
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186 SkString etype;
187 this->getType(&etype);
188 SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32());
189
190 const SkMetaData& md = this->getMetaData();
191 SkMetaData::Iter iter(md);
192 SkMetaData::Type mtype;
193 int count;
194 const char* name;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000195
halcanary96fcdcc2015-08-27 07:41:13 -0700196 while ((name = iter.next(&mtype, &count)) != nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000197 {
198 SkASSERT(count > 0);
199
200 SkDebugf(" <%s>=", name);
201 switch (mtype) {
202 case SkMetaData::kS32_Type: // vector version???
203 {
204 int32_t value;
205 md.findS32(name, &value);
206 SkDebugf("%d ", value);
207 }
208 break;
209 case SkMetaData::kScalar_Type:
210 {
halcanary96fcdcc2015-08-27 07:41:13 -0700211 const SkScalar* values = md.findScalars(name, &count, nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000212 SkDebugf("%f", SkScalarToFloat(values[0]));
213 for (int i = 1; i < count; i++)
214 SkDebugf(", %f", SkScalarToFloat(values[i]));
215 SkDebugf(" ");
216 }
217 break;
218 case SkMetaData::kString_Type:
219 {
220 const char* value = md.findString(name);
221 SkASSERT(value);
222 SkDebugf("<%s> ", value);
223 }
224 break;
225 case SkMetaData::kPtr_Type: // vector version???
226 {
227 void* value;
228 md.findPtr(name, &value);
229 SkDebugf("%p ", value);
230 }
231 break;
232 case SkMetaData::kBool_Type: // vector version???
233 {
234 bool value;
235 md.findBool(name, &value);
236 SkDebugf("%s ", value ? "true" : "false");
237 }
238 break;
239 default:
tomhudson@google.com0c00f212011-12-28 14:59:50 +0000240 SkDEBUGFAIL("unknown metadata type returned from iterator");
reed@android.com8a1c16f2008-12-17 15:59:43 +0000241 break;
242 }
243 }
244 SkDebugf("\n");
245 }
246#endif
247
248///////////////////////////////////////////////////////////////////////////////////////
249
250#ifdef SK_DEBUG
251// #define SK_TRACE_EVENTSx
252#endif
253
254#ifdef SK_TRACE_EVENTS
255 static void event_log(const char s[])
256 {
257 SkDEBUGF(("%s\n", s));
258 }
259
260 #define EVENT_LOG(s) event_log(s)
261 #define EVENT_LOGN(s, n) do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0)
262#else
263 #define EVENT_LOG(s)
264 #define EVENT_LOGN(s, n)
265#endif
266
mtklein1b249332015-07-07 12:21:21 -0700267#include "SkMutex.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +0000268#include "SkTime.h"
269
reed@google.com9998c662011-11-17 22:09:47 +0000270class SkEvent_Globals {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000271public:
reed@google.com9998c662011-11-17 22:09:47 +0000272 SkEvent_Globals() {
halcanary96fcdcc2015-08-27 07:41:13 -0700273 fEventQHead = nullptr;
274 fEventQTail = nullptr;
275 fDelayQHead = nullptr;
reed@google.com9998c662011-11-17 22:09:47 +0000276 SkDEBUGCODE(fEventCounter = 0;)
277 }
278
reed@android.com8a1c16f2008-12-17 15:59:43 +0000279 SkMutex fEventMutex;
280 SkEvent* fEventQHead, *fEventQTail;
281 SkEvent* fDelayQHead;
282 SkDEBUGCODE(int fEventCounter;)
283};
284
reed@google.com9998c662011-11-17 22:09:47 +0000285static SkEvent_Globals& getGlobals() {
286 // leak this, so we don't incure any shutdown perf hit
287 static SkEvent_Globals* gGlobals = new SkEvent_Globals;
288 return *gGlobals;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000289}
290
reed@google.com87fac4a2011-08-04 13:50:17 +0000291///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000292
reed@google.com87fac4a2011-08-04 13:50:17 +0000293void SkEvent::postDelay(SkMSec delay) {
294 if (!fTargetID && !fTargetProc) {
reed@google.comc514dde2011-08-03 19:41:24 +0000295 delete this;
reed@google.com87fac4a2011-08-04 13:50:17 +0000296 return;
297 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000298
reed@google.com87fac4a2011-08-04 13:50:17 +0000299 if (delay) {
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700300 this->postTime(GetMSecsSinceStartup() + delay);
reed@google.com87fac4a2011-08-04 13:50:17 +0000301 return;
302 }
303
reed@google.com9998c662011-11-17 22:09:47 +0000304 SkEvent_Globals& globals = getGlobals();
reed@google.com87fac4a2011-08-04 13:50:17 +0000305
306 globals.fEventMutex.acquire();
307 bool wasEmpty = SkEvent::Enqueue(this);
308 globals.fEventMutex.release();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000309
reed@google.com87fac4a2011-08-04 13:50:17 +0000310 // call outside of us holding the mutex
311 if (wasEmpty) {
312 SkEvent::SignalNonEmptyQueue();
reed@google.comc514dde2011-08-03 19:41:24 +0000313 }
314}
315
reed@google.com87fac4a2011-08-04 13:50:17 +0000316void SkEvent::postTime(SkMSec time) {
317 if (!fTargetID && !fTargetProc) {
318 delete this;
319 return;
320 }
321
reed@google.com9998c662011-11-17 22:09:47 +0000322 SkEvent_Globals& globals = getGlobals();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000323
reed@google.com87fac4a2011-08-04 13:50:17 +0000324 globals.fEventMutex.acquire();
325 SkMSec queueDelay = SkEvent::EnqueueTime(this, time);
326 globals.fEventMutex.release();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000327
reed@google.com87fac4a2011-08-04 13:50:17 +0000328 // call outside of us holding the mutex
329 if ((int32_t)queueDelay != ~0) {
330 SkEvent::SignalQueueTimer(queueDelay);
331 }
332}
333
334bool SkEvent::Enqueue(SkEvent* evt) {
reed@google.com9998c662011-11-17 22:09:47 +0000335 SkEvent_Globals& globals = getGlobals();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000336 // gEventMutex acquired by caller
337
338 SkASSERT(evt);
339
halcanary96fcdcc2015-08-27 07:41:13 -0700340 bool wasEmpty = globals.fEventQHead == nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000341
342 if (globals.fEventQTail)
343 globals.fEventQTail->fNextEvent = evt;
344 globals.fEventQTail = evt;
halcanary96fcdcc2015-08-27 07:41:13 -0700345 if (globals.fEventQHead == nullptr)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000346 globals.fEventQHead = evt;
halcanary96fcdcc2015-08-27 07:41:13 -0700347 evt->fNextEvent = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000348
349 SkDEBUGCODE(++globals.fEventCounter);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000350
351 return wasEmpty;
352}
353
reed@google.com87fac4a2011-08-04 13:50:17 +0000354SkEvent* SkEvent::Dequeue() {
reed@google.com9998c662011-11-17 22:09:47 +0000355 SkEvent_Globals& globals = getGlobals();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000356 globals.fEventMutex.acquire();
357
358 SkEvent* evt = globals.fEventQHead;
reed@google.com87fac4a2011-08-04 13:50:17 +0000359 if (evt) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000360 SkDEBUGCODE(--globals.fEventCounter);
361
reed@android.com8a1c16f2008-12-17 15:59:43 +0000362 globals.fEventQHead = evt->fNextEvent;
halcanary96fcdcc2015-08-27 07:41:13 -0700363 if (globals.fEventQHead == nullptr) {
364 globals.fEventQTail = nullptr;
reed@google.com87fac4a2011-08-04 13:50:17 +0000365 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000366 }
367 globals.fEventMutex.release();
368
reed@android.com8a1c16f2008-12-17 15:59:43 +0000369 return evt;
370}
371
reed@google.com87fac4a2011-08-04 13:50:17 +0000372bool SkEvent::QHasEvents() {
reed@google.com9998c662011-11-17 22:09:47 +0000373 SkEvent_Globals& globals = getGlobals();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000374
375 // this is not thread accurate, need a semaphore for that
halcanary96fcdcc2015-08-27 07:41:13 -0700376 return globals.fEventQHead != nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000377}
378
379#ifdef SK_TRACE_EVENTS
380 static int gDelayDepth;
381#endif
382
reed@google.com87fac4a2011-08-04 13:50:17 +0000383SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) {
reed@google.com9998c662011-11-17 22:09:47 +0000384 SkEvent_Globals& globals = getGlobals();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000385 // gEventMutex acquired by caller
386
387 SkEvent* curr = globals.fDelayQHead;
halcanary96fcdcc2015-08-27 07:41:13 -0700388 SkEvent* prev = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000389
reed@google.com87fac4a2011-08-04 13:50:17 +0000390 while (curr) {
391 if (SkMSec_LT(time, curr->fTime)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000392 break;
reed@google.com87fac4a2011-08-04 13:50:17 +0000393 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000394 prev = curr;
395 curr = curr->fNextEvent;
396 }
397
398 evt->fTime = time;
399 evt->fNextEvent = curr;
halcanary96fcdcc2015-08-27 07:41:13 -0700400 if (prev == nullptr) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000401 globals.fDelayQHead = evt;
reed@google.com87fac4a2011-08-04 13:50:17 +0000402 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000403 prev->fNextEvent = evt;
reed@google.com87fac4a2011-08-04 13:50:17 +0000404 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000405
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700406 SkMSec delay = globals.fDelayQHead->fTime - GetMSecsSinceStartup();
reed@google.com87fac4a2011-08-04 13:50:17 +0000407 if ((int32_t)delay <= 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000408 delay = 1;
reed@google.com87fac4a2011-08-04 13:50:17 +0000409 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000410 return delay;
411}
412
reed@google.com87fac4a2011-08-04 13:50:17 +0000413///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000414
415#include "SkEventSink.h"
416
reed@google.com87fac4a2011-08-04 13:50:17 +0000417bool SkEvent::ProcessEvent() {
418 SkEvent* evt = SkEvent::Dequeue();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000419 SkAutoTDelete<SkEvent> autoDelete(evt);
reed@google.com87fac4a2011-08-04 13:50:17 +0000420 bool again = false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000421
422 EVENT_LOGN("ProcessEvent", (int32_t)evt);
423
reed@google.com87fac4a2011-08-04 13:50:17 +0000424 if (evt) {
425 (void)SkEventSink::DoEvent(*evt);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000426 again = SkEvent::QHasEvents();
427 }
428 return again;
429}
430
431void SkEvent::ServiceQueueTimer()
432{
reed@google.com9998c662011-11-17 22:09:47 +0000433 SkEvent_Globals& globals = getGlobals();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000434
435 globals.fEventMutex.acquire();
436
437 bool wasEmpty = false;
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700438 SkMSec now = GetMSecsSinceStartup();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000439 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
reed@android.comf2b98d62010-12-20 18:26:13 +0000472int SkEvent::CountEventsOnQueue() {
reed@google.com9998c662011-11-17 22:09:47 +0000473 SkEvent_Globals& globals = getGlobals();
reed@android.comf2b98d62010-12-20 18:26:13 +0000474 globals.fEventMutex.acquire();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000475
reed@android.comf2b98d62010-12-20 18:26:13 +0000476 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
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700487SkMSec SkEvent::GetMSecsSinceStartup() {
488 static const double kEpoch = SkTime::GetMSecs();
489 return static_cast<SkMSec>(SkTime::GetMSecs() - kEpoch);
490}
491
reed@google.com9998c662011-11-17 22:09:47 +0000492///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000493
reed@google.com9998c662011-11-17 22:09:47 +0000494void SkEvent::Init() {}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000495
reed@google.com9998c662011-11-17 22:09:47 +0000496void SkEvent::Term() {
497 SkEvent_Globals& globals = getGlobals();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000498
499 SkEvent* evt = globals.fEventQHead;
reed@google.com9998c662011-11-17 22:09:47 +0000500 while (evt) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000501 SkEvent* next = evt->fNextEvent;
502 delete evt;
503 evt = next;
504 }
505
506 evt = globals.fDelayQHead;
reed@google.com9998c662011-11-17 22:09:47 +0000507 while (evt) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000508 SkEvent* next = evt->fNextEvent;
509 delete evt;
510 evt = next;
511 }
512}