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 all 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
47 changes: 47 additions & 0 deletions impeller/core/allocator_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,52 @@ TEST(AllocatorTest, TextureDescriptorCompatibility) {
}
}

TEST(AllocatorTest, RangeTest) {
{
Range a = Range{0, 10};
Range b = Range{10, 20};
auto merged = a.Merge(b);

EXPECT_EQ(merged.offset, 0u);
EXPECT_EQ(merged.length, 30u);
}

{
Range a = Range{0, 10};
Range b = Range{100, 20};
auto merged = a.Merge(b);

EXPECT_EQ(merged.offset, 0u);
EXPECT_EQ(merged.length, 120u);
}

{
Range a = Range{0, 10};
Range b = Range{100, 20};
auto merged = b.Merge(a);

EXPECT_EQ(merged.offset, 0u);
EXPECT_EQ(merged.length, 120u);
}

{
Range a = Range{0, 10};
Range b = Range{100, 0};
auto merged = b.Merge(a);

EXPECT_EQ(merged.offset, 0u);
EXPECT_EQ(merged.length, 10u);
}

{
Range a = Range{0, 10};
Range b = Range{0, 10};
auto merged = b.Merge(a);

EXPECT_EQ(merged.offset, 0u);
EXPECT_EQ(merged.length, 10u);
}
}

} // namespace testing
} // namespace impeller
14 changes: 14 additions & 0 deletions impeller/core/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FLUTTER_IMPELLER_CORE_RANGE_H_
#define FLUTTER_IMPELLER_CORE_RANGE_H_

#include <algorithm>
#include <cstddef>

namespace impeller {
Expand All @@ -21,6 +22,19 @@ struct Range {
constexpr bool operator==(const Range& o) const {
return offset == o.offset && length == o.length;
}

/// @brief Create a new range that is a union of this range and other.
constexpr Range Merge(const Range& other) {
if (other.length == 0) {
return *this;
}
if (length == 0) {
return other;
}
auto end_offset = std::max(offset + length, other.offset + other.length);
auto start_offset = std::min(offset, other.offset);
return Range{start_offset, end_offset - start_offset};
}
};

} // namespace impeller
Expand Down
35 changes: 23 additions & 12 deletions impeller/renderer/backend/gles/device_buffer_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
#include <cstring>
#include <memory>

#include "flutter/fml/trace_event.h"
#include "impeller/base/allocation.h"
#include "impeller/base/config.h"
#include "impeller/base/validation.h"

namespace impeller {

Expand Down Expand Up @@ -53,13 +51,22 @@ bool DeviceBufferGLES::OnCopyHostBuffer(const uint8_t* source,

std::memmove(backing_store_->GetBuffer() + offset,
source + source_range.offset, source_range.length);
++generation_;
Flush(Range{offset, source_range.length});

return true;
}

void DeviceBufferGLES::Flush(std::optional<Range> range) const {
generation_++;
if (!range.has_value()) {
dirty_range_ = Range{
0, static_cast<size_t>(backing_store_->GetLength().GetByteSize())};
} else {
if (dirty_range_.has_value()) {
dirty_range_ = dirty_range_->Merge(range.value());
} else {
dirty_range_ = range.value();
}
}
}

static GLenum ToTarget(DeviceBufferGLES::BindingType type) {
Expand All @@ -86,14 +93,17 @@ bool DeviceBufferGLES::BindAndUploadDataIfNecessary(BindingType type) const {
const auto& gl = reactor_->GetProcTable();

gl.BindBuffer(target_type, buffer.value());

if (upload_generation_ != generation_) {
TRACE_EVENT1(
"impeller", "BufferData", "Bytes",
std::to_string(backing_store_->GetLength().GetByteSize()).c_str());
if (!initialized_) {
gl.BufferData(target_type, backing_store_->GetLength().GetByteSize(),
backing_store_->GetBuffer(), GL_STATIC_DRAW);
upload_generation_ = generation_;
nullptr, GL_DYNAMIC_DRAW);
initialized_ = true;
}

if (dirty_range_.has_value()) {
auto range = dirty_range_.value();
gl.BufferSubData(target_type, range.offset, range.length,
backing_store_->GetBuffer() + range.offset);
dirty_range_ = std::nullopt;
}

return true;
Expand Down Expand Up @@ -122,7 +132,8 @@ void DeviceBufferGLES::UpdateBufferData(
if (update_buffer_data) {
update_buffer_data(backing_store_->GetBuffer(),
backing_store_->GetLength().GetByteSize());
++generation_;
Flush(Range{
0, static_cast<size_t>(backing_store_->GetLength().GetByteSize())});
}
}

Expand Down
4 changes: 2 additions & 2 deletions impeller/renderer/backend/gles/device_buffer_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class DeviceBufferGLES final
ReactorGLES::Ref reactor_;
HandleGLES handle_;
mutable std::shared_ptr<Allocation> backing_store_;
mutable uint32_t generation_ = 0;
mutable uint32_t upload_generation_ = 0;
mutable std::optional<Range> dirty_range_ = std::nullopt;
mutable bool initialized_ = false;

// |DeviceBuffer|
uint8_t* OnGetContents() const override;
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/gles/proc_table_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ struct GLProc {
PROC(BlendEquationSeparate); \
PROC(BlendFuncSeparate); \
PROC(BufferData); \
PROC(BufferSubData); \
PROC(CheckFramebufferStatus); \
PROC(Clear); \
PROC(ClearColor); \
Expand Down