diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 77c0b6aeec..7464bb2c8c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -24,7 +24,7 @@ - Fix: [#14682] Crash when painting Swinging Ships with invalid subtype. - Fix: [#14707] Crash when window is closed during text input. - Fix: [#14710] Ride/Track Design preview does not show if it costs more money than available. -- Improved: [#14712]: Improve startup times. +- Improved: [#14712, #14716]: Improve startup times. 0.3.3 (2021-03-13) ------------------------------------------------------------------------ diff --git a/src/openrct2/rct12/SawyerChunk.cpp b/src/openrct2/rct12/SawyerChunk.cpp index b5db22a579..6873c94924 100644 --- a/src/openrct2/rct12/SawyerChunk.cpp +++ b/src/openrct2/rct12/SawyerChunk.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -10,6 +10,7 @@ #include "SawyerChunk.h" #include "../core/Memory.hpp" +#include "SawyerChunkReader.h" SawyerChunk::SawyerChunk(SAWYER_ENCODING encoding, void* data, size_t length) { @@ -20,5 +21,5 @@ SawyerChunk::SawyerChunk(SAWYER_ENCODING encoding, void* data, size_t length) SawyerChunk::~SawyerChunk() { - Memory::Free(_data); + SawyerChunkReader::FreeChunk(_data); } diff --git a/src/openrct2/rct12/SawyerChunkReader.cpp b/src/openrct2/rct12/SawyerChunkReader.cpp index f1bf44933f..cf03dfdc5b 100644 --- a/src/openrct2/rct12/SawyerChunkReader.cpp +++ b/src/openrct2/rct12/SawyerChunkReader.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -27,8 +27,9 @@ constexpr const char* EXCEPTION_MSG_DESTINATION_TOO_SMALL = "Chunk data larger t constexpr const char* EXCEPTION_MSG_INVALID_CHUNK_ENCODING = "Invalid chunk encoding."; constexpr const char* EXCEPTION_MSG_ZERO_SIZED_CHUNK = "Encountered zero-sized chunk."; -SawyerChunkReader::SawyerChunkReader(OpenRCT2::IStream* stream) +SawyerChunkReader::SawyerChunkReader(OpenRCT2::IStream* stream, bool persistentChunks) : _stream(stream) + , _createsPersistentChunks(persistentChunks) { } @@ -78,7 +79,10 @@ std::shared_ptr SawyerChunkReader::ReadChunk() { throw SawyerChunkException(EXCEPTION_MSG_ZERO_SIZED_CHUNK); } - buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + if (_createsPersistentChunks) + { + buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + } return std::make_shared( static_cast(header.encoding), buffer, uncompressedLength); } @@ -126,7 +130,10 @@ std::shared_ptr SawyerChunkReader::ReadChunkTrack() { throw SawyerChunkException(EXCEPTION_MSG_ZERO_SIZED_CHUNK); } - buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + if (_createsPersistentChunks) + { + buffer = static_cast(FinaliseLargeTempBuffer(buffer, uncompressedLength)); + } return std::make_shared(SAWYER_ENCODING::RLE, buffer, uncompressedLength); } catch (const std::exception&) @@ -158,6 +165,11 @@ void SawyerChunkReader::ReadChunk(void* dst, size_t length) } } +void SawyerChunkReader::FreeChunk(void* data) +{ + FreeLargeTempBuffer(data); +} + size_t SawyerChunkReader::DecodeChunk(void* dst, size_t dstCapacity, const void* src, const sawyercoding_chunk_header& header) { size_t resultLength; @@ -315,9 +327,7 @@ void* SawyerChunkReader::AllocateLargeTempBuffer() void* SawyerChunkReader::FinaliseLargeTempBuffer(void* buffer, size_t len) { #ifdef __USE_HEAP_ALLOC__ - auto finalBuffer = std::malloc(len); - std::memcpy(finalBuffer, buffer, len); - HeapFree(GetProcessHeap(), 0, buffer); + auto finalBuffer = HeapReAlloc(GetProcessHeap(), 0, buffer, len); #else auto finalBuffer = static_cast(std::realloc(buffer, len)); #endif diff --git a/src/openrct2/rct12/SawyerChunkReader.h b/src/openrct2/rct12/SawyerChunkReader.h index 8fb370b25e..0873c8b845 100644 --- a/src/openrct2/rct12/SawyerChunkReader.h +++ b/src/openrct2/rct12/SawyerChunkReader.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014-2020 OpenRCT2 developers + * Copyright (c) 2014-2021 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 @@ -36,15 +36,17 @@ namespace OpenRCT2 /** * Reads sawyer encoding chunks from a data stream. This can be used to read - * SC6, SV6 and RCT2 objects. + * SC6, SV6 and RCT2 objects. persistentChunks is a hint to the reader that the chunk will be preserved, + * and thus the chunk memory should be shrunk. */ class SawyerChunkReader final { private: OpenRCT2::IStream* const _stream = nullptr; + const bool _createsPersistentChunks = false; public: - explicit SawyerChunkReader(OpenRCT2::IStream* stream); + explicit SawyerChunkReader(OpenRCT2::IStream* stream, bool persistentChunks = false); /** * Skips the next chunk in the stream without decoding or reading its data @@ -84,6 +86,11 @@ public: return result; } + /** + * Frees the chunk data, to be used when destructing SawyerChunks + */ + static void FreeChunk(void* data); + private: static size_t DecodeChunk(void* dst, size_t dstCapacity, const void* src, const sawyercoding_chunk_header& header); static size_t DecodeChunkRLERepeat(void* dst, size_t dstCapacity, const void* src, size_t srcLength);