blob: b109b56463212efe1ff9fae2b9ddb24de43d1f60 [file] [log] [blame]
John Stiles5c7bb322020-10-22 11:09:15 -04001/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SKSL_POOL
9#define SKSL_POOL
10
11#include <memory>
12
John Stiles23e68662020-10-29 10:17:15 -040013#include "src/sksl/SkSLMemoryPool.h"
14
John Stiles5c7bb322020-10-22 11:09:15 -040015namespace SkSL {
16
John Stiles23e68662020-10-29 10:17:15 -040017/**
18 * Efficiently allocates memory for IRNodes in an SkSL program. Optimized for allocate/release
19 * performance over memory efficiency.
20 *
21 * All allocated IRNodes must be released back to the pool before it can be destroyed or recycled.
22 */
John Stiles5c7bb322020-10-22 11:09:15 -040023
24class Pool {
25public:
26 ~Pool();
27
John Stiles2d68ea32020-10-22 15:42:27 -040028 // Creates a pool to store IRNodes during program creation. Call attachToThread() to start using
29 // the pool for IRNode allocations. When your program is complete, call pool->detachFromThread()
30 // to take ownership of the pool and its nodes. Before destroying any of the program's nodes,
31 // make sure to reattach the pool by calling pool->attachToThread() again.
32 static std::unique_ptr<Pool> Create();
John Stiles5c7bb322020-10-22 11:09:15 -040033
John Stiles2d68ea32020-10-22 15:42:27 -040034 // Gives up ownership of a pool; conceptually, this deletes it. In practice, on some platforms,
35 // it is expensive to free and reallocate pools, so this gives us an opportunity to reuse the
John Stiles15bfe382020-10-27 19:07:05 -040036 // allocation for future Create calls.
John Stiles2d68ea32020-10-22 15:42:27 -040037 static void Recycle(std::unique_ptr<Pool> pool);
38
39 // Explicitly frees a previously recycled pool (if any), reclaiming the memory.
40 static void FreeRecycledPool() { Recycle(nullptr); }
41
42 // Attaches a pool to the current thread.
43 // It is an error to call this while a pool is already attached.
44 void attachToThread();
45
46 // Once you are done creating or destroying IRNodes in the pool, detach it from the thread.
John Stiles5c7bb322020-10-22 11:09:15 -040047 // It is an error to call this while no pool is attached.
48 void detachFromThread();
49
John Stiles270b5c02020-10-27 17:49:37 -040050 // Retrieves a node from the thread pool. If the pool is exhausted, or if the requested size
51 // exceeds the size that we can deliver from a pool, this will just allocate memory.
52 static void* AllocIRNode(size_t size);
John Stiles5c7bb322020-10-22 11:09:15 -040053
54 // Releases a node that was created by AllocIRNode. This will return it to the pool, or free it,
55 // as appropriate. Make sure to free all nodes, since some of them may be real allocations.
56 static void FreeIRNode(void* node_v);
57
58private:
John Stiles2d68ea32020-10-22 15:42:27 -040059 void checkForLeaks();
60
John Stiles15bfe382020-10-27 19:07:05 -040061 Pool() = default; // use Create to make a pool
John Stiles23e68662020-10-29 10:17:15 -040062 std::unique_ptr<SkSL::MemoryPool> fMemPool;
John Stiles5c7bb322020-10-22 11:09:15 -040063};
64
65} // namespace SkSL
66
67#endif