Skip to content

Commit

Permalink
Merge pull request #1527 from CesiumGS/shared-assets-kring
Browse files Browse the repository at this point in the history
Refactor texture creation to avoid the need for a global lock
  • Loading branch information
azrogers authored Oct 10, 2024
2 parents 0f341f0 + c042a39 commit 62bdd81
Show file tree
Hide file tree
Showing 26 changed files with 1,352 additions and 696 deletions.
54 changes: 30 additions & 24 deletions Source/CesiumRuntime/Private/Cesium3DTileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
#include "Cesium3DTilesetLoadFailureDetails.h"
#include "Cesium3DTilesetRoot.h"
#include "CesiumActors.h"
#include "CesiumAsync/SharedAssetDepot.h"
#include "CesiumBoundingVolumeComponent.h"
#include "CesiumCamera.h"
#include "CesiumCameraManager.h"
#include "CesiumCommon.h"
#include "CesiumCustomVersion.h"
#include "CesiumGeospatial/GlobeTransforms.h"
#include "CesiumGltf/ImageCesium.h"
#include "CesiumGltf/ImageAsset.h"
#include "CesiumGltf/Ktx2TranscodeTargets.h"
#include "CesiumGltf/SharedAssetDepot.h"
#include "CesiumGltfComponent.h"
#include "CesiumGltfPointsSceneProxyUpdater.h"
#include "CesiumGltfPrimitiveComponent.h"
Expand All @@ -41,6 +41,7 @@
#include "Engine/TextureRenderTarget2D.h"
#include "Engine/World.h"
#include "EngineUtils.h"
#include "ExtensionImageAssetUnreal.h"
#include "GameFramework/PlayerController.h"
#include "Kismet/GameplayStatics.h"
#include "LevelSequenceActor.h"
Expand Down Expand Up @@ -866,7 +867,7 @@ class UnrealResourcePreparer
}

virtual void* prepareRasterInLoadThread(
CesiumGltf::ImageCesium& image,
CesiumGltf::ImageAsset& image,
const std::any& rendererOptions) override {
auto ppOptions =
std::any_cast<FRasterOverlayRendererOptions*>(&rendererOptions);
Expand All @@ -889,19 +890,31 @@ class UnrealResourcePreparer
}
}

CesiumGltf::SharedAsset<CesiumGltf::ImageCesium> imageAsset(
std::move(image));
// TODO: sRGB should probably be configurable on the raster overlay.
bool sRGB = true;

const ExtensionImageAssetUnreal& extension =
ExtensionImageAssetUnreal::getOrCreate(
CesiumAsync::AsyncSystem(nullptr), // TODO
image,
sRGB,
pOptions->useMipmaps,
std::nullopt);

// Because raster overlay images are never shared (at least currently!), the
// future should already be resolved by the time we get here.
check(extension.getFuture().isReady());

auto texture = CesiumTextureUtility::loadTextureAnyThreadPart(
imageAsset,
image,
TextureAddress::TA_Clamp,
TextureAddress::TA_Clamp,
pOptions->filter,
pOptions->useMipmaps,
pOptions->group,
// TODO: sRGB should probably be configurable on the raster overlay.
true,
sRGB,
std::nullopt);

return texture.Release();
}

