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