BioGTK  6.5.0
A .NET library & program for annotating, editing various microscopy imaging formats using Bioformats supported images. Including whole slide, pyramidal, and series.
Loading...
Searching...
No Matches
BioGTK.SlideGLArea Class Reference

A GTK GLArea widget that renders pyramidal slide tiles directly on the GPU. Eliminates ReadPixels overhead by rendering to screen instead of copying to CPU. Supports SkiaSharp overlay for annotations via GRContext. More...

Inheritance diagram for BioGTK.SlideGLArea:

Public Member Functions

void UploadTileTexture (TileIndex index, byte[] pixelData, int tileWidth, int tileHeight)
 Upload a tile texture to the GPU. Call from the main thread.
 
bool HasTileTexture (TileIndex index)
 Check if a tile texture is already in the GPU cache.
 
void ReleaseTileTexture (TileIndex index)
 Release a specific tile texture.
 
void ReleaseLevelTextures (int level)
 Release all textures for a specific pyramid level.
 
void ClearTextureCache ()
 Clear all cached textures.
 
void RequestRedraw ()
 Request a redraw of the GLArea.
 
void SetTilesToRender (IEnumerable< TileRenderInfo > tiles)
 Prepare tiles for rendering. Call before RequestRedraw().
 
byte[] ReadPixels ()
 Read pixels from the current framebuffer (for export/save operations). This is slow - only use for export, not display.
 

Properties

List< TileRenderInfoTilesToRender = new() [get]
 
bool NeedsRedraw = true [get, set]
 

Events

Action< SKCanvas, int, int > OnSkiaRender
 Event fired during Skia rendering phase for annotation drawing.
 

Detailed Description

A GTK GLArea widget that renders pyramidal slide tiles directly on the GPU. Eliminates ReadPixels overhead by rendering to screen instead of copying to CPU. Supports SkiaSharp overlay for annotations via GRContext.

Definition at line 19 of file SlideGLArea.cs.

Constructor & Destructor Documentation

◆ SlideGLArea()

BioGTK.SlideGLArea.SlideGLArea ( )

Definition at line 115 of file SlideGLArea.cs.

116 {
117 HasDepthBuffer = false;
118 HasStencilBuffer = false;
119 AutoRender = false; // We control when to render
120
121 Realized += OnRealized;
122 //Unrealize += OnUnrealize;
123 Render += OnRender;
124 Resize += OnResized;
125 }

Member Function Documentation

◆ ClearTextureCache()

void BioGTK.SlideGLArea.ClearTextureCache ( )

Clear all cached textures.

Definition at line 481 of file SlideGLArea.cs.

482 {
483 if (!_glInitialized) return;
484
485 MakeCurrent();
486
487 foreach (var tex in _textureCache.Values)
488 {
489 GL.DeleteTexture(tex);
490 }
491 _textureCache.Clear();
492 }

◆ HasTileTexture()

bool BioGTK.SlideGLArea.HasTileTexture ( TileIndex index)

Check if a tile texture is already in the GPU cache.

Definition at line 443 of file SlideGLArea.cs.

444 {
445 return _textureCache.ContainsKey(index);
446 }

◆ ReadPixels()

byte[] BioGTK.SlideGLArea.ReadPixels ( )

Read pixels from the current framebuffer (for export/save operations). This is slow - only use for export, not display.

Definition at line 532 of file SlideGLArea.cs.