Expand Down Expand Up @@ -960,7 +973,7 @@ class UnrealResourcePreparer
const Cesium3DTilesSelection::TileContent& content = tile.getContent();
const Cesium3DTilesSelection::TileRenderContent* pRenderContent =
content.getRenderContent();
if (pRenderContent) {
if (pMainThreadRendererResources != nullptr && pRenderContent != nullptr) {
UCesiumGltfComponent* pGltfContent =
reinterpret_cast<UCesiumGltfComponent*>(
pRenderContent->getRenderResources());
Expand Down Expand Up @@ -990,7 +1003,7 @@ class UnrealResourcePreparer
UCesiumGltfComponent* pGltfContent =
reinterpret_cast<UCesiumGltfComponent*>(
pRenderContent->getRenderResources());
if (pGltfContent) {
if (pMainThreadRendererResources != nullptr && pGltfContent != nullptr) {
pGltfContent->DetachRasterTile(
tile,
rasterTile,
Expand Down Expand Up @@ -2032,20 +2045,17 @@ void ACesium3DTileset::updateLastViewUpdateResultState(
}

if (this->LogAssetStats && this->_pTileset) {
const CesiumGltf::SingleAssetDepot<CesiumGltf::ImageCesium>* imageDepot =
this->_pTileset->getSharedAssetDepot().getImageDepot();
float averageAge;
size_t deletionCount;
imageDepot->getDeletionStats(averageAge, deletionCount);
const CesiumAsync::SharedAssetDepot<CesiumGltf::ImageAsset>& imageDepot =
*this->_pTileset->getSharedAssetSystem().pImage;
UE_LOG(
LogCesium,
Display,
TEXT(
"Images depot: %d distinct assets, %d total usages, %d assets pending deletion, %f average age"),
imageDepot->getDistinctCount(),
imageDepot->getUsageCount(),
deletionCount,
averageAge);
"Images depot: %d distinct assets, %d total usages, %d assets pending deletion, %d total size in bytes"),
imageDepot.getDistinctCount(),
imageDepot.getUsageCount(),
imageDepot.getDeletionCandidateCount(),
imageDepot.getDeletionCandidateTotalSizeBytes());
}
}
}
Expand Down Expand Up @@ -2220,10 +2230,6 @@ void ACesium3DTileset::Tick(float DeltaTime) {
}

this->UpdateLoadStatus();

if (this->_pTileset) {
this->_pTileset->getSharedAssetDepot().deletionTick();
}
}

