Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / text / gpu / SubRunAllocator.cpp
1 /*
2  * Copyright 2021 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 "include/core/SkMath.h"
9 #include "src/text/gpu/SubRunAllocator.h"
10
11 #include <cstddef>
12 #include <memory>
13 #include <new>
14 #include <utility>
15
16 namespace sktext::gpu {
17
18 // -- BagOfBytes ---------------------------------------------------------------------------------
19 BagOfBytes::BagOfBytes(char* bytes, size_t size, size_t firstHeapAllocation)
20         : fFibProgression(size, firstHeapAllocation) {
21     SkASSERT_RELEASE(size < kMaxByteSize);
22     SkASSERT_RELEASE(firstHeapAllocation < kMaxByteSize);
23
24     std::size_t space = size;
25     void* ptr = bytes;
26     if (bytes && std::align(kMaxAlignment, sizeof(Block), ptr, space)) {
27         this->setupBytesAndCapacity(bytes, size);
28         new (fEndByte) Block(nullptr, nullptr);
29     }
30 }
31
32 BagOfBytes::BagOfBytes(size_t firstHeapAllocation)
33         : BagOfBytes(nullptr, 0, firstHeapAllocation) {}
34
35 BagOfBytes::~BagOfBytes() {
36     Block* cursor = reinterpret_cast<Block*>(fEndByte);
37     while (cursor != nullptr) {
38         char* toDelete = cursor->fBlockStart;
39         cursor = cursor->fPrevious;
40         delete [] toDelete;
41     }
42 }
43
44 BagOfBytes::Block::Block(char* previous, char* startOfBlock)
45         : fBlockStart{startOfBlock}
46         , fPrevious{reinterpret_cast<Block*>(previous)} {}
47
48 void* BagOfBytes::alignedBytes(int size, int alignment) {
49     SkASSERT_RELEASE(0 < size && size < kMaxByteSize);
50     SkASSERT_RELEASE(0 < alignment && alignment <= kMaxAlignment);
51     SkASSERT_RELEASE(SkIsPow2(alignment));
52
53     return this->allocateBytes(size, alignment);
54 }
55
56 void BagOfBytes::setupBytesAndCapacity(char* bytes, int size) {
57     // endByte must be aligned to the maximum alignment to allow tracking alignment using capacity;
58     // capacity and endByte are both aligned to max alignment.
59     intptr_t endByte = reinterpret_cast<intptr_t>(bytes + size - sizeof(Block)) & -kMaxAlignment;
60     fEndByte  = reinterpret_cast<char*>(endByte);
61     fCapacity = fEndByte - bytes;
62 }
63
64 void BagOfBytes::needMoreBytes(int requestedSize, int alignment) {
65     int nextBlockSize = fFibProgression.nextBlockSize();
66     const int size = PlatformMinimumSizeWithOverhead(
67             std::max(requestedSize, nextBlockSize), kAllocationAlignment);
68     char* const bytes = new char[size];
69     // fEndByte is changed by setupBytesAndCapacity. Remember it to link back to.
70     char* const previousBlock = fEndByte;
71     this->setupBytesAndCapacity(bytes, size);
72
73     // Make a block to delete these bytes, and points to the previous block.
74     new (fEndByte) Block{previousBlock, bytes};
75
76     // Make fCapacity the alignment for the requested object.
77     fCapacity = fCapacity & -alignment;
78     SkASSERT(fCapacity >= requestedSize);
79 }
80
81 // -- SubRunAllocator ----------------------------------------------------------------------------
82 SubRunAllocator::SubRunAllocator(char* bytes, int size, int firstHeapAllocation)
83         : fAlloc{bytes, SkTo<size_t>(size), SkTo<size_t>(firstHeapAllocation)} {
84     SkASSERT_RELEASE(SkTFitsIn<size_t>(size));
85     SkASSERT_RELEASE(SkTFitsIn<size_t>(firstHeapAllocation));
86 }
87
88 SubRunAllocator::SubRunAllocator(int firstHeapAllocation)
89         : SubRunAllocator(nullptr, 0, firstHeapAllocation) { }
90
91 void* SubRunAllocator::alignedBytes(int unsafeSize, int unsafeAlignment) {
92     return fAlloc.alignedBytes(unsafeSize, unsafeAlignment);
93 }
94
95 }  // namespace sktext::gpu