Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make tile content loading asynchronous #338

Merged
merged 23 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2851783
_attempt_ to use futures for the tile content loader interface
nithinp7 Jun 4, 2021
98b65c0
fix cherry-pick, format
nithinp7 Sep 7, 2021
b68440a
don't pass functions as references in lambda capture
nithinp7 Sep 8, 2021
b762be0
pass asset accessor and request headers to tile content loading
nithinp7 Sep 8, 2021
2a9538d
fix pessimizing-moves
nithinp7 Sep 8, 2021
e46184a
changes + remove extraneous newline
nithinp7 Sep 9, 2021
835de62
improve async logic in Tile.cpp
nithinp7 Sep 13, 2021
be1d76c
wip, some cleanup/workarounds in Tile.cpp async code
nithinp7 Sep 14, 2021
f37a1db
TileContentLoadInput is now the only argument for content loading
nithinp7 Sep 14, 2021
84a6e70
make inner tiles merging happen on worker thread
nithinp7 Sep 15, 2021
3298756
Allow unwrapped Future continuations to be mutable.
kring Sep 15, 2021
e15d172
Formatting.
kring Sep 15, 2021
cdae0aa
fix test, removed lambda workaround in Tile.cpp
nithinp7 Sep 15, 2021
dbcbce9
remove this from lambda capture
nithinp7 Sep 16, 2021
db0392d
remove two lines that had no effect
nithinp7 Sep 16, 2021
2898882
address review comments, simplify TileContentLoadInput
nithinp7 Sep 16, 2021
3f6d0ab
format
nithinp7 Sep 16, 2021
4042d0b
address review comments
nithinp7 Sep 21, 2021
73b0945
move loadInput into lambda capture
nithinp7 Sep 22, 2021
1a46a22
format
nithinp7 Sep 22, 2021
4e13dfa
Doc tweak, remove unused headers.
kring Sep 24, 2021
acb2294
Merge remote-tracking branch 'origin/main' into async-tile-load
kring Sep 24, 2021
521fe41
Update CHANGES.md.
kring Sep 24, 2021
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
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### v0.7.1 - ????

##### Additions :tada:
- Made tile content loading asynchronous and allowed it to make further network requests, to Ion or otherwise.

##### Fixes :wrench:

- Fixed a bug introduced in v0.7.0 where Bing credits were not being collected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class CESIUM3DTILESSELECTION_API ExternalTilesetContent final
* The result will only contain the `childTiles` and the `pNewTileContext`.
* Other fields will be empty or have default values.
*/
std::unique_ptr<TileContentLoadResult>
CesiumAsync::Future<std::unique_ptr<TileContentLoadResult>>
load(const TileContentLoadInput& input) override;

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Cesium3DTilesSelection/TileContentLoader.h"
#include "Cesium3DTilesSelection/TileID.h"
#include "Cesium3DTilesSelection/TileRefine.h"
#include "CesiumAsync/AsyncSystem.h"
#include "CesiumGltf/GltfReader.h"
#include <cstddef>
#include <glm/mat4x4.hpp>
Expand All @@ -27,7 +28,7 @@ class CESIUM3DTILESSELECTION_API GltfContent final : public TileContentLoader {
* The result will only contain the `model`. Other fields will be
* empty or have default values.
*/
std::unique_ptr<TileContentLoadResult>
CesiumAsync::Future<std::unique_ptr<TileContentLoadResult>>
load(const TileContentLoadInput& input) override;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "Cesium3DTilesSelection/TileContentLoader.h"
#include "Cesium3DTilesSelection/TileID.h"
#include "Cesium3DTilesSelection/TileRefine.h"
#include "CesiumAsync/AsyncSystem.h"

#include <gsl/span>
#include <spdlog/fwd.h>
Expand Down Expand Up @@ -97,7 +98,7 @@ class CESIUM3DTILESSELECTION_API TileContentFactory final {
* no loader registered for the magic header of the given
* input, and no loader for the content type of the input.
*/
static std::unique_ptr<TileContentLoadResult>
static CesiumAsync::Future<std::unique_ptr<TileContentLoadResult>>
createContent(const TileContentLoadInput& input);

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "Cesium3DTilesSelection/TileID.h"
#include "Cesium3DTilesSelection/TileRefine.h"
#include "Cesium3DTilesSelection/TilesetOptions.h"
#include "CesiumAsync/AsyncSystem.h"
#include "CesiumAsync/IAssetAccessor.h"
#include "CesiumAsync/IAssetRequest.h"

#include <gsl/span>
#include <spdlog/fwd.h>
Expand All @@ -29,46 +32,39 @@ struct CESIUM3DTILESSELECTION_API TileContentLoadInput {
/**
* @brief Creates a new, uninitialized instance for the given tile.
*
* The `data`, `contentType` and `url` will have default values,
* and have to be initialized before this instance is passed to
* one of the loader functions.
* The `asyncSystem`, `pLogger`, `pAssetAccessor` and `pRequest` will have
* default values, and have to be initialized before this instance is passed
* to one of the loader functions.
*
* @param pLogger The logger that will be used
* @param tile The {@link Tile} that the content belongs to
*/
TileContentLoadInput(
const std::shared_ptr<spdlog::logger> pLogger,
const Tile& tile);
TileContentLoadInput(const Tile& tile);

/**
* @brief Creates a new instance for the given tile.
* @brief Creates a new instance
*
* @param asyncSystem The async system to use for tile content loading.
* @param pLogger The logger that will be used
* @param data The actual data that the tile content will be created from
* @param contentType The content type, if the data was received via a
* network response
* @param url The URL that the data was loaded from
* @param tile The {@link Tile} that the content belongs to
* @param pAssetAccessor The asset accessor to make further requests with.
* @param pRequest The original tile request and its response.
* @param data The content data to use. The response data will be used
nithinp7 marked this conversation as resolved.
Show resolved Hide resolved
* instead if this is left as `std::nullopt`.
* @param tile The {@link Tile} that the content belongs to.
*/
TileContentLoadInput(
const std::shared_ptr<spdlog::logger> pLogger,
const gsl::span<const std::byte>& data,
const std::string& contentType,
const std::string& url,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<spdlog::logger>& pLogger,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumAsync::IAssetRequest>& pRequest,
const Tile& tile);

/**
* @brief Creates a new instance.
*
* For many types of tile content, only the `data` field is required. The
* other parameters are used for content that can generate child tiles, like
* external tilesets or composite tiles.
*
* @param asyncSystem The async system to use for tile content loading.
* @param pLogger The logger that will be used
* @param data The actual data that the tile content will be created from
* @param contentType The content type, if the data was received via a
* network response
* @param url The URL that the data was loaded from
* @param pAssetAccessor The asset accessor to make further requests with.
* @param pRequest The original tile request and its response.
* @param tileID The {@link TileID}
* @param tileBoundingVolume The tile {@link BoundingVolume}
* @param tileContentBoundingVolume The tile content {@link BoundingVolume}
Expand All @@ -77,10 +73,10 @@ struct CESIUM3DTILESSELECTION_API TileContentLoadInput {
* @param tileTransform The tile transform
*/
TileContentLoadInput(
const std::shared_ptr<spdlog::logger> pLogger,
const gsl::span<const std::byte>& data,
const std::string& contentType,
const std::string& url,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<spdlog::logger>& pLogger,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumAsync::IAssetRequest>& pRequest,
const TileID& tileID,
const BoundingVolume& tileBoundingVolume,
const std::optional<BoundingVolume>& tileContentBoundingVolume,
Expand All @@ -90,36 +86,24 @@ struct CESIUM3DTILESSELECTION_API TileContentLoadInput {
const TilesetContentOptions& contentOptions);

/**
* @brief The logger that receives details of loading errors and warnings.
* @brief The async system to use for tile content loading.
*/
std::shared_ptr<spdlog::logger> pLogger;
CesiumAsync::AsyncSystem asyncSystem;

/**
* @brief The raw input data.
*
* The {@link TileContentFactory} will try to determine the type of the
* data using the first four bytes (i.e. the "magic header"). If this
* does not succeed, it will try to determine the type based on the
* `contentType` field.
* @brief The logger that receives details of loading errors and warnings.
*/
gsl::span<const std::byte> data;
std::shared_ptr<spdlog::logger> pLogger;

/**
* @brief The content type.
*
* If the data was obtained via a HTTP response, then this will be
* the `Content-Type` of that response. The {@link TileContentFactory}
* will try to interpret the data based on this content type.
*
* If the data was not directly obtained from an HTTP response, then
* this may be the empty string.
* @brief The asset accessor to make further requests with.
*/
std::string contentType;
std::shared_ptr<CesiumAsync::IAssetAccessor> pAssetAccessor;

/**
* @brief The source URL.
* @brief The asset request and response data for the tile.
*/
std::string url;
std::shared_ptr<CesiumAsync::IAssetRequest> pRequest;

/**
* @brief The {@link TileID}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

#include "Cesium3DTilesSelection/TileContentLoadInput.h"
#include "Cesium3DTilesSelection/TileContentLoadResult.h"
#include "CesiumAsync/AsyncSystem.h"
#include "CesiumAsync/IAssetAccessor.h"
#include <string>
#include <utility>
#include <vector>

namespace Cesium3DTilesSelection {
/**
Expand All @@ -20,7 +25,7 @@ class CESIUM3DTILESSELECTION_API TileContentLoader {
* @return The {@link TileContentLoadResult}. This may be the `nullptr` if the
* tile content could not be loaded.
*/
virtual std::unique_ptr<TileContentLoadResult>
virtual CesiumAsync::Future<std::unique_ptr<TileContentLoadResult>>
load(const TileContentLoadInput& input) = 0;
};
} // namespace Cesium3DTilesSelection
8 changes: 6 additions & 2 deletions Cesium3DTilesSelection/src/Batched3DModelContent.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Batched3DModelContent.h"
#include "Cesium3DTilesSelection/GltfContent.h"
#include "Cesium3DTilesSelection/spdlog-cesium.h"
#include "CesiumAsync/IAssetResponse.h"
#include "CesiumGltf/ModelEXT_feature_metadata.h"
#include "CesiumUtility/Tracing.h"
#include "upgradeBatchTableToFeatureMetadata.h"
Expand Down Expand Up @@ -74,9 +75,12 @@ rapidjson::Document parseFeatureTableJsonData(

} // namespace

std::unique_ptr<TileContentLoadResult>
CesiumAsync::Future<std::unique_ptr<TileContentLoadResult>>
Batched3DModelContent::load(const TileContentLoadInput& input) {
return load(input.pLogger, input.url, input.data);
return input.asyncSystem.createResolvedFuture(load(
input.pLogger,
input.pRequest->url(),
input.pRequest->response()->data()));
}

std::unique_ptr<TileContentLoadResult> Batched3DModelContent::load(
Expand Down
2 changes: 1 addition & 1 deletion Cesium3DTilesSelection/src/Batched3DModelContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CESIUM3DTILESSELECTION_API Batched3DModelContent final
* The result will only contain the `model`. Other fields will be
* empty or have default values.
*/
std::unique_ptr<TileContentLoadResult>
CesiumAsync::Future<std::unique_ptr<TileContentLoadResult>>
load(const TileContentLoadInput& input) override;

/**
Expand Down
Loading