Skip to content

Commit

Permalink
fix: force memory free allocation when disposing materials and geomet…
Browse files Browse the repository at this point in the history
…ries (#463)
  • Loading branch information
alvarosabu authored Dec 9, 2023
1 parent 00d71eb commit 1ef3533
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 18 deletions.
2 changes: 1 addition & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"vue-router": "^4.2.5"
},
"devDependencies": {
"@tresjs/leches": "^0.13.0",
"@tresjs/leches": "0.15.0-next.3",
"@tweakpane/plugin-essentials": "^0.2.0",
"unplugin-auto-import": "^0.17.1",
"vite-plugin-glsl": "^1.2.0",
Expand Down
7 changes: 7 additions & 0 deletions playground/src/pages/empty.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script setup>
</script>

<template>
<div />
</template>
49 changes: 49 additions & 0 deletions playground/src/pages/perf/AkuAku.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { useGLTF } from '@tresjs/cientos'
import { useControls } from '@tresjs/leches'
const { nodes } = await useGLTF(
'https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/aku-aku/AkuAku.gltf',
{ draco: true },
)
const model = nodes.AkuAku
/* useControls({
button: {
label: 'Manual dispose',
type: 'button',
onClick() {
disposeModel()
},
},
}) */
function disposeModel() {
console.log('disposingModel')
model.traverse((child) => {
if (child.isMesh) {
// Dispose of the material
if (child.material) {
child.material.dispose()
}
// Dispose of the geometry
if (child.geometry) {
child.geometry.dispose()
}
}
})
console.log('disposingModel Finished')
}
model.traverse((child) => {
if (child.material) {
console.log('child.material', child.material.uuid)
}
})
</script>

<template>
<primitive :object="model" />
</template>
65 changes: 65 additions & 0 deletions playground/src/pages/perf/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { BasicShadowMap, SRGBColorSpace, NoToneMapping } from 'three'
import { TresLeches, Perf, useControls } from '@tresjs/leches'
import '@tresjs/leches/styles'
import { OrbitControls } from '@tresjs/cientos'
import { useRouter } from 'vue-router'
import AkuAku from './AkuAku.vue'
const gl = {
clearColor: '#82DBC5',
shadows: true,
alpha: false,
shadowMapType: BasicShadowMap,
outputColorSpace: SRGBColorSpace,
toneMapping: NoToneMapping,
}
const router = useRouter()
const { sphere } = useControls({
sphere: true,
})
const ctx = ref(null)
watchEffect(() => {
if (!ctx.value) return
console.log('ctx', ctx.value)
})
useControls({
button: {
label: 'Render dispose',
type: 'button',
onClick() {
ctx.value.dispose()
},
},
})
</script>

<template>
<TresLeches />
<TresCanvas
v-bind="gl"
ref="ctx"
>
<Perf />
<TresPerspectiveCamera :position="[3, 3, 3]" />
<OrbitControls />
<Suspense>
<AkuAku v-if="sphere" />
</Suspense>
<!-- <TresMesh
v-if="sphere.value"
:position="[0, 0, 0]"
>
<TresSphereGeometry />
<TresMeshStandardMaterial color="teal" />
</TresMesh> -->
<TresAmbientLight :intensity="1" />
</TresCanvas>
</template>
10 changes: 10 additions & 0 deletions playground/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ const routes = [
name: 'Click Blocking Box',
component: () => import('./pages/click-blocking-box.vue'),
},
{
path: '/perf',
name: 'Perf',
component: () => import('./pages/perf/index.vue'),
},
{
path: '/empty',
name: 'empty',
component: () => import('./pages/empty.vue'),
},
]
export const router = createRouter({
history: createWebHistory(),
Expand Down
43 changes: 33 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions src/components/TresCanvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,13 @@ const mountCustomRenderer = (context: TresContext) => {
render(h(InternalComponent), scene.value as unknown as TresObject)
}
const dispose = (context: TresContext) => {
const dispose = (context: TresContext, force = false) => {
scene.value.children = []
if (force) {
context.renderer.value.dispose()
context.renderer.value.renderLists.dispose()
context.renderer.value.forceContextLoss()
}
mountCustomRenderer(context)
resume()
}
Expand All @@ -111,7 +116,7 @@ const disableRender = computed(() => props.disableRender)
const context = shallowRef<TresContext | null>(null)
defineExpose({ context })
defineExpose({ context, dispose: () => dispose(context.value as TresContext, true) })
onMounted(() => {
const existingCanvas = canvas as Ref<HTMLCanvasElement>
Expand Down
1 change: 0 additions & 1 deletion src/composables/useTresContextProvider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export function useTresContextProvider({
}

provide('useTres', toProvide)

return toProvide
}

Expand Down
13 changes: 9 additions & 4 deletions src/core/nodeOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,15 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
const disposeMaterialsAndGeometries = (object3D: Object3D) => {
const tresObject3D = object3D as TresObject3D

if (!object3D.userData.tres__materialViaProp) tresObject3D.material?.dispose()
if (!object3D.userData.tres__geometryViaProp)
if (!object3D.userData.tres__materialViaProp) {
tresObject3D.material?.dispose()
tresObject3D.material = undefined
}

if (!object3D.userData.tres__geometryViaProp) {
tresObject3D.geometry?.dispose()
tresObject3D.geometry = undefined
}
}

const deregisterAtPointerEventHandler = scene?.userData.tres__deregisterAtPointerEventHandler
Expand Down Expand Up @@ -161,6 +167,7 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
deregisterCamera?.(object as Camera)
}

node.removeFromParent?.()
object3D.traverse((child: Object3D) => {
disposeMaterialsAndGeometries(child)
deregisterCameraIfRequired(child)
Expand All @@ -172,8 +179,6 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
deregisterAtPointerEventHandlerIfRequired?.(object3D as TresObject)
}

node.removeFromParent?.()

node.dispose?.()
},
patchProp(node, prop, _prevValue, nextValue) {
Expand Down

0 comments on commit 1ef3533

Please sign in to comment.