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