Skip to content

Commit

Permalink
Revert "Use spin lock in SkIDChangeListener"
Browse files Browse the repository at this point in the history
This reverts commit a624a53.

Reason for revert: Bad perf

Original change's description:
> Use spin lock in SkIDChangeListener
> 
> This lock should almost never be contested. This simplifies things and
> also avoid mutex locks when one thread has multiple refs on a path,
> image, ...
> 
> Change-Id: I909b490363cb9e81b38ed9edd04272133fb2692b
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274676
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

TBR=bsalomon@google.com,brianosman@google.com

Change-Id: I45ec3241906429e4d0783b68ebe6398079b73d36
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274956
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
  • Loading branch information
bsalomon authored and Skia Commit-Bot committed Mar 4, 2020
1 parent 20ed48e commit 64a3f8f
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 33 deletions.
1 change: 0 additions & 1 deletion BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,6 @@ static_library("pathkit") {
"src/core/SkRRect.cpp",
"src/core/SkRect.cpp",
"src/core/SkSemaphore.cpp",
"src/core/SkSpinlock.cpp",
"src/core/SkStream.cpp",
"src/core/SkString.cpp",
"src/core/SkStringUtils.cpp",
Expand Down
10 changes: 5 additions & 5 deletions include/private/SkIDChangeListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#define SkIDChangeListener_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/private/SkSpinlock.h"
#include "include/private/SkMutex.h"
#include "include/private/SkTDArray.h"

#include <atomic>
Expand Down Expand Up @@ -49,7 +49,7 @@ class SkIDChangeListener : public SkRefCnt {
* Add a new listener to the list. It must not already be deregistered. Also clears out
* previously deregistered listeners.
*/
void add(sk_sp<SkIDChangeListener> listener);
void add(sk_sp<SkIDChangeListener> listener, bool singleThreaded = false);

/**
* The number of registered listeners (including deregisterd listeners that are yet-to-be
Expand All @@ -58,13 +58,13 @@ class SkIDChangeListener : public SkRefCnt {
int count();

/** Calls changed() on all listeners that haven't been deregistered and resets the list. */
void changed();
void changed(bool singleThreaded = false);

/** Resets without calling changed() on the listeners. */
void reset();
void reset(bool singleThreaded = false);

private:
SkSpinlock fSpinlock;
SkMutex fMutex;
SkTDArray<SkIDChangeListener*> fListeners; // pointers are reffed
};

Expand Down
62 changes: 41 additions & 21 deletions src/core/SkIDChangeListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ using List = SkIDChangeListener::List;
List::List() = default;

List::~List() {
// We don't need the lock. No other thread should have this list while it's being
// We don't need the mutex. No other thread should have this list while it's being
// destroyed.
for (int i = 0; i < fListeners.count(); ++i) {
if (!fListeners[i]->shouldDeregister()) {
Expand All @@ -34,41 +34,61 @@ List::~List() {
}
}

void List::add(sk_sp<SkIDChangeListener> listener) {
void List::add(sk_sp<SkIDChangeListener> listener, bool singleThreaded) {
if (!listener) {
return;
}
SkASSERT(!listener->shouldDeregister());

SkAutoSpinlock lock(fSpinlock);
// Clean out any stale listeners before we append the new one.
for (int i = 0; i < fListeners.count(); ++i) {
if (fListeners[i]->shouldDeregister()) {
fListeners[i]->unref();
fListeners.removeShuffle(i--); // No need to preserve the order after i.
auto add = [&] {
// Clean out any stale listeners before we append the new one.
for (int i = 0; i < fListeners.count(); ++i) {
if (fListeners[i]->shouldDeregister()) {
fListeners[i]->unref();
fListeners.removeShuffle(i--); // No need to preserve the order after i.
}
}
*fListeners.append() = listener.release();
};

if (singleThreaded) {
add();
} else {
SkAutoMutexExclusive lock(fMutex);
add();
}
*fListeners.append() = listener.release();
}

int List::count() {
SkAutoSpinlock lock(fSpinlock);
SkAutoMutexExclusive lock(fMutex);
return fListeners.count();
}

void List::changed() {
SkAutoSpinlock lock(fSpinlock);
for (SkIDChangeListener* listener : fListeners) {
if (!listener->shouldDeregister()) {
listener->changed();
void List::changed(bool singleThreaded) {
auto visit = [this]() {
for (SkIDChangeListener* listener : fListeners) {
if (!listener->shouldDeregister()) {
listener->changed();
}
// Listeners get at most one shot, so whether these triggered or not, blow them away.
listener->unref();
}
// Listeners get at most one shot, so whether these triggered or not, blow them away.
listener->unref();
fListeners.reset();
};

if (singleThreaded) {
visit();
} else {
SkAutoMutexExclusive lock(fMutex);
visit();
}
fListeners.reset();
}

void List::reset() {
SkAutoSpinlock lock(fSpinlock);
fListeners.unrefAll();
void List::reset(bool singleThreaded) {
if (singleThreaded) {
fListeners.unrefAll();
} else {
SkAutoMutexExclusive lock(fMutex);
fListeners.unrefAll();
}
}
8 changes: 6 additions & 2 deletions src/core/SkPathRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,17 @@ void SkPathRef::addGenIDChangeListener(sk_sp<SkIDChangeListener> listener) {
if (this == gEmpty) {
return;
}
fGenIDChangeListeners.add(std::move(listener));
bool singleThreaded = this->unique();
fGenIDChangeListeners.add(std::move(listener), singleThreaded);
}

int SkPathRef::genIDChangeListenerCount() { return fGenIDChangeListeners.count(); }

// we need to be called *before* the genID gets changed or zerod
void SkPathRef::callGenIDChangeListeners() { fGenIDChangeListeners.changed(); }
void SkPathRef::callGenIDChangeListeners() {
bool singleThreaded = this->unique();
fGenIDChangeListeners.changed(singleThreaded);
}

SkRRect SkPathRef::getRRect() const {
const SkRect& bounds = this->getBounds();
Expand Down
8 changes: 5 additions & 3 deletions src/core/SkPixelRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,23 @@ void SkPixelRef::addGenIDChangeListener(sk_sp<SkIDChangeListener> listener) {
return;
}
SkASSERT(!listener->shouldDeregister());
fGenIDChangeListeners.add(std::move(listener));
bool singleThreaded = this->unique();
fGenIDChangeListeners.add(std::move(listener), singleThreaded);
}

// we need to be called *before* the genID gets changed or zerod
void SkPixelRef::callGenIDChangeListeners() {
bool singleThreaded = this->unique();
// We don't invalidate ourselves if we think another SkPixelRef is sharing our genID.
if (this->genIDIsUnique()) {
fGenIDChangeListeners.changed();
fGenIDChangeListeners.changed(singleThreaded);
if (fAddedToCache.exchange(false)) {
SkNotifyBitmapGenIDIsStale(this->getGenerationID());
}
} else {
// Listeners get at most one shot, so even though these weren't triggered or not, blow them
// away.
fGenIDChangeListeners.reset();
fGenIDChangeListeners.reset(singleThreaded);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/image/SkImage_Lazy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,8 @@ GrColorType SkImage_Lazy::colorTypeOfLockTextureProxy(const GrCaps* caps) const

#if SK_SUPPORT_GPU
void SkImage_Lazy::addUniqueIDListener(sk_sp<SkIDChangeListener> listener) const {
fUniqueIDListeners.add(std::move(listener));
bool singleThreaded = this->unique();
fUniqueIDListeners.add(std::move(listener), singleThreaded);
}
#endif

Expand Down

0 comments on commit 64a3f8f

Please sign in to comment.