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