Use thread_local on iOS

Using thread_local on iOS requires iOS 9 or greater. Chrome for iOS
now requires 13, Skia sets the minimum to 11 for test builds, and
Flutter actively does not support 8 or earlier. Dropping support for
iOS 8 in practice and moving to iOS 9 makes it possible to use
thread_local without reservations on iOS.

Change-Id: Ib80cbe24e8154be650f343643281384c17356242
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/447497
Reviewed-by: Heather Miller <hcm@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
Ben Wagner 2021-09-09 22:48:58 -04:00 committed by SkCQ
parent 498bfa4a85
commit 3d9c73c100
8 changed files with 5 additions and 102 deletions

View File

@ -13,13 +13,6 @@
#include "include/core/SkTypes.h"
#include "include/private/SkTArray.h"
#if defined(SK_BUILD_FOR_IOS) && \
(!defined(__IPHONE_9_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
#define SKSL_USE_THREAD_LOCAL 0
#else
#define SKSL_USE_THREAD_LOCAL 1
#endif
using SKSL_INT = int64_t;
using SKSL_FLOAT = float;

View File

@ -336,14 +336,6 @@ int main(int argc, char** argv) {
i = frame_count - 1 - i;
const auto start = std::chrono::steady_clock::now();
#if defined(SK_BUILD_FOR_IOS)
// iOS doesn't support thread_local on versions less than 9.0.
auto anim = skottie::Animation::Builder()
.setResourceProvider(rp)
.setPrecompInterceptor(precomp_interceptor)
.make(static_cast<const char*>(data->data()), data->size());
auto sink = MakeSink(FLAGS_format[0], scale_matrix);
#else
thread_local static auto* anim =
skottie::Animation::Builder()
.setResourceProvider(rp)
@ -351,7 +343,6 @@ int main(int argc, char** argv) {
.make(static_cast<const char*>(data->data()), data->size())
.release();
thread_local static auto* sink = MakeSink(FLAGS_format[0], scale_matrix).release();
#endif
if (sink && anim) {
anim->seekFrame(frame0 + i * fps_scale);

View File

@ -21,12 +21,10 @@
bool gSkUseThreadLocalStrikeCaches_IAcknowledgeThisIsIncrediblyExperimental = false;
SkStrikeCache* SkStrikeCache::GlobalStrikeCache() {
#if !defined(SK_BUILD_FOR_IOS)
if (gSkUseThreadLocalStrikeCaches_IAcknowledgeThisIsIncrediblyExperimental) {
static thread_local auto* cache = new SkStrikeCache;
return cache;
}
#endif
static auto* cache = new SkStrikeCache;
return cache;
}

View File

@ -579,14 +579,14 @@ SkVMBlitter::~SkVMBlitter() {
}
SkLRUCache<SkVMBlitter::Key, skvm::Program>* SkVMBlitter::TryAcquireProgramCache() {
#if 1 && defined(SKVM_JIT)
#if defined(SKVM_JIT)
thread_local static SkLRUCache<Key, skvm::Program> cache{64};
return &cache;
#else
// iOS in particular does not support thread_local until iOS 9.0.
// On the other hand, we'll never be able to JIT there anyway.
// It's probably fine to not cache any interpreted programs, anywhere.
return nullptr;
// iOS now supports thread_local since iOS 9.
// On the other hand, we'll never be able to JIT there anyway.
// It's probably fine to not cache any interpreted programs, anywhere.
return nullptr;
#endif
}

View File

@ -33,7 +33,6 @@
namespace skgpu::v1 {
// If we have thread local, then cache memory for a single AtlasTextOp.
#if defined(GR_HAS_THREAD_LOCAL)
static thread_local void* gCache = nullptr;
void* AtlasTextOp::operator new(size_t s) {
if (gCache != nullptr) {
@ -55,7 +54,6 @@ void AtlasTextOp::ClearCache() {
::operator delete(gCache);
gCache = nullptr;
}
#endif
AtlasTextOp::AtlasTextOp(MaskType maskType,
bool needsTransform,

View File

@ -12,11 +12,6 @@
#include "src/gpu/ops/GrMeshDrawOp.h"
#include "src/gpu/text/GrTextBlob.h"
#if !defined(SK_BUILD_FOR_IOS) || \
(defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_9_0)
#define GR_HAS_THREAD_LOCAL
#endif
class GrRecordingContext;
namespace skgpu::v1 {
@ -33,13 +28,9 @@ public:
}
}
#if defined(GR_HAS_THREAD_LOCAL)
void* operator new(size_t s);
void operator delete(void* b) noexcept;
static void ClearCache();
#else
static void ClearCache() {}
#endif
static const int kVerticesPerGlyph = GrAtlasSubRun::kVerticesPerGlyph;
static const int kIndicesPerGlyph = 6;

View File

@ -13,8 +13,6 @@
namespace SkSL {
#if SKSL_USE_THREAD_LOCAL
static thread_local MemoryPool* sMemPool = nullptr;
static MemoryPool* get_thread_local_memory_pool() {
@ -25,32 +23,6 @@ static void set_thread_local_memory_pool(MemoryPool* memPool) {
sMemPool = memPool;
}
#else
#include <pthread.h>
static pthread_key_t get_pthread_key() {
static pthread_key_t sKey = []{
pthread_key_t key;
int result = pthread_key_create(&key, /*destructor=*/nullptr);
if (result != 0) {
SK_ABORT("pthread_key_create failure: %d", result);
}
return key;
}();
return sKey;
}
static MemoryPool* get_thread_local_memory_pool() {
return static_cast<MemoryPool*>(pthread_getspecific(get_pthread_key()));
}
static void set_thread_local_memory_pool(MemoryPool* poolData) {
pthread_setspecific(get_pthread_key(), poolData);
}
#endif // SKSL_USE_THREAD_LOCAL
Pool::~Pool() {
if (get_thread_local_memory_pool() == fMemPool.get()) {
SkDEBUGFAIL("SkSL pool is being destroyed while it is still attached to the thread");

View File

@ -25,10 +25,6 @@
#include "src/sksl/ir/SkSLPrefixExpression.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#if !SKSL_USE_THREAD_LOCAL
#include <pthread.h>
#endif // !SKSL_USE_THREAD_LOCAL
namespace SkSL {
namespace dsl {
@ -326,8 +322,6 @@ void DSLWriter::ReportErrors(PositionInfo pos) {
GetErrorReporter().reportPendingErrors(pos);
}
#if SKSL_USE_THREAD_LOCAL
thread_local DSLWriter* instance = nullptr;
bool DSLWriter::IsActive() {
@ -345,40 +339,6 @@ void DSLWriter::SetInstance(std::unique_ptr<DSLWriter> newInstance) {
instance = newInstance.release();
}
#else
static void destroy_dslwriter(void* dslWriter) {
delete static_cast<DSLWriter*>(dslWriter);
}
static pthread_key_t get_pthread_key() {
static pthread_key_t sKey = []{
pthread_key_t key;
int result = pthread_key_create(&key, destroy_dslwriter);
if (result != 0) {
SK_ABORT("pthread_key_create failure: %d", result);
}
return key;
}();
return sKey;
}
bool DSLWriter::IsActive() {
return pthread_getspecific(get_pthread_key()) != nullptr;
}
DSLWriter& DSLWriter::Instance() {
DSLWriter* instance = static_cast<DSLWriter*>(pthread_getspecific(get_pthread_key()));
SkASSERTF(instance, "dsl::Start() has not been called");
return *instance;
}
void DSLWriter::SetInstance(std::unique_ptr<DSLWriter> instance) {
delete static_cast<DSLWriter*>(pthread_getspecific(get_pthread_key()));
pthread_setspecific(get_pthread_key(), instance.release());
}
#endif
} // namespace dsl
} // namespace SkSL