gfx/skia/trunk/src/views/SkEvent.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/views/SkEvent.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,508 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#include "SkEvent.h"
    1.14 +
    1.15 +void SkEvent::initialize(const char* type, size_t typeLen,
    1.16 +                         SkEventSinkID targetID) {
    1.17 +    fType = NULL;
    1.18 +    setType(type, typeLen);
    1.19 +    f32 = 0;
    1.20 +    fTargetID = targetID;
    1.21 +    fTargetProc = NULL;
    1.22 +#ifdef SK_DEBUG
    1.23 +    fTime = 0;
    1.24 +    fNextEvent = NULL;
    1.25 +#endif
    1.26 +}
    1.27 +
    1.28 +SkEvent::SkEvent()
    1.29 +{
    1.30 +    initialize("", 0, 0);
    1.31 +}
    1.32 +
    1.33 +SkEvent::SkEvent(const SkEvent& src)
    1.34 +{
    1.35 +    *this = src;
    1.36 +    if (((size_t) fType & 1) == 0)
    1.37 +        setType(src.fType);
    1.38 +}
    1.39 +
    1.40 +SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID)
    1.41 +{
    1.42 +    initialize(type.c_str(), type.size(), targetID);
    1.43 +}
    1.44 +
    1.45 +SkEvent::SkEvent(const char type[], SkEventSinkID targetID)
    1.46 +{
    1.47 +    SkASSERT(type);
    1.48 +    initialize(type, strlen(type), targetID);
    1.49 +}
    1.50 +
    1.51 +SkEvent::~SkEvent()
    1.52 +{
    1.53 +    if (((size_t) fType & 1) == 0)
    1.54 +        sk_free((void*) fType);
    1.55 +}
    1.56 +
    1.57 +static size_t makeCharArray(char* buffer, size_t compact)
    1.58 +{
    1.59 +    size_t bits = (size_t) compact >> 1;
    1.60 +    memcpy(buffer, &bits, sizeof(compact));
    1.61 +    buffer[sizeof(compact)] = 0;
    1.62 +    return strlen(buffer);
    1.63 +}
    1.64 +
    1.65 +void SkEvent::getType(SkString* str) const
    1.66 +{
    1.67 +    if (str)
    1.68 +    {
    1.69 +        if ((size_t) fType & 1) // not a pointer
    1.70 +        {
    1.71 +            char chars[sizeof(size_t) + 1];
    1.72 +            size_t len = makeCharArray(chars, (size_t) fType);
    1.73 +            str->set(chars, len);
    1.74 +        }
    1.75 +        else
    1.76 +            str->set(fType);
    1.77 +    }
    1.78 +}
    1.79 +
    1.80 +bool SkEvent::isType(const SkString& str) const
    1.81 +{
    1.82 +    return this->isType(str.c_str(), str.size());
    1.83 +}
    1.84 +
    1.85 +bool SkEvent::isType(const char type[], size_t typeLen) const
    1.86 +{
    1.87 +    if (typeLen == 0)
    1.88 +        typeLen = strlen(type);
    1.89 +    if ((size_t) fType & 1) {   // not a pointer
    1.90 +        char chars[sizeof(size_t) + 1];
    1.91 +        size_t len = makeCharArray(chars, (size_t) fType);
    1.92 +        return len == typeLen && strncmp(chars, type, typeLen) == 0;
    1.93 +    }
    1.94 +    return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0;
    1.95 +}
    1.96 +
    1.97 +void SkEvent::setType(const char type[], size_t typeLen)
    1.98 +{
    1.99 +    if (typeLen == 0)
   1.100 +        typeLen = strlen(type);
   1.101 +    if (typeLen <= sizeof(fType)) {
   1.102 +        size_t slot = 0;
   1.103 +        memcpy(&slot, type, typeLen);
   1.104 +        if (slot << 1 >> 1 != slot)
   1.105 +            goto useCharStar;
   1.106 +        slot <<= 1;
   1.107 +        slot |= 1;
   1.108 +        fType = (char*) slot;
   1.109 +    } else {
   1.110 +useCharStar:
   1.111 +        fType = (char*) sk_malloc_throw(typeLen + 1);
   1.112 +        SkASSERT(((size_t) fType & 1) == 0);
   1.113 +        memcpy(fType, type, typeLen);
   1.114 +        fType[typeLen] = 0;
   1.115 +    }
   1.116 +}
   1.117 +
   1.118 +void SkEvent::setType(const SkString& type)
   1.119 +{
   1.120 +    setType(type.c_str());
   1.121 +}
   1.122 +
   1.123 +////////////////////////////////////////////////////////////////////////////
   1.124 +
   1.125 +#include "SkParse.h"
   1.126 +
   1.127 +void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node)
   1.128 +{
   1.129 +    const char* name = dom.findAttr(node, "type");
   1.130 +    if (name)
   1.131 +        this->setType(name);
   1.132 +
   1.133 +    const char* value;
   1.134 +    if ((value = dom.findAttr(node, "fast32")) != NULL)
   1.135 +    {
   1.136 +        int32_t n;
   1.137 +        if (SkParse::FindS32(value, &n))
   1.138 +            this->setFast32(n);
   1.139 +    }
   1.140 +
   1.141 +    for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node))
   1.142 +    {
   1.143 +        if (strcmp(dom.getName(node), "data"))
   1.144 +        {
   1.145 +            SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));)
   1.146 +            continue;
   1.147 +        }
   1.148 +
   1.149 +        name = dom.findAttr(node, "name");
   1.150 +        if (name == NULL)
   1.151 +        {
   1.152 +            SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");)
   1.153 +            continue;
   1.154 +        }
   1.155 +
   1.156 +        if ((value = dom.findAttr(node, "s32")) != NULL)
   1.157 +        {
   1.158 +            int32_t n;
   1.159 +            if (SkParse::FindS32(value, &n))
   1.160 +                this->setS32(name, n);
   1.161 +        }
   1.162 +        else if ((value = dom.findAttr(node, "scalar")) != NULL)
   1.163 +        {
   1.164 +            SkScalar x;
   1.165 +            if (SkParse::FindScalar(value, &x))
   1.166 +                this->setScalar(name, x);
   1.167 +        }
   1.168 +        else if ((value = dom.findAttr(node, "string")) != NULL)
   1.169 +            this->setString(name, value);
   1.170 +#ifdef SK_DEBUG
   1.171 +        else
   1.172 +        {
   1.173 +            SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name);
   1.174 +        }
   1.175 +#endif
   1.176 +    }
   1.177 +}
   1.178 +
   1.179 +#ifdef SK_DEBUG
   1.180 +
   1.181 +    #ifndef SkScalarToFloat
   1.182 +        #define SkScalarToFloat(x)  ((x) / 65536.f)
   1.183 +    #endif
   1.184 +
   1.185 +    void SkEvent::dump(const char title[])
   1.186 +    {
   1.187 +        if (title)
   1.188 +            SkDebugf("%s ", title);
   1.189 +
   1.190 +        SkString    etype;
   1.191 +        this->getType(&etype);
   1.192 +        SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32());
   1.193 +
   1.194 +        const SkMetaData&   md = this->getMetaData();
   1.195 +        SkMetaData::Iter    iter(md);
   1.196 +        SkMetaData::Type    mtype;
   1.197 +        int                 count;
   1.198 +        const char*         name;
   1.199 +
   1.200 +        while ((name = iter.next(&mtype, &count)) != NULL)
   1.201 +        {
   1.202 +            SkASSERT(count > 0);
   1.203 +
   1.204 +            SkDebugf(" <%s>=", name);
   1.205 +            switch (mtype) {
   1.206 +            case SkMetaData::kS32_Type:     // vector version???
   1.207 +                {
   1.208 +                    int32_t value;
   1.209 +                    md.findS32(name, &value);
   1.210 +                    SkDebugf("%d ", value);
   1.211 +                }
   1.212 +                break;
   1.213 +            case SkMetaData::kScalar_Type:
   1.214 +                {
   1.215 +                    const SkScalar* values = md.findScalars(name, &count, NULL);
   1.216 +                    SkDebugf("%f", SkScalarToFloat(values[0]));
   1.217 +                    for (int i = 1; i < count; i++)
   1.218 +                        SkDebugf(", %f", SkScalarToFloat(values[i]));
   1.219 +                    SkDebugf(" ");
   1.220 +                }
   1.221 +                break;
   1.222 +            case SkMetaData::kString_Type:
   1.223 +                {
   1.224 +                    const char* value = md.findString(name);
   1.225 +                    SkASSERT(value);
   1.226 +                    SkDebugf("<%s> ", value);
   1.227 +                }
   1.228 +                break;
   1.229 +            case SkMetaData::kPtr_Type:     // vector version???
   1.230 +                {
   1.231 +                    void*   value;
   1.232 +                    md.findPtr(name, &value);
   1.233 +                    SkDebugf("%p ", value);
   1.234 +                }
   1.235 +                break;
   1.236 +            case SkMetaData::kBool_Type:    // vector version???
   1.237 +                {
   1.238 +                    bool    value;
   1.239 +                    md.findBool(name, &value);
   1.240 +                    SkDebugf("%s ", value ? "true" : "false");
   1.241 +                }
   1.242 +                break;
   1.243 +            default:
   1.244 +                SkDEBUGFAIL("unknown metadata type returned from iterator");
   1.245 +                break;
   1.246 +            }
   1.247 +        }
   1.248 +        SkDebugf("\n");
   1.249 +    }
   1.250 +#endif
   1.251 +
   1.252 +///////////////////////////////////////////////////////////////////////////////////////
   1.253 +
   1.254 +#ifdef SK_DEBUG
   1.255 +// #define SK_TRACE_EVENTSx
   1.256 +#endif
   1.257 +
   1.258 +#ifdef SK_TRACE_EVENTS
   1.259 +    static void event_log(const char s[])
   1.260 +    {
   1.261 +        SkDEBUGF(("%s\n", s));
   1.262 +    }
   1.263 +
   1.264 +    #define EVENT_LOG(s)        event_log(s)
   1.265 +    #define EVENT_LOGN(s, n)    do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0)
   1.266 +#else
   1.267 +    #define EVENT_LOG(s)
   1.268 +    #define EVENT_LOGN(s, n)
   1.269 +#endif
   1.270 +
   1.271 +#include "SkThread.h"
   1.272 +#include "SkTime.h"
   1.273 +
   1.274 +class SkEvent_Globals {
   1.275 +public:
   1.276 +    SkEvent_Globals() {
   1.277 +        fEventQHead = NULL;
   1.278 +        fEventQTail = NULL;
   1.279 +        fDelayQHead = NULL;
   1.280 +        SkDEBUGCODE(fEventCounter = 0;)
   1.281 +    }
   1.282 +
   1.283 +    SkMutex     fEventMutex;
   1.284 +    SkEvent*    fEventQHead, *fEventQTail;
   1.285 +    SkEvent*    fDelayQHead;
   1.286 +    SkDEBUGCODE(int fEventCounter;)
   1.287 +};
   1.288 +
   1.289 +static SkEvent_Globals& getGlobals() {
   1.290 +    // leak this, so we don't incure any shutdown perf hit
   1.291 +    static SkEvent_Globals* gGlobals = new SkEvent_Globals;
   1.292 +    return *gGlobals;
   1.293 +}
   1.294 +
   1.295 +///////////////////////////////////////////////////////////////////////////////
   1.296 +
   1.297 +void SkEvent::postDelay(SkMSec delay) {
   1.298 +    if (!fTargetID && !fTargetProc) {
   1.299 +        delete this;
   1.300 +        return;
   1.301 +    }
   1.302 +
   1.303 +    if (delay) {
   1.304 +        this->postTime(SkTime::GetMSecs() + delay);
   1.305 +        return;
   1.306 +    }
   1.307 +
   1.308 +    SkEvent_Globals& globals = getGlobals();
   1.309 +
   1.310 +    globals.fEventMutex.acquire();
   1.311 +    bool wasEmpty = SkEvent::Enqueue(this);
   1.312 +    globals.fEventMutex.release();
   1.313 +
   1.314 +    // call outside of us holding the mutex
   1.315 +    if (wasEmpty) {
   1.316 +        SkEvent::SignalNonEmptyQueue();
   1.317 +    }
   1.318 +}
   1.319 +
   1.320 +void SkEvent::postTime(SkMSec time) {
   1.321 +    if (!fTargetID && !fTargetProc) {
   1.322 +        delete this;
   1.323 +        return;
   1.324 +    }
   1.325 +
   1.326 +    SkEvent_Globals& globals = getGlobals();
   1.327 +
   1.328 +    globals.fEventMutex.acquire();
   1.329 +    SkMSec queueDelay = SkEvent::EnqueueTime(this, time);
   1.330 +    globals.fEventMutex.release();
   1.331 +
   1.332 +    // call outside of us holding the mutex
   1.333 +    if ((int32_t)queueDelay != ~0) {
   1.334 +        SkEvent::SignalQueueTimer(queueDelay);
   1.335 +    }
   1.336 +}
   1.337 +
   1.338 +bool SkEvent::Enqueue(SkEvent* evt) {
   1.339 +    SkEvent_Globals& globals = getGlobals();
   1.340 +    //  gEventMutex acquired by caller
   1.341 +
   1.342 +    SkASSERT(evt);
   1.343 +
   1.344 +    bool wasEmpty = globals.fEventQHead == NULL;
   1.345 +
   1.346 +    if (globals.fEventQTail)
   1.347 +        globals.fEventQTail->fNextEvent = evt;
   1.348 +    globals.fEventQTail = evt;
   1.349 +    if (globals.fEventQHead == NULL)
   1.350 +        globals.fEventQHead = evt;
   1.351 +    evt->fNextEvent = NULL;
   1.352 +
   1.353 +    SkDEBUGCODE(++globals.fEventCounter);
   1.354 +
   1.355 +    return wasEmpty;
   1.356 +}
   1.357 +
   1.358 +SkEvent* SkEvent::Dequeue() {
   1.359 +    SkEvent_Globals& globals = getGlobals();
   1.360 +    globals.fEventMutex.acquire();
   1.361 +
   1.362 +    SkEvent* evt = globals.fEventQHead;
   1.363 +    if (evt) {
   1.364 +        SkDEBUGCODE(--globals.fEventCounter);
   1.365 +
   1.366 +        globals.fEventQHead = evt->fNextEvent;
   1.367 +        if (globals.fEventQHead == NULL) {
   1.368 +            globals.fEventQTail = NULL;
   1.369 +        }
   1.370 +    }
   1.371 +    globals.fEventMutex.release();
   1.372 +
   1.373 +    return evt;
   1.374 +}
   1.375 +
   1.376 +bool SkEvent::QHasEvents() {
   1.377 +    SkEvent_Globals& globals = getGlobals();
   1.378 +
   1.379 +    // this is not thread accurate, need a semaphore for that
   1.380 +    return globals.fEventQHead != NULL;
   1.381 +}
   1.382 +
   1.383 +#ifdef SK_TRACE_EVENTS
   1.384 +    static int gDelayDepth;
   1.385 +#endif
   1.386 +
   1.387 +SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) {
   1.388 +    SkEvent_Globals& globals = getGlobals();
   1.389 +    //  gEventMutex acquired by caller
   1.390 +
   1.391 +    SkEvent* curr = globals.fDelayQHead;
   1.392 +    SkEvent* prev = NULL;
   1.393 +
   1.394 +    while (curr) {
   1.395 +        if (SkMSec_LT(time, curr->fTime)) {
   1.396 +            break;
   1.397 +        }
   1.398 +        prev = curr;
   1.399 +        curr = curr->fNextEvent;
   1.400 +    }
   1.401 +
   1.402 +    evt->fTime = time;
   1.403 +    evt->fNextEvent = curr;
   1.404 +    if (prev == NULL) {
   1.405 +        globals.fDelayQHead = evt;
   1.406 +    } else {
   1.407 +        prev->fNextEvent = evt;
   1.408 +    }
   1.409 +
   1.410 +    SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs();
   1.411 +    if ((int32_t)delay <= 0) {
   1.412 +        delay = 1;
   1.413 +    }
   1.414 +    return delay;
   1.415 +}
   1.416 +
   1.417 +///////////////////////////////////////////////////////////////////////////////
   1.418 +
   1.419 +#include "SkEventSink.h"
   1.420 +
   1.421 +bool SkEvent::ProcessEvent() {
   1.422 +    SkEvent*                evt = SkEvent::Dequeue();
   1.423 +    SkAutoTDelete<SkEvent>  autoDelete(evt);
   1.424 +    bool                    again = false;
   1.425 +
   1.426 +    EVENT_LOGN("ProcessEvent", (int32_t)evt);
   1.427 +
   1.428 +    if (evt) {
   1.429 +        (void)SkEventSink::DoEvent(*evt);
   1.430 +        again = SkEvent::QHasEvents();
   1.431 +    }
   1.432 +    return again;
   1.433 +}
   1.434 +
   1.435 +void SkEvent::ServiceQueueTimer()
   1.436 +{
   1.437 +    SkEvent_Globals& globals = getGlobals();
   1.438 +
   1.439 +    globals.fEventMutex.acquire();
   1.440 +
   1.441 +    bool        wasEmpty = false;
   1.442 +    SkMSec      now = SkTime::GetMSecs();
   1.443 +    SkEvent*    evt = globals.fDelayQHead;
   1.444 +
   1.445 +    while (evt)
   1.446 +    {
   1.447 +        if (SkMSec_LT(now, evt->fTime))
   1.448 +            break;
   1.449 +
   1.450 +#ifdef SK_TRACE_EVENTS
   1.451 +        --gDelayDepth;
   1.452 +        SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth);
   1.453 +        const char* idStr = evt->findString("id");
   1.454 +        if (idStr)
   1.455 +            SkDebugf(" (%s)", idStr);
   1.456 +        SkDebugf("\n");
   1.457 +#endif
   1.458 +
   1.459 +        SkEvent* next = evt->fNextEvent;
   1.460 +        if (SkEvent::Enqueue(evt))
   1.461 +            wasEmpty = true;
   1.462 +        evt = next;
   1.463 +    }
   1.464 +    globals.fDelayQHead = evt;
   1.465 +
   1.466 +    SkMSec time = evt ? evt->fTime - now : 0;
   1.467 +
   1.468 +    globals.fEventMutex.release();
   1.469 +
   1.470 +    if (wasEmpty)
   1.471 +        SkEvent::SignalNonEmptyQueue();
   1.472 +
   1.473 +    SkEvent::SignalQueueTimer(time);
   1.474 +}
   1.475 +
   1.476 +int SkEvent::CountEventsOnQueue() {
   1.477 +    SkEvent_Globals& globals = getGlobals();
   1.478 +    globals.fEventMutex.acquire();
   1.479 +
   1.480 +    int count = 0;
   1.481 +    const SkEvent* evt = globals.fEventQHead;
   1.482 +    while (evt) {
   1.483 +        count += 1;
   1.484 +        evt = evt->fNextEvent;
   1.485 +    }
   1.486 +    globals.fEventMutex.release();
   1.487 +
   1.488 +    return count;
   1.489 +}
   1.490 +
   1.491 +///////////////////////////////////////////////////////////////////////////////
   1.492 +
   1.493 +void SkEvent::Init() {}
   1.494 +
   1.495 +void SkEvent::Term() {
   1.496 +    SkEvent_Globals& globals = getGlobals();
   1.497 +
   1.498 +    SkEvent* evt = globals.fEventQHead;
   1.499 +    while (evt) {
   1.500 +        SkEvent* next = evt->fNextEvent;
   1.501 +        delete evt;
   1.502 +        evt = next;
   1.503 +    }
   1.504 +
   1.505 +    evt = globals.fDelayQHead;
   1.506 +    while (evt) {
   1.507 +        SkEvent* next = evt->fNextEvent;
   1.508 +        delete evt;
   1.509 +        evt = next;
   1.510 +    }
   1.511 +}

mercurial