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#pragma once
6
7#include <algorithm>
8#include <memory>
9#include <string>
10#include <type_traits>
11
12#include "flutter/fml/macros.h"
13#include "impeller/base/allocation.h"
14#include "impeller/core/buffer.h"
15#include "impeller/core/buffer_view.h"
16#include "impeller/core/platform.h"
17
18namespace impeller {
19
20class HostBuffer final : public std::enable_shared_from_this<HostBuffer>,
21 public Allocation,
22 public Buffer {
23 public:
24 static std::shared_ptr<HostBuffer> Create();
25
26 // |Buffer|
27 virtual ~HostBuffer();
28
29 void SetLabel(std::string label);
30
31 //----------------------------------------------------------------------------
32 /// @brief Emplace uniform data onto the host buffer. Ensure that backend
33 /// specific uniform alignment requirements are respected.
34 ///
35 /// @param[in] uniform The uniform struct to emplace onto the buffer.
36 ///
37 /// @tparam UniformType The type of the uniform struct.
38 ///
39 /// @return The buffer view.
40 ///
41 template <class UniformType,
42 class = std::enable_if_t<std::is_standard_layout_v<UniformType>>>
43 [[nodiscard]] BufferView EmplaceUniform(const UniformType& uniform) {
44 const auto alignment =
45 std::max(a: alignof(UniformType), b: DefaultUniformAlignment());
46 return Emplace(buffer: reinterpret_cast<const void*>(&uniform), // buffer
47 length: sizeof(UniformType), // size
48 align: alignment // alignment
49 );
50 }
51
52 //----------------------------------------------------------------------------
53 /// @brief Emplace storage buffer data onto the host buffer. Ensure that
54 /// backend specific uniform alignment requirements are respected.
55 ///
56 /// @param[in] uniform The storage buffer to emplace onto the buffer.
57 ///
58 /// @tparam StorageBufferType The type of the shader storage buffer.
59 ///
60 /// @return The buffer view.
61 ///
62 template <
63 class StorageBufferType,
64 class = std::enable_if_t<std::is_standard_layout_v<StorageBufferType>>>
65 [[nodiscard]] BufferView EmplaceStorageBuffer(
66 const StorageBufferType& buffer) {
67 const auto alignment =
68 std::max(a: alignof(StorageBufferType), b: DefaultUniformAlignment());
69 return Emplace(&buffer, // buffer
70 sizeof(StorageBufferType), // size
71 alignment // alignment
72 );
73 }
74
75 //----------------------------------------------------------------------------
76 /// @brief Emplace non-uniform data (like contiguous vertices) onto the
77 /// host buffer.
78 ///
79 /// @param[in] buffer The buffer data.
80 ///
81 /// @tparam BufferType The type of the buffer data.
82 ///
83 /// @return The buffer view.
84 ///
85 template <class BufferType,
86 class = std::enable_if_t<std::is_standard_layout_v<BufferType>>>
87 [[nodiscard]] BufferView Emplace(const BufferType& buffer) {
88 return Emplace(buffer: reinterpret_cast<const void*>(&buffer), // buffer
89 length: sizeof(BufferType), // size
90 align: alignof(BufferType) // alignment
91 );
92 }
93
94 [[nodiscard]] BufferView Emplace(const void* buffer,
95 size_t length,
96 size_t align);
97
98 using EmplaceProc = std::function<void(uint8_t* buffer)>;
99
100 //----------------------------------------------------------------------------
101 /// @brief Emplaces undefined data onto the managed buffer and gives the
102 /// caller a chance to update it using the specified callback. The
103 /// buffer is guaranteed to have enough space for length bytes. It
104 /// is the responsibility of the caller to not exceed the bounds
105 /// of the buffer returned in the EmplaceProc.
106 ///
107 /// @param[in] cb A callback that will be passed a ptr to the
108 /// underlying host buffer.
109 ///
110 /// @return The buffer view.
111 ///
112 BufferView Emplace(size_t length, size_t align, const EmplaceProc& cb);
113
114 //----------------------------------------------------------------------------
115 /// @brief Resets the contents of the HostBuffer to nothing so it can be
116 /// reused.
117 void Reset();
118
119 //----------------------------------------------------------------------------
120 /// @brief Returns the size of the HostBuffer in memory in bytes.
121 size_t GetSize() const;
122
123 private:
124 mutable std::shared_ptr<DeviceBuffer> device_buffer_;
125 mutable size_t device_buffer_generation_ = 0u;
126 size_t generation_ = 1u;
127 std::string label_;
128
129 // |Buffer|
130 std::shared_ptr<const DeviceBuffer> GetDeviceBuffer(
131 Allocator& allocator) const override;
132
133 [[nodiscard]] BufferView Emplace(const void* buffer, size_t length);
134
135 HostBuffer();
136
137 FML_DISALLOW_COPY_AND_ASSIGN(HostBuffer);
138};
139
140} // namespace impeller
141

source code of flutter_engine/flutter/impeller/core/host_buffer.h