533 {
534 if (!_glInitialized) return null;
535
536 MakeCurrent();
537
538 int width = AllocatedWidth;
539 int height = AllocatedHeight;
540
541 byte[] pixels = new byte[width * height * 4];
542 GL.ReadPixels(0, 0, width, height, PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
543
544 return pixels;
545 }

◆ ReleaseLevelTextures()

void BioGTK.SlideGLArea.ReleaseLevelTextures ( int level)

Release all textures for a specific pyramid level.

Definition at line 464 of file SlideGLArea.cs.

465 {
466 if (!_glInitialized) return;
467
468 MakeCurrent();
469
470 var toRemove = _textureCache.Where(kvp => kvp.Key.Level == level).ToList();
471 foreach (var kvp in toRemove)
472 {
473 GL.DeleteTexture(kvp.Value);
474 _textureCache.Remove(kvp.Key);
475 }
476 }

◆ ReleaseTileTexture()

void BioGTK.SlideGLArea.ReleaseTileTexture ( TileIndex index)

Release a specific tile texture.

Definition at line 451 of file SlideGLArea.cs.

452 {
453 if (_textureCache.TryGetValue(index, out int tex))
454 {
455 MakeCurrent();
456 GL.DeleteTexture(tex);
457 _textureCache.Remove(index);
458 }
459 }

◆ RequestRedraw()

void BioGTK.SlideGLArea.RequestRedraw ( )

Request a redraw of the GLArea.

Definition at line 512 of file SlideGLArea.cs.

513 {
514 NeedsRedraw = true;
515 QueueRender();
516 }

◆ SetTilesToRender()

void BioGTK.SlideGLArea.SetTilesToRender ( IEnumerable< TileRenderInfo > tiles)

Prepare tiles for rendering. Call before RequestRedraw().

Definition at line 521 of file SlideGLArea.cs.

522 {
523 TilesToRender.Clear();
524 TilesToRender.AddRange(tiles);
525 Console.WriteLine($"Set {TilesToRender.Count} tiles to render");
526 }

◆ UploadTileTexture()

void BioGTK.SlideGLArea.UploadTileTexture ( TileIndex index,
byte[] pixelData,
int tileWidth,
int tileHeight )

Upload a tile texture to the GPU. Call from the main thread.

Definition at line 390 of file SlideGLArea.cs.

391 {
392 if (!_glInitialized)
393 {
394 Console.WriteLine("WARNING: GL not initialized, cannot upload texture");
395 return;
396 }
397
398 if (pixelData == null || pixelData.Length == 0)
399 {
400 Console.WriteLine($"WARNING: Empty pixel data for tile {index}");
401 return;
402 }
403
404 MakeCurrent();
405
406 // Check if already cached
407 if (_textureCache.ContainsKey(index))
408 {
409 Console.WriteLine($"Tile {index} already cached");
410 return;
411 }
412
413 // Evict old textures if cache is full
414 if (_textureCache.Count >= MAX_CACHED_TEXTURES)
415 {
416 EvictOldestTextures(MAX_CACHED_TEXTURES / 4);
417 }
418
419 // Create and upload texture
420 int tex = GL.GenTexture();
421 GL.BindTexture(TextureTarget.Texture2D, tex);
422
423 GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
424
425 // CRITICAL FIX: Use Rgba instead of Bgra for internal format consistency
426 GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba,
427 tileWidth, tileHeight, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixelData);
428
429 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
430 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
431 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
432 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
433
434 GL.BindTexture(TextureTarget.Texture2D, 0);
435
436 _textureCache[index] = tex;
437 Console.WriteLine($"Uploaded tile {index} as texture {tex} ({tileWidth}x{tileHeight}, {pixelData.Length} bytes)");
438 }

Property Documentation

◆ NeedsRedraw

bool BioGTK.SlideGLArea.NeedsRedraw = true
getset

Definition at line 56 of file SlideGLArea.cs.

56{ get; set; } = true;

◆ TilesToRender

List<TileRenderInfo> BioGTK.SlideGLArea.TilesToRender = new()
get

Definition at line 55 of file SlideGLArea.cs.

55{ get; } = new();

Event Documentation

◆ OnSkiaRender

Action<SKCanvas, int, int> BioGTK.SlideGLArea.OnSkiaRender

Event fired during Skia rendering phase for annotation drawing.

Definition at line 61 of file SlideGLArea.cs.


The documentation for this class was generated from the following file: