Commit d511948b by Jamie Madill Committed by Commit Bot

Use FastVector in angle::Subject.

This improves object binding performance. We no longer need to check two containers when manipulating the bound subjects/observers. Bug: angleproject:2763 Change-Id: I0ccb2e76be47bd8a28fba5a0c3eff857aa166bb7 Reviewed-on: https://chromium-review.googlesource.com/1227795 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 20c01390
...@@ -42,70 +42,36 @@ Subject::~Subject() ...@@ -42,70 +42,36 @@ Subject::~Subject()
bool Subject::hasObservers() const bool Subject::hasObservers() const
{ {
return !mFastObservers.empty(); return !mObservers.empty();
} }
ANGLE_INLINE void Subject::addObserver(ObserverBinding *observer) ANGLE_INLINE void Subject::addObserver(ObserverBinding *observer)
{ {
ASSERT(!IsInContainer(mFastObservers, observer) && !IsInContainer(mSlowObservers, observer)); ASSERT(!IsInContainer(mObservers, observer));
mObservers.push_back(observer);
if (!mFastObservers.full())
{
mFastObservers.push_back(observer);
}
else
{
mSlowObservers.push_back(observer);
}
} }
ANGLE_INLINE void Subject::removeObserver(ObserverBinding *observer) ANGLE_INLINE void Subject::removeObserver(ObserverBinding *observer)
{ {
// TODO(jmadill): De-duplicate remove code. http://anglebug.com/2763 ASSERT(IsInContainer(mObservers, observer));
if (mSlowObservers.empty()) size_t len = mObservers.size() - 1;
for (size_t index = 0; index < len; ++index)
{ {
size_t fastLen = mFastObservers.size(); if (mObservers[index] == observer)
for (size_t index = 0; index < fastLen; ++index)
{ {
if (mFastObservers[index] == observer) mObservers[index] = mObservers[len];
{ break;
mFastObservers[index] = mFastObservers[fastLen - 1];
mFastObservers.pop_back();
}
}
}
else
{
auto iter = std::find(mFastObservers.begin(), mFastObservers.end(), observer);
if (iter != mFastObservers.end())
{
size_t index = iter - mFastObservers.begin();
std::swap(mFastObservers[index], mFastObservers[mFastObservers.size() - 1]);
mFastObservers.resize(mFastObservers.size() - 1);
mFastObservers.push_back(mSlowObservers.back());
mSlowObservers.pop_back();
ASSERT(mFastObservers.full());
}
else
{
auto slowIter = std::find(mSlowObservers.begin(), mSlowObservers.end(), observer);
ASSERT(slowIter != mSlowObservers.end());
mSlowObservers.erase(slowIter);
} }
} }
mObservers.pop_back();
} }
void Subject::onStateChange(const gl::Context *context, SubjectMessage message) const void Subject::onStateChange(const gl::Context *context, SubjectMessage message) const
{ {
if (mFastObservers.empty()) if (mObservers.empty())
return; return;
for (const angle::ObserverBinding *receiver : mFastObservers) for (const angle::ObserverBinding *receiver : mObservers)
{
receiver->onStateChange(context, message);
}
for (const angle::ObserverBinding *receiver : mSlowObservers)
{ {
receiver->onStateChange(context, message); receiver->onStateChange(context, message);
} }
...@@ -113,17 +79,11 @@ void Subject::onStateChange(const gl::Context *context, SubjectMessage message) ...@@ -113,17 +79,11 @@ void Subject::onStateChange(const gl::Context *context, SubjectMessage message)
void Subject::resetObservers() void Subject::resetObservers()
{ {
for (angle::ObserverBinding *observer : mFastObservers) for (angle::ObserverBinding *observer : mObservers)
{
observer->onSubjectReset();
}
mFastObservers.clear();
for (angle::ObserverBinding *observer : mSlowObservers)
{ {
observer->onSubjectReset(); observer->onSubjectReset();
} }
mSlowObservers.clear(); mObservers.clear();
} }
// ObserverBinding implementation. // ObserverBinding implementation.
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#ifndef LIBANGLE_OBSERVER_H_ #ifndef LIBANGLE_OBSERVER_H_
#define LIBANGLE_OBSERVER_H_ #define LIBANGLE_OBSERVER_H_
#include "common/FixedVector.h" #include "common/FastVector.h"
#include "common/angleutils.h" #include "common/angleutils.h"
namespace gl namespace gl
...@@ -68,8 +68,7 @@ class Subject : NonCopyable ...@@ -68,8 +68,7 @@ class Subject : NonCopyable
// Keep a short list of observers so we can allocate/free them quickly. But since we support // Keep a short list of observers so we can allocate/free them quickly. But since we support
// unlimited bindings, have a spill-over list of that uses dynamic allocation. // unlimited bindings, have a spill-over list of that uses dynamic allocation.
static constexpr size_t kMaxFixedObservers = 8; static constexpr size_t kMaxFixedObservers = 8;
angle::FixedVector<ObserverBinding *, kMaxFixedObservers> mFastObservers; angle::FastVector<ObserverBinding *, kMaxFixedObservers> mObservers;
std::vector<ObserverBinding *> mSlowObservers;
}; };
// Keeps a binding between a Subject and Observer, with a specific subject index. // Keeps a binding between a Subject and Observer, with a specific subject index.
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_ #define LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_
#include "common/Color.h" #include "common/Color.h"
#include "common/FixedVector.h"
#include "libANGLE/renderer/vulkan/vk_utils.h" #include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx namespace rx
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment