blob: 256710173917d5ba170ca7aa8bf8498870944cea [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/core/host_buffer.h"
#include <algorithm>
#include <cstring>
#include "flutter/fml/logging.h"
#include "impeller/core/allocator.h"
#include "impeller/core/buffer_view.h"
#include "impeller/core/device_buffer.h"
namespace impeller {
std::shared_ptr<HostBuffer> HostBuffer::Create() {
return std::shared_ptr<HostBuffer>(new HostBuffer());
}
HostBuffer::HostBuffer() = default;
HostBuffer::~HostBuffer() = default;
void HostBuffer::SetLabel(std::string label) {
label_ = std::move(label);
}
BufferView HostBuffer::Emplace(const void* buffer,
size_t length,
size_t align) {
if (align == 0 || (GetLength() % align) == 0) {
return Emplace(buffer, length);
}
{
auto pad = Emplace(nullptr, align - (GetLength() % align));
if (!pad) {
return {};
}
}
return Emplace(buffer, length);
}
BufferView HostBuffer::Emplace(const void* buffer, size_t length) {
auto old_length = GetLength();
if (!Truncate(old_length + length)) {
return {};
}
generation_++;
if (buffer) {
::memmove(GetBuffer() + old_length, buffer, length);
}
return BufferView{shared_from_this(), GetBuffer(), Range{old_length, length}};
}
BufferView HostBuffer::Emplace(size_t length,
size_t align,
const EmplaceProc& cb) {
if (!cb) {
return {};
}
auto old_length = GetLength();
if (!Truncate(old_length + length)) {
return {};
}
generation_++;
cb(GetBuffer() + old_length);
return BufferView{shared_from_this(), GetBuffer(), Range{old_length, length}};
}
std::shared_ptr<const DeviceBuffer> HostBuffer::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_;
}
void HostBuffer::Reset() {
generation_ += 1;
device_buffer_ = nullptr;
bool did_truncate = Truncate(0);
FML_CHECK(did_truncate);
}
size_t HostBuffer::GetSize() const {
return GetReservedLength();
}
} // namespace impeller