diff --git a/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h b/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h index 0f5959c52..08120ae2b 100644 --- a/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h +++ b/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h @@ -85,7 +85,8 @@ class RequestDispatcher { void TakeCompletedWork(size_t maxCount, std::vector& out); - size_t GetPendingCount(); + size_t GetPendingRequestsCount(); + size_t GetTotalPendingCount(); void GetRequestsStats(size_t& queued, size_t& inFlight, size_t& done); @@ -580,7 +581,7 @@ class CESIUM3DTILESSELECTION_API Tileset final { std::vector& outRequestWork, std::vector& outImmediateWork); - void addWorkToRequestDispatcher(std::vector& workVector); + void addWorkToRequestDispatcher(const std::vector& workVector, size_t maxSimultaneousRequests); void dispatchProcessingWork(std::vector& workVector); diff --git a/Cesium3DTilesSelection/src/Tileset.cpp b/Cesium3DTilesSelection/src/Tileset.cpp index 54288cdc1..3f9346dbf 100644 --- a/Cesium3DTilesSelection/src/Tileset.cpp +++ b/Cesium3DTilesSelection/src/Tileset.cpp @@ -419,7 +419,7 @@ Tileset::updateView(const std::vector& frustums, float deltaTime) { this->_pTilesetContentManager->getNumberOfRastersLoading(); result.rastersLoaded = this->_pTilesetContentManager->getNumberOfRastersLoaded(); - result.requestsPending = this->_requestDispatcher.GetPendingCount(); + result.requestsPending = this->_requestDispatcher.GetTotalPendingCount(); assertViewResults(); @@ -1474,8 +1474,11 @@ void Tileset::_processWorkerThreadLoadQueue() { newImmediateWork); // Add all content requests to the dispatcher - if (newRequestWork.size() > 0) - addWorkToRequestDispatcher(newRequestWork); + size_t maxTileLoads = + static_cast(this->_options.maximumSimultaneousTileLoads); + if (newRequestWork.size() > 0) { + addWorkToRequestDispatcher(newRequestWork, maxTileLoads); +} // // Define a queue of work to dispatch @@ -1493,8 +1496,6 @@ void Tileset::_processWorkerThreadLoadQueue() { assert(numberOfRastersLoading >= 0); size_t totalLoads = static_cast(numberOfTilesLoading) + static_cast(numberOfRastersLoading); - size_t maxTileLoads = - static_cast(this->_options.maximumSimultaneousTileLoads); // If there are slots available, add some completed request work if (totalLoads < maxTileLoads) { @@ -1708,10 +1709,31 @@ void Tileset::discoverLoadWork( } } -void Tileset::addWorkToRequestDispatcher( - std::vector& workVector) { +void Tileset::addWorkToRequestDispatcher(const std::vector& workVector, size_t maxSimultaneousRequests) { - for (TileLoadWork& work : workVector) { + // Determine how much incoming work we will accept + // Don't exceed our the max count passed in + size_t pendingRequestCount = this->_requestDispatcher.GetPendingRequestsCount(); + assert(pendingRequestCount <= maxSimultaneousRequests); + + size_t slotsOpen = maxSimultaneousRequests - pendingRequestCount; + if (slotsOpen == 0) + return; + + std::vector workToSubmit; + if (slotsOpen >= workVector.size ()) { + // We can take all incoming work + workToSubmit = workVector; + } + else { + // We can only take part of the incoming work + // Just submit the highest priority + workToSubmit = workVector; + std::sort(workToSubmit.begin(), workToSubmit.end()); + workToSubmit.resize(slotsOpen); + } + + for (TileLoadWork& work : workToSubmit) { assert(!work.requestUrl.empty()); // Mark this tile as loading now so it doesn't get queued next frame @@ -1737,7 +1759,7 @@ void Tileset::addWorkToRequestDispatcher( workVector.size()); _requestDispatcher.QueueRequestWork( - workVector, + workToSubmit, this->_pTilesetContentManager->getRequestHeaders()); _requestDispatcher.WakeIfNeeded(); @@ -1900,7 +1922,12 @@ void RequestDispatcher::stageRequestWork( } } -size_t RequestDispatcher::GetPendingCount() { +size_t RequestDispatcher::GetPendingRequestsCount() { + std::lock_guard lock(_requestsLock); + return _queuedWork.size() + _inFlightWork.size(); +} + +size_t RequestDispatcher::GetTotalPendingCount() { std::lock_guard lock(_requestsLock); return _queuedWork.size() + _inFlightWork.size() + _doneWork.size(); }