• 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 <cstddef>
12 #include <memory>
13 #include "include/core/SkTypes.h"
14 
15 namespace SkSL {
16 
17 class MemoryPool;
18 
19 /**
20  * Efficiently allocates memory in an SkSL program. Optimized for allocate/release performance over
21  * memory efficiency.
22  *
23  * All allocated memory must be released back to the pool before it can be destroyed or recycled.
24  */
25 
26 class SK_API Pool {
27 public:
28     ~Pool();
29 
30     // Creates a pool to store objects during program creation. Call attachToThread() to start using
31     // the pool for its allocations. When your program is complete, call pool->detachFromThread() to
32     // take ownership of the pool and its allocations. Before freeing any of the program's
33     // allocations, make sure to reattach the pool by calling pool->attachToThread() again.
34     static std::unique_ptr<Pool> Create();
35 
36     // Attaches a pool to the current thread.
37     // It is an error to call this while a pool is already attached.
38     void attachToThread();
39 
40     // Once you are done creating or destroying objects in the pool, detach it from the thread.
41     // It is an error to call this while no pool is attached.
42     void detachFromThread();
43 
44     // Allocates memory from the thread pool. If the pool is exhausted, an additional block of pool
45     // storage will be created to hold the data.
46     static void* AllocMemory(size_t size);
47 
48     // Releases memory that was created by AllocMemory. All objects in the pool must be freed before
49     // the pool can be destroyed.
50     static void FreeMemory(void* ptr);
51 
52     static bool IsAttached();
53 
54 private:
55     Pool();  // use Create to make a pool
56     std::unique_ptr<SkSL::MemoryPool> fMemPool;
57 };
58 
59 /**
60  * If your class inherits from Poolable, its objects will be allocated from the pool.
61  */
62 class Poolable {
63 public:
64     // Override operator new and delete to allow us to use a memory pool.
new(const size_t size)65     static void* operator new(const size_t size) {
66         return Pool::AllocMemory(size);
67     }
68 
delete(void * ptr)69     static void operator delete(void* ptr) {
70         Pool::FreeMemory(ptr);
71     }
72 };
73 
74 /**
75  * Temporarily attaches a pool to the current thread within a scope.
76  */
77 class AutoAttachPoolToThread {
78 public:
AutoAttachPoolToThread(Pool * p)79     AutoAttachPoolToThread(Pool* p) : fPool(p) {
80         if (fPool) {
81             fPool->attachToThread();
82         }
83     }
~AutoAttachPoolToThread()84     ~AutoAttachPoolToThread() {
85         if (fPool) {
86             fPool->detachFromThread();
87         }
88     }
89 
90 private:
91     Pool* fPool = nullptr;
92 };
93 
94 
95 }  // namespace SkSL
96 
97 #endif
98