Skip to content

Commit cd91db8

Browse files
committed
proper cleanup of textures
1 parent 654f4d8 commit cd91db8

5 files changed

Lines changed: 44 additions & 9 deletions

File tree

webgpu/camera.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,11 @@ def get_shader_code(self):
152152
def __del__(self):
153153
del self.uniforms
154154

155-
def register_callbacks(self, input_handler, redraw_function, get_position_function=None):
155+
def set_render_functions(self, redraw_function, get_position_function=None):
156156
self._render_function = redraw_function
157157
self._get_position_function = get_position_function
158+
159+
def register_callbacks(self, input_handler):
158160
input_handler.on_mousedown(self._on_mousedown)
159161
input_handler.on_mouseup(self._on_mouseup)
160162
input_handler.on_mouseout(self._on_mouseup)

webgpu/canvas.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,12 @@ class Canvas:
7777

7878
device: Device
7979
depth_format: TextureFormat
80-
depth_texture: Texture
81-
multisample_texture: Texture
82-
multisample: MultisampleState
83-
target_texture: Texture
80+
depth_texture: Texture = None
81+
multisample_texture: Texture = None
82+
multisample: MultisampleState = None
83+
target_texture: Texture = None
84+
select_depth_texture: Texture = None
85+
select_texture: Texture = None
8486

8587
width: int = 0
8688
height: int = 0
@@ -142,6 +144,14 @@ def update_html_canvas(self, html_canvas):
142144
self.context.unconfigure()
143145

144146
self.canvas = html_canvas
147+
self.destroy_textures()
148+
149+
if html_canvas is None:
150+
self.context = None
151+
for func in self._on_update_html_canvas:
152+
func(html_canvas)
153+
return
154+
145155
self.context = html_canvas.getContext("webgpu")
146156
self.context.configure(
147157
{
@@ -207,10 +217,24 @@ def save_screenshot(self, filename: str):
207217
canvas.remove()
208218
path.write_bytes(b64decode(canvas.toDataURL(format).split(",")[1]))
209219

220+
def destroy_textures(self):
221+
with self._update_mutex:
222+
for tex in [
223+
self.target_texture,
224+
self.multisample_texture,
225+
self.depth_texture,
226+
self.select_texture,
227+
self.select_depth_texture,
228+
]:
229+
if tex is not None:
230+
tex.destroy()
231+
210232
@debounce(5)
211233
def resize(self):
212234
with self._update_mutex:
213235
canvas = self.canvas
236+
if canvas is None:
237+
return
214238
rect = canvas.getBoundingClientRect()
215239
width = int(rect.width)
216240
height = int(rect.height)
@@ -229,6 +253,9 @@ def resize(self):
229253
canvas.height = height
230254

231255
device = self.device
256+
257+
self.destroy_textures()
258+
232259
self.target_texture = device.createTexture(
233260
size=[width, height, 1],
234261
sampleCount=1,

webgpu/input_handler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def set_canvas(self, html_canvas):
2020
if self.html_canvas:
2121
self.unregister_callbacks()
2222
self.html_canvas = html_canvas
23-
self.register_callbacks()
23+
if self.html_canvas:
24+
self.register_callbacks()
2425

2526
def __on_mousedown(self, _):
2627
self._is_mousedown = True

webgpu/scene.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ def init(self, canvas):
104104

105105
camera = self.options.camera
106106
self._js_render = platform.create_proxy(self._render_direct)
107-
camera.register_callbacks(self.input_handler, self.render, self.get_position)
107+
camera.set_render_functions(self.render, self.get_position)
108+
camera.register_callbacks(self.input_handler)
108109
# if is_pyodide:
109110
# _scenes_by_id[self.id] = self
110111

@@ -121,9 +122,11 @@ def init(self, canvas):
121122
canvas.on_update_html_canvas(self.__on_update_html_canvas)
122123

123124
def __on_update_html_canvas(self, html_canvas):
124-
self.input_handler.unregister_callbacks()
125125
self.input_handler.set_canvas(html_canvas)
126-
self.options.camera.register_callbacks(self.input_handler, self.render, self.get_position)
126+
if html_canvas is not None:
127+
camera = self.options.camera
128+
camera.set_render_functions(self.render, self.get_position)
129+
camera.set_canvas(self.canvas)
127130

128131
def get_position(self, x: int, y: int):
129132
objects = self.render_objects

webgpu/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
_device: Device = None
1111

1212
_lock_init_device = threading.Lock()
13+
14+
1315
def init_device_sync():
1416
global _device
1517
with _lock_init_device:

0 commit comments

Comments
 (0)