|
|
@ -571,6 +571,8 @@ public class Game : GameWindow { |
|
|
|
List<Photo> allPhotos = new(); |
|
|
|
List<Photo> photos = new(); |
|
|
|
HashSet<Photo> loadedImages = new(); |
|
|
|
HashSet<Photo> loadingImages = new(); |
|
|
|
readonly object loadedImagesLock = new(); |
|
|
|
int photoIndex = 0; |
|
|
|
int ribbonIndex = 0; |
|
|
|
Shader shader = new(); |
|
|
@ -777,10 +779,10 @@ public class Game : GameWindow { |
|
|
|
|
|
|
|
// Load photos from a directory.
|
|
|
|
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\photos-test\");
|
|
|
|
string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\"); |
|
|
|
// string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\");
|
|
|
|
// string[] files = Directory.GetFiles(@"G:\DCIM\100EOSR6\");
|
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Pictures\photos\2018\06\23");
|
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000");
|
|
|
|
string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000"); |
|
|
|
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\");
|
|
|
|
|
|
|
|
for (int i = 0; i < files.Count(); i++) { |
|
|
@ -809,43 +811,62 @@ public class Game : GameWindow { |
|
|
|
base.OnUnload(); |
|
|
|
} |
|
|
|
|
|
|
|
private async void LoadAndUnloadImagesAsync() { |
|
|
|
int minLoadedImage = Math.Max(0, photoIndex - 20); |
|
|
|
int maxLoadedImage = Math.Min(photoIndex + 20, photos.Count - 1); |
|
|
|
// First, unload images that haven't been touched in a while.
|
|
|
|
// FIXME: also cancel any of these if they still have an in-progress loading task?
|
|
|
|
private void UnloadImages() { |
|
|
|
// Unload images that haven't been touched in a while.
|
|
|
|
// FIXME: keep around thumbnail-sized textures?
|
|
|
|
while (loadedImages.Count > 60) { |
|
|
|
long earliestTime = long.MaxValue; |
|
|
|
Photo? earliest = null; |
|
|
|
foreach (Photo photo in loadedImages) { |
|
|
|
if (photo.LastTouch < earliestTime) { |
|
|
|
earliest = photo; |
|
|
|
earliestTime = photo.LastTouch; |
|
|
|
lock (loadedImagesLock) { |
|
|
|
while (loadedImages.Count > 60) { |
|
|
|
long earliestTime = long.MaxValue; |
|
|
|
Photo? earliest = null; |
|
|
|
foreach (Photo photo in loadedImages) { |
|
|
|
if (photo.LastTouch < earliestTime) { |
|
|
|
earliest = photo; |
|
|
|
earliestTime = photo.LastTouch; |
|
|
|
} |
|
|
|
} |
|
|
|
if (earliest != null) { |
|
|
|
// Console.WriteLine($"loadedImages.Count: {loadedImages.Count}, evicting {earliest.Filename} @ {earliestTime}");
|
|
|
|
// TODO: we have to free textures on the GL thread, but could we do that async'ly to keep the UI responsive?
|
|
|
|
earliest.Unload(); |
|
|
|
loadedImages.Remove(earliest); |
|
|
|
} |
|
|
|
} |
|
|
|
if (earliest != null) { |
|
|
|
Console.WriteLine($"loadedImages.Count: {loadedImages.Count}, evicting {earliest.Filename} @ {earliestTime}"); |
|
|
|
// TODO: we have to free textures on the GL thread, but could we do that async'ly to keep the UI responsive?
|
|
|
|
earliest.Unload(); |
|
|
|
loadedImages.Remove(earliest); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private async void LoadImagesAsync() { |
|
|
|
foreach (Photo p in loadingImages) { |
|
|
|
if (p.Loaded) { |
|
|
|
lock (loadedImagesLock) { |
|
|
|
loadedImages.Add(p); |
|
|
|
loadingImages.Remove(p); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// Then, start loading any images that are in our window but not yet loaded.
|
|
|
|
// Start loading any images that are in our window but not yet loaded.
|
|
|
|
int minLoadedImage = Math.Max(0, photoIndex - 20); |
|
|
|
int maxLoadedImage = Math.Min(photoIndex + 20, photos.Count - 1); |
|
|
|
List<Photo> toLoad = new(); |
|
|
|
for (int i = minLoadedImage; i <= maxLoadedImage; i++) { |
|
|
|
if (!loadedImages.Contains(photos[i])) { |
|
|
|
Console.WriteLine("loading " + i); |
|
|
|
loadedImages.Add(photos[i]); |
|
|
|
await Task.Run( () => { photos[i].LoadAsync(); }); |
|
|
|
lock (loadedImagesLock) { |
|
|
|
if (!loadedImages.Contains(photos[i]) && !loadingImages.Contains(photos[i])) { |
|
|
|
Console.WriteLine("loading " + i); |
|
|
|
loadingImages.Add(photos[i]); |
|
|
|
toLoad.Add(photos[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
foreach (Photo p in toLoad) { |
|
|
|
await Task.Run( () => { p.LoadAsync(); }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected override void OnRenderFrame(FrameEventArgs e) { |
|
|
|
base.OnRenderFrame(e); |
|
|
|
fpsCounter.Update(); |
|
|
|
|
|
|
|
LoadAndUnloadImagesAsync(); |
|
|
|
UnloadImages(); |
|
|
|
LoadImagesAsync(); |
|
|
|
|
|
|
|
GL.Clear(ClearBufferMask.ColorBufferBit); |
|
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObject); |
|
|
|