Hash :
5a77200b
Author :
Date :
2023-02-08T17:10:28
Metal: Implement parallel shader linking. Update the Metal library cache to be thread safe. Change absl::flat_hash_map back to std::unordered_map because the value types now contain a mutex which must not move. Only generate async compilation tasks for shaders that were not already compiled and in the cache. Collapse some of the link methods in ProgramMtl that only had one call site. All linking is now done in ProgramMtl::link and ProgramMtl::load. Support disabling parallel linking using the new enableParallelMtlLibraryCompilation feature. Bug: chromium:1385510 Change-Id: I71ba71a34d994066729df7e4170911f88c89de4a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4234153 Reviewed-by: Quyen Le <lehoangquyen@chromium.org> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WorkerThread:
// Asychronous tasks/threads for ANGLE, similar to a TaskRunner in Chromium.
// Can be implemented as different targets, depending on platform.
//
#ifndef COMMON_WORKER_THREAD_H_
#define COMMON_WORKER_THREAD_H_
#include <array>
#include <memory>
#include <vector>
#include "common/debug.h"
#include "platform/PlatformMethods.h"
namespace angle
{
class WorkerThreadPool;
// A callback function with no return value and no arguments.
class Closure
{
public:
virtual ~Closure() = default;
virtual void operator()() = 0;
};
// An event that we can wait on, useful for joining worker threads.
class WaitableEvent : angle::NonCopyable
{
public:
WaitableEvent();
virtual ~WaitableEvent();
// Waits indefinitely for the event to be signaled.
virtual void wait() = 0;
// Peeks whether the event is ready. If ready, wait() will not block.
virtual bool isReady() = 0;
template <class T>
// Waits on multiple events. T should be some container of std::shared_ptr<WaitableEvent>.
static void WaitMany(T *waitables)
{
for (auto &waitable : *waitables)
{
waitable->wait();
}
}
template <class T>
// Checks if all events are ready. T should be some container of std::shared_ptr<WaitableEvent>.
static bool AllReady(T *waitables)
{
for (auto &waitable : *waitables)
{
if (!waitable->isReady())
{
return false;
}
}
return true;
}
};
// A waitable event that is always ready.
class WaitableEventDone final : public WaitableEvent
{
public:
void wait() override;
bool isReady() override;
};
// Request WorkerThreads from the WorkerThreadPool. Each pool can keep worker threads around so
// we avoid the costly spin up and spin down time.
class WorkerThreadPool : angle::NonCopyable
{
public:
WorkerThreadPool();
virtual ~WorkerThreadPool();
// Creates a new thread pool.
// If numThreads is 0, the pool will choose the best number of threads to run.
// If numThreads is 1, the pool will be single-threaded. Tasks will run on the calling thread.
// Other numbers indicate how many threads the pool should spawn.
// Note that based on build options, this class may not actually run tasks in threads, or it may
// hook into the provided PlatformMethods::postWorkerTask, in which case numThreads is ignored.
static std::shared_ptr<WorkerThreadPool> Create(size_t numThreads, PlatformMethods *platform);
// Returns an event to wait on for the task to finish. If the pool fails to create the task,
// returns null. This function is thread-safe.
virtual std::shared_ptr<WaitableEvent> postWorkerTask(std::shared_ptr<Closure> task) = 0;
virtual bool isAsync() = 0;
private:
};
} // namespace angle
#endif // COMMON_WORKER_THREAD_H_