blob: 0b3d33a0d602bd436ee31dd5f9b2e2228bc16994 [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/**
John Stilesb69a9d42020-11-19 14:50:56 -050018 * Efficiently allocates memory in an SkSL program. Optimized for allocate/release performance over
19 * memory efficiency.
John Stiles23e68662020-10-29 10:17:15 -040020 *
John Stilesb69a9d42020-11-19 14:50:56 -050021 * All allocated memory must be released back to the pool before it can be destroyed or recycled.
John Stiles23e68662020-10-29 10:17:15 -040022 */
John Stiles5c7bb322020-10-22 11:09:15 -040023
24class Pool {
25public:
26 ~Pool();
27
John Stilesb69a9d42020-11-19 14:50:56 -050028 // Creates a pool to store objects during program creation. Call attachToThread() to start using
29 // the pool for its allocations. When your program is complete, call pool->detachFromThread() to
30 // take ownership of the pool and its allocations. Before freeing any of the program's
31 // allocations, make sure to reattach the pool by calling pool->attachToThread() again.
John Stiles2d68ea32020-10-22 15:42:27 -040032 static std::unique_ptr<Pool> Create();
John Stiles5c7bb322020-10-22 11:09:15 -040033
John Stiles2d68ea32020-10-22 15:42:27 -040034 // Attaches a pool to the current thread.
35 // It is an error to call this while a pool is already attached.
36 void attachToThread();
37
John Stilesb69a9d42020-11-19 14:50:56 -050038 // Once you are done creating or destroying objects in the pool, detach it from the thread.
John Stiles5c7bb322020-10-22 11:09:15 -040039 // It is an error to call this while no pool is attached.
40 void detachFromThread();
41
John Stilesb69a9d42020-11-19 14:50:56 -050042 // Allocates memory from the thread pool. If the pool is exhausted, an additional block of pool
43 // storage will be created to hold the data.
44 static void* AllocMemory(size_t size);
John Stiles5c7bb322020-10-22 11:09:15 -040045
John Stilesb69a9d42020-11-19 14:50:56 -050046 // Releases memory that was created by AllocMemory. All objects in the pool must be freed before
47 // the pool can be destroyed.
48 static void FreeMemory(void* ptr);
John Stiles5c7bb322020-10-22 11:09:15 -040049
Ethan Nicholas624a5292021-04-16 14:54:43 -040050 static bool IsAttached();
51
John Stiles5c7bb322020-10-22 11:09:15 -040052private:
John Stiles15bfe382020-10-27 19:07:05 -040053 Pool() = default; // use Create to make a pool
John Stiles23e68662020-10-29 10:17:15 -040054 std::unique_ptr<SkSL::MemoryPool> fMemPool;
John Stiles5c7bb322020-10-22 11:09:15 -040055};
56
John Stiles5d1b5a22021-02-01 19:08:45 -050057/**
58 * If your class inherits from Poolable, its objects will be allocated from the pool.
59 */
60class Poolable {
61public:
62 // Override operator new and delete to allow us to use a memory pool.
63 static void* operator new(const size_t size) {
64 return Pool::AllocMemory(size);
65 }
66
67 static void operator delete(void* ptr) {
68 Pool::FreeMemory(ptr);
69 }
70};
71
John Stiles0cac5ed2021-08-06 11:40:39 -040072/**
73 * Temporarily attaches a pool to the current thread within a scope.
74 */
75class AutoAttachPoolToThread {
76public:
77 AutoAttachPoolToThread(Pool* p) : fPool(p) {
78 if (fPool) {
79 fPool->attachToThread();
80 }
81 }
82 ~AutoAttachPoolToThread() {
83 if (fPool) {
84 fPool->detachFromThread();
85 }
86 }
87
88private:
89 Pool* fPool = nullptr;
90};
91
92
John Stiles5c7bb322020-10-22 11:09:15 -040093} // namespace SkSL
94
95#endif