# HG changeset patch # User Sebastien Jodogne # Date 1605863676 -3600 # Node ID 2c2512918a0fc3df2798b6fbc3f41dfa6cf0c5f8 # Parent 24462a259d8d4c2b94484063f6e776bd099be99b fix in prefetching diff -r 24462a259d8d -r 2c2512918a0f Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Nov 19 19:20:45 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Nov 20 10:14:36 2020 +0100 @@ -1392,24 +1392,21 @@ // Prepare prefetching prefetchQueue_.clear(); - for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++) + + if (1) // TODO - DISABLE PREFETCHING { - size_t a = cursor_->GetPrefetchIndex(i); - if (a == cursorIndex) + for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++) { - if (quality == DisplayedFrameQuality_Low) + size_t a = cursor_->GetPrefetchIndex(i); + if (a != cursorIndex) { - prefetchQueue_.push_back(PrefetchItem(a, true)); + prefetchQueue_.push_back(PrefetchItem(a, i < 2)); } } - else - { - prefetchQueue_.push_back(PrefetchItem(a, i < 2)); - } } ScheduleNextPrefetch(); - + if (observer_.get() != NULL) { observer_->SignalFrameUpdated(*this, cursor_->GetCurrentIndex(), @@ -1509,28 +1506,6 @@ } - bool RenderCurrentSceneUsingCache(unsigned int& quality) - { - assert(cursor_.get() != NULL); - assert(frames_.get() != NULL); - - const size_t cursorIndex = cursor_->GetCurrentIndex(); - const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); - const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); - - FramesCache::Accessor accessor(*cache_, instance.GetSopInstanceUid(), frameNumber); - if (accessor.IsValid()) - { - quality = accessor.GetQuality(); - RenderCurrentScene(accessor.GetImage(), instance, frames_->GetFrameGeometry(cursorIndex)); - return true; - } - else - { - return false; - } - } - void RenderCurrentSceneFromCommand(const Orthanc::ImageAccessor& frame, const std::string& loadedSopInstanceUid, unsigned int loadedFrameNumber, @@ -1543,12 +1518,45 @@ const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); - // Only change the same if the loaded frame still corresponds to the current cursor + // Only change the scene if the loaded frame still corresponds to the current cursor if (instance.GetSopInstanceUid() == loadedSopInstanceUid && frameNumber == loadedFrameNumber) { - RenderCurrentScene(frame, instance, frames_->GetFrameGeometry(cursorIndex)); - SetupPrefetchAfterRendering(quality); + const OrthancStone::CoordinateSystem3D plane = frames_->GetFrameGeometry(cursorIndex); + + if (quality == DisplayedFrameQuality_Low) + { + FramesCache::Accessor accessor(*cache_, instance.GetSopInstanceUid(), frameNumber); + if (accessor.IsValid() && + accessor.GetQuality() == QUALITY_FULL) + { + // A high-res image was downloaded in between: Use this cached image instead of the low-res + RenderCurrentScene(accessor.GetImage(), instance, plane); + SetupPrefetchAfterRendering(DisplayedFrameQuality_High); + } + else + { + // This frame is only available in low-res: Download the full DICOM + RenderCurrentScene(frame, instance, plane); + SetupPrefetchAfterRendering(quality); + + /** + * The command "SetupPrefetchAfterRendering()" must be + * after "SetupPrefetchAfterRendering(quality)", as the + * DICOM instance might already be cached by the oracle, + * which makes a call to "observer_->SignalFrameUpdated()" + * with a low quality, whereas the high quality is + * available. + **/ + ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); + } + } + else + { + assert(quality == DisplayedFrameQuality_High); + SetupPrefetchAfterRendering(quality); + RenderCurrentScene(frame, instance, plane); + } } } } @@ -1864,8 +1872,30 @@ { const size_t cursorIndex = cursor_->GetCurrentIndex(); - unsigned int cachedQuality; - if (!RenderCurrentSceneUsingCache(cachedQuality)) + const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); + const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); + + FramesCache::Accessor accessor(*cache_, instance.GetSopInstanceUid(), frameNumber); + if (accessor.IsValid()) + { + RenderCurrentScene(accessor.GetImage(), instance, frames_->GetFrameGeometry(cursorIndex)); + + DisplayedFrameQuality quality; + + if (accessor.GetQuality() < QUALITY_FULL) + { + // This frame is only available in low-res: Download the full DICOM + ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); + quality = DisplayedFrameQuality_Low; + } + else + { + quality = DisplayedFrameQuality_High; + } + + SetupPrefetchAfterRendering(quality); + } + else { // This frame is not cached yet: Load it if (source_.HasDicomWebRendered()) @@ -1877,18 +1907,6 @@ ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); } } - else if (cachedQuality < QUALITY_FULL) - { - // This frame is only available in low-res: Download the full DICOM - ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); - quality = DisplayedFrameQuality_Low; - } - else - { - quality = DisplayedFrameQuality_High; - } - - SetupPrefetchAfterRendering(quality); } }