From f32aa2a516d47eb5fdd205385b9cbacbb5ed3aba Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 18 Nov 2019 14:22:55 -0800 Subject: [PATCH] Fabric: Moving `MeasureCache` into `TextLayoutManager` Summary: We will have several consumers for the measure infra soon (TextInput will use the same TextLayoutManager). It makes sense to move the cache there. In the future, iOS and Android implementations will probably use a bit different (platform-specific) cache implementations because we will implement the ability to measure "opaque"/platform-specific text containers alongside with normal AttributeStrings. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D18445855 fbshipit-source-id: 7b7a65152ac13c74525da695612ae034904e82bf --- .../paragraph/ParagraphComponentDescriptor.h | 11 -------- .../paragraph/ParagraphMeasurementCache.h | 27 ------------------- .../text/paragraph/ParagraphShadowNode.cpp | 23 +++------------- .../text/paragraph/ParagraphShadowNode.h | 11 -------- .../platform/android/TextLayoutManager.cpp | 12 +++++++++ .../platform/android/TextLayoutManager.h | 12 ++++++++- .../platform/ios/TextLayoutManager.h | 6 +++++ .../platform/ios/TextLayoutManager.mm | 11 +++++--- 8 files changed, 39 insertions(+), 74 deletions(-) delete mode 100644 ReactCommon/fabric/components/text/paragraph/ParagraphMeasurementCache.h diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h b/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h index fbdb45e71aa..8b9fa266034 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h @@ -7,10 +7,8 @@ #pragma once -#include "ParagraphMeasurementCache.h" #include "ParagraphShadowNode.h" -#include #include #include #include @@ -36,10 +34,6 @@ class ParagraphComponentDescriptor final // Every single `ParagraphShadowNode` will have a reference to // a shared `TextLayoutManager`. textLayoutManager_ = std::make_shared(contextContainer); - // Every single `ParagraphShadowNode` will have a reference to - // a shared `EvictingCacheMap`, a simple LRU cache for Paragraph - // measurements. - measureCache_ = std::make_unique(); } protected: @@ -54,10 +48,6 @@ class ParagraphComponentDescriptor final // and communicate text rendering metrics to mounting layer. paragraphShadowNode->setTextLayoutManager(textLayoutManager_); - // `ParagraphShadowNode` uses this to cache the results of text rendering - // measurements. - paragraphShadowNode->setMeasureCache(measureCache_.get()); - paragraphShadowNode->dirtyLayout(); // All `ParagraphShadowNode`s must have leaf Yoga nodes with properly @@ -67,7 +57,6 @@ class ParagraphComponentDescriptor final private: SharedTextLayoutManager textLayoutManager_; - std::unique_ptr measureCache_; }; } // namespace react diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphMeasurementCache.h b/ReactCommon/fabric/components/text/paragraph/ParagraphMeasurementCache.h deleted file mode 100644 index f745b9823f9..00000000000 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphMeasurementCache.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include - -namespace facebook { -namespace react { - -using ParagraphMeasurementCacheKey = - std::tuple; -using ParagraphMeasurementCacheValue = Size; -using ParagraphMeasurementCache = SimpleThreadSafeCache< - ParagraphMeasurementCacheKey, - ParagraphMeasurementCacheValue, - 256>; - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp index a15c17f30b2..e1a0be32944 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.cpp @@ -6,8 +6,7 @@ */ #include "ParagraphShadowNode.h" -#include -#include "ParagraphMeasurementCache.h" + #include "ParagraphState.h" namespace facebook { @@ -33,12 +32,6 @@ void ParagraphShadowNode::setTextLayoutManager( textLayoutManager_ = textLayoutManager; } -void ParagraphShadowNode::setMeasureCache( - ParagraphMeasurementCache const *cache) { - ensureUnsealed(); - measureCache_ = cache; -} - void ParagraphShadowNode::updateStateIfNeeded() { ensureUnsealed(); @@ -68,18 +61,8 @@ Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const { return {0, 0}; } - ParagraphAttributes const paragraphAttributes = - getProps()->paragraphAttributes; - - assert(measureCache_); - - return measureCache_->get( - ParagraphMeasurementCacheKey{ - attributedString, paragraphAttributes, layoutConstraints}, - [&](ParagraphMeasurementCacheKey const &key) { - return textLayoutManager_->measure( - attributedString, paragraphAttributes, layoutConstraints); - }); + return textLayoutManager_->measure( + attributedString, getProps()->paragraphAttributes, layoutConstraints); } void ParagraphShadowNode::layout(LayoutContext layoutContext) { diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h index 37cac3e9853..c6513462cf9 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphShadowNode.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include @@ -57,15 +56,6 @@ class ParagraphShadowNode : public ConcreteViewShadowNode< */ void setTextLayoutManager(SharedTextLayoutManager textLayoutManager); - /* - * Associates a shared LRU cache with the node. - * `ParagraphShadowNode` uses this to cache the results of - * text rendering measurements. - * By design, the ParagraphComponentDescriptor outlives all - * shadow nodes, so it's safe for this to be a raw pointer. - */ - void setMeasureCache(ParagraphMeasurementCache const *cache); - #pragma mark - LayoutableShadowNode void layout(LayoutContext layoutContext) override; @@ -79,7 +69,6 @@ class ParagraphShadowNode : public ConcreteViewShadowNode< void updateStateIfNeeded(); SharedTextLayoutManager textLayoutManager_; - ParagraphMeasurementCache const *measureCache_; /* * Cached attributed string that represents the content of the subtree started diff --git a/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.cpp b/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.cpp index b0ce10152f0..88a7b161b18 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.cpp +++ b/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.cpp @@ -26,6 +26,18 @@ Size TextLayoutManager::measure( AttributedString attributedString, ParagraphAttributes paragraphAttributes, LayoutConstraints layoutConstraints) const { + return measureCache_.get( + MeasureCacheKey{attributedString, paragraphAttributes, layoutConstraints}, + [&](MeasureCacheKey const &key) { + return doMeasure( + attributedString, paragraphAttributes, layoutConstraints); + }); +} + +Size TextLayoutManager::doMeasure( + AttributedString attributedString, + ParagraphAttributes paragraphAttributes, + LayoutConstraints layoutConstraints) const { const jni::global_ref &fabricUIManager = contextContainer_->at>("FabricUIManager"); diff --git a/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.h b/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.h index 87bd311838a..1e126f311d5 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.h +++ b/ReactCommon/fabric/textlayoutmanager/platform/android/TextLayoutManager.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace facebook { namespace react { @@ -45,9 +46,18 @@ class TextLayoutManager { void *getNativeTextLayoutManager() const; private: - void *self_; + Size doMeasure( + AttributedString attributedString, + ParagraphAttributes paragraphAttributes, + LayoutConstraints layoutConstraints) const; + using MeasureCacheKey = + std::tuple; + using MeasureCache = SimpleThreadSafeCache; + + void *self_; ContextContainer::Shared contextContainer_; + MeasureCache measureCache_{}; }; } // namespace react diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h index 3085b32552f..56ecc5f69a4 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace facebook { namespace react { @@ -44,7 +45,12 @@ class TextLayoutManager { void *getNativeTextLayoutManager() const; private: + using MeasureCacheKey = + std::tuple; + using MeasureCache = SimpleThreadSafeCache; + void *self_; + MeasureCache measureCache_{}; }; } // namespace react diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm index 40fd08804a9..4d3f7ee861e 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.mm @@ -34,10 +34,13 @@ Size TextLayoutManager::measure( ParagraphAttributes paragraphAttributes, LayoutConstraints layoutConstraints) const { - RCTTextLayoutManager *textLayoutManager = (__bridge RCTTextLayoutManager *)self_; - return [textLayoutManager measureWithAttributedString:attributedString - paragraphAttributes:paragraphAttributes - layoutConstraints:layoutConstraints]; + return measureCache_.get( + MeasureCacheKey{attributedString, paragraphAttributes, layoutConstraints}, [&](MeasureCacheKey const &key) { + RCTTextLayoutManager *textLayoutManager = (__bridge RCTTextLayoutManager *)self_; + return [textLayoutManager measureWithAttributedString:attributedString + paragraphAttributes:paragraphAttributes + layoutConstraints:layoutConstraints]; + }); } } // namespace react