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 #include "src/sksl/SkSLPool.h"
9
10 #include "include/core/SkTypes.h"
11
12 #if defined(SK_GANESH)
13 // With GPU support, SkSL::MemoryPool is really GrMemoryPool
14 #include "src/gpu/ganesh/GrMemoryPool.h"
15 #endif
16
17 #define VLOG(...) // printf(__VA_ARGS__)
18
19 namespace SkSL {
20
21 static thread_local MemoryPool* sMemPool = nullptr;
22
get_thread_local_memory_pool()23 static MemoryPool* get_thread_local_memory_pool() {
24 return sMemPool;
25 }
26
set_thread_local_memory_pool(MemoryPool * memPool)27 static void set_thread_local_memory_pool(MemoryPool* memPool) {
28 sMemPool = memPool;
29 }
30
~Pool()31 Pool::~Pool() {
32 if (get_thread_local_memory_pool() == fMemPool.get()) {
33 SkDEBUGFAIL("SkSL pool is being destroyed while it is still attached to the thread");
34 set_thread_local_memory_pool(nullptr);
35 }
36
37 fMemPool->reportLeaks();
38 SkASSERT(fMemPool->isEmpty());
39
40 VLOG("DELETE Pool:0x%016llX\n", (uint64_t)fMemPool.get());
41 }
42
Create()43 std::unique_ptr<Pool> Pool::Create() {
44 auto pool = std::unique_ptr<Pool>(new Pool);
45 pool->fMemPool = MemoryPool::Make(/*preallocSize=*/65536, /*minAllocSize=*/32768);
46 VLOG("CREATE Pool:0x%016llX\n", (uint64_t)pool->fMemPool.get());
47 return pool;
48 }
49
IsAttached()50 bool Pool::IsAttached() {
51 return get_thread_local_memory_pool();
52 }
53
attachToThread()54 void Pool::attachToThread() {
55 VLOG("ATTACH Pool:0x%016llX\n", (uint64_t)fMemPool.get());
56 SkASSERT(get_thread_local_memory_pool() == nullptr);
57 set_thread_local_memory_pool(fMemPool.get());
58 }
59
detachFromThread()60 void Pool::detachFromThread() {
61 MemoryPool* memPool = get_thread_local_memory_pool();
62 VLOG("DETACH Pool:0x%016llX\n", (uint64_t)memPool);
63 SkASSERT(memPool == fMemPool.get());
64 memPool->resetScratchSpace();
65 set_thread_local_memory_pool(nullptr);
66 }
67
AllocMemory(size_t size)68 void* Pool::AllocMemory(size_t size) {
69 // Is a pool attached?
70 MemoryPool* memPool = get_thread_local_memory_pool();
71 if (memPool) {
72 void* ptr = memPool->allocate(size);
73 VLOG("ALLOC Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)ptr);
74 return ptr;
75 }
76
77 // There's no pool attached. Allocate memory using the system allocator.
78 void* ptr = ::operator new(size);
79 VLOG("ALLOC Pool:__________________ 0x%016llX\n", (uint64_t)ptr);
80 return ptr;
81 }
82
FreeMemory(void * ptr)83 void Pool::FreeMemory(void* ptr) {
84 // Is a pool attached?
85 MemoryPool* memPool = get_thread_local_memory_pool();
86 if (memPool) {
87 VLOG("FREE Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)ptr);
88 memPool->release(ptr);
89 return;
90 }
91
92 // There's no pool attached. Free it using the system allocator.
93 VLOG("FREE Pool:__________________ 0x%016llX\n", (uint64_t)ptr);
94 ::operator delete(ptr);
95 }
96
97 } // namespace SkSL
98