• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
13 #include "src/sksl/SkSLMemoryPool.h"
14 
15 namespace SkSL {
16 
17 /**
18  * Efficiently allocates memory in an SkSL program. Optimized for allocate/release performance over
19  * memory efficiency.
20  *
21  * All allocated memory must be released back to the pool before it can be destroyed or recycled.
22  */
23 
24 class Pool {
25 public:
26     ~Pool();
27 
28     // 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.
32     static std::unique_ptr<Pool> Create();
33 
34     // 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 
38     // Once you are done creating or destroying objects in the pool, detach it from the thread.
39     // It is an error to call this while no pool is attached.
40     void detachFromThread();
41 
42     // 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);
45 
46     // 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);
49 
50     static bool IsAttached();
51 
52 private:
53     Pool() = default;  // use Create to make a pool
54     std::unique_ptr<SkSL::MemoryPool> fMemPool;
55 };
56 
57 /**
58  * If your class inherits from Poolable, its objects will be allocated from the pool.
59  */
60 class Poolable {
61 public:
62     // Override operator new and delete to allow us to use a memory pool.
new(const size_t size)63     static void* operator new(const size_t size) {
64         return Pool::AllocMemory(size);
65     }
66 
delete(void * ptr)67     static void operator delete(void* ptr) {
68         Pool::FreeMemory(ptr);
69     }
70 };
71 
72 /**
73  * Temporarily attaches a pool to the current thread within a scope.
74  */
75 class AutoAttachPoolToThread {
76 public:
AutoAttachPoolToThread(Pool * p)77     AutoAttachPoolToThread(Pool* p) : fPool(p) {
78         if (fPool) {
79             fPool->attachToThread();
80         }
81     }
~AutoAttachPoolToThread()82     ~AutoAttachPoolToThread() {
83         if (fPool) {
84             fPool->detachFromThread();
85         }
86     }
87 
88 private:
89     Pool* fPool = nullptr;
90 };
91 
92 
93 }  // namespace SkSL
94 
95 #endif
96