| … | … | @@ -370,10 +370,9 @@ def _attempt_reconnect(): |
| 370 | 370 | _detector.register() |
| 371 | 371 | _detector.set_resize_callback(_on_shm_resized) |
| 372 | 372 | |
| 373 | # Re-initialize tile baker | |
| 374 | from .shm_protocol import REGION_SIZE | |
| 375 | tile_ring_offset = REGION_SIZE * 2 | |
| 376 | tile_ring_size = TILE_RING_SIZE | |
| 373 | # Re-initialize tile baker (use actual region size, not default) | |
| 374 | tile_ring_offset = _shm._region_size * 2 | |
| 375 | tile_ring_size = _shm.size - tile_ring_offset | |
| 377 | 376 | _baker = TileBaker(_shm, tile_size=128, max_mips=8) |
| 378 | 377 | _baker.init_ring_buffer(tile_ring_offset, tile_ring_size) |
| 379 | 378 |
| … | … | @@ -106,24 +106,29 @@ class ShmRegion: |
| 106 | 106 | def open(self, name: str, size: int) -> bool: |
| 107 | 107 | """Open an existing shared memory region (reader — will NOT unlink). |
| 108 | 108 | |
| 109 | If the SHM file is smaller than requested size, uses the actual | |
| 110 | file size to avoid mmap ValueError. | |
| 109 | Uses the actual file size and derives region_size from layout: | |
| 110 | shm = region0 + region1 + 8MB_tile_ring → region_size = (actual - 8MB) / 2 | |
| 111 | 111 | """ |
| 112 | 112 | self._name = name |
| 113 | 113 | path = f"/dev/shm{name}" |
| 114 | 114 | try: |
| 115 | 115 | self._fd = os.open(path, os.O_RDWR) |
| 116 | # Check actual file size to handle version mismatch | |
| 116 | # Use actual file size (handles resize and version mismatch) | |
| 117 | 117 | actual_size = os.fstat(self._fd).st_size |
| 118 | if actual_size < size: | |
| 118 | if actual_size != size: | |
| 119 | 119 | print( |
| 120 | f"BlenderBridge: SHM size mismatch — expected {size}, " | |
| 121 | f"got {actual_size}. Using actual size. " | |
| 122 | f"Restart Godot with updated .so to fix." | |
| 120 | f"BlenderBridge: SHM size {actual_size} " | |
| 121 | f"(expected {size}), using actual." | |
| 123 | 122 | ) |
| 124 | size = actual_size | |
| 123 | size = actual_size | |
| 125 | 124 | self._mm = mmap.mmap(self._fd, size) |
| 126 | 125 | self._size = size |
| 126 | # Derive region size from layout: 2 regions + 8 MB tile ring | |
| 127 | tile_ring = 8 * 1024 * 1024 | |
| 128 | if size > tile_ring: | |
| 129 | self._region_size = (size - tile_ring) // 2 | |
| 130 | else: | |
| 131 | self._region_size = REGION_SIZE | |
| 127 | 132 | self._owner = False |
| 128 | 133 | return True |
| 129 | 134 | except OSError: |
| … | … | @@ -867,7 +867,7 @@ void BlenderBridge::import_changes(Node *root) { |
| 867 | 867 | cursor += 4; |
| 868 | 868 | |
| 869 | 869 | // Bounds check: ensure position data fits within the entry |
| 870 | if (vert_count > 100000 || cursor + vert_count * 12 > data_end) { | |
| 870 | if (vert_count == 0 || cursor + vert_count * 12 > data_end) { | |
| 871 | 871 | UtilityFunctions::printerr("BlenderBridge: vert_count out of bounds: ", (int)vert_count); |
| 872 | 872 | continue; |
| 873 | 873 | } |