void ACesium3DTileset::EndPlay(const EEndPlayReason::Type EndPlayReason) {
Expand Down
41 changes: 21 additions & 20 deletions Source/CesiumRuntime/Private/CesiumEncodedFeaturesMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ encodeFeatureIdAttribute(const FCesiumFeatureIdAttribute& attribute) {

std::optional<EncodedFeatureIdSet> encodeFeatureIdTexture(
const FCesiumFeatureIdTexture& texture,
TMap<const CesiumGltf::ImageCesium*, TWeakPtr<LoadedTextureResult>>&
TMap<const CesiumGltf::ImageAsset*, TWeakPtr<LoadedTextureResult>>&
featureIdTextureMap) {
const ECesiumFeatureIdTextureStatus status =
UCesiumFeatureIdTextureBlueprintLibrary::GetFeatureIDTextureStatus(
Expand All @@ -114,7 +114,7 @@ std::optional<EncodedFeatureIdSet> encodeFeatureIdTexture(

const CesiumGltf::FeatureIdTextureView& featureIdTextureView =
texture.getFeatureIdTextureView();
const CesiumGltf::ImageCesium* pFeatureIdImage =
const CesiumGltf::ImageAsset* pFeatureIdImage =
featureIdTextureView.getImage();

TRACE_CPUPROFILER_EVENT_SCOPE(Cesium::EncodeFeatureIdTexture)
Expand Down Expand Up @@ -143,11 +143,11 @@ std::optional<EncodedFeatureIdSet> encodeFeatureIdTexture(
}

// Copy the image, so that we can keep a copy of it in the glTF.
CesiumGltf::SharedAsset<CesiumGltf::ImageCesium> imageCopy =
CesiumGltf::SharedAsset(CesiumGltf::ImageCesium(*pFeatureIdImage));
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> pImageCopy =
new CesiumGltf::ImageAsset(*pFeatureIdImage);
encodedFeatureIdTexture.pTexture =
MakeShared<LoadedTextureResult>(std::move(*loadTextureAnyThreadPart(
imageCopy,
*pImageCopy,
addressX,
addressY,
TextureFilter::TF_Nearest,
Expand Down Expand Up @@ -177,7 +177,7 @@ EncodedPrimitiveFeatures encodePrimitiveFeaturesAnyThreadPart(

// Not all feature ID sets are necessarily textures, but reserve the max
// amount just in case.
TMap<const CesiumGltf::ImageCesium*, TWeakPtr<LoadedTextureResult>>
TMap<const CesiumGltf::ImageAsset*, TWeakPtr<LoadedTextureResult>>
featureIdTextureMap;
featureIdTextureMap.Reserve(featureIDSetDescriptions.Num());

Expand Down Expand Up @@ -510,11 +510,12 @@ EncodedPropertyTable encodePropertyTableAnyThreadPart(
? floorSqrtFeatureCount
: (floorSqrtFeatureCount + 1);

CesiumGltf::SharedAsset<CesiumGltf::ImageCesium> image;
image->width = image->height = textureDimension;
image->bytesPerChannel = encodedFormat.bytesPerChannel;
image->channels = encodedFormat.channels;
image->pixelData.resize(
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> pImage =
new CesiumGltf::ImageAsset();
pImage->width = pImage->height = textureDimension;
pImage->bytesPerChannel = encodedFormat.bytesPerChannel;
pImage->channels = encodedFormat.channels;
pImage->pixelData.resize(
textureDimension * textureDimension * encodedFormat.bytesPerChannel *
encodedFormat.channels);

Expand All @@ -523,18 +524,18 @@ EncodedPropertyTable encodePropertyTableAnyThreadPart(
CesiumEncodedMetadataParseColorFromString::encode(
*pDescription,
property,
gsl::span(image->pixelData),
gsl::span(pImage->pixelData),
encodedFormat.bytesPerChannel * encodedFormat.channels);
} else /* info.Conversion == ECesiumEncodedMetadataConversion::Coerce */ {
CesiumEncodedMetadataCoerce::encode(
*pDescription,
property,
gsl::span(image->pixelData),
gsl::span(pImage->pixelData),
encodedFormat.bytesPerChannel * encodedFormat.channels);
}

encodedProperty.pTexture = loadTextureAnyThreadPart(
image,
*pImage,
TextureAddress::TA_Clamp,
TextureAddress::TA_Clamp,
TextureFilter::TF_Nearest,
Expand Down Expand Up @@ -591,7 +592,7 @@ EncodedPropertyTable encodePropertyTableAnyThreadPart(
EncodedPropertyTexture encodePropertyTextureAnyThreadPart(
const FCesiumPropertyTextureDescription& propertyTextureDescription,
const FCesiumPropertyTexture& propertyTexture,
TMap<const CesiumGltf::ImageCesium*, TWeakPtr<LoadedTextureResult>>&
TMap<const CesiumGltf::ImageAsset*, TWeakPtr<LoadedTextureResult>>&
propertyTexturePropertyMap) {

TRACE_CPUPROFILER_EVENT_SCOPE(Cesium::EncodePropertyTexture)
Expand Down Expand Up @@ -640,7 +641,7 @@ EncodedPropertyTexture encodePropertyTextureAnyThreadPart(
encodedProperty.channels[i] = channels[i];
}

const CesiumGltf::ImageCesium* pImage = property.getImage();
const CesiumGltf::ImageAsset* pImage = property.getImage();

TWeakPtr<LoadedTextureResult>* pMappedUnrealImageIt =
propertyTexturePropertyMap.Find(pImage);
Expand All @@ -657,11 +658,11 @@ EncodedPropertyTexture encodePropertyTextureAnyThreadPart(
}

// Copy the image, so that we can keep a copy of it in the glTF.
CesiumGltf::SharedAsset<CesiumGltf::ImageCesium> imageCopy =
CesiumGltf::SharedAsset(CesiumGltf::ImageCesium(*pImage));
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> pImageCopy =
new CesiumGltf::ImageAsset(*pImage);
encodedProperty.pTexture =
MakeShared<LoadedTextureResult>(std::move(*loadTextureAnyThreadPart(
imageCopy,
*pImageCopy,
addressX,
addressY,
// TODO: account for texture filter
Expand Down Expand Up @@ -771,7 +772,7 @@ EncodedModelMetadata encodeModelMetadataAnyThreadPart(
UCesiumModelMetadataBlueprintLibrary::GetPropertyTextures(metadata);
result.propertyTextures.Reserve(propertyTextures.Num());

TMap<const CesiumGltf::ImageCesium*, TWeakPtr<LoadedTextureResult>>
TMap<const CesiumGltf::ImageAsset*, TWeakPtr<LoadedTextureResult>>
propertyTexturePropertyMap;
propertyTexturePropertyMap.Reserve(propertyTextures.Num());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ EncodedPropertyTexture encodePropertyTextureAnyThreadPart(
const FCesiumPropertyTextureDescription& propertyTextureDescription,
const FCesiumPropertyTexture& propertyTexture,
TMap<
const CesiumGltf::ImageCesium*,
const CesiumGltf::ImageAsset*,
TWeakPtr<CesiumTextureUtility::LoadedTextureResult>>&
propertyTexturePropertyMap);

Expand Down
Loading

0 comments on commit 62bdd81

Please sign in to comment.