Browse Source

Trade: add ImporterFlag::ZeroCopy.

It's great to see how the design nicely fermented over the three and
half (!!) years. This is a completely opt-in feature for all plugins
involved, so if the plugin decides to not do anything about it, it
doesn't have to. The actual enforcements will come later.
pull/240/head
Vladimír Vondruš 5 years ago
parent
commit
7c3c0635e5
  1. 4
      src/Magnum/Trade/AbstractImporter.cpp
  2. 25
      src/Magnum/Trade/AbstractImporter.h
  3. 11
      src/Magnum/Trade/Test/AbstractImporterTest.cpp

4
src/Magnum/Trade/AbstractImporter.cpp

@ -1176,6 +1176,7 @@ Debug& operator<<(Debug& debug, const ImporterFlag value) {
/* LCOV_EXCL_START */
#define _c(v) case ImporterFlag::v: return debug << "::" #v;
_c(Verbose)
_c(ZeroCopy)
#undef _c
/* LCOV_EXCL_STOP */
}
@ -1185,7 +1186,8 @@ Debug& operator<<(Debug& debug, const ImporterFlag value) {
Debug& operator<<(Debug& debug, const ImporterFlags value) {
return Containers::enumSetDebugOutput(debug, value, "Trade::ImporterFlags{}", {
ImporterFlag::Verbose});
ImporterFlag::Verbose,
ImporterFlag::ZeroCopy});
}
}}

25
src/Magnum/Trade/AbstractImporter.h

@ -113,6 +113,28 @@ enum class ImporterFlag: UnsignedByte {
*/
Verbose = 1 << 0,
/**
* Opt-in to zero-copy import, if possible. When this flag is set and
* @ref AbstractImporter::openMemory() is used, returned @ref AnimationData,
* @ref ImageData, @ref MaterialData, @ref MeshData and @ref SkinData
* instances may be views on memory passed to
* @relativeref{AbstractImporter,openMemory()} instead of allocated copies,
* indicated with @ref DataFlag::ExternallyOwned.
*
* Since it's not always possible to directly reference the input memory
* (for example because the input data may need to be parsed from text,
* gathered from an incompatible data layout or patched in some way), this
* flag doesn't put any requirement on the importer --- plugins that don't
* support zero-copy import will behave the same as if this flag was not
* set.
*
* Setting this flag however means you're responsible to keep the memory
* passed to @relativeref{AbstractImporter,openMemory()} in scope for as
* long as any `*Data` instances referencing it are alive.
* @m_since_latest
*/
ZeroCopy = 1 << 1,
/** @todo ~~Y flip~~ Y up for images, "I want to import just once, don't copy" ... */
};
@ -654,7 +676,8 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
* scope until the importer is destructed, @ref close() is called or
* another file is opened. This allows the implementation to directly
* operate on the provided memory, without having to allocate a local
* copy to extend its lifetime.
* copy to extend its lifetime. See also @ref ImporterFlag::ZeroCopy
* for a possibility of further optimizations.
* @see @ref features(), @ref openFile(), @ref openState()
*/
bool openMemory(Containers::ArrayView<const void> memory);

11
src/Magnum/Trade/Test/AbstractImporterTest.cpp

@ -586,14 +586,13 @@ void AbstractImporterTest::setFlags() {
CORRADE_COMPARE(importer.flags(), ImporterFlag::Verbose);
CORRADE_COMPARE(importer._flags, ImporterFlag::Verbose);
/** @todo use a real flag when we have more than one */
importer.addFlags(ImporterFlag(4));
CORRADE_COMPARE(importer.flags(), ImporterFlag::Verbose|ImporterFlag(4));
CORRADE_COMPARE(importer._flags, ImporterFlag::Verbose|ImporterFlag(4));
importer.addFlags(ImporterFlag::ZeroCopy);
CORRADE_COMPARE(importer.flags(), ImporterFlag::Verbose|ImporterFlag::ZeroCopy);
CORRADE_COMPARE(importer._flags, ImporterFlag::Verbose|ImporterFlag::ZeroCopy);
importer.clearFlags(ImporterFlag::Verbose);
CORRADE_COMPARE(importer.flags(), ImporterFlag(4));
CORRADE_COMPARE(importer._flags, ImporterFlag(4));
CORRADE_COMPARE(importer.flags(), ImporterFlag::ZeroCopy);
CORRADE_COMPARE(importer._flags, ImporterFlag::ZeroCopy);
}
void AbstractImporterTest::setFlagsFileOpened() {

Loading…
Cancel
Save