Index: skia/views/SkEvent.cpp |
=================================================================== |
--- skia/views/SkEvent.cpp (revision 16859) |
+++ skia/views/SkEvent.cpp (working copy) |
@@ -1,565 +0,0 @@ |
-/* libs/graphics/views/SkEvent.cpp |
-** |
-** Copyright 2006, The Android Open Source Project |
-** |
-** Licensed under the Apache License, Version 2.0 (the "License"); |
-** you may not use this file except in compliance with the License. |
-** You may obtain a copy of the License at |
-** |
-** http://www.apache.org/licenses/LICENSE-2.0 |
-** |
-** Unless required by applicable law or agreed to in writing, software |
-** distributed under the License is distributed on an "AS IS" BASIS, |
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-** See the License for the specific language governing permissions and |
-** limitations under the License. |
-*/ |
- |
-#include "SkEvent.h" |
- |
-void SkEvent::initialize(const char* type, size_t typeLen) { |
- fType = NULL; |
- setType(type, typeLen); |
- f32 = 0; |
-#ifdef SK_DEBUG |
- fTargetID = 0; |
- fTime = 0; |
- fNextEvent = NULL; |
-#endif |
- SkDEBUGCODE(fDebugTrace = false;) |
-} |
- |
-SkEvent::SkEvent() |
-{ |
- initialize("", 0); |
-} |
- |
-SkEvent::SkEvent(const SkEvent& src) |
-{ |
- *this = src; |
- if (((size_t) fType & 1) == 0) |
- setType(src.fType); |
-} |
- |
-SkEvent::SkEvent(const SkString& type) |
-{ |
- initialize(type.c_str(), type.size()); |
-} |
- |
-SkEvent::SkEvent(const char type[]) |
-{ |
- SkASSERT(type); |
- initialize(type, strlen(type)); |
-} |
- |
-SkEvent::~SkEvent() |
-{ |
- if (((size_t) fType & 1) == 0) |
- sk_free((void*) fType); |
-} |
- |
-static size_t makeCharArray(char* buffer, size_t compact) |
-{ |
- size_t bits = (size_t) compact >> 1; |
- memcpy(buffer, &bits, sizeof(compact)); |
- buffer[sizeof(compact)] = 0; |
- return strlen(buffer); |
-} |
- |
-#if 0 |
-const char* SkEvent::getType() const |
-{ |
- if ((size_t) fType & 1) { // not a pointer |
- char chars[sizeof(size_t) + 1]; |
- size_t len = makeCharArray(chars, (size_t) fType); |
- fType = (char*) sk_malloc_throw(len); |
- SkASSERT(((size_t) fType & 1) == 0); |
- memcpy(fType, chars, len); |
- } |
- return fType; |
-} |
-#endif |
- |
-void SkEvent::getType(SkString* str) const |
-{ |
- if (str) |
- { |
- if ((size_t) fType & 1) // not a pointer |
- { |
- char chars[sizeof(size_t) + 1]; |
- size_t len = makeCharArray(chars, (size_t) fType); |
- str->set(chars, len); |
- } |
- else |
- str->set(fType); |
- } |
-} |
- |
-bool SkEvent::isType(const SkString& str) const |
-{ |
- return this->isType(str.c_str(), str.size()); |
-} |
- |
-bool SkEvent::isType(const char type[], size_t typeLen) const |
-{ |
- if (typeLen == 0) |
- typeLen = strlen(type); |
- if ((size_t) fType & 1) { // not a pointer |
- char chars[sizeof(size_t) + 1]; |
- size_t len = makeCharArray(chars, (size_t) fType); |
- return len == typeLen && strncmp(chars, type, typeLen) == 0; |
- } |
- return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0; |
-} |
- |
-void SkEvent::setType(const char type[], size_t typeLen) |
-{ |
- if (typeLen == 0) |
- typeLen = strlen(type); |
- if (typeLen <= sizeof(fType)) { |
- size_t slot = 0; |
- memcpy(&slot, type, typeLen); |
- if (slot << 1 >> 1 != slot) |
- goto useCharStar; |
- slot <<= 1; |
- slot |= 1; |
- fType = (char*) slot; |
- } else { |
-useCharStar: |
- fType = (char*) sk_malloc_throw(typeLen + 1); |
- SkASSERT(((size_t) fType & 1) == 0); |
- memcpy(fType, type, typeLen); |
- fType[typeLen] = 0; |
- } |
-} |
- |
-void SkEvent::setType(const SkString& type) |
-{ |
- setType(type.c_str()); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////// |
- |
-#include "SkParse.h" |
- |
-void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node) |
-{ |
- const char* name = dom.findAttr(node, "type"); |
- if (name) |
- this->setType(name); |
- |
- const char* value; |
- if ((value = dom.findAttr(node, "fast32")) != NULL) |
- { |
- int32_t n; |
- if (SkParse::FindS32(value, &n)) |
- this->setFast32(n); |
- } |
- |
- for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node)) |
- { |
- if (strcmp(dom.getName(node), "data")) |
- { |
- SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));) |
- continue; |
- } |
- |
- name = dom.findAttr(node, "name"); |
- if (name == NULL) |
- { |
- SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");) |
- continue; |
- } |
- |
- if ((value = dom.findAttr(node, "s32")) != NULL) |
- { |
- int32_t n; |
- if (SkParse::FindS32(value, &n)) |
- this->setS32(name, n); |
- } |
- else if ((value = dom.findAttr(node, "scalar")) != NULL) |
- { |
- SkScalar x; |
- if (SkParse::FindScalar(value, &x)) |
- this->setScalar(name, x); |
- } |
- else if ((value = dom.findAttr(node, "string")) != NULL) |
- this->setString(name, value); |
-#ifdef SK_DEBUG |
- else |
- { |
- SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name); |
- } |
-#endif |
- } |
-} |
- |
-#ifdef SK_DEBUG |
- |
- #ifndef SkScalarToFloat |
- #define SkScalarToFloat(x) ((x) / 65536.f) |
- #endif |
- |
- void SkEvent::dump(const char title[]) |
- { |
- if (title) |
- SkDebugf("%s ", title); |
- |
- SkString etype; |
- this->getType(&etype); |
- SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32()); |
- |
- const SkMetaData& md = this->getMetaData(); |
- SkMetaData::Iter iter(md); |
- SkMetaData::Type mtype; |
- int count; |
- const char* name; |
- |
- while ((name = iter.next(&mtype, &count)) != NULL) |
- { |
- SkASSERT(count > 0); |
- |
- SkDebugf(" <%s>=", name); |
- switch (mtype) { |
- case SkMetaData::kS32_Type: // vector version??? |
- { |
- int32_t value; |
- md.findS32(name, &value); |
- SkDebugf("%d ", value); |
- } |
- break; |
- case SkMetaData::kScalar_Type: |
- { |
- const SkScalar* values = md.findScalars(name, &count, NULL); |
- SkDebugf("%f", SkScalarToFloat(values[0])); |
- for (int i = 1; i < count; i++) |
- SkDebugf(", %f", SkScalarToFloat(values[i])); |
- SkDebugf(" "); |
- } |
- break; |
- case SkMetaData::kString_Type: |
- { |
- const char* value = md.findString(name); |
- SkASSERT(value); |
- SkDebugf("<%s> ", value); |
- } |
- break; |
- case SkMetaData::kPtr_Type: // vector version??? |
- { |
- void* value; |
- md.findPtr(name, &value); |
- SkDebugf("%p ", value); |
- } |
- break; |
- case SkMetaData::kBool_Type: // vector version??? |
- { |
- bool value; |
- md.findBool(name, &value); |
- SkDebugf("%s ", value ? "true" : "false"); |
- } |
- break; |
- default: |
- SkASSERT(!"unknown metadata type returned from iterator"); |
- break; |
- } |
- } |
- SkDebugf("\n"); |
- } |
-#endif |
- |
-/////////////////////////////////////////////////////////////////////////////////////// |
- |
-#ifdef SK_DEBUG |
-// #define SK_TRACE_EVENTSx |
-#endif |
- |
-#ifdef SK_TRACE_EVENTS |
- static void event_log(const char s[]) |
- { |
- SkDEBUGF(("%s\n", s)); |
- } |
- |
- #define EVENT_LOG(s) event_log(s) |
- #define EVENT_LOGN(s, n) do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0) |
-#else |
- #define EVENT_LOG(s) |
- #define EVENT_LOGN(s, n) |
-#endif |
- |
-#include "SkGlobals.h" |
-#include "SkThread.h" |
-#include "SkTime.h" |
- |
-#define SK_Event_GlobalsTag SkSetFourByteTag('e', 'v', 'n', 't') |
- |
-class SkEvent_Globals : public SkGlobals::Rec { |
-public: |
- SkMutex fEventMutex; |
- SkEvent* fEventQHead, *fEventQTail; |
- SkEvent* fDelayQHead; |
- SkDEBUGCODE(int fEventCounter;) |
-}; |
- |
-static SkGlobals::Rec* create_globals() |
-{ |
- SkEvent_Globals* rec = new SkEvent_Globals; |
- rec->fEventQHead = NULL; |
- rec->fEventQTail = NULL; |
- rec->fDelayQHead = NULL; |
- SkDEBUGCODE(rec->fEventCounter = 0;) |
- return rec; |
-} |
- |
-bool SkEvent::Post(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay) |
-{ |
- if (delay) |
- return SkEvent::PostTime(evt, sinkID, SkTime::GetMSecs() + delay); |
- |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- |
- evt->fTargetID = sinkID; |
- |
-#ifdef SK_TRACE_EVENTS |
- { |
- SkString str("SkEvent::Post("); |
- str.append(evt->getType()); |
- str.append(", 0x"); |
- str.appendHex(sinkID); |
- str.append(", "); |
- str.appendS32(delay); |
- str.append(")"); |
- event_log(str.c_str()); |
- } |
-#endif |
- |
- globals.fEventMutex.acquire(); |
- bool wasEmpty = SkEvent::Enqueue(evt); |
- globals.fEventMutex.release(); |
- |
- // call outside of us holding the mutex |
- if (wasEmpty) |
- SkEvent::SignalNonEmptyQueue(); |
- return true; |
-} |
- |
-#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(SK_FIND_MEMORY_LEAKS) |
-SkMSec gMaxDrawTime; |
-#endif |
- |
-bool SkEvent::PostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time) |
-{ |
-#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(SK_FIND_MEMORY_LEAKS) |
- gMaxDrawTime = time; |
-#endif |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- |
- evt->fTargetID = sinkID; |
- |
-#ifdef SK_TRACE_EVENTS |
- { |
- SkString str("SkEvent::Post("); |
- str.append(evt->getType()); |
- str.append(", 0x"); |
- str.appendHex(sinkID); |
- str.append(", "); |
- str.appendS32(time); |
- str.append(")"); |
- event_log(str.c_str()); |
- } |
-#endif |
- |
- globals.fEventMutex.acquire(); |
- SkMSec queueDelay = SkEvent::EnqueueTime(evt, time); |
- globals.fEventMutex.release(); |
- |
- // call outside of us holding the mutex |
- if ((int32_t)queueDelay != ~0) |
- SkEvent::SignalQueueTimer(queueDelay); |
- return true; |
-} |
- |
-bool SkEvent::Enqueue(SkEvent* evt) |
-{ |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- // gEventMutex acquired by caller |
- |
- SkASSERT(evt); |
- |
- bool wasEmpty = globals.fEventQHead == NULL; |
- |
- if (globals.fEventQTail) |
- globals.fEventQTail->fNextEvent = evt; |
- globals.fEventQTail = evt; |
- if (globals.fEventQHead == NULL) |
- globals.fEventQHead = evt; |
- evt->fNextEvent = NULL; |
- |
- SkDEBUGCODE(++globals.fEventCounter); |
-// SkDebugf("Enqueue: count=%d\n", gEventCounter); |
- |
- return wasEmpty; |
-} |
- |
-SkEvent* SkEvent::Dequeue(SkEventSinkID* sinkID) |
-{ |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- globals.fEventMutex.acquire(); |
- |
- SkEvent* evt = globals.fEventQHead; |
- if (evt) |
- { |
- SkDEBUGCODE(--globals.fEventCounter); |
- |
- if (sinkID) |
- *sinkID = evt->fTargetID; |
- |
- globals.fEventQHead = evt->fNextEvent; |
- if (globals.fEventQHead == NULL) |
- globals.fEventQTail = NULL; |
- } |
- globals.fEventMutex.release(); |
- |
-// SkDebugf("Dequeue: count=%d\n", gEventCounter); |
- |
- return evt; |
-} |
- |
-bool SkEvent::QHasEvents() |
-{ |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- |
- // this is not thread accurate, need a semaphore for that |
- return globals.fEventQHead != NULL; |
-} |
- |
-#ifdef SK_TRACE_EVENTS |
- static int gDelayDepth; |
-#endif |
- |
-SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) |
-{ |
-#ifdef SK_TRACE_EVENTS |
- SkDebugf("enqueue-delay %s %d (%d)", evt->getType(), time, gDelayDepth); |
- const char* idStr = evt->findString("id"); |
- if (idStr) |
- SkDebugf(" (%s)", idStr); |
- SkDebugf("\n"); |
- ++gDelayDepth; |
-#endif |
- |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- // gEventMutex acquired by caller |
- |
- SkEvent* curr = globals.fDelayQHead; |
- SkEvent* prev = NULL; |
- |
- while (curr) |
- { |
- if (SkMSec_LT(time, curr->fTime)) |
- break; |
- prev = curr; |
- curr = curr->fNextEvent; |
- } |
- |
- evt->fTime = time; |
- evt->fNextEvent = curr; |
- if (prev == NULL) |
- globals.fDelayQHead = evt; |
- else |
- prev->fNextEvent = evt; |
- |
- SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs(); |
- if ((int32_t)delay <= 0) |
- delay = 1; |
- return delay; |
-} |
- |
-////////////////////////////////////////////////////////////////////////////// |
- |
-#include "SkEventSink.h" |
- |
-bool SkEvent::ProcessEvent() |
-{ |
- SkEventSinkID sinkID; |
- SkEvent* evt = SkEvent::Dequeue(&sinkID); |
- SkAutoTDelete<SkEvent> autoDelete(evt); |
- bool again = false; |
- |
- EVENT_LOGN("ProcessEvent", (int32_t)evt); |
- |
- if (evt) |
- { |
- (void)SkEventSink::DoEvent(*evt, sinkID); |
- again = SkEvent::QHasEvents(); |
- } |
- return again; |
-} |
- |
-void SkEvent::ServiceQueueTimer() |
-{ |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- |
- globals.fEventMutex.acquire(); |
- |
- bool wasEmpty = false; |
- SkMSec now = SkTime::GetMSecs(); |
- SkEvent* evt = globals.fDelayQHead; |
- |
- while (evt) |
- { |
- if (SkMSec_LT(now, evt->fTime)) |
- break; |
- |
-#ifdef SK_TRACE_EVENTS |
- --gDelayDepth; |
- SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth); |
- const char* idStr = evt->findString("id"); |
- if (idStr) |
- SkDebugf(" (%s)", idStr); |
- SkDebugf("\n"); |
-#endif |
- |
- SkEvent* next = evt->fNextEvent; |
- if (SkEvent::Enqueue(evt)) |
- wasEmpty = true; |
- evt = next; |
- } |
- globals.fDelayQHead = evt; |
- |
- SkMSec time = evt ? evt->fTime - now : 0; |
- |
- globals.fEventMutex.release(); |
- |
- if (wasEmpty) |
- SkEvent::SignalNonEmptyQueue(); |
- |
- SkEvent::SignalQueueTimer(time); |
-} |
- |
-//////////////////////////////////////////////////////////////// |
- |
-void SkEvent::Init() |
-{ |
-} |
- |
-void SkEvent::Term() |
-{ |
- SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); |
- |
- SkEvent* evt = globals.fEventQHead; |
- while (evt) |
- { |
- SkEvent* next = evt->fNextEvent; |
- delete evt; |
- evt = next; |
- } |
- |
- evt = globals.fDelayQHead; |
- while (evt) |
- { |
- SkEvent* next = evt->fNextEvent; |
- delete evt; |
- evt = next; |
- } |
-} |
- |