Started caching HandleGLES's hash and made them immutable (#56800)
https://github.com/flutter/flutter/issues/159177
test exempt: no functional change, performance
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
diff --git a/impeller/renderer/backend/gles/handle_gles.h b/impeller/renderer/backend/gles/handle_gles.h
index 3e7b44f..80220f5 100644
--- a/impeller/renderer/backend/gles/handle_gles.h
+++ b/impeller/renderer/backend/gles/handle_gles.h
@@ -34,10 +34,8 @@
/// OpenGL object handles, these handles can be collected on any
/// thread as long as their destruction is scheduled in a reactor.
///
-struct HandleGLES {
- HandleType type = HandleType::kUnknown;
- std::optional<UniqueID> name;
-
+class HandleGLES {
+ public:
//----------------------------------------------------------------------------
/// @brief Creates a dead handle.
///
@@ -52,7 +50,7 @@
///
/// @return True if dead, False otherwise.
///
- constexpr bool IsDead() const { return !name.has_value(); }
+ constexpr bool IsDead() const { return !name_.has_value(); }
//----------------------------------------------------------------------------
/// @brief Get the hash value of this handle. Handles can be used as map
@@ -60,9 +58,7 @@
///
struct Hash {
std::size_t operator()(const HandleGLES& handle) const {
- return fml::HashCombine(
- std::underlying_type_t<decltype(handle.type)>(handle.type),
- handle.name);
+ return handle.GetHash();
}
};
@@ -71,17 +67,32 @@
///
struct Equal {
bool operator()(const HandleGLES& lhs, const HandleGLES& rhs) const {
- return lhs.type == rhs.type && lhs.name == rhs.name;
+ return lhs.type_ == rhs.type_ && lhs.name_ == rhs.name_;
}
};
+ HandleType GetType() const { return type_; }
+ const std::optional<UniqueID>& GetName() const { return name_; }
+ std::size_t GetHash() const { return hash_; }
+
private:
+ HandleType type_ = HandleType::kUnknown;
+ std::optional<UniqueID> name_;
+ std::size_t hash_;
+
friend class ReactorGLES;
- HandleGLES(HandleType p_type, UniqueID p_name) : type(p_type), name(p_name) {}
+ HandleGLES(HandleType p_type, UniqueID p_name)
+ : type_(p_type),
+ name_(p_name),
+ hash_(fml::HashCombine(std::underlying_type_t<decltype(p_type)>(p_type),
+ p_name)) {}
HandleGLES(HandleType p_type, std::optional<UniqueID> p_name)
- : type(p_type), name(p_name) {}
+ : type_(p_type),
+ name_(p_name),
+ hash_(fml::HashCombine(std::underlying_type_t<decltype(p_type)>(p_type),
+ p_name)) {}
static HandleGLES Create(HandleType type) {
return HandleGLES{type, UniqueID{}};
@@ -94,12 +105,13 @@
inline std::ostream& operator<<(std::ostream& out,
const impeller::HandleGLES& handle) {
- out << HandleTypeToString(handle.type) << "(";
+ out << HandleTypeToString(handle.GetType()) << "(";
if (handle.IsDead()) {
out << "DEAD";
} else {
- if (handle.name.has_value()) {
- out << handle.name.value().id;
+ const std::optional<impeller::UniqueID>& name = handle.GetName();
+ if (name.has_value()) {
+ out << name.value().id;
} else {
out << "UNNAMED";
}
diff --git a/impeller/renderer/backend/gles/reactor_gles.cc b/impeller/renderer/backend/gles/reactor_gles.cc
index b465051..a86b211 100644
--- a/impeller/renderer/backend/gles/reactor_gles.cc
+++ b/impeller/renderer/backend/gles/reactor_gles.cc
@@ -84,7 +84,7 @@
if (CanReactOnCurrentThread()) {
for (auto& handle : handles_) {
if (handle.second.name.has_value()) {
- CollectGLHandle(*proc_table_, handle.first.type,
+ CollectGLHandle(*proc_table_, handle.first.GetType(),
handle.second.name.value());
}
}
@@ -145,7 +145,7 @@
}
std::optional<GLuint> ReactorGLES::GetGLHandle(const HandleGLES& handle) const {
- if (handle.type == HandleType::kFence) {
+ if (handle.GetType() == HandleType::kFence) {
return std::nullopt;
}
std::optional<ReactorGLES::GLStorage> gl_handle = GetHandle(handle);
@@ -156,7 +156,7 @@
}
std::optional<GLsync> ReactorGLES::GetGLFence(const HandleGLES& handle) const {
- if (handle.type != HandleType::kFence) {
+ if (handle.GetType() != HandleType::kFence) {
return std::nullopt;
}
std::optional<ReactorGLES::GLStorage> gl_handle = GetHandle(handle);
@@ -287,7 +287,7 @@
}
// Create live handles.
if (!handle.second.name.has_value()) {
- auto gl_handle = CreateGLHandle(gl, handle.first.type);
+ auto gl_handle = CreateGLHandle(gl, handle.first.GetType());
if (!gl_handle) {
VALIDATION_LOG << "Could not create GL handle.";
return false;
@@ -296,9 +296,9 @@
}
// Set pending debug labels.
if (handle.second.pending_debug_label.has_value() &&
- handle.first.type != HandleType::kFence) {
+ handle.first.GetType() != HandleType::kFence) {
handles_to_name.emplace_back(std::make_tuple(
- ToDebugResourceType(handle.first.type),
+ ToDebugResourceType(handle.first.GetType()),
handle.second.name.value().handle,
std::move(handle.second.pending_debug_label.value())));
handle.second.pending_debug_label = std::nullopt;
@@ -318,7 +318,7 @@
// This could be false if the handle was created and collected without
// use. We still need to get rid of map entry.
if (storage.has_value()) {
- CollectGLHandle(gl, std::get<0>(handle).type, storage.value());
+ CollectGLHandle(gl, std::get<0>(handle).GetType(), storage.value());
}
}
diff --git a/impeller/renderer/backend/gles/reactor_gles.h b/impeller/renderer/backend/gles/reactor_gles.h
index 3781640..881e2a9 100644
--- a/impeller/renderer/backend/gles/reactor_gles.h
+++ b/impeller/renderer/backend/gles/reactor_gles.h
@@ -278,7 +278,7 @@
// Make sure the container is one where erasing items during iteration doesn't
// invalidate other iterators.
- using LiveHandles = std::unordered_map<HandleGLES,
+ using LiveHandles = std::unordered_map<const HandleGLES,
LiveHandle,
HandleGLES::Hash,
HandleGLES::Equal>;
diff --git a/impeller/renderer/backend/gles/test/pipeline_library_gles_unittests.cc b/impeller/renderer/backend/gles/test/pipeline_library_gles_unittests.cc
index 23d54c4..34dcff5 100644
--- a/impeller/renderer/backend/gles/test/pipeline_library_gles_unittests.cc
+++ b/impeller/renderer/backend/gles/test/pipeline_library_gles_unittests.cc
@@ -38,8 +38,8 @@
// The program handles should be live and equal.
ASSERT_FALSE(pipeline_gles.GetProgramHandle().IsDead());
ASSERT_FALSE(new_pipeline_gles.GetProgramHandle().IsDead());
- ASSERT_EQ(pipeline_gles.GetProgramHandle().name.value(),
- new_pipeline_gles.GetProgramHandle().name.value());
+ ASSERT_EQ(pipeline_gles.GetProgramHandle().GetName().value(),
+ new_pipeline_gles.GetProgramHandle().GetName().value());
}
TEST_P(PipelineLibraryGLESTest, ChangingSpecConstantsCausesNewProgramObject) {
@@ -63,8 +63,8 @@
// The program handles should be live and equal.
ASSERT_FALSE(pipeline_gles.GetProgramHandle().IsDead());
ASSERT_FALSE(new_pipeline_gles.GetProgramHandle().IsDead());
- ASSERT_FALSE(pipeline_gles.GetProgramHandle().name.value() ==
- new_pipeline_gles.GetProgramHandle().name.value());
+ ASSERT_FALSE(pipeline_gles.GetProgramHandle().GetName().value() ==
+ new_pipeline_gles.GetProgramHandle().GetName().value());
}
// NOLINTEND(bugprone-unchecked-optional-access)
diff --git a/impeller/renderer/backend/gles/test/texture_gles_unittests.cc b/impeller/renderer/backend/gles/test/texture_gles_unittests.cc
index ceafa3a..fd17972 100644
--- a/impeller/renderer/backend/gles/test/texture_gles_unittests.cc
+++ b/impeller/renderer/backend/gles/test/texture_gles_unittests.cc
@@ -44,7 +44,7 @@
if (!sync_fence.has_value()) {
return;
}
- EXPECT_EQ(sync_fence.value().type, HandleType::kFence);
+ EXPECT_EQ(sync_fence.value().GetType(), HandleType::kFence);
std::optional<GLsync> sync =
context_gles.GetReactor()->GetGLFence(sync_fence.value());
diff --git a/impeller/renderer/backend/gles/texture_gles.cc b/impeller/renderer/backend/gles/texture_gles.cc
index 682e2cf..748fb5e 100644
--- a/impeller/renderer/backend/gles/texture_gles.cc
+++ b/impeller/renderer/backend/gles/texture_gles.cc
@@ -159,7 +159,7 @@
VALIDATION_LOG << "Cannot wrap a dead handle.";
return nullptr;
}
- if (external_handle.type != HandleType::kTexture) {
+ if (external_handle.GetType() != HandleType::kTexture) {
VALIDATION_LOG << "Cannot wrap a non-texture handle.";
return nullptr;
}