Flutter Impeller
allocation.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <algorithm>
8 #include <cstring>
9 
11 
12 namespace impeller {
13 
14 Allocation::Allocation() = default;
15 
17  ::free(buffer_);
18 }
19 
20 uint8_t* Allocation::GetBuffer() const {
21  return buffer_;
22 }
23 
25  return length_;
26 }
27 
29  return reserved_;
30 }
31 
32 bool Allocation::Truncate(Bytes length, bool npot) {
33  const auto reserved = npot ? ReserveNPOT(length) : Reserve(length);
34  if (!reserved) {
35  return false;
36  }
37  FML_CHECK(reserved_ >= length);
38  length_ = length;
39  return true;
40 }
41 
42 absl::StatusOr<uint64_t> Allocation::NextPowerOfTwoSize(uint64_t x) {
43  if (x > (static_cast<uint64_t>(1) << 63)) {
44  return absl::InvalidArgumentError("Out of range");
45  }
46  if (x == 0) {
47  return 1;
48  }
49 
50  --x;
51 
52  x |= x >> 1;
53  x |= x >> 2;
54  x |= x >> 4;
55  x |= x >> 8;
56  x |= x >> 16;
57  x |= x >> 32;
58 
59  return x + 1;
60 }
61 
62 bool Allocation::ReserveNPOT(Bytes reserved) {
63  // Reserve at least one page of data.
64  reserved = std::max(Bytes{4096u}, reserved);
65  absl::StatusOr<uint64_t> npot_size =
66  NextPowerOfTwoSize(reserved.GetByteSize());
67  if (!npot_size.ok()) {
68  return false;
69  }
70  return Reserve(Bytes{*npot_size});
71 }
72 
73 bool Allocation::Reserve(Bytes reserved) {
74  if (reserved <= reserved_) {
75  return true;
76  }
77 
78  auto new_allocation = ::realloc(buffer_, reserved.GetByteSize());
79  if (!new_allocation) {
80  // If new length is zero, a minimum non-zero sized allocation is returned.
81  // So this check will not trip and this routine will indicate success as
82  // expected.
83  VALIDATION_LOG << "Allocation failed. Out of host memory.";
84  return false;
85  }
86 
87  buffer_ = static_cast<uint8_t*>(new_allocation);
88  reserved_ = reserved;
89 
90  return true;
91 }
92 
93 std::shared_ptr<fml::Mapping> CreateMappingWithCopy(const uint8_t* contents,
94  Bytes length) {
95  if (contents == nullptr) {
96  return nullptr;
97  }
98 
99  auto allocation = std::make_shared<Allocation>();
100  if (!allocation->Truncate(length)) {
101  return nullptr;
102  }
103 
104  std::memmove(allocation->GetBuffer(), contents, length.GetByteSize());
105 
106  return CreateMappingFromAllocation(allocation);
107 }
108 
109 std::shared_ptr<fml::Mapping> CreateMappingFromAllocation(
110  const std::shared_ptr<Allocation>& allocation) {
111  if (!allocation) {
112  return nullptr;
113  }
114  return std::make_shared<fml::NonOwnedMapping>(
115  reinterpret_cast<const uint8_t*>(allocation->GetBuffer()), //
116  allocation->GetLength().GetByteSize(), //
117  [allocation](auto, auto) {} //
118  );
119 }
120 
121 std::shared_ptr<fml::Mapping> CreateMappingWithString(std::string string) {
122  auto buffer = std::make_shared<std::string>(std::move(string));
123  return std::make_unique<fml::NonOwnedMapping>(
124  reinterpret_cast<const uint8_t*>(buffer->c_str()), buffer->length(),
125  [buffer](auto, auto) {});
126 }
127 
128 } // namespace impeller
uint8_t * GetBuffer() const
Gets the pointer to the start of the allocation.
Definition: allocation.cc:20
Bytes GetReservedLength() const
Gets the reserved length of the allocation. Calls to truncate may be ignored till the length exceeds ...
Definition: allocation.cc:28
static absl::StatusOr< uint64_t > NextPowerOfTwoSize(uint64_t x)
Gets the next power of two size.
Definition: allocation.cc:42
~Allocation()
Destroys the allocation.
Definition: allocation.cc:16
Allocation()
Constructs a new zero-sized allocation.
Bytes GetLength() const
Gets the length of the allocation.
Definition: allocation.cc:24
bool Truncate(Bytes length, bool npot=true)
Resize the underlying allocation to at least given number of bytes.
Definition: allocation.cc:32
constexpr uint64_t GetByteSize() const
int32_t x
std::shared_ptr< fml::Mapping > CreateMappingWithString(std::string string)
Creates a mapping with string data.
Definition: allocation.cc:121
std::shared_ptr< fml::Mapping > CreateMappingWithCopy(const uint8_t *contents, Bytes length)
Creates a mapping with copy of the bytes.
Definition: allocation.cc:93
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Creates a mapping from allocation.
Definition: allocation.cc:109
#define VALIDATION_LOG
Definition: validation.h:91