1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Optimize FileAccessCompressed::get_buffer by using memcpy.

This commit is contained in:
Lukas Tenbrink
2025-03-15 18:06:28 +01:00
parent b377562b52
commit b67e213b16

View File

@@ -247,7 +247,11 @@ bool FileAccessCompressed::eof_reached() const {
}
uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
if (p_length == 0) {
return 0;
}
ERR_FAIL_NULL_V(p_dst, -1);
ERR_FAIL_COND_V_MSG(f.is_null(), -1, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode.");
@@ -256,29 +260,38 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con
return 0;
}
for (uint64_t i = 0; i < p_length; i++) {
p_dst[i] = read_ptr[read_pos];
read_pos++;
if (read_pos >= read_block_size) {
read_block++;
uint64_t dst_idx = 0;
while (true) {
// Copy over as much of our current block as possible.
const uint32_t copied_bytes_count = MIN(p_length - dst_idx, read_block_size - read_pos);
memcpy(p_dst + dst_idx, read_ptr + read_pos, copied_bytes_count);
dst_idx += copied_bytes_count;
read_pos += copied_bytes_count;
if (read_block < read_block_count) {
//read another block of compressed data
f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize);
int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt.");
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
read_pos = 0;
} else {
read_block--;
at_end = true;
if (i + 1 < p_length) {
read_eof = true;
}
return i + 1;
}
if (dst_idx == p_length) {
// We're done! We read back all that was requested.
return p_length;
}
// We're not done yet; try reading the next block.
read_block++;
if (read_block >= read_block_count) {
// We're done! We read back the whole file.
read_block--;
at_end = true;
if (dst_idx + 1 < p_length) {
read_eof = true;
}
return dst_idx + 1;
}
// Read the next block of compressed data.
f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize);
int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt.");
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
read_pos = 0;
}
return p_length;