| 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
5 #include "impeller/base/allocation.h"
6
7 #include <algorithm>
8 #include <cstring>
9
10 #include "flutter/fml/logging.h"
11 #include "impeller/base/validation.h"
12
13 namespace impeller {
14
15 Allocation::Allocation() = default;
16
17 Allocation::~Allocation() {
18 ::free(buffer_);
19 }
20
21 uint8_t* Allocation::GetBuffer() const {
22 return buffer_;
23 }
24
25 size_t Allocation::GetLength() const {
26 return length_;
27 }
28
29 size_t Allocation::GetReservedLength() const {
30 return reserved_;
31 }
32
33 bool Allocation::Truncate(size_t length, bool npot) {
34 const auto reserved = npot ? ReserveNPOT(length) : Reserve(length);
35 if (!reserved) {
36 return false;
37 }
38 length_ = length;
39 return true;
40 }
41
42 uint32_t Allocation::NextPowerOfTwoSize(uint32_t x) {
43 if (x == 0) {
44 return 1;
45 }
46
47 --x;
48
49 x |= x >> 1;
50 x |= x >> 2;
51 x |= x >> 4;
52 x |= x >> 8;
53 x |= x >> 16;
54
55 return x + 1;
56 }
57
58 bool Allocation::ReserveNPOT(size_t reserved) {
59 // Reserve at least one page of data.
60 reserved = std::max<size_t>(4096u, reserved);
61 return Reserve(NextPowerOfTwoSize(reserved));
62 }
63
64 bool Allocation::Reserve(size_t reserved) {
65 if (reserved <= reserved_) {
66 return true;
67 }
68
69 auto new_allocation = ::realloc(buffer_, reserved);
70 if (!new_allocation) {
71 // If new length is zero, a minimum non-zero sized allocation is returned.
72 // So this check will not trip and this routine will indicate success as
73 // expected.
74 VALIDATION_LOG << "Allocation failed. Out of host memory.";
75 return false;
76 }
77
78 buffer_ = static_cast<uint8_t*>(new_allocation);
79 reserved_ = reserved;
80
81 return true;
82 }
83
84 std::shared_ptr<fml::Mapping> CreateMappingWithCopy(const uint8_t* contents,
85 size_t length) {
86 if (contents == nullptr) {
87 return nullptr;
88 }
89
90 auto allocation = std::make_shared<Allocation>();
91 if (!allocation->Truncate(length)) {
92 return nullptr;
93 }
94
95 std::memmove(allocation->GetBuffer(), contents, length);
96
97 return CreateMappingFromAllocation(allocation);
98 }
99
100 std::shared_ptr<fml::Mapping> CreateMappingFromAllocation(
101 const std::shared_ptr<Allocation>& allocation) {
102 if (!allocation) {
103 return nullptr;
104 }
105 return std::make_shared<fml::NonOwnedMapping>(
106 reinterpret_cast<const uint8_t*>(allocation->GetBuffer()), //
107 allocation->GetLength(), //
108 [allocation](auto, auto) {} //
109 );
110 }
111
112 std::shared_ptr<fml::Mapping> CreateMappingWithString(std::string string) {
113 auto buffer = std::make_shared<std::string>(std::move(string));
114 return std::make_unique<fml::NonOwnedMapping>(
115 reinterpret_cast<const uint8_t*>(buffer->c_str()), buffer->length(),
116 [buffer](auto, auto) {});
117 }
118
119 } // namespace impeller
impeller::Allocation::~Allocation
~Allocation()
Definition: allocation.cc:17
allocation.h
impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:42
validation.h
impeller::CreateMappingFromAllocation
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Definition: allocation.cc:100
impeller::Allocation::Allocation
Allocation()
impeller::Allocation::GetReservedLength
size_t GetReservedLength() const
Definition: allocation.cc:29
impeller::Allocation::GetLength
size_t GetLength() const
Definition: allocation.cc:25
impeller::Allocation::GetBuffer
uint8_t * GetBuffer() const
Definition: allocation.cc:21
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::CreateMappingWithString
std::shared_ptr< fml::Mapping > CreateMappingWithString(std::string string)
Definition: allocation.cc:112
impeller::CreateMappingWithCopy
std::shared_ptr< fml::Mapping > CreateMappingWithCopy(const uint8_t *contents, size_t length)
Definition: allocation.cc:84
impeller
Definition: aiks_context.cc:10
impeller::Allocation::Truncate
bool Truncate(size_t length, bool npot=true)
Definition: allocation.cc:33