comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1671:2c2512918a0f

fix in prefetching
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 20 Nov 2020 10:14:36 +0100
parents 24462a259d8d
children 570398585b5f
comparison
equal deleted inserted replaced
1670:24462a259d8d 1671:2c2512918a0f
1390 { 1390 {
1391 const size_t cursorIndex = cursor_->GetCurrentIndex(); 1391 const size_t cursorIndex = cursor_->GetCurrentIndex();
1392 1392
1393 // Prepare prefetching 1393 // Prepare prefetching
1394 prefetchQueue_.clear(); 1394 prefetchQueue_.clear();
1395 for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++) 1395
1396 { 1396 if (1) // TODO - DISABLE PREFETCHING
1397 size_t a = cursor_->GetPrefetchIndex(i); 1397 {
1398 if (a == cursorIndex) 1398 for (size_t i = 0; i < cursor_->GetPrefetchSize() && i < 16; i++)
1399 { 1399 {
1400 if (quality == DisplayedFrameQuality_Low) 1400 size_t a = cursor_->GetPrefetchIndex(i);
1401 if (a != cursorIndex)
1401 { 1402 {
1402 prefetchQueue_.push_back(PrefetchItem(a, true)); 1403 prefetchQueue_.push_back(PrefetchItem(a, i < 2));
1403 } 1404 }
1404 } 1405 }
1405 else
1406 {
1407 prefetchQueue_.push_back(PrefetchItem(a, i < 2));
1408 }
1409 } 1406 }
1410 1407
1411 ScheduleNextPrefetch(); 1408 ScheduleNextPrefetch();
1412 1409
1413 if (observer_.get() != NULL) 1410 if (observer_.get() != NULL)
1414 { 1411 {
1415 observer_->SignalFrameUpdated(*this, cursor_->GetCurrentIndex(), 1412 observer_->SignalFrameUpdated(*this, cursor_->GetCurrentIndex(),
1416 frames_->GetFramesCount(), quality); 1413 frames_->GetFramesCount(), quality);
1417 } 1414 }
1507 //lock->GetCompositor().Refresh(scene); 1504 //lock->GetCompositor().Refresh(scene);
1508 lock->Invalidate(); 1505 lock->Invalidate();
1509 } 1506 }
1510 1507
1511 1508
1512 bool RenderCurrentSceneUsingCache(unsigned int& quality)
1513 {
1514 assert(cursor_.get() != NULL);
1515 assert(frames_.get() != NULL);
1516
1517 const size_t cursorIndex = cursor_->GetCurrentIndex();
1518 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1519 const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1520
1521 FramesCache::Accessor accessor(*cache_, instance.GetSopInstanceUid(), frameNumber);
1522 if (accessor.IsValid())
1523 {
1524 quality = accessor.GetQuality();
1525 RenderCurrentScene(accessor.GetImage(), instance, frames_->GetFrameGeometry(cursorIndex));
1526 return true;
1527 }
1528 else
1529 {
1530 return false;
1531 }
1532 }
1533
1534 void RenderCurrentSceneFromCommand(const Orthanc::ImageAccessor& frame, 1509 void RenderCurrentSceneFromCommand(const Orthanc::ImageAccessor& frame,
1535 const std::string& loadedSopInstanceUid, 1510 const std::string& loadedSopInstanceUid,
1536 unsigned int loadedFrameNumber, 1511 unsigned int loadedFrameNumber,
1537 DisplayedFrameQuality quality) 1512 DisplayedFrameQuality quality)
1538 { 1513 {
1541 { 1516 {
1542 const size_t cursorIndex = cursor_->GetCurrentIndex(); 1517 const size_t cursorIndex = cursor_->GetCurrentIndex();
1543 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); 1518 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1544 const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); 1519 const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1545 1520
1546 // Only change the same if the loaded frame still corresponds to the current cursor 1521 // Only change the scene if the loaded frame still corresponds to the current cursor
1547 if (instance.GetSopInstanceUid() == loadedSopInstanceUid && 1522 if (instance.GetSopInstanceUid() == loadedSopInstanceUid &&
1548 frameNumber == loadedFrameNumber) 1523 frameNumber == loadedFrameNumber)
1549 { 1524 {
1550 RenderCurrentScene(frame, instance, frames_->GetFrameGeometry(cursorIndex)); 1525 const OrthancStone::CoordinateSystem3D plane = frames_->GetFrameGeometry(cursorIndex);
1551 SetupPrefetchAfterRendering(quality); 1526
1527 if (quality == DisplayedFrameQuality_Low)
1528 {
1529 FramesCache::Accessor accessor(*cache_, instance.GetSopInstanceUid(), frameNumber);
1530 if (accessor.IsValid() &&
1531 accessor.GetQuality() == QUALITY_FULL)
1532 {
1533 // A high-res image was downloaded in between: Use this cached image instead of the low-res
1534 RenderCurrentScene(accessor.GetImage(), instance, plane);
1535 SetupPrefetchAfterRendering(DisplayedFrameQuality_High);
1536 }
1537 else
1538 {
1539 // This frame is only available in low-res: Download the full DICOM
1540 RenderCurrentScene(frame, instance, plane);
1541 SetupPrefetchAfterRendering(quality);
1542
1543 /**
1544 * The command "SetupPrefetchAfterRendering()" must be
1545 * after "SetupPrefetchAfterRendering(quality)", as the
1546 * DICOM instance might already be cached by the oracle,
1547 * which makes a call to "observer_->SignalFrameUpdated()"
1548 * with a low quality, whereas the high quality is
1549 * available.
1550 **/
1551 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1552 }
1553 }
1554 else
1555 {
1556 assert(quality == DisplayedFrameQuality_High);
1557 SetupPrefetchAfterRendering(quality);
1558 RenderCurrentScene(frame, instance, plane);
1559 }
1552 } 1560 }
1553 } 1561 }
1554 } 1562 }
1555 1563
1556 void ScheduleLoadFullDicomFrame(size_t cursorIndex, 1564 void ScheduleLoadFullDicomFrame(size_t cursorIndex,
1862 if (cursor_.get() != NULL && 1870 if (cursor_.get() != NULL &&
1863 frames_.get() != NULL) 1871 frames_.get() != NULL)
1864 { 1872 {
1865 const size_t cursorIndex = cursor_->GetCurrentIndex(); 1873 const size_t cursorIndex = cursor_->GetCurrentIndex();
1866 1874
1867 unsigned int cachedQuality; 1875 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1868 if (!RenderCurrentSceneUsingCache(cachedQuality)) 1876 const size_t frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1877
1878 FramesCache::Accessor accessor(*cache_, instance.GetSopInstanceUid(), frameNumber);
1879 if (accessor.IsValid())
1880 {
1881 RenderCurrentScene(accessor.GetImage(), instance, frames_->GetFrameGeometry(cursorIndex));
1882
1883 DisplayedFrameQuality quality;
1884
1885 if (accessor.GetQuality() < QUALITY_FULL)
1886 {
1887 // This frame is only available in low-res: Download the full DICOM
1888 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1889 quality = DisplayedFrameQuality_Low;
1890 }
1891 else
1892 {
1893 quality = DisplayedFrameQuality_High;
1894 }
1895
1896 SetupPrefetchAfterRendering(quality);
1897 }
1898 else
1869 { 1899 {
1870 // This frame is not cached yet: Load it 1900 // This frame is not cached yet: Load it
1871 if (source_.HasDicomWebRendered()) 1901 if (source_.HasDicomWebRendered())
1872 { 1902 {
1873 ScheduleLoadRenderedFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); 1903 ScheduleLoadRenderedFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1875 else 1905 else
1876 { 1906 {
1877 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */); 1907 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1878 } 1908 }
1879 } 1909 }
1880 else if (cachedQuality < QUALITY_FULL)
1881 {
1882 // This frame is only available in low-res: Download the full DICOM
1883 ScheduleLoadFullDicomFrame(cursorIndex, PRIORITY_HIGH, false /* not a prefetch */);
1884 quality = DisplayedFrameQuality_Low;
1885 }
1886 else
1887 {
1888 quality = DisplayedFrameQuality_High;
1889 }
1890
1891 SetupPrefetchAfterRendering(quality);
1892 } 1910 }
1893 } 1911 }
1894 1912
1895 1913
1896 void ChangeFrame(SeriesCursor::Action action) 1914 void ChangeFrame(SeriesCursor::Action action)