diff options
Diffstat (limited to 'src/core/SkTaskGroup2D.h')
-rw-r--r-- | src/core/SkTaskGroup2D.h | 123 |
1 files changed, 0 insertions, 123 deletions
diff --git a/src/core/SkTaskGroup2D.h b/src/core/SkTaskGroup2D.h deleted file mode 100644 index 20915cf9d7..0000000000 --- a/src/core/SkTaskGroup2D.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkTaskGroup2D_DEFINED -#define SkTaskGroup2D_DEFINED - -#include "SkTaskGroup.h" - -#include <mutex> -#include <vector> - -// The interface for doing work on a 2D grid with possible initialization on columns. -class SkWorkKernel2D { -public: - // Return false iff the column needs initialization and such initialization is not finished yet. - virtual bool work2D(int row, int column, int thread) = 0; - - // Return false if no initialization is done for this colum (e.g., it's already initialized; or - // maybe some other thread is initializing the column). - virtual bool initColumn(int column, int thread) = 0; - - virtual ~SkWorkKernel2D() {} -}; - -// A 2D grid (height rows x width columns) of tasks to be executed on a given executor with -// threadCnt number of threads. -// -// The height (number of rows) is fixed. The width (number of columns) may be dynamically expanded. -// -// The task on row i and column j is abstracted as work2D(i, j, t). Parameter t is the thread id and -// it shouldn't affect the work to be done. It's only used to allow some variables that are not -// thread safe and should be used exclusively by one thread (e.g., thread allocators). We guarantee -// that the task on the same row will be executed in order (i.e., work2D(1, 1, t) is guaranteed to -// finish before calling work2D(1, 2, t)). Tasks in different rows can happen in any order. -// -// There are also width number of init calls, one per column. work2D(i, j, t) may return false if -// column j requires initialization but it's not initialized yet. In that case, a thread t needs to -// call initColumn(j, t) once to unblock all rows that depend on the initialization of column j. -// (Again, t shouldn't affect the init work to be done; it's just for some non-thread-safe -// variables). The init calls have no order requirement so we can call them in any order. -// -// Multiple therads may try to init the same column j at the same time. InitFn is expected to handle -// this gracefully (e.g., let only one thread do the init and return immediately for other threads). -class SkTaskGroup2D { -public: - SkTaskGroup2D(SkWorkKernel2D* kernel, int height, SkExecutor* executor, int threadCnt) - : fKernel(kernel), fHeight(height), fThreadCnt(threadCnt), fIsFinishing(false) - , fWidth(0), fThreadsGroup(new SkTaskGroup(*executor)) {} - - virtual ~SkTaskGroup2D() {} - - virtual void addColumn(); // Add a new column of tasks. - - void start(); // start threads to execute tasks - void finish(); // wait and finish all tasks (no more tasks can be added after calling this) - - SK_ALWAYS_INLINE bool isFinishing() const { - return fIsFinishing; - } - -protected: - static constexpr int MAX_CACHE_LINE = 64; - - // Finish all tasks on the threadId and then return. - virtual void work(int threadId) = 0; - - // Initialize a column that needs to be initialized. The parameter initCol is not thread safe - // and should only be exclusively accessed by the working thread which will modify it to the - // column that may need to be initialized next. - void initAnUninitializedColumn(int& initCol, int threadId) { - bool didSomeInit = false; - while (initCol < fWidth && !didSomeInit) { - didSomeInit = fKernel->initColumn(initCol++, threadId); - } - } - - SkWorkKernel2D* fKernel; - const int fHeight; - const int fThreadCnt; - - std::atomic<bool> fIsFinishing; - std::atomic<int> fWidth; - - std::unique_ptr<SkTaskGroup> fThreadsGroup; -}; - -// A simple spinning task group that assumes height equals threadCnt. -class SkSpinningTaskGroup2D final : public SkTaskGroup2D { -public: - SkSpinningTaskGroup2D(SkWorkKernel2D* kernel, int h, SkExecutor* x, int t) - : SkTaskGroup2D(kernel, h, x, t) { - SkASSERT(h == t); // height must be equal to threadCnt - } - -protected: - void work(int threadId) override; -}; - -class SkFlexibleTaskGroup2D final : public SkTaskGroup2D { -public: - SkFlexibleTaskGroup2D(SkWorkKernel2D* kernel, int h, SkExecutor* x, int t) - : SkTaskGroup2D(kernel, h, x, t), fRowData(h) {} - -protected: - void work(int threadId) override; - -private: - // alignas(MAX_CACHE_LINE) to avoid false sharing by cache lines - struct alignas(MAX_CACHE_LINE) RowData { - RowData() : fNextColumn(0) {} - - int fNextColumn; // next column index to work - std::mutex fMutex; // the mutex for the thread to acquire - }; - - std::vector<RowData> fRowData; -}; - -#endif//SkTaskGroup2D_DEFINED |