Skip to content

Commit

Permalink
Trade: docs and example for zero-copy import.
Browse files Browse the repository at this point in the history
  • Loading branch information
mosra committed Oct 24, 2021
1 parent 5e7443a commit dfea5bd
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
18 changes: 18 additions & 0 deletions doc/snippets/MagnumTrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,24 @@ importer->openFile("scene.gltf"); // memory-maps all files
}
#endif

#if defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT))
{
Containers::Pointer<Trade::AbstractImporter> importer;
/* [AbstractImporter-usage-zerocopy] */
importer->addFlags(Trade::ImporterFlag::ZeroCopy);

Containers::Array<const char, Utility::Directory::MapDeleter> memory;
if(!(memory = Utility::Directory::mapRead("huge-file.gltf")) ||
!importer->openMemory(memory))
Fatal{} << "Can't memory-map and open the file";

/* Depending on the importer, the actual vertex/index data will get paged from
the above file into the physical memory only once you actually access them */
Containers::Optional<Trade::MeshData> mesh = importer->mesh("huge-cathedral");
/* [AbstractImporter-usage-zerocopy] */
}
#endif

{
Containers::Pointer<Trade::AbstractImporter> importer;
Int materialIndex;
Expand Down
35 changes: 35 additions & 0 deletions src/Magnum/Trade/AbstractImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,41 @@ name doesn't exist.
- Texture names using @ref textureName() & @ref textureForName(), imported
with @ref texture(const std::string&)
@subsection Trade-AbstractImporter-usage-zerocopy Zero-copy data import
Some file formats have the data structured in a way that allows them to be
loaded directly into memory or onto the GPU and used as-is. If you memory-map
such a a file and open it with a capable importer, it can give you a view on a
sub-range of the memory-mapped file instead of allocating a copy. Importers
advertise such capabilities with @ref ImporterFeature::ZeroCopyImages,
@relativeref{ImporterFeature,ZeroCopyMeshIndices},
@relativeref{ImporterFeature,ZeroCopyMeshVertices} and related flags. Because
this puts additional constraints on data lifetime, you have to explicitly
enable the behavior with @ref ImporterFlag::ZeroCopy. Then use
@ref openMemory() to open the memory and ensure it stays in scope for as long
as you operate on the instances returned from the importer:
@snippet MagnumTrade.cpp AbstractImporter-usage-zerocopy
Returned instances that reference the original memory are indicated with a
presence of @ref DataFlag::ExternallyOwned. If you use the mutable
@ref openMemory(Containers::ArrayView<void>) overload, the returned data will
have also @ref DataFlag::Mutable set, allowing you to do in-place modifications
on the original file.
In some cases the importer might still need to process the data on import ---
for example converting image endianness or flipping image origin, and in that
case it'll still return a copy of the data, indicated with
@ref DataFlag::Owned instead. To enforce zero-copy behavior, enable one of the
@ref ImporterFlag::ForceZeroCopyImages, ... flags, providing the plugin
actually supports the corresponding feature. In that case import of particular
data will fail instead of returning a copy, which is useful when you want to,
for example, operate in-place on the imported file or when it's needed to avoid
accidental slowdowns.
See documentation of a particular importer plugin for information about
provided zero-copy features and their limitations.
@subsection Trade-AbstractImporter-usage-state Internal importer state
Some importers, especially ones that make use of well-known external libraries,
Expand Down

0 comments on commit dfea5bd

Please sign in to comment.