• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 
9 #include "SkEventSink.h"
10 #include "SkMutex.h"
11 #include "SkTime.h"
12 
13 class SkEventSink_Globals {
14 public:
SkEventSink_Globals()15     SkEventSink_Globals() {
16         fNextSinkID = 0;
17         fSinkHead = nullptr;
18     }
19 
20     SkMutex         fSinkMutex;
21     SkEventSinkID   fNextSinkID;
22     SkEventSink*    fSinkHead;
23 };
24 
getGlobals()25 static SkEventSink_Globals& getGlobals() {
26     // leak this, so we don't incur any shutdown perf hit
27     static SkEventSink_Globals* gGlobals = new SkEventSink_Globals;
28     return *gGlobals;
29 }
30 
SkEventSink()31 SkEventSink::SkEventSink() {
32     SkEventSink_Globals& globals = getGlobals();
33 
34     globals.fSinkMutex.acquire();
35 
36     fID = ++globals.fNextSinkID;
37     fNextSink = globals.fSinkHead;
38     globals.fSinkHead = this;
39 
40     globals.fSinkMutex.release();
41 }
42 
~SkEventSink()43 SkEventSink::~SkEventSink() {
44     SkEventSink_Globals& globals = getGlobals();
45 
46     globals.fSinkMutex.acquire();
47 
48     SkEventSink* sink = globals.fSinkHead;
49     SkEventSink* prev = nullptr;
50 
51     for (;;) {
52         SkEventSink* next = sink->fNextSink;
53         if (sink == this) {
54             if (prev) {
55                 prev->fNextSink = next;
56             } else {
57                 globals.fSinkHead = next;
58             }
59             break;
60         }
61         prev = sink;
62         sink = next;
63     }
64     globals.fSinkMutex.release();
65 }
66 
doEvent(const SkEvent & evt)67 bool SkEventSink::doEvent(const SkEvent& evt) {
68     return this->onEvent(evt);
69 }
70 
doQuery(SkEvent * evt)71 bool SkEventSink::doQuery(SkEvent* evt) {
72     SkASSERT(evt);
73     return this->onQuery(evt);
74 }
75 
onEvent(const SkEvent &)76 bool SkEventSink::onEvent(const SkEvent&) {
77     return false;
78 }
79 
onQuery(SkEvent *)80 bool SkEventSink::onQuery(SkEvent*) {
81     return false;
82 }
83 
84 ///////////////////////////////////////////////////////////////////////////////
85 
FindSink(SkEventSinkID sinkID)86 SkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID)
87 {
88     if (sinkID == 0)
89         return nullptr;
90 
91     SkEventSink_Globals&    globals = getGlobals();
92     SkAutoMutexAcquire      ac(globals.fSinkMutex);
93     SkEventSink*            sink = globals.fSinkHead;
94 
95     while (sink)
96     {
97         if (sink->getSinkID() == sinkID)
98             return sink;
99         sink = sink->fNextSink;
100     }
101     return nullptr;
102 }
103