Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions impeller/aiks/testing/context_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ class ContextMock : public Context {
(),
(const, override));

MOCK_METHOD(const std::shared_ptr<HostBuffer>,
GetTransientsBuffer,
(),
(const, override));

MOCK_METHOD(void, Shutdown, (), (override));
};

Expand Down
1 change: 0 additions & 1 deletion impeller/base/allocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#define FLUTTER_IMPELLER_BASE_ALLOCATION_H_

#include <cstdint>
#include <limits>
#include <memory>

#include "flutter/fml/mapping.h"
Expand Down
119 changes: 59 additions & 60 deletions impeller/core/host_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,31 @@

#include "impeller/core/host_buffer.h"

#include <algorithm>
#include <cstring>

#include "flutter/fml/logging.h"
#include <tuple>

#include "impeller/core/allocator.h"
#include "impeller/core/buffer_view.h"
#include "impeller/core/device_buffer.h"
#include "impeller/core/device_buffer_descriptor.h"
#include "impeller/core/formats.h"

namespace impeller {

std::shared_ptr<HostBuffer> HostBuffer::Create() {
return std::shared_ptr<HostBuffer>(new HostBuffer());
constexpr size_t kAllocatorBlockSize = 1024000; // 1024 Kb.

std::shared_ptr<HostBuffer> HostBuffer::Create(
const std::shared_ptr<Allocator>& allocator) {
return std::shared_ptr<HostBuffer>(new HostBuffer(allocator));
}

HostBuffer::HostBuffer() = default;
HostBuffer::HostBuffer(const std::shared_ptr<Allocator>& allocator) {
state_->allocator = allocator;
DeviceBufferDescriptor desc;
desc.size = kAllocatorBlockSize;
desc.storage_mode = StorageMode::kHostVisible;
state_->device_buffers.push_back(allocator->CreateBuffer(desc));
}

HostBuffer::~HostBuffer() = default;

Expand All @@ -30,104 +39,96 @@ void HostBuffer::SetLabel(std::string label) {
BufferView HostBuffer::Emplace(const void* buffer,
size_t length,
size_t align) {
auto [device_buffer, range] = state_->Emplace(buffer, length, align);
auto [data, range, device_buffer] = state_->Emplace(buffer, length, align);
if (!device_buffer) {
return {};
}
return BufferView{state_, device_buffer, range};
return BufferView{std::move(device_buffer), data, range};
}

BufferView HostBuffer::Emplace(const void* buffer, size_t length) {
auto [device_buffer, range] = state_->Emplace(buffer, length);
auto [data, range, device_buffer] = state_->Emplace(buffer, length);
if (!device_buffer) {
return {};
}
return BufferView{state_, device_buffer, range};
return BufferView{std::move(device_buffer), data, range};
}

BufferView HostBuffer::Emplace(size_t length,
size_t align,
const EmplaceProc& cb) {
auto [buffer, range] = state_->Emplace(length, align, cb);
if (!buffer) {
auto [data, range, device_buffer] = state_->Emplace(length, align, cb);
if (!device_buffer) {
return {};
}
return BufferView{state_, buffer, range};
return BufferView{std::move(device_buffer), data, range};
}

std::shared_ptr<const DeviceBuffer> HostBuffer::GetDeviceBuffer(
Allocator& allocator) const {
return state_->GetDeviceBuffer(allocator);
return nullptr;
}

void HostBuffer::Reset() {
state_->Reset();
}

size_t HostBuffer::GetSize() const {
return state_->GetReservedLength();
}

size_t HostBuffer::GetLength() const {
return state_->GetLength();
void HostBuffer::HostBufferState::MaybeCreateNewBuffer() {
if (current_buffer + 1 >= device_buffers.size()) {
DeviceBufferDescriptor desc;
desc.size = kAllocatorBlockSize;
desc.storage_mode = StorageMode::kHostVisible;
device_buffers.push_back(allocator->CreateBuffer(desc));
}
current_buffer++;
offset = 0;
}

std::pair<uint8_t*, Range> HostBuffer::HostBufferState::Emplace(
size_t length,
size_t align,
const EmplaceProc& cb) {
std::tuple<uint8_t*, Range, std::shared_ptr<DeviceBuffer>>
HostBuffer::HostBufferState::Emplace(size_t length,
size_t align,
const EmplaceProc& cb) {
if (!cb) {
return {};
}
auto old_length = GetLength();
if (!Truncate(old_length + length)) {
return {};
if (old_length + length > kAllocatorBlockSize) {
MaybeCreateNewBuffer();
}
generation++;
cb(GetBuffer() + old_length);

return std::make_pair(GetBuffer(), Range{old_length, length});
}
cb(GetCurrentBuffer()->OnGetContents() + old_length);

std::shared_ptr<const DeviceBuffer>
HostBuffer::HostBufferState::GetDeviceBuffer(Allocator& allocator) const {
if (generation == device_buffer_generation) {
return device_buffer;
}
auto new_buffer = allocator.CreateBufferWithCopy(GetBuffer(), GetLength());
if (!new_buffer) {
return nullptr;
}
new_buffer->SetLabel(label);
device_buffer_generation = generation;
device_buffer = std::move(new_buffer);
return device_buffer;
offset += length;
return std::make_tuple(GetCurrentBuffer()->OnGetContents(),
Range{old_length, length}, GetCurrentBuffer());
}

std::pair<uint8_t*, Range> HostBuffer::HostBufferState::Emplace(
const void* buffer,
size_t length) {
std::tuple<uint8_t*, Range, std::shared_ptr<DeviceBuffer>>
HostBuffer::HostBufferState::Emplace(const void* buffer, size_t length) {
auto old_length = GetLength();
if (!Truncate(old_length + length)) {
return {};
if (old_length + length > kAllocatorBlockSize) {
MaybeCreateNewBuffer();
}
generation++;

if (buffer) {
::memmove(GetBuffer() + old_length, buffer, length);
::memmove(GetCurrentBuffer()->OnGetContents() + old_length, buffer, length);
}
return std::make_pair(GetBuffer(), Range{old_length, length});
offset += length;
return std::make_tuple(GetCurrentBuffer()->OnGetContents(),
Range{old_length, length}, GetCurrentBuffer());
}

std::pair<uint8_t*, Range> HostBuffer::HostBufferState::Emplace(
const void* buffer,
size_t length,
size_t align) {
std::tuple<uint8_t*, Range, std::shared_ptr<DeviceBuffer>>
HostBuffer::HostBufferState::Emplace(const void* buffer,
size_t length,
size_t align) {
if (align == 0 || (GetLength() % align) == 0) {
return Emplace(buffer, length);
}

{
auto [buffer, range] = Emplace(nullptr, align - (GetLength() % align));
auto [buffer, range, device_buffer] =
Emplace(nullptr, align - (GetLength() % align));
if (!buffer) {
return {};
}
Expand All @@ -137,10 +138,8 @@ std::pair<uint8_t*, Range> HostBuffer::HostBufferState::Emplace(
}

void HostBuffer::HostBufferState::Reset() {
generation += 1;
device_buffer = nullptr;
bool did_truncate = Truncate(0);
FML_CHECK(did_truncate);
offset = 0u;
current_buffer++;
}

} // namespace impeller
48 changes: 22 additions & 26 deletions impeller/core/host_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
#define FLUTTER_IMPELLER_CORE_HOST_BUFFER_H_

#include <algorithm>
#include <functional>
#include <memory>
#include <string>
#include <type_traits>

#include "impeller/base/allocation.h"
#include "impeller/core/buffer.h"
#include "impeller/core/buffer_view.h"
#include "impeller/core/platform.h"
Expand All @@ -19,7 +19,8 @@ namespace impeller {

class HostBuffer final : public Buffer {
public:
static std::shared_ptr<HostBuffer> Create();
static std::shared_ptr<HostBuffer> Create(
const std::shared_ptr<Allocator>& allocator);

// |Buffer|
virtual ~HostBuffer();
Expand Down Expand Up @@ -114,36 +115,31 @@ class HostBuffer final : public Buffer {
/// reused.
void Reset();

//----------------------------------------------------------------------------
/// @brief Returns the capacity of the HostBuffer in memory in bytes.
size_t GetSize() const;
private:
struct HostBufferState {
[[nodiscard]] std::tuple<uint8_t*, Range, std::shared_ptr<DeviceBuffer>>
Emplace(const void* buffer, size_t length);

//----------------------------------------------------------------------------
/// @brief Returns the size of the currently allocated HostBuffer memory in
/// bytes.
size_t GetLength() const;
std::tuple<uint8_t*, Range, std::shared_ptr<DeviceBuffer>>
Emplace(size_t length, size_t align, const EmplaceProc& cb);

private:
struct HostBufferState : public Buffer, public Allocation {
std::shared_ptr<const DeviceBuffer> GetDeviceBuffer(
Allocator& allocator) const override;
std::tuple<uint8_t*, Range, std::shared_ptr<DeviceBuffer>>
Emplace(const void* buffer, size_t length, size_t align);

[[nodiscard]] std::pair<uint8_t*, Range> Emplace(const void* buffer,
size_t length);
void Reset();

std::pair<uint8_t*, Range> Emplace(size_t length,
size_t align,
const EmplaceProc& cb);
size_t GetLength() const { return offset; }

std::pair<uint8_t*, Range> Emplace(const void* buffer,
size_t length,
size_t align);
void MaybeCreateNewBuffer();

void Reset();
std::shared_ptr<DeviceBuffer> GetCurrentBuffer() {
return device_buffers[current_buffer];
}

mutable std::shared_ptr<DeviceBuffer> device_buffer;
mutable size_t device_buffer_generation = 0u;
size_t generation = 1u;
std::shared_ptr<Allocator> allocator;
std::vector<std::shared_ptr<DeviceBuffer>> device_buffers;
size_t current_buffer = 0u;
size_t offset = 0u;
std::string label;
};

Expand All @@ -155,7 +151,7 @@ class HostBuffer final : public Buffer {

[[nodiscard]] BufferView Emplace(const void* buffer, size_t length);

HostBuffer();
explicit HostBuffer(const std::shared_ptr<Allocator>& allocator);

HostBuffer(const HostBuffer&) = delete;

Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/inline_pass_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

#include <utility>

#include "impeller/base/allocation.h"
#include "impeller/base/validation.h"
#include "impeller/core/formats.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/entity/entity_pass_target.h"
#include "impeller/renderer/command_buffer.h"

Expand Down
7 changes: 7 additions & 0 deletions impeller/renderer/backend/gles/context_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "impeller/base/config.h"
#include "impeller/base/validation.h"
#include "impeller/core/host_buffer.h"
#include "impeller/renderer/backend/gles/command_buffer_gles.h"
#include "impeller/renderer/backend/gles/gpu_tracer_gles.h"

Expand Down Expand Up @@ -65,6 +66,7 @@ ContextGLES::ContextGLES(
std::shared_ptr<SamplerLibraryGLES>(new SamplerLibraryGLES(
device_capabilities_->SupportsDecalSamplerAddressMode()));
}
host_buffer_ = HostBuffer::Create(resource_allocator_);
gpu_tracer_ = std::make_shared<GPUTracerGLES>(GetReactor()->GetProcTable(),
enable_gpu_tracing);
is_valid_ = true;
Expand Down Expand Up @@ -132,6 +134,11 @@ std::shared_ptr<CommandBuffer> ContextGLES::CreateCommandBuffer() const {
new CommandBufferGLES(weak_from_this(), reactor_));
}

// |Context|
const std::shared_ptr<HostBuffer> ContextGLES::GetTransientsBuffer() const {
return host_buffer_;
}

// |Context|
const std::shared_ptr<const Capabilities>& ContextGLES::GetCapabilities()
const {
Expand Down
5 changes: 5 additions & 0 deletions impeller/renderer/backend/gles/context_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <unordered_map>
#include "flutter/fml/macros.h"
#include "impeller/base/backend_cast.h"
#include "impeller/core/host_buffer.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "impeller/core/host_buffer.h"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

#include "impeller/renderer/backend/gles/allocator_gles.h"
#include "impeller/renderer/backend/gles/capabilities_gles.h"
#include "impeller/renderer/backend/gles/gpu_tracer_gles.h"
Expand Down Expand Up @@ -52,6 +53,7 @@ class ContextGLES final : public Context,
std::shared_ptr<SamplerLibraryGLES> sampler_library_;
std::shared_ptr<AllocatorGLES> resource_allocator_;
std::shared_ptr<GPUTracerGLES> gpu_tracer_;
std::shared_ptr<HostBuffer> host_buffer_;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::shared_ptr<HostBuffer> host_buffer_;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// Note: This is stored separately from the ProcTableGLES CapabilitiesGLES
// in order to satisfy the Context::GetCapabilities signature which returns
Expand Down Expand Up @@ -88,6 +90,9 @@ class ContextGLES final : public Context,
// |Context|
const std::shared_ptr<const Capabilities>& GetCapabilities() const override;

// |Context|
const std::shared_ptr<HostBuffer> GetTransientsBuffer() const override;

// |Context|
void Shutdown() override;

Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/metal/context_mtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class ContextMTL final : public Context,
// |Context|
const std::shared_ptr<const Capabilities>& GetCapabilities() const override;

// |Context|
const std::shared_ptr<HostBuffer> GetTransientsBuffer() const override;

void SetCapabilities(const std::shared_ptr<const Capabilities>& capabilities);

// |Context|
Expand Down Expand Up @@ -129,6 +132,7 @@ class ContextMTL final : public Context,
#endif // IMPELLER_DEBUG
std::deque<std::function<void()>> tasks_awaiting_gpu_;
std::unique_ptr<SyncSwitchObserver> sync_switch_observer_;
std::shared_ptr<HostBuffer> host_buffer_;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::shared_ptr<HostBuffer> host_buffer_;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

bool is_valid_ = false;

ContextMTL(
Expand Down
Loading