Make ActivatedRasterOverlay public and in CesiumRasterOverlays.

This commit is contained in:
Kevin Ring 2025-09-12 21:09:22 +10:00
parent 00e9d0691d
commit c792367f8f
22 changed files with 817 additions and 900 deletions

View File

@ -8,9 +8,12 @@
#include <memory>
namespace CesiumRasterOverlays {
class ActivatedRasterOverlay;
}
namespace Cesium3DTilesSelection {
class ActivatedRasterOverlay;
class Tile;
/**
@ -224,7 +227,7 @@ public:
*/
static RasterMappedTo3DTile* mapOverlayToTile(
double maximumScreenSpaceError,
Cesium3DTilesSelection::ActivatedRasterOverlay& activatedOverlay,
CesiumRasterOverlays::ActivatedRasterOverlay& activatedOverlay,
Tile& tile,
std::vector<CesiumGeospatial::Projection>& missingProjections,
const CesiumGeospatial::Ellipsoid& ellipsoid CESIUM_DEFAULT_ELLIPSOID);

View File

@ -14,9 +14,12 @@
#include <span>
#include <vector>
namespace CesiumRasterOverlays {
class ActivatedRasterOverlay;
}
namespace Cesium3DTilesSelection {
class ActivatedRasterOverlay;
class LoadedTileEnumerator;
struct TilesetOptions;
@ -166,30 +169,9 @@ public:
TileRasterOverlayStatus
updateTileOverlays(const TilesetOptions& tilesetOptions, Tile& tile);
/**
* @brief Gets the overlays in this collection.
*/
const std::vector<
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlay>>&
getOverlays() const;
/**
* @brief Gets the tile providers in this collection. Each tile provider
* corresponds with the overlay at the same position in the collection
* returned by {@link getOverlays}.
*/
const std::vector<CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>>&
getTileProviders() const;
/**
* @brief Gets the placeholder tile providers in this collection. Each
* placeholder tile provider corresponds with the overlay at the same position
* in the collection returned by {@link getOverlays}.
*/
const std::vector<CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>>&
getPlaceholderTileProviders() const;
CesiumRasterOverlays::ActivatedRasterOverlay>>&
getActivatedOverlays() const;
/**
* @brief Finds the tile provider for a given overlay.
@ -261,7 +243,7 @@ public:
size_t size() const noexcept;
private:
ActivatedRasterOverlay*
CesiumRasterOverlays::ActivatedRasterOverlay*
findActivatedForOverlay(const CesiumRasterOverlays::RasterOverlay& overlay);
struct OverlayList;

View File

@ -1,161 +0,0 @@
#include "ActivatedRasterOverlay.h"
#include "EmptyRasterOverlayTileProvider.h"
#include <Cesium3DTilesSelection/LoadedTileEnumerator.h>
#include <Cesium3DTilesSelection/Tile.h>
#include <CesiumGeometry/Rectangle.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayExternals.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <glm/vec2.hpp>
#include <spdlog/spdlog.h>
using namespace CesiumGeometry;
using namespace CesiumGeospatial;
using namespace CesiumRasterOverlays;
using namespace CesiumUtility;
namespace Cesium3DTilesSelection {
ActivatedRasterOverlay::ActivatedRasterOverlay(
const RasterOverlayExternals& externals,
const IntrusivePointer<RasterOverlay>& pOverlay,
const LoadedTileEnumerator& loadedTiles,
const Ellipsoid& ellipsoid)
: _pOverlay(pOverlay),
_pPlaceholderTileProvider(
pOverlay->createPlaceholder(externals, ellipsoid)),
_pPlaceholderTile(nullptr),
_pTileProvider(nullptr),
_tileDataBytes(0),
_totalTilesCurrentlyLoading(0),
_throttledTilesCurrentlyLoading(0) {
this->_pPlaceholderTile = new RasterOverlayTile(
*this->_pPlaceholderTileProvider,
glm::dvec2(0.0),
Rectangle());
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> future =
pOverlay->createTileProvider(
externals.asyncSystem,
externals.pAssetAccessor,
externals.pCreditSystem,
externals.pPrepareRendererResources,
externals.pLogger,
nullptr);
// Add a placeholder for this overlay to existing geometry tiles.
for (Tile& tile : loadedTiles) {
// The tile rectangle and geometric error don't matter for a placeholder.
// - When a tile is transitioned from Unloaded (or FailedTemporarily) to
// ContentLoading, raster overlay tiles will be mapped to the tile
// automatically by TilesetContentManager, so we don't need to map the
// raster tiles to this unloaded or unloading tile now.
// - When a tile is already failed to load, there is no need to map the
// raster tiles to the tile as it is not rendered any way
TileLoadState tileState = tile.getState();
if (tileState == TileLoadState::ContentLoading ||
tileState == TileLoadState::ContentLoaded ||
tileState == TileLoadState::Done) {
// Only tiles with renderable content should have raster overlays
// attached. In the ContentLoading state, we won't know yet whether the
// content is renderable, so assume that it is for now and
// `setTileContent` will clear them out if necessary.
if (tile.getContent().isRenderContent() ||
tileState == TileLoadState::ContentLoading) {
tile.getMappedRasterTiles().emplace_back(this->_pPlaceholderTile, -1);
}
}
}
// This continuation, by capturing thiz, keeps the instance from being
// destroyed. But it does not keep the RasterOverlayCollection itself alive.
IntrusivePointer<ActivatedRasterOverlay> thiz = this;
// TODO: dangerous to do this in the constructor, because no one else can
// possibly have a reference to it yet.
std::move(future)
.catchInMainThread(
[](const std::exception& e)
-> RasterOverlay::CreateTileProviderResult {
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::Unknown,
nullptr,
fmt::format(
"Error while creating tile provider: {0}",
e.what())});
})
.thenInMainThread([pOverlay, thiz, externals](
RasterOverlay::CreateTileProviderResult&& result) {
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
if (result) {
pProvider = *result;
} else {
// Report error creating the tile provider.
const RasterOverlayLoadFailureDetails& failureDetails =
result.error();
SPDLOG_LOGGER_ERROR(externals.pLogger, failureDetails.message);
if (pOverlay->getOptions().loadErrorCallback) {
pOverlay->getOptions().loadErrorCallback(failureDetails);
}
// Create a tile provider that does not provide any tiles at all.
pProvider = new EmptyRasterOverlayTileProvider(
pOverlay,
externals.asyncSystem);
}
thiz->_pTileProvider = pProvider;
});
}
ActivatedRasterOverlay::~ActivatedRasterOverlay() = default;
const RasterOverlay* ActivatedRasterOverlay::getOverlay() const noexcept {
return this->_pOverlay;
}
RasterOverlay* ActivatedRasterOverlay::getOverlay() noexcept {
return this->_pOverlay;
}
const CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getTileProvider() const noexcept {
return this->_pTileProvider;
}
CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getTileProvider() noexcept {
return this->_pTileProvider;
}
const CesiumRasterOverlays::RasterOverlayTile*
ActivatedRasterOverlay::getPlaceholderTile() const noexcept {
return this->_pPlaceholderTile;
}
CesiumRasterOverlays::RasterOverlayTile*
ActivatedRasterOverlay::getPlaceholderTile() noexcept {
return this->_pPlaceholderTile;
}
IntrusivePointer<RasterOverlayTile> ActivatedRasterOverlay::getTile(
const CesiumGeometry::Rectangle& rectangle,
const glm::dvec2& targetScreenPixels) {
if (this->_pTileProvider == nullptr) {
return this->_pPlaceholderTile;
}
if (!rectangle.overlaps(this->_pTileProvider->getCoverageRectangle())) {
return nullptr;
}
return new RasterOverlayTile(
*this->_pTileProvider,
targetScreenPixels,
rectangle);
}
} // namespace Cesium3DTilesSelection

View File

@ -1,90 +0,0 @@
#pragma once
#include <CesiumGeometry/Rectangle.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/ReferenceCounted.h>
#include <glm/vec2.hpp>
namespace CesiumRasterOverlays {
class RasterOverlay;
class RasterOverlayExternals;
class RasterOverlayTile;
class RasterOverlayTileProvider;
} // namespace CesiumRasterOverlays
namespace Cesium3DTilesSelection {
class LoadedTileEnumerator;
class ActivatedRasterOverlay
: public CesiumUtility::ReferenceCountedNonThreadSafe<
ActivatedRasterOverlay> {
public:
ActivatedRasterOverlay(
const CesiumRasterOverlays::RasterOverlayExternals& externals,
const CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>& pOverlay,
const LoadedTileEnumerator& loadedTiles,
const CesiumGeospatial::Ellipsoid& ellipsoid);
~ActivatedRasterOverlay();
const CesiumRasterOverlays::RasterOverlay* getOverlay() const noexcept;
CesiumRasterOverlays::RasterOverlay* getOverlay() noexcept;
const CesiumRasterOverlays::RasterOverlayTileProvider*
getTileProvider() const noexcept;
CesiumRasterOverlays::RasterOverlayTileProvider* getTileProvider() noexcept;
const CesiumRasterOverlays::RasterOverlayTile*
getPlaceholderTile() const noexcept;
CesiumRasterOverlays::RasterOverlayTile* getPlaceholderTile() noexcept;
/**
* @brief Returns a new {@link RasterOverlayTile} with the given
* specifications.
*
* The returned tile will not start loading immediately. To start loading,
* call {@link RasterOverlayTileProvider::loadTile} or
* {@link RasterOverlayTileProvider::loadTileThrottled}.
*
* @param rectangle The rectangle that the returned image must cover. It is
* allowed to cover a slightly larger rectangle in order to maintain pixel
* alignment. It may also cover a smaller rectangle when the overlay itself
* does not cover the entire rectangle.
* @param targetScreenPixels The maximum number of pixels on the screen that
* this tile is meant to cover. The overlay image should be approximately this
* many pixels divided by the
* {@link RasterOverlayOptions::maximumScreenSpaceError} in order to achieve
* the desired level-of-detail, but it does not need to be exactly this size.
* @return The tile.
*/
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlayTile>
getTile(
const CesiumGeometry::Rectangle& rectangle,
const glm::dvec2& targetScreenPixels);
private:
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlay>
_pOverlay;
CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>
_pPlaceholderTileProvider;
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlayTile>
_pPlaceholderTile;
CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>
_pTileProvider;
int64_t _tileDataBytes;
int32_t _totalTilesCurrentlyLoading;
int32_t _throttledTilesCurrentlyLoading;
};
} // namespace Cesium3DTilesSelection

View File

@ -1,5 +1,3 @@
#include "ActivatedRasterOverlay.h"
#include <Cesium3DTilesSelection/BoundingVolume.h>
#include <Cesium3DTilesSelection/IPrepareRendererResources.h>
#include <Cesium3DTilesSelection/RasterMappedTo3DTile.h>
@ -9,6 +7,7 @@
#include <CesiumGeospatial/BoundingRegion.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlayUtilities.h>
@ -248,8 +247,8 @@ bool RasterMappedTo3DTile::loadThrottled() noexcept {
return true;
}
RasterOverlayTileProvider& provider = pLoading->getTileProvider();
return provider.loadTileThrottled(*pLoading);
ActivatedRasterOverlay& activated = pLoading->getActivatedOverlay();
return activated.loadTileThrottled(*pLoading);
}
namespace {
@ -303,7 +302,7 @@ RasterMappedTo3DTile* addRealTile(
/*static*/ RasterMappedTo3DTile* RasterMappedTo3DTile::mapOverlayToTile(
double maximumScreenSpaceError,
Cesium3DTilesSelection::ActivatedRasterOverlay& activatedOverlay,
ActivatedRasterOverlay& activatedOverlay,
Tile& tile,
std::vector<Projection>& missingProjections,
const CesiumGeospatial::Ellipsoid& ellipsoid) {

View File

@ -1,6 +1,3 @@
#include "ActivatedRasterOverlay.h"
#include "EmptyRasterOverlayTileProvider.h"
#include <Cesium3DTilesSelection/LoadedTileEnumerator.h>
#include <Cesium3DTilesSelection/RasterMappedTo3DTile.h>
#include <Cesium3DTilesSelection/RasterOverlayCollection.h>
@ -9,6 +6,7 @@
#include <Cesium3DTilesSelection/TilesetOptions.h>
#include <CesiumAsync/Future.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
@ -54,15 +52,7 @@ const std::vector<CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>>
// externally and may become invalid before the async operations complete.
struct RasterOverlayCollection::OverlayList
: public CesiumUtility::ReferenceCountedNonThreadSafe<OverlayList> {
std::vector<
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlay>>
overlays{};
std::vector<CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>>
tileProviders{};
std::vector<CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>>
placeholders{};
std::vector<CesiumUtility::IntrusivePointer<RasterOverlay>> overlays{};
std::vector<CesiumUtility::IntrusivePointer<ActivatedRasterOverlay>>
activatedOverlays{};
@ -75,15 +65,17 @@ RasterOverlayCollection::RasterOverlayCollection(
: _loadedTiles(loadedTiles),
_externals{externals},
_ellipsoid(ellipsoid),
_pOverlays(nullptr) {}
_pOverlays(new OverlayList()) {}
RasterOverlayCollection::~RasterOverlayCollection() noexcept {
if (this->_pOverlays) {
OverlayList& list = *this->_pOverlays;
if (!list.overlays.empty()) {
for (int64_t i = static_cast<int64_t>(list.overlays.size() - 1); i >= 0;
if (!list.activatedOverlays.empty()) {
for (int64_t i = static_cast<int64_t>(list.activatedOverlays.size() - 1);
i >= 0;
--i) {
this->remove(list.overlays[static_cast<size_t>(i)].get());
this->remove(
list.activatedOverlays[static_cast<size_t>(i)]->getOverlay());
}
}
}
@ -96,14 +88,9 @@ void RasterOverlayCollection::setLoadedTileEnumerator(
void RasterOverlayCollection::add(
const CesiumUtility::IntrusivePointer<RasterOverlay>& pOverlay) {
// CESIUM_TRACE_USE_TRACK_SET(this->_loadingSlots);
if (!this->_pOverlays)
this->_pOverlays = new OverlayList();
IntrusivePointer<OverlayList> pList = this->_pOverlays;
// IntrusivePointer<ActivatedRasterOverlay>& pActivated =
pList->overlays.push_back(pOverlay);
pList->activatedOverlays.emplace_back(new ActivatedRasterOverlay(
RasterOverlayExternals{
.pAssetAccessor = this->_externals.pAssetAccessor,
@ -113,8 +100,34 @@ void RasterOverlayCollection::add(
.pCreditSystem = this->_externals.pCreditSystem,
.pLogger = this->_externals.pLogger},
pOverlay,
this->_loadedTiles,
this->_ellipsoid));
CesiumRasterOverlays::RasterOverlayTile* pPlaceholderTile =
pList->activatedOverlays.back()->getPlaceholderTile();
// Add a placeholder for this overlay to existing geometry tiles.
for (Tile& tile : this->_loadedTiles) {
// The tile rectangle and geometric error don't matter for a placeholder.
// - When a tile is transitioned from Unloaded (or FailedTemporarily) to
// ContentLoading, raster overlay tiles will be mapped to the tile
// automatically by TilesetContentManager, so we don't need to map the
// raster tiles to this unloaded or unloading tile now.
// - When a tile is already failed to load, there is no need to map the
// raster tiles to the tile as it is not rendered any way
TileLoadState tileState = tile.getState();
if (tileState == TileLoadState::ContentLoading ||
tileState == TileLoadState::ContentLoaded ||
tileState == TileLoadState::Done) {
// Only tiles with renderable content should have raster overlays
// attached. In the ContentLoading state, we won't know yet whether the
// content is renderable, so assume that it is for now and
// `setTileContent` will clear them out if necessary.
if (tile.getContent().isRenderContent() ||
tileState == TileLoadState::ContentLoading) {
tile.getMappedRasterTiles().emplace_back(pPlaceholderTile, -1);
}
}
}
}
void RasterOverlayCollection::remove(
@ -151,23 +164,20 @@ void RasterOverlayCollection::remove(
OverlayList& list = *this->_pOverlays;
CESIUM_ASSERT(list.overlays.size() == list.tileProviders.size());
CESIUM_ASSERT(list.overlays.size() == list.placeholders.size());
auto it = std::find_if(
list.overlays.begin(),
list.overlays.end(),
[pOverlay](const IntrusivePointer<RasterOverlay>& pCheck) noexcept {
return pCheck == pOverlay;
list.activatedOverlays.begin(),
list.activatedOverlays.end(),
[pOverlay](
const IntrusivePointer<ActivatedRasterOverlay>& pCheck) noexcept {
return pCheck->getOverlay() == pOverlay;
});
if (it == list.overlays.end()) {
if (it == list.activatedOverlays.end()) {
return;
}
int64_t index = it - list.overlays.begin();
int64_t index = it - list.activatedOverlays.begin();
list.activatedOverlays.erase(list.activatedOverlays.begin() + index);
list.overlays.erase(list.overlays.begin() + index);
list.tileProviders.erase(list.tileProviders.begin() + index);
list.placeholders.erase(list.placeholders.begin() + index);
}
std::vector<CesiumGeospatial::Projection>
@ -267,33 +277,10 @@ TileRasterOverlayStatus RasterOverlayCollection::updateTileOverlays(
return result;
}
const std::vector<CesiumUtility::IntrusivePointer<RasterOverlay>>&
RasterOverlayCollection::getOverlays() const {
if (!this->_pOverlays)
return emptyOverlays;
return this->_pOverlays->overlays;
}
/**
* @brief Gets the tile providers in this collection. Each tile provider
* corresponds with the overlay at the same position in the collection
* returned by {@link getOverlays}.
*/
const std::vector<CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>>&
RasterOverlayCollection::getTileProviders() const {
if (!this->_pOverlays)
return emptyTileProviders;
return this->_pOverlays->tileProviders;
}
const std::vector<CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>>&
RasterOverlayCollection::getPlaceholderTileProviders() const {
if (!this->_pOverlays)
return emptyTileProviders;
return this->_pOverlays->placeholders;
const std::vector<CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::ActivatedRasterOverlay>>&
RasterOverlayCollection::getActivatedOverlays() const {
return this->_pOverlays->activatedOverlays;
}
RasterOverlayTileProvider* RasterOverlayCollection::findTileProviderForOverlay(
@ -307,20 +294,17 @@ RasterOverlayTileProvider* RasterOverlayCollection::findTileProviderForOverlay(
const RasterOverlayTileProvider*
RasterOverlayCollection::findTileProviderForOverlay(
const RasterOverlay& overlay) const noexcept {
if (!this->_pOverlays)
return nullptr;
auto it = std::find_if(
this->_pOverlays->activatedOverlays.begin(),
this->_pOverlays->activatedOverlays.end(),
[&overlay](
const IntrusivePointer<ActivatedRasterOverlay>& pCheck) noexcept {
return pCheck->getOverlay() == &overlay;
});
const auto& overlays = this->_pOverlays->overlays;
const auto& tileProviders = this->_pOverlays->tileProviders;
CESIUM_ASSERT(overlays.size() == tileProviders.size());
for (size_t i = 0; i < overlays.size() && i < tileProviders.size(); ++i) {
if (overlays[i].get() == &overlay)
return tileProviders[i].get();
}
return nullptr;
return it == this->_pOverlays->activatedOverlays.end()
? nullptr
: (*it)->getTileProvider();
}
RasterOverlayTileProvider*
@ -336,35 +320,26 @@ RasterOverlayCollection::findPlaceholderTileProviderForOverlay(
const RasterOverlayTileProvider*
RasterOverlayCollection::findPlaceholderTileProviderForOverlay(
const RasterOverlay& overlay) const noexcept {
if (!this->_pOverlays)
return nullptr;
auto it = std::find_if(
this->_pOverlays->activatedOverlays.begin(),
this->_pOverlays->activatedOverlays.end(),
[&overlay](
const IntrusivePointer<ActivatedRasterOverlay>& pCheck) noexcept {
return pCheck->getOverlay() == &overlay;
});
const auto& overlays = this->_pOverlays->overlays;
const auto& placeholders = this->_pOverlays->placeholders;
CESIUM_ASSERT(overlays.size() == placeholders.size());
for (size_t i = 0; i < overlays.size() && i < placeholders.size(); ++i) {
if (overlays[i].get() == &overlay)
return placeholders[i].get();
}
return nullptr;
return it == this->_pOverlays->activatedOverlays.end()
? nullptr
: (*it)->getPlaceholderTileProvider();
}
RasterOverlayCollection::const_iterator
RasterOverlayCollection::begin() const noexcept {
if (!this->_pOverlays)
return emptyOverlays.begin();
return this->_pOverlays->overlays.begin();
}
RasterOverlayCollection::const_iterator
RasterOverlayCollection::end() const noexcept {
if (!this->_pOverlays)
return emptyOverlays.end();
return this->_pOverlays->overlays.end();
}
@ -372,7 +347,7 @@ size_t RasterOverlayCollection::size() const noexcept {
if (!this->_pOverlays)
return 0;
return this->_pOverlays->overlays.size();
return this->_pOverlays->activatedOverlays.size();
}
ActivatedRasterOverlay*

View File

@ -38,6 +38,7 @@
#include <CesiumGltf/Image.h>
#include <CesiumGltfContent/GltfUtilities.h>
#include <CesiumGltfReader/GltfReader.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
@ -1278,9 +1279,9 @@ void TilesetContentManager::waitUntilIdle() {
this->_externals.asyncSystem.dispatchMainThreadTasks();
rasterOverlayTilesLoading = 0;
for (const auto& pTileProvider :
this->_overlayCollection.getTileProviders()) {
rasterOverlayTilesLoading += pTileProvider->getNumberOfTilesLoading();
for (const auto& pActivated :
this->_overlayCollection.getActivatedOverlays()) {
rasterOverlayTilesLoading += pActivated->getNumberOfTilesLoading();
}
}
}
@ -1341,9 +1342,9 @@ int32_t TilesetContentManager::getNumberOfTilesLoaded() const noexcept {
int64_t TilesetContentManager::getTotalDataUsed() const noexcept {
int64_t bytes = this->_tilesDataUsed;
for (const auto& pTileProvider :
this->_overlayCollection.getTileProviders()) {
bytes += pTileProvider->getTileDataBytes();
for (const auto& pActivated :
this->_overlayCollection.getActivatedOverlays()) {
bytes += pActivated->getTileDataBytes();
}
return bytes;

View File

@ -7,6 +7,7 @@
#include <Cesium3DTilesSelection/TilesetFrameState.h>
#include <Cesium3DTilesSelection/TilesetViewGroup.h>
#include <Cesium3DTilesSelection/ViewUpdateResult.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumUtility/Assert.h>
@ -180,8 +181,12 @@ void TilesetViewGroup::finishFrame(
// per-raster overlay credit
const RasterOverlayCollection& overlayCollection = tileset.getOverlays();
for (auto& pTileProvider : overlayCollection.getTileProviders()) {
const std::optional<Credit>& overlayCredit = pTileProvider->getCredit();
for (auto& pActivated : overlayCollection.getActivatedOverlays()) {
if (pActivated->getTileProvider() == nullptr)
continue;
const std::optional<Credit>& overlayCredit =
pActivated->getTileProvider()->getCredit();
if (overlayCredit) {
this->_currentFrameCredits.addCreditReference(overlayCredit.value());
}

View File

@ -0,0 +1,185 @@
#pragma once
#include <CesiumAsync/Future.h>
#include <CesiumAsync/SharedFuture.h>
#include <CesiumGeometry/Rectangle.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/ReferenceCounted.h>
#include <glm/vec2.hpp>
namespace CesiumRasterOverlays {
class RasterOverlay;
class RasterOverlayExternals;
class RasterOverlayTile;
class RasterOverlayTileProvider;
struct TileProviderAndTile;
} // namespace CesiumRasterOverlays
namespace CesiumRasterOverlays {
class ActivatedRasterOverlay
: public CesiumUtility::ReferenceCountedNonThreadSafe<
ActivatedRasterOverlay> {
public:
ActivatedRasterOverlay(
const CesiumRasterOverlays::RasterOverlayExternals& externals,
const CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>& pOverlay,
const CesiumGeospatial::Ellipsoid& ellipsoid);
~ActivatedRasterOverlay();
CesiumAsync::SharedFuture<void>& getReadyEvent();
const CesiumRasterOverlays::RasterOverlay* getOverlay() const noexcept;
CesiumRasterOverlays::RasterOverlay* getOverlay() noexcept;
const CesiumRasterOverlays::RasterOverlayTileProvider*
getTileProvider() const noexcept;
CesiumRasterOverlays::RasterOverlayTileProvider* getTileProvider() noexcept;
const CesiumRasterOverlays::RasterOverlayTileProvider*
getPlaceholderTileProvider() const noexcept;
CesiumRasterOverlays::RasterOverlayTileProvider*
getPlaceholderTileProvider() noexcept;
const CesiumRasterOverlays::RasterOverlayTile*
getPlaceholderTile() const noexcept;
CesiumRasterOverlays::RasterOverlayTile* getPlaceholderTile() noexcept;
/**
* @brief Returns a new {@link RasterOverlayTile} with the given
* specifications.
*
* The returned tile will not start loading immediately. To start loading,
* call {@link RasterOverlayTileProvider::loadTile} or
* {@link RasterOverlayTileProvider::loadTileThrottled}.
*
* @param rectangle The rectangle that the returned image must cover. It is
* allowed to cover a slightly larger rectangle in order to maintain pixel
* alignment. It may also cover a smaller rectangle when the overlay itself
* does not cover the entire rectangle.
* @param targetScreenPixels The maximum number of pixels on the screen that
* this tile is meant to cover. The overlay image should be approximately this
* many pixels divided by the
* {@link RasterOverlayOptions::maximumScreenSpaceError} in order to achieve
* the desired level-of-detail, but it does not need to be exactly this size.
* @return The tile.
*/
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlayTile>
getTile(
const CesiumGeometry::Rectangle& rectangle,
const glm::dvec2& targetScreenPixels);
/**
* @brief Gets the number of bytes of tile data that are currently loaded.
*/
int64_t getTileDataBytes() const noexcept;
/**
* @brief Returns the number of tiles that are currently loading.
*/
uint32_t getNumberOfTilesLoading() const noexcept;
/**
* @brief Removes a no-longer-referenced tile from this provider's cache and
* deletes it.
*
* This function is not supposed to be called by client. Calling this method
* in a tile with a reference count greater than 0 will result in undefined
* behavior.
*
* @param pTile The tile, which must have no oustanding references.
*/
void removeTile(RasterOverlayTile* pTile) noexcept;
/**
* @brief Loads a tile immediately, without throttling requests.
*
* If the tile is not in the `Tile::LoadState::Unloaded` state, this method
* returns without doing anything. Otherwise, it puts the tile into the
* `Tile::LoadState::Loading` state and begins the asynchronous process
* to load the tile. When the process completes, the tile will be in the
* `Tile::LoadState::Loaded` or `Tile::LoadState::Failed` state.
*
* Calling this method on many tiles at once can result in very slow
* performance. Consider using {@link loadTileThrottled} instead.
*
* @param tile The tile to load.
* @return A future that, when the tile is loaded, resolves to the loaded tile
* and the tile provider that loaded it.
*/
CesiumAsync::Future<TileProviderAndTile> loadTile(RasterOverlayTile& tile);
/**
* @brief Loads a tile, unless there are too many tile loads already in
* progress.
*
* If the tile is not in the `Tile::LoadState::Unloading` state, this method
* returns true without doing anything. If too many tile loads are
* already in flight, it returns false without doing anything. Otherwise, it
* puts the tile into the `Tile::LoadState::Loading` state, begins the
* asynchronous process to load the tile, and returns true. When the process
* completes, the tile will be in the `Tile::LoadState::Loaded` or
* `Tile::LoadState::Failed` state.
*
* The number of allowable simultaneous tile requests is provided in the
* {@link RasterOverlayOptions::maximumSimultaneousTileLoads} property of
* {@link RasterOverlay::getOptions}.
*
* @param tile The tile to load.
* @returns True if the tile load process is started or is already complete,
* false if the load could not be started because too many loads are already
* in progress.
*/
bool loadTileThrottled(RasterOverlayTile& tile);
private:
CesiumAsync::Future<TileProviderAndTile>
doLoad(RasterOverlayTile& tile, bool isThrottledLoad);
/**
* @brief Begins the process of loading of a tile.
*
* This method should be called at the beginning of the tile load process.
*
* @param isThrottledLoad True if the load was originally throttled.
*/
void beginTileLoad(bool isThrottledLoad) noexcept;
/**
* @brief Finalizes loading of a tile.
*
* This method should be called at the end of the tile load process,
* no matter whether the load succeeded or failed.
*
* @param isThrottledLoad True if the load was originally throttled.
*/
void finalizeTileLoad(bool isThrottledLoad) noexcept;
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlay>
_pOverlay;
CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>
_pPlaceholderTileProvider;
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlayTile>
_pPlaceholderTile;
CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>
_pTileProvider;
int64_t _tileDataBytes;
int32_t _totalTilesCurrentlyLoading;
int32_t _throttledTilesCurrentlyLoading;
CesiumAsync::SharedFuture<void> _readyEvent;
};
} // namespace CesiumRasterOverlays

View File

@ -15,6 +15,7 @@ struct Credit;
namespace CesiumRasterOverlays {
class ActivatedRasterOverlay;
class RasterOverlay;
class RasterOverlayTileProvider;
@ -99,7 +100,7 @@ public:
* _must_ remain valid for the entire lifetime of the tile. If the tile
* provider is destroyed before the tile, undefined behavior will result.
*/
RasterOverlayTile(RasterOverlayTileProvider& tileProvider) noexcept;
RasterOverlayTile(ActivatedRasterOverlay& activatedOverlay) noexcept;
/**
* @brief Creates a new instance.
@ -122,26 +123,26 @@ public:
* itself does not cover the entire rectangle.
*/
RasterOverlayTile(
RasterOverlayTileProvider& tileProvider,
ActivatedRasterOverlay& activatedOverlay,
const glm::dvec2& targetScreenPixels,
const CesiumGeometry::Rectangle& imageryRectangle) noexcept;
/** @brief Default destructor. */
~RasterOverlayTile();
/**
* @brief Returns the {@link RasterOverlayTileProvider} that created this instance.
*/
RasterOverlayTileProvider& getTileProvider() noexcept {
return *this->_pTileProvider;
}
ActivatedRasterOverlay& getActivatedOverlay() noexcept;
const ActivatedRasterOverlay& getActivatedOverlay() const noexcept;
/**
* @brief Returns the {@link RasterOverlayTileProvider} that created this instance.
*/
const RasterOverlayTileProvider& getTileProvider() const noexcept {
return *this->_pTileProvider;
}
RasterOverlayTileProvider& getTileProvider() noexcept;
/**
* @brief Returns the {@link RasterOverlayTileProvider} that created this instance.
*/
const RasterOverlayTileProvider& getTileProvider() const noexcept;
/**
* @brief Returns the {@link RasterOverlay} that created this instance.
@ -245,17 +246,24 @@ public:
return this->_moreDetailAvailable;
}
private:
friend class RasterOverlayTileProvider;
/**
* @brief Sets the load state of this tile.
*
* This function is not supposed to be called by clients.
*
* @private
*/
void setState(LoadState newState) noexcept;
private:
friend class ActivatedRasterOverlay;
// This is a raw pointer instead of an IntrusivePointer in order to avoid
// circular references, particularly among a placeholder tile provider and
// placeholder tile. However, to avoid undefined behavior, the tile provider
// is required to outlive the tile. In normal use, the RasterOverlayCollection
// ensures that this is true.
RasterOverlayTileProvider* _pTileProvider;
ActivatedRasterOverlay* _pActivatedOverlay;
glm::dvec2 _targetScreenPixels;
CesiumGeometry::Rectangle _rectangle;
std::vector<CesiumUtility::Credit> _tileCredits;

View File

@ -147,21 +147,6 @@ class CESIUMRASTEROVERLAYS_API RasterOverlayTileProvider
: public CesiumUtility::ReferenceCountedNonThreadSafe<
RasterOverlayTileProvider> {
public:
/**
* Constructs a placeholder tile provider.
*
* @see RasterOverlayTileProvider::isPlaceholder
*
* @param pOwner The raster overlay that created this tile provider.
* @param externals The external interfaces for use by the raster overlay.
* @param ellipsoid The {@link CesiumGeospatial::Ellipsoid}.
*/
RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const RasterOverlayExternals& externals,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) noexcept;
/**
* @brief Creates a new instance.
*
@ -179,19 +164,6 @@ public:
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::Rectangle& coverageRectangle) noexcept;
/**
* Constructs a placeholder tile provider.
* @deprecated Use the overload that takes a \ref RasterOverlayExternals
* instead.
*/
RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) noexcept;
/**
* @brief Creates a new instance.
* @deprecated Use the overload that takes a \ref RasterOverlayExternals
@ -268,75 +240,11 @@ public:
*/
const CesiumGeometry::Rectangle& getCoverageRectangle() const noexcept;
/**
* @brief Gets the number of bytes of tile data that are currently loaded.
*/
int64_t getTileDataBytes() const noexcept;
/**
* @brief Returns the number of tiles that are currently loading.
*/
uint32_t getNumberOfTilesLoading() const noexcept;
/**
* @brief Removes a no-longer-referenced tile from this provider's cache and
* deletes it.
*
* This function is not supposed to be called by client. Calling this method
* in a tile with a reference count greater than 0 will result in undefined
* behavior.
*
* @param pTile The tile, which must have no oustanding references.
*/
void removeTile(RasterOverlayTile* pTile) noexcept;
/**
* @brief Get the per-TileProvider {@link CesiumUtility::Credit} if one exists.
*/
const std::optional<CesiumUtility::Credit>& getCredit() const noexcept;
/**
* @brief Loads a tile immediately, without throttling requests.
*
* If the tile is not in the `Tile::LoadState::Unloaded` state, this method
* returns without doing anything. Otherwise, it puts the tile into the
* `Tile::LoadState::Loading` state and begins the asynchronous process
* to load the tile. When the process completes, the tile will be in the
* `Tile::LoadState::Loaded` or `Tile::LoadState::Failed` state.
*
* Calling this method on many tiles at once can result in very slow
* performance. Consider using {@link loadTileThrottled} instead.
*
* @param tile The tile to load.
* @return A future that, when the tile is loaded, resolves to the loaded tile
* and the tile provider that loaded it.
*/
CesiumAsync::Future<TileProviderAndTile> loadTile(RasterOverlayTile& tile);
/**
* @brief Loads a tile, unless there are too many tile loads already in
* progress.
*
* If the tile is not in the `Tile::LoadState::Unloading` state, this method
* returns true without doing anything. If too many tile loads are
* already in flight, it returns false without doing anything. Otherwise, it
* puts the tile into the `Tile::LoadState::Loading` state, begins the
* asynchronous process to load the tile, and returns true. When the process
* completes, the tile will be in the `Tile::LoadState::Loaded` or
* `Tile::LoadState::Failed` state.
*
* The number of allowable simultaneous tile requests is provided in the
* {@link RasterOverlayOptions::maximumSimultaneousTileLoads} property of
* {@link RasterOverlay::getOptions}.
*
* @param tile The tile to load.
* @returns True if the tile load process is started or is already complete,
* false if the load could not be started because too many loads are already
* in progress.
*/
bool loadTileThrottled(RasterOverlayTile& tile);
protected:
/**
* @brief Loads the image for a tile.
*
@ -346,6 +254,7 @@ protected:
virtual CesiumAsync::Future<LoadedRasterOverlayImage>
loadTileImage(const RasterOverlayTile& overlayTile) = 0;
protected:
/**
* @brief Loads an image from a URL and optionally some request headers.
*
@ -361,29 +270,6 @@ protected:
const std::vector<CesiumAsync::IAssetAccessor::THeader>& headers = {},
LoadTileImageFromUrlOptions&& options = {}) const;
private:
CesiumAsync::Future<TileProviderAndTile>
doLoad(RasterOverlayTile& tile, bool isThrottledLoad);
/**
* @brief Begins the process of loading of a tile.
*
* This method should be called at the beginning of the tile load process.
*
* @param isThrottledLoad True if the load was originally throttled.
*/
void beginTileLoad(bool isThrottledLoad) noexcept;
/**
* @brief Finalizes loading of a tile.
*
* This method should be called at the end of the tile load process,
* no matter whether the load succeeded or failed.
*
* @param isThrottledLoad True if the load was originally throttled.
*/
void finalizeTileLoad(bool isThrottledLoad) noexcept;
private:
struct DestructionCompleteDetails {
CesiumAsync::Promise<void> promise;
@ -395,13 +281,6 @@ private:
std::optional<CesiumUtility::Credit> _credit;
CesiumGeospatial::Projection _projection;
CesiumGeometry::Rectangle _coverageRectangle;
CesiumUtility::IntrusivePointer<RasterOverlayTile> _pPlaceholder;
int64_t _tileDataBytes;
int32_t _totalTilesCurrentlyLoading;
int32_t _throttledTilesCurrentlyLoading;
std::optional<DestructionCompleteDetails> _destructionCompleteDetails;
CESIUM_TRACE_DECLARE_TRACK_SET(
_loadingSlots,
"Raster Overlay Tile Loading Slot")
};
} // namespace CesiumRasterOverlays

View File

@ -0,0 +1,383 @@
#include "EmptyRasterOverlayTileProvider.h"
#include <CesiumGeometry/Rectangle.h>
#include <CesiumGltf/ImageAsset.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayExternals.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <glm/vec2.hpp>
#include <spdlog/spdlog.h>
using namespace CesiumGeometry;
using namespace CesiumGeospatial;
using namespace CesiumGltf;
using namespace CesiumUtility;
namespace CesiumRasterOverlays {
ActivatedRasterOverlay::ActivatedRasterOverlay(
const RasterOverlayExternals& externals,
const IntrusivePointer<RasterOverlay>& pOverlay,
const Ellipsoid& ellipsoid)
: _pOverlay(pOverlay),
_pPlaceholderTileProvider(
pOverlay->createPlaceholder(externals, ellipsoid)),
_pPlaceholderTile(nullptr),
_pTileProvider(nullptr),
_tileDataBytes(0),
_totalTilesCurrentlyLoading(0),
_throttledTilesCurrentlyLoading(0),
_readyEvent(externals.asyncSystem.createResolvedFuture().share()) {
this->_pPlaceholderTile =
new RasterOverlayTile(*this, glm::dvec2(0.0), Rectangle());
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> future =
pOverlay->createTileProvider(
externals.asyncSystem,
externals.pAssetAccessor,
externals.pCreditSystem,
externals.pPrepareRendererResources,
externals.pLogger,
nullptr);
// This continuation, by capturing thiz, keeps the instance from being
// destroyed. But it does not keep the RasterOverlayCollection itself alive.
IntrusivePointer<ActivatedRasterOverlay> thiz = this;
// TODO: dangerous to do this in the constructor, because no one else can
// possibly have a reference to it yet.
this->_readyEvent =
std::move(future)
.catchInMainThread(
[](const std::exception& e)
-> RasterOverlay::CreateTileProviderResult {
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::Unknown,
nullptr,
fmt::format(
"Error while creating tile provider: {0}",
e.what())});
})
.thenInMainThread(
[pOverlay, thiz, externals](
RasterOverlay::CreateTileProviderResult&& result) {
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
if (result) {
pProvider = *result;
} else {
// Report error creating the tile provider.
const RasterOverlayLoadFailureDetails& failureDetails =
result.error();
SPDLOG_LOGGER_ERROR(
externals.pLogger,
failureDetails.message);
if (pOverlay->getOptions().loadErrorCallback) {
pOverlay->getOptions().loadErrorCallback(failureDetails);
}
// Create a tile provider that does not provide any tiles at
// all.
pProvider = new EmptyRasterOverlayTileProvider(
pOverlay,
externals.asyncSystem);
}
thiz->_pTileProvider = pProvider;
})
.share();
}
ActivatedRasterOverlay::~ActivatedRasterOverlay() {
// Explicitly release the placeholder first, because RasterOverlayTiles must
// be destroyed before the tile provider that created them.
if (this->_pPlaceholderTile) {
CESIUM_ASSERT(this->_pPlaceholderTile->getReferenceCount() == 1);
this->_pPlaceholderTile.reset();
}
}
CesiumAsync::SharedFuture<void>& ActivatedRasterOverlay::getReadyEvent() {
return this->_readyEvent;
}
const RasterOverlay* ActivatedRasterOverlay::getOverlay() const noexcept {
return this->_pOverlay;
}
RasterOverlay* ActivatedRasterOverlay::getOverlay() noexcept {
return this->_pOverlay;
}
const CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getTileProvider() const noexcept {
return this->_pTileProvider;
}
CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getTileProvider() noexcept {
return this->_pTileProvider;
}
const CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getPlaceholderTileProvider() const noexcept {
return this->_pPlaceholderTileProvider;
}
CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getPlaceholderTileProvider() noexcept {
return this->_pPlaceholderTileProvider;
}
const CesiumRasterOverlays::RasterOverlayTile*
ActivatedRasterOverlay::getPlaceholderTile() const noexcept {
return this->_pPlaceholderTile;
}
CesiumRasterOverlays::RasterOverlayTile*
ActivatedRasterOverlay::getPlaceholderTile() noexcept {
return this->_pPlaceholderTile;
}
IntrusivePointer<RasterOverlayTile> ActivatedRasterOverlay::getTile(
const CesiumGeometry::Rectangle& rectangle,
const glm::dvec2& targetScreenPixels) {
if (this->_pTileProvider == nullptr) {
return this->_pPlaceholderTile;
}
if (!rectangle.overlaps(this->_pTileProvider->getCoverageRectangle())) {
return nullptr;
}
return new RasterOverlayTile(*this, targetScreenPixels, rectangle);
}
int64_t ActivatedRasterOverlay::getTileDataBytes() const noexcept {
return this->_tileDataBytes;
}
uint32_t ActivatedRasterOverlay::getNumberOfTilesLoading() const noexcept {
CESIUM_ASSERT(this->_totalTilesCurrentlyLoading > -1);
return static_cast<uint32_t>(this->_totalTilesCurrentlyLoading);
}
void ActivatedRasterOverlay::removeTile(RasterOverlayTile* pTile) noexcept {
CESIUM_ASSERT(pTile->getReferenceCount() == 0);
if (pTile->getImage()) {
this->_tileDataBytes -= pTile->getImage()->sizeBytes;
}
}
CesiumAsync::Future<TileProviderAndTile>
ActivatedRasterOverlay::loadTile(RasterOverlayTile& tile) {
if (!this->_pTileProvider) {
// Refuse to load if the tile provider isn't ready yet.
return this->_pPlaceholderTileProvider->getAsyncSystem()
.createResolvedFuture(
TileProviderAndTile{this->_pPlaceholderTileProvider, nullptr});
}
return this->doLoad(tile, false);
}
bool ActivatedRasterOverlay::loadTileThrottled(RasterOverlayTile& tile) {
if (tile.getState() != RasterOverlayTile::LoadState::Unloaded) {
return true;
}
if (this->_throttledTilesCurrentlyLoading >=
this->_pOverlay->getOptions().maximumSimultaneousTileLoads) {
return false;
}
this->doLoad(tile, true);
return true;
}
namespace {
struct LoadResult {
RasterOverlayTile::LoadState state = RasterOverlayTile::LoadState::Unloaded;
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> pImage = nullptr;
CesiumGeometry::Rectangle rectangle = {};
std::vector<Credit> credits = {};
void* pRendererResources = nullptr;
bool moreDetailAvailable = true;
};
/**
* @brief Processes the given `LoadedRasterOverlayImage`, producing a
* `LoadResult`.
*
* This function is intended to be called on the worker thread.
*
* If the given `loadedImage` contains no valid image data, then a
* `LoadResult` with the state `RasterOverlayTile::LoadState::Failed` will be
* returned.
*
* Otherwise, the image data will be passed to
* `IPrepareRasterOverlayRendererResources::prepareRasterInLoadThread`, and the
* function will return a `LoadResult` with the image, the prepared renderer
* resources, and the state `RasterOverlayTile::LoadState::Loaded`.
*
* @param tileId The {@link TileID} - only used for logging
* @param pPrepareRendererResources The `IPrepareRasterOverlayRendererResources`
* @param pLogger The logger
* @param loadedImage The `LoadedRasterOverlayImage`
* @param rendererOptions Renderer options
* @return The `LoadResult`
*/
LoadResult createLoadResultFromLoadedImage(
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
LoadedRasterOverlayImage&& loadedImage,
const std::any& rendererOptions) {
if (!loadedImage.pImage) {
loadedImage.errorList.logError(pLogger, "Failed to load image for tile");
LoadResult result;
result.state = RasterOverlayTile::LoadState::Failed;
return result;
}
if (loadedImage.errorList.hasErrors()) {
loadedImage.errorList.logError(
pLogger,
"Errors while loading image for tile");
}
if (!loadedImage.errorList.warnings.empty()) {
loadedImage.errorList.logWarning(
pLogger,
"Warnings while loading image for tile");
}
CesiumGltf::ImageAsset& image = *loadedImage.pImage;
const int32_t bytesPerPixel = image.channels * image.bytesPerChannel;
const int64_t requiredBytes =
static_cast<int64_t>(image.width) * image.height * bytesPerPixel;
if (image.width > 0 && image.height > 0 &&
image.pixelData.size() >= static_cast<size_t>(requiredBytes)) {
CESIUM_TRACE(
"Prepare Raster " + std::to_string(image.width) + "x" +
std::to_string(image.height) + "x" + std::to_string(image.channels) +
"x" + std::to_string(image.bytesPerChannel));
void* pRendererResources = nullptr;
if (pPrepareRendererResources) {
pRendererResources = pPrepareRendererResources->prepareRasterInLoadThread(
image,
rendererOptions);
}
LoadResult result;
result.state = RasterOverlayTile::LoadState::Loaded;
result.pImage = loadedImage.pImage;
result.rectangle = loadedImage.rectangle;
result.credits = std::move(loadedImage.credits);
result.pRendererResources = pRendererResources;
result.moreDetailAvailable = loadedImage.moreDetailAvailable;
return result;
}
LoadResult result;
result.pRendererResources = nullptr;
result.state = RasterOverlayTile::LoadState::Failed;
result.moreDetailAvailable = false;
return result;
}
} // namespace
CesiumAsync::Future<TileProviderAndTile>
ActivatedRasterOverlay::doLoad(RasterOverlayTile& tile, bool isThrottledLoad) {
if (tile.getState() != RasterOverlayTile::LoadState::Unloaded) {
// Already loading or loaded, do nothing.
return this->_pTileProvider->getAsyncSystem().createResolvedFuture(
TileProviderAndTile{this->_pTileProvider, nullptr});
}
// Don't let this tile be destroyed while it's loading.
tile.setState(RasterOverlayTile::LoadState::Loading);
this->beginTileLoad(isThrottledLoad);
// Keep the tile and tile provider alive while the async operation is in
// progress.
IntrusivePointer<RasterOverlayTile> pTile = &tile;
IntrusivePointer<ActivatedRasterOverlay> thiz = this;
return this->_pTileProvider->loadTileImage(tile)
.thenInWorkerThread(
[pPrepareRendererResources =
this->_pTileProvider->getPrepareRendererResources(),
pLogger = this->_pTileProvider->getLogger(),
rendererOptions = this->_pOverlay->getOptions().rendererOptions](
LoadedRasterOverlayImage&& loadedImage) {
return createLoadResultFromLoadedImage(
pPrepareRendererResources,
pLogger,
std::move(loadedImage),
rendererOptions);
})
.thenInMainThread(
[thiz, pTile, isThrottledLoad](LoadResult&& result) noexcept {
pTile->_rectangle = result.rectangle;
pTile->_pRendererResources = result.pRendererResources;
pTile->_pImage = std::move(result.pImage);
pTile->_tileCredits = std::move(result.credits);
pTile->_moreDetailAvailable =
result.moreDetailAvailable
? RasterOverlayTile::MoreDetailAvailable::Yes
: RasterOverlayTile::MoreDetailAvailable::No;
pTile->setState(result.state);
if (pTile->getImage() != nullptr) {
ImageAsset& imageCesium = *pTile->getImage();
// If the image size hasn't been overridden, store the pixelData
// size now. We'll add this number to our total memory usage now,
// and remove it when the tile is later unloaded, and we must use
// the same size in each case.
if (imageCesium.sizeBytes < 0) {
imageCesium.sizeBytes = int64_t(imageCesium.pixelData.size());
}
thiz->_tileDataBytes += imageCesium.sizeBytes;
}
thiz->finalizeTileLoad(isThrottledLoad);
return TileProviderAndTile{thiz->getTileProvider(), pTile};
})
.catchInMainThread(
[thiz, pTile, isThrottledLoad](const std::exception& /*e*/) {
pTile->_pRendererResources = nullptr;
pTile->_pImage = nullptr;
pTile->_tileCredits = {};
pTile->_moreDetailAvailable =
RasterOverlayTile::MoreDetailAvailable::No;
pTile->setState(RasterOverlayTile::LoadState::Failed);
thiz->finalizeTileLoad(isThrottledLoad);
return TileProviderAndTile{thiz->getTileProvider(), pTile};
});
}
void ActivatedRasterOverlay::beginTileLoad(bool isThrottledLoad) noexcept {
++this->_totalTilesCurrentlyLoading;
if (isThrottledLoad) {
++this->_throttledTilesCurrentlyLoading;
}
}
void ActivatedRasterOverlay::finalizeTileLoad(bool isThrottledLoad) noexcept {
--this->_totalTilesCurrentlyLoading;
if (isThrottledLoad) {
--this->_throttledTilesCurrentlyLoading;
}
}
} // namespace CesiumRasterOverlays

View File

@ -7,9 +7,7 @@
#include <optional>
using namespace CesiumRasterOverlays;
namespace Cesium3DTilesSelection {
namespace CesiumRasterOverlays {
EmptyRasterOverlayTileProvider::EmptyRasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
@ -32,4 +30,4 @@ EmptyRasterOverlayTileProvider::loadTileImage(
.createResolvedFuture<CesiumRasterOverlays::LoadedRasterOverlayImage>({});
}
} // namespace Cesium3DTilesSelection
} // namespace CesiumRasterOverlays

View File

@ -2,7 +2,7 @@
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
namespace Cesium3DTilesSelection {
namespace CesiumRasterOverlays {
class EmptyRasterOverlayTileProvider
: public CesiumRasterOverlays::RasterOverlayTileProvider {

View File

@ -32,7 +32,11 @@ public:
asyncSystem,
pAssetAccessor,
pCreditSystem,
ellipsoid) {}
std::nullopt,
nullptr,
spdlog::default_logger(),
CesiumGeospatial::GeographicProjection(ellipsoid),
CesiumGeometry::Rectangle()) {}
virtual CesiumAsync::Future<LoadedRasterOverlayImage>
loadTileImage(const RasterOverlayTile& /* overlayTile */) override {

View File

@ -1,3 +1,4 @@
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
@ -10,8 +11,8 @@ using namespace CesiumAsync;
namespace CesiumRasterOverlays {
RasterOverlayTile::RasterOverlayTile(
RasterOverlayTileProvider& tileProvider) noexcept
: _pTileProvider(&tileProvider),
ActivatedRasterOverlay& activatedOverlay) noexcept
: _pActivatedOverlay(&activatedOverlay),
_targetScreenPixels(0.0),
_rectangle(CesiumGeometry::Rectangle(0.0, 0.0, 0.0, 0.0)),
_tileCredits(),
@ -21,10 +22,10 @@ RasterOverlayTile::RasterOverlayTile(
_moreDetailAvailable(MoreDetailAvailable::Unknown) {}
RasterOverlayTile::RasterOverlayTile(
RasterOverlayTileProvider& tileProvider,
ActivatedRasterOverlay& activatedOverlay,
const glm::dvec2& targetScreenPixels,
const CesiumGeometry::Rectangle& rectangle) noexcept
: _pTileProvider(&tileProvider),
: _pActivatedOverlay(&activatedOverlay),
_targetScreenPixels(targetScreenPixels),
_rectangle(rectangle),
_tileCredits(),
@ -34,9 +35,10 @@ RasterOverlayTile::RasterOverlayTile(
_moreDetailAvailable(MoreDetailAvailable::Unknown) {}
RasterOverlayTile::~RasterOverlayTile() {
RasterOverlayTileProvider& tileProvider = *this->_pTileProvider;
this->_pActivatedOverlay->removeTile(this);
tileProvider.removeTile(this);
RasterOverlayTileProvider& tileProvider =
*this->_pActivatedOverlay->getTileProvider();
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources = tileProvider.getPrepareRendererResources();
@ -58,15 +60,30 @@ RasterOverlayTile::~RasterOverlayTile() {
}
}
RasterOverlay& RasterOverlayTile::getOverlay() noexcept {
return this->_pTileProvider->getOwner();
ActivatedRasterOverlay& RasterOverlayTile::getActivatedOverlay() noexcept {
return *this->_pActivatedOverlay;
}
const ActivatedRasterOverlay&
RasterOverlayTile::getActivatedOverlay() const noexcept {
return *this->_pActivatedOverlay;
}
RasterOverlayTileProvider& RasterOverlayTile::getTileProvider() noexcept {
return *this->_pActivatedOverlay->getTileProvider();
}
const RasterOverlayTileProvider&
RasterOverlayTile::getTileProvider() const noexcept {
return *this->_pActivatedOverlay->getTileProvider();
}
RasterOverlay& RasterOverlayTile::getOverlay() noexcept {
return *this->_pActivatedOverlay->getOverlay();
}
/**
* @brief Returns the {@link RasterOverlay} that created this instance.
*/
const RasterOverlay& RasterOverlayTile::getOverlay() const noexcept {
return this->_pTileProvider->getOwner();
return *this->_pActivatedOverlay->getOverlay();
}
void RasterOverlayTile::loadInMainThread() {
@ -75,7 +92,7 @@ void RasterOverlayTile::loadInMainThread() {
}
// Do the final main thread raster loading
RasterOverlayTileProvider& tileProvider = *this->_pTileProvider;
RasterOverlayTileProvider& tileProvider = this->getTileProvider();
this->_pRendererResources =
tileProvider.getPrepareRendererResources()->prepareRasterInMainThread(
*this,

View File

@ -41,22 +41,6 @@ using namespace CesiumUtility;
namespace CesiumRasterOverlays {
RasterOverlayTileProvider::RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const RasterOverlayExternals& externals,
const CesiumGeospatial::Ellipsoid& ellipsoid) noexcept
: _pOwner(const_intrusive_cast<RasterOverlay>(pOwner)),
_externals(externals),
_credit(std::nullopt),
_projection(CesiumGeospatial::GeographicProjection(ellipsoid)),
_coverageRectangle(CesiumGeospatial::GeographicProjection::
computeMaximumProjectedRectangle(ellipsoid)),
_pPlaceholder(new RasterOverlayTile(*this)),
_tileDataBytes(0),
_totalTilesCurrentlyLoading(0),
_throttledTilesCurrentlyLoading(0),
_destructionCompleteDetails() {}
RasterOverlayTileProvider::RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const RasterOverlayExternals& externals,
@ -68,28 +52,8 @@ RasterOverlayTileProvider::RasterOverlayTileProvider(
_credit(credit),
_projection(projection),
_coverageRectangle(coverageRectangle),
_pPlaceholder(nullptr),
_tileDataBytes(0),
_totalTilesCurrentlyLoading(0),
_throttledTilesCurrentlyLoading(0),
_destructionCompleteDetails() {}
RasterOverlayTileProvider::RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const CesiumGeospatial::Ellipsoid& ellipsoid) noexcept
: RasterOverlayTileProvider(
pOwner,
RasterOverlayExternals{
.pAssetAccessor = pAssetAccessor,
.pPrepareRendererResources = nullptr,
.asyncSystem = asyncSystem,
.pCreditSystem = pCreditSystem,
.pLogger = nullptr},
ellipsoid) {}
RasterOverlayTileProvider::RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
@ -114,13 +78,6 @@ RasterOverlayTileProvider::RasterOverlayTileProvider(
coverageRectangle) {}
RasterOverlayTileProvider::~RasterOverlayTileProvider() noexcept {
// Explicitly release the placeholder first, because RasterOverlayTiles must
// be destroyed before the tile provider that created them.
if (this->_pPlaceholder) {
CESIUM_ASSERT(this->_pPlaceholder->getReferenceCount() == 1);
this->_pPlaceholder = nullptr;
}
if (this->_destructionCompleteDetails) {
this->_destructionCompleteDetails->promise.resolve();
}
@ -182,52 +139,11 @@ RasterOverlayTileProvider::getCoverageRectangle() const noexcept {
return this->_coverageRectangle;
}
int64_t RasterOverlayTileProvider::getTileDataBytes() const noexcept {
return this->_tileDataBytes;
}
uint32_t RasterOverlayTileProvider::getNumberOfTilesLoading() const noexcept {
CESIUM_ASSERT(this->_totalTilesCurrentlyLoading > -1);
return static_cast<uint32_t>(this->_totalTilesCurrentlyLoading);
}
void RasterOverlayTileProvider::removeTile(RasterOverlayTile* pTile) noexcept {
CESIUM_ASSERT(pTile->getReferenceCount() == 0);
if (pTile->getImage()) {
this->_tileDataBytes -= pTile->getImage()->sizeBytes;
}
}
const std::optional<CesiumUtility::Credit>&
RasterOverlayTileProvider::getCredit() const noexcept {
return _credit;
}
CesiumAsync::Future<TileProviderAndTile>
RasterOverlayTileProvider::loadTile(RasterOverlayTile& tile) {
if (this->_pPlaceholder) {
// Refuse to load placeholders.
return this->getAsyncSystem().createResolvedFuture(
TileProviderAndTile{this, nullptr});
}
return this->doLoad(tile, false);
}
bool RasterOverlayTileProvider::loadTileThrottled(RasterOverlayTile& tile) {
if (tile.getState() != RasterOverlayTile::LoadState::Unloaded) {
return true;
}
if (this->_throttledTilesCurrentlyLoading >=
this->getOwner().getOptions().maximumSimultaneousTileLoads) {
return false;
}
this->doLoad(tile, true);
return true;
}
CesiumAsync::Future<LoadedRasterOverlayImage>
RasterOverlayTileProvider::loadTileImageFromUrl(
const std::string& url,
@ -316,193 +232,6 @@ RasterOverlayTileProvider::loadTileImageFromUrl(
});
}
namespace {
struct LoadResult {
RasterOverlayTile::LoadState state = RasterOverlayTile::LoadState::Unloaded;
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> pImage = nullptr;
CesiumGeometry::Rectangle rectangle = {};
std::vector<Credit> credits = {};
void* pRendererResources = nullptr;
bool moreDetailAvailable = true;
};
/**
* @brief Processes the given `LoadedRasterOverlayImage`, producing a
* `LoadResult`.
*
* This function is intended to be called on the worker thread.
*
* If the given `loadedImage` contains no valid image data, then a
* `LoadResult` with the state `RasterOverlayTile::LoadState::Failed` will be
* returned.
*
* Otherwise, the image data will be passed to
* `IPrepareRasterOverlayRendererResources::prepareRasterInLoadThread`, and the
* function will return a `LoadResult` with the image, the prepared renderer
* resources, and the state `RasterOverlayTile::LoadState::Loaded`.
*
* @param tileId The {@link TileID} - only used for logging
* @param pPrepareRendererResources The `IPrepareRasterOverlayRendererResources`
* @param pLogger The logger
* @param loadedImage The `LoadedRasterOverlayImage`
* @param rendererOptions Renderer options
* @return The `LoadResult`
*/
LoadResult createLoadResultFromLoadedImage(
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
LoadedRasterOverlayImage&& loadedImage,
const std::any& rendererOptions) {
if (!loadedImage.pImage) {
loadedImage.errorList.logError(pLogger, "Failed to load image for tile");
LoadResult result;
result.state = RasterOverlayTile::LoadState::Failed;
return result;
}
if (loadedImage.errorList.hasErrors()) {
loadedImage.errorList.logError(
pLogger,
"Errors while loading image for tile");
}
if (!loadedImage.errorList.warnings.empty()) {
loadedImage.errorList.logWarning(
pLogger,
"Warnings while loading image for tile");
}
CesiumGltf::ImageAsset& image = *loadedImage.pImage;
const int32_t bytesPerPixel = image.channels * image.bytesPerChannel;
const int64_t requiredBytes =
static_cast<int64_t>(image.width) * image.height * bytesPerPixel;
if (image.width > 0 && image.height > 0 &&
image.pixelData.size() >= static_cast<size_t>(requiredBytes)) {
CESIUM_TRACE(
"Prepare Raster " + std::to_string(image.width) + "x" +
std::to_string(image.height) + "x" + std::to_string(image.channels) +
"x" + std::to_string(image.bytesPerChannel));
void* pRendererResources = nullptr;
if (pPrepareRendererResources) {
pRendererResources = pPrepareRendererResources->prepareRasterInLoadThread(
image,
rendererOptions);
}
LoadResult result;
result.state = RasterOverlayTile::LoadState::Loaded;
result.pImage = loadedImage.pImage;
result.rectangle = loadedImage.rectangle;
result.credits = std::move(loadedImage.credits);
result.pRendererResources = pRendererResources;
result.moreDetailAvailable = loadedImage.moreDetailAvailable;
return result;
}
LoadResult result;
result.pRendererResources = nullptr;
result.state = RasterOverlayTile::LoadState::Failed;
result.moreDetailAvailable = false;
return result;
}
} // namespace
CesiumAsync::Future<TileProviderAndTile> RasterOverlayTileProvider::doLoad(
RasterOverlayTile& tile,
bool isThrottledLoad) {
if (tile.getState() != RasterOverlayTile::LoadState::Unloaded) {
// Already loading or loaded, do nothing.
return this->getAsyncSystem().createResolvedFuture(
TileProviderAndTile{this, nullptr});
}
// CESIUM_TRACE_USE_TRACK_SET(this->_loadingSlots);
// Don't let this tile be destroyed while it's loading.
tile.setState(RasterOverlayTile::LoadState::Loading);
this->beginTileLoad(isThrottledLoad);
// Keep the tile and tile provider alive while the async operation is in
// progress.
IntrusivePointer<RasterOverlayTile> pTile = &tile;
IntrusivePointer<RasterOverlayTileProvider> thiz = this;
return this->loadTileImage(tile)
.thenInWorkerThread(
[pPrepareRendererResources = this->getPrepareRendererResources(),
pLogger = this->getLogger(),
rendererOptions = this->_pOwner->getOptions().rendererOptions](
LoadedRasterOverlayImage&& loadedImage) {
return createLoadResultFromLoadedImage(
pPrepareRendererResources,
pLogger,
std::move(loadedImage),
rendererOptions);
})
.thenInMainThread(
[thiz, pTile, isThrottledLoad](LoadResult&& result) noexcept {
pTile->_rectangle = result.rectangle;
pTile->_pRendererResources = result.pRendererResources;
pTile->_pImage = std::move(result.pImage);
pTile->_tileCredits = std::move(result.credits);
pTile->_moreDetailAvailable =
result.moreDetailAvailable
? RasterOverlayTile::MoreDetailAvailable::Yes
: RasterOverlayTile::MoreDetailAvailable::No;
pTile->setState(result.state);
if (pTile->getImage() != nullptr) {
ImageAsset& imageCesium = *pTile->getImage();
// If the image size hasn't been overridden, store the pixelData
// size now. We'll add this number to our total memory usage now,
// and remove it when the tile is later unloaded, and we must use
// the same size in each case.
if (imageCesium.sizeBytes < 0) {
imageCesium.sizeBytes = int64_t(imageCesium.pixelData.size());
}
thiz->_tileDataBytes += imageCesium.sizeBytes;
}
thiz->finalizeTileLoad(isThrottledLoad);
return TileProviderAndTile{thiz, pTile};
})
.catchInMainThread(
[thiz, pTile, isThrottledLoad](const std::exception& /*e*/) {
pTile->_pRendererResources = nullptr;
pTile->_pImage = nullptr;
pTile->_tileCredits = {};
pTile->_moreDetailAvailable =
RasterOverlayTile::MoreDetailAvailable::No;
pTile->setState(RasterOverlayTile::LoadState::Failed);
thiz->finalizeTileLoad(isThrottledLoad);
return TileProviderAndTile{thiz, pTile};
});
}
void RasterOverlayTileProvider::beginTileLoad(bool isThrottledLoad) noexcept {
++this->_totalTilesCurrentlyLoading;
if (isThrottledLoad) {
++this->_throttledTilesCurrentlyLoading;
}
}
void RasterOverlayTileProvider::finalizeTileLoad(
bool isThrottledLoad) noexcept {
--this->_totalTilesCurrentlyLoading;
if (isThrottledLoad) {
--this->_throttledTilesCurrentlyLoading;
}
}
TileProviderAndTile::~TileProviderAndTile() noexcept {
// Ensure the tile is released before the tile provider.
pTile = nullptr;

View File

@ -23,6 +23,7 @@
#include <CesiumNativeTests/SimpleTaskProcessor.h>
#include <CesiumNativeTests/readFile.h>
#include <CesiumNativeTests/waitForFuture.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
@ -130,22 +131,27 @@ TEST_CASE("Add raster overlay to glTF") {
IntrusivePointer<TileMapServiceRasterOverlay> pRasterOverlay =
new TileMapServiceRasterOverlay("test", tmr);
IntrusivePointer<ActivatedRasterOverlay> pActivated =
new ActivatedRasterOverlay(
RasterOverlayExternals{
.pAssetAccessor = pMockAssetAccessor,
.pPrepareRendererResources = nullptr,
.asyncSystem = asyncSystem,
.pCreditSystem = nullptr,
.pLogger = spdlog::default_logger()},
pRasterOverlay,
Ellipsoid::WGS84);
auto future =
pRasterOverlay
->createTileProvider(
asyncSystem,
pMockAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr)
.thenInMainThread([&gltf, &modelToEcef, textureCoordinateIndex](
RasterOverlay::CreateTileProviderResult&&
tileProviderResult) {
REQUIRE(tileProviderResult);
pActivated->getReadyEvent()
.thenInMainThread([&gltf,
&modelToEcef,
textureCoordinateIndex,
pActivated]() {
REQUIRE(pActivated->getTileProvider());
IntrusivePointer<RasterOverlayTileProvider> pTileProvider =
*tileProviderResult;
pActivated->getTileProvider();
std::optional<RasterOverlayDetails> details =
RasterOverlayUtilities::createRasterOverlayTextureCoordinates(
@ -176,7 +182,7 @@ TEST_CASE("Add raster overlay to glTF") {
// Get a raster overlay texture of the proper dimensions.
IntrusivePointer<RasterOverlayTile> pRasterTile =
pTileProvider->getTile(
pActivated->getTile(
details->rasterOverlayRectangles[0],
targetScreenPixels);
@ -186,7 +192,7 @@ TEST_CASE("Add raster overlay to glTF") {
pRasterTile->getRectangle());
// Go load the texture.
return pTileProvider->loadTile(*pRasterTile)
return pActivated->loadTile(*pRasterTile)
.thenPassThrough(std::move(textureTranslationAndScale));
})
.thenInMainThread([&gltf, textureCoordinateIndex](

View File

@ -6,6 +6,7 @@
#include <CesiumNativeTests/SimpleAssetRequest.h>
#include <CesiumNativeTests/SimpleTaskProcessor.h>
#include <CesiumNativeTests/readFile.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/GeoJsonDocumentRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumUtility/Math.h>
@ -72,25 +73,24 @@ TEST_CASE(
std::string,
std::shared_ptr<CesiumNativeTests::SimpleAssetRequest>>());
nonstd::expected_lite::expected<
IntrusivePointer<RasterOverlayTileProvider>,
CesiumRasterOverlays::RasterOverlayLoadFailureDetails>
result = pOverlay
->createTileProvider(
asyncSystem,
pAssetAccessor,
std::make_shared<CreditSystem>(),
nullptr,
spdlog::default_logger(),
pOverlay)
.waitInMainThread();
IntrusivePointer<ActivatedRasterOverlay> pActivated =
new ActivatedRasterOverlay(
RasterOverlayExternals{
.pAssetAccessor = pAssetAccessor,
.pPrepareRendererResources = nullptr,
.asyncSystem = asyncSystem,
.pCreditSystem = nullptr,
.pLogger = spdlog::default_logger()},
pOverlay,
Ellipsoid::WGS84);
REQUIRE(result);
const IntrusivePointer<RasterOverlayTileProvider>& pProvider = *result;
pActivated->getReadyEvent().waitInMainThread();
REQUIRE(pActivated->getTileProvider() != nullptr);
const CesiumGeometry::Rectangle fullRectangle =
builder.toGlobeRectangle().toSimpleRectangle();
RasterOverlayTile tile{*pProvider, glm::dvec2(256, 256), fullRectangle};
RasterOverlayTile tile{*pActivated, glm::dvec2(256, 256), fullRectangle};
// Generate random tiles but use a constant seed so the results are the same
// every run.
@ -110,8 +110,8 @@ TEST_CASE(
std::max(y1, y2)};
IntrusivePointer<RasterOverlayTile> pTile;
pTile.emplace(*pProvider, glm::dvec2(256, 256), thisRect);
pTile.emplace(*pActivated, glm::dvec2(256, 256), thisRect);
pProvider->loadTile(*pTile).waitInMainThread();
pActivated->loadTile(*pTile).waitInMainThread();
}
}
}

View File

@ -11,6 +11,7 @@
#include <CesiumGeospatial/WebMercatorProjection.h>
#include <CesiumNativeTests/SimpleAssetAccessor.h>
#include <CesiumNativeTests/SimpleAssetRequest.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
@ -164,34 +165,28 @@ TEST_CASE("QuadtreeRasterOverlayTileProvider getTile") {
AsyncSystem asyncSystem(pTaskProcessor);
IntrusivePointer<TestRasterOverlay> pOverlay = new TestRasterOverlay("Test");
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
pOverlay
->createTileProvider(
asyncSystem,
pAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr)
.thenInMainThread(
[&pProvider](RasterOverlay::CreateTileProviderResult&& created) {
CHECK(created);
pProvider = *created;
});
IntrusivePointer<ActivatedRasterOverlay> pActivated =
new ActivatedRasterOverlay(
RasterOverlayExternals{
pAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
pOverlay,
Ellipsoid::WGS84);
asyncSystem.dispatchMainThreadTasks();
REQUIRE(pProvider);
REQUIRE(!pProvider->isPlaceholder());
REQUIRE(pActivated->getTileProvider() != nullptr);
SUBCASE("uses root tile for a large area") {
Rectangle rectangle =
GeographicProjection::computeMaximumProjectedRectangle(
Ellipsoid::WGS84);
IntrusivePointer<RasterOverlayTile> pTile =
pProvider->getTile(rectangle, glm::dvec2(256));
pProvider->loadTile(*pTile);
pActivated->getTile(rectangle, glm::dvec2(256));
pActivated->loadTile(*pTile);
while (pTile->getState() != RasterOverlayTile::LoadState::Loaded) {
asyncSystem.dispatchMainThreadTasks();
@ -215,7 +210,7 @@ TEST_CASE("QuadtreeRasterOverlayTileProvider getTile") {
glm::dvec2 center(0.1, 0.2);
TestTileProvider* pTestProvider =
static_cast<TestTileProvider*>(pProvider.get());
static_cast<TestTileProvider*>(pActivated->getTileProvider());
// Select a rectangle that spans four tiles at tile level 8.
const uint32_t expectedLevel = 8;
@ -246,8 +241,8 @@ TEST_CASE("QuadtreeRasterOverlayTileProvider getTile") {
pTestProvider->errorTiles.emplace_back(*southeastID);
IntrusivePointer<RasterOverlayTile> pTile =
pProvider->getTile(tileRectangle, targetScreenPixels);
pProvider->loadTile(*pTile);
pActivated->getTile(tileRectangle, targetScreenPixels);
pActivated->loadTile(*pTile);
while (pTile->getState() != RasterOverlayTile::LoadState::Loaded) {
asyncSystem.dispatchMainThreadTasks();

View File

@ -6,6 +6,7 @@
#include <CesiumNativeTests/SimpleTaskProcessor.h>
#include <CesiumNativeTests/readFile.h>
#include <CesiumNativeTests/waitForFuture.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/TileMapServiceRasterOverlay.h>
@ -71,25 +72,28 @@ TEST_CASE("TileMapServiceRasterOverlay") {
new TileMapServiceRasterOverlay("test", tmr);
SUBCASE("can load images") {
RasterOverlay::CreateTileProviderResult result = waitForFuture(
IntrusivePointer<ActivatedRasterOverlay> pActivated =
new ActivatedRasterOverlay(
RasterOverlayExternals{
pMockAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
pRasterOverlay,
CesiumGeospatial::Ellipsoid::WGS84);
waitForFuture(
asyncSystem,
pRasterOverlay->createTileProvider(
asyncSystem,
pMockAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr));
pActivated->getReadyEvent().thenImmediately([]() {}));
REQUIRE(result);
REQUIRE(pActivated->getTileProvider());
CesiumUtility::IntrusivePointer<RasterOverlayTileProvider> pTileProvider =
*result;
IntrusivePointer<RasterOverlayTile> pTile = pTileProvider->getTile(
pTileProvider->getCoverageRectangle(),
IntrusivePointer<RasterOverlayTile> pTile = pActivated->getTile(
pActivated->getTileProvider()->getCoverageRectangle(),
glm::dvec2(256.0, 256.0));
REQUIRE(pTile);
waitForFuture(asyncSystem, pTileProvider->loadTile(*pTile));
waitForFuture(asyncSystem, pActivated->loadTile(*pTile));
REQUIRE(pTile->getImage());

View File

@ -2,6 +2,7 @@
#include <CesiumNativeTests/SimpleAssetAccessor.h>
#include <CesiumNativeTests/SimpleTaskProcessor.h>
#include <CesiumNativeTests/readFile.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/UrlTemplateRasterOverlay.h>
@ -42,32 +43,26 @@ TEST_CASE("UrlTemplateRasterOverlay getTile") {
"Test",
"http://example.com/{x}/{y}/{z}.png");
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
pOverlay
->createTileProvider(
asyncSystem,
pAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr)
.thenInMainThread(
[&pProvider](RasterOverlay::CreateTileProviderResult&& created) {
CHECK(created);
pProvider = *created;
});
IntrusivePointer<ActivatedRasterOverlay> pActivated =
new ActivatedRasterOverlay(
RasterOverlayExternals{
pAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
pOverlay,
Ellipsoid::WGS84);
asyncSystem.dispatchMainThreadTasks();
REQUIRE(pProvider);
REQUIRE(!pProvider->isPlaceholder());
REQUIRE(pActivated->getTileProvider() != nullptr);
Rectangle rectangle =
GeographicProjection::computeMaximumProjectedRectangle(Ellipsoid::WGS84);
IntrusivePointer<RasterOverlayTile> pTile =
pProvider->getTile(rectangle, glm::dvec2(256));
pProvider->loadTile(*pTile);
pActivated->getTile(rectangle, glm::dvec2(256));
pActivated->loadTile(*pTile);
while (pTile->getState() != RasterOverlayTile::LoadState::Loaded) {
asyncSystem.dispatchMainThreadTasks();