Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Libload/ Libfree have issues with multiple scenes. #805

Closed
RockyMadio opened this issue Aug 22, 2018 · 2 comments
Closed

Libload/ Libfree have issues with multiple scenes. #805

RockyMadio opened this issue Aug 22, 2018 · 2 comments
Assignees
Labels

Comments

@RockyMadio
Copy link

If you execute libload and libfree on a single scene, it will work perfectly fine.
But if this scene is having an overlay scene OR being a background scene of another scene, after libfreeing the data, the game will crash right away.

You can reset the scene , but libload will not longer work. It says that library is still loaded, but nothing will appear.

I hope this issue will be set on high priority.
http://pasteall.org/blend/index.php?id=50213
http://pasteall.org/blend/index.php?id=50214

the test data has a great size for testing purpose.

@RockyMadio
Copy link
Author

S to load, and A to free

@panzergame
Copy link
Contributor

@RockyMadio : Could you test the branch ge_bug_fix_805 please ?

panzergame added a commit that referenced this issue Sep 5, 2018
panzergame added a commit that referenced this issue Sep 6, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the scene conversion of a libloaded scene. And the minor
task is avoiding end up with only a part of scene materials using all the lights
present.

The first point is solved by the introduction of a ressource base class:
BL_Ressource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is an opaque intptr_t and the function
BL_Ressource::Belong(intptr_t) return true when the passed library identifier
match the one of the ressource.
The classes inheriting from BL_Ressource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

This last class is used to wrap bAction and link the BL_ScalarInterpolator of
the action. All the actions are converted and registered during scene conversion
as the cost is negligeable.
All these ressource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveRessources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveRessources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

Fix issue: #805
panzergame added a commit that referenced this issue Sep 9, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the scene conversion of a libloaded scene. And the minor
task is avoiding end up with only a part of scene materials using all the lights
present.

The first point is solved by the introduction of a ressource base class:
BL_Ressource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is an opaque intptr_t and the function
BL_Ressource::Belong(intptr_t) return true when the passed library identifier
match the one of the ressource.
The classes inheriting from BL_Ressource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

This last class is used to wrap bAction and link the BL_ScalarInterpolator of
the action. All the actions are converted and registered during scene conversion
as the cost is negligeable.
All these ressource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveRessources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveRessources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

Fix issue: #805
@lordloki lordloki added this to In progress in 0.2.4 Sep 15, 2018
panzergame added a commit that referenced this issue Sep 22, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the scene conversion of a libloaded scene. And the minor
task is avoiding end up with only a part of scene materials using all the lights
present.

The first point is solved by the introduction of a ressource base class:
BL_Ressource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is an opaque intptr_t and the function
BL_Ressource::Belong(intptr_t) return true when the passed library identifier
match the one of the ressource.
The classes inheriting from BL_Ressource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

This last class is used to wrap bAction and link the BL_ScalarInterpolator of
the action. All the actions are converted and registered during scene conversion
as the cost is negligeable.
All these ressource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveRessources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveRessources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

Fix issue: #805
panzergame added a commit that referenced this issue Sep 28, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the conversion of a libloaded scene. And the minor task is
avoiding end up with only a part of scene materials using all present lights.

The first point is solved by the introduction of a resource base class:
BL_Resource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is opaque type Bl_Resource::Library
and the function BL_Resource::Belong(Library) returns true when the passed
library identifier match the one of the resource.
The classes inheriting from BL_Resource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

All these resource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveResources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Some modifications were introduced to ease the libfree. The class BL_ActionData
is used to wrap bAction and link the BL_ScalarInterpolator of the action. All
the actions are converted and registered during scene conversion as the cost is
negligeable.
When a RAS_Texture is free (indirectly by material free while lib free) if the
renderer is non null, then the texture unregister itself from the renderer, this
mechanism of texture users is near to be obsolete.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

Fix issue #805.
panzergame added a commit that referenced this issue Sep 30, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the conversion of a libloaded scene. And the minor task is
avoiding end up with only a part of scene materials using all present lights.

The first point is solved by the introduction of a resource base class:
BL_Resource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is opaque type Bl_Resource::Library
and the function BL_Resource::Belong(Library) returns true when the passed
library identifier match the one of the resource.
The classes inheriting from BL_Resource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

All these resource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveResources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Some modifications were introduced to ease the libfree. The class BL_ActionData
is used to wrap bAction and link the BL_ScalarInterpolator of the action. All
the actions are converted and registered during scene conversion as the cost is
negligeable.
When a RAS_Texture is free (indirectly by material free while lib free) if the
renderer is non null, then the texture unregister itself from the renderer, this
mechanism of texture users is near to be obsolete.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

While reviewing and testing #805, two bugs were noticed. First the animations
were not merged in the targeted scene, second the textures could be initialized
in the conversion thread whithout opengl context.

The first report is fixed by in case of scenes merging creating a converter
which aim the conversion of animations of all scenes to merge, the function
BL_ConvertActions is called with this converter and convert all actions
from a library.
The second issue is resolved by moving the call to InitTextures in
KX_BlenderMaterial::ReloadShader which is the only place called synchronously
during material conversion.

Fix issue #805.
panzergame added a commit that referenced this issue Oct 1, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the conversion of a libloaded scene. And the minor task is
avoiding end up with only a part of scene materials using all present lights.

The first point is solved by the introduction of a resource base class:
BL_Resource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is opaque type Bl_Resource::Library
and the function BL_Resource::Belong(Library) returns true when the passed
library identifier match the one of the resource.
The classes inheriting from BL_Resource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

All these resource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveResources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Some modifications were introduced to ease the libfree. The class BL_ActionData
is used to wrap bAction and link the BL_ScalarInterpolator of the action. All
the actions are converted and registered during scene conversion as the cost is
negligeable.
When a RAS_Texture is free (indirectly by material free while lib free) if the
renderer is non null, then the texture unregister itself from the renderer, this
mechanism of texture users is near to be obsolete.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

While reviewing and testing #805, two bugs were noticed. First the animations
were not merged in the targeted scene, second the textures could be initialized
in the conversion thread whithout opengl context.

The first report is fixed by in case of scenes merging creating a converter
which aim the conversion of animations of all scenes to merge, the function
BL_ConvertActions is called with this converter and convert all actions
from a library.
The second issue is resolved by moving the call to InitTextures in
KX_BlenderMaterial::ReloadShader which is the only place called synchronously
during material conversion.

Fix issue #805.
panzergame added a commit that referenced this issue Oct 1, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the conversion of a libloaded scene. And the minor task is
avoiding end up with only a part of scene materials using all present lights.

The first point is solved by the introduction of a resource base class:
BL_Resource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is opaque type Bl_Resource::Library
and the function BL_Resource::Belong(Library) returns true when the passed
library identifier match the one of the resource.
The classes inheriting from BL_Resource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

All these resource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveResources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Some modifications were introduced to ease the libfree. The class BL_ActionData
is used to wrap bAction and link the BL_ScalarInterpolator of the action. All
the actions are converted and registered during scene conversion as the cost is
negligeable.
When a RAS_Texture is free (indirectly by material free while lib free) if the
renderer is non null, then the texture unregister itself from the renderer, this
mechanism of texture users is near to be obsolete.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

While reviewing and testing #805, two bugs were noticed. First the animations
were not merged in the targeted scene, second the textures could be initialized
in the conversion thread whithout opengl context.

The first report is fixed by in case of scenes merging creating a converter
which aim the conversion of animations of all scenes to merge, the function
BL_ConvertActions is called with this converter and convert all actions
from a library.
The second issue is resolved by moving the call to InitTextures in
KX_BlenderMaterial::ReloadShader which is the only place called synchronously
during material conversion.

Fix issue #805.
panzergame added a commit that referenced this issue Oct 1, 2018
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the conversion of a libloaded scene. And the minor task is
avoiding end up with only a part of scene materials using all present lights.

The first point is solved by the introduction of a resource base class:
BL_Resource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is opaque type Bl_Resource::Library
and the function BL_Resource::Belong(Library) returns true when the passed
library identifier match the one of the resource.
The classes inheriting from BL_Resource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

All these resource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveResources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Some modifications were introduced to ease the libfree. The class BL_ActionData
is used to wrap bAction and link the BL_ScalarInterpolator of the action. All
the actions are converted and registered during scene conversion as the cost is
negligeable.
When a RAS_Texture is free (indirectly by material free while lib free) if the
renderer is non null, then the texture unregister itself from the renderer, this
mechanism of texture users is near to be obsolete.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

While reviewing and testing #805, two bugs were noticed. First the animations
were not merged in the targeted scene, second the textures could be initialized
in the conversion thread whithout opengl context.

The first report is fixed by in case of scenes merging creating a converter
which aim the conversion of animations of all scenes to merge, the function
BL_ConvertActions is called with this converter and convert all actions
from a library.
The second issue is resolved by moving the call to InitTextures in
KX_BlenderMaterial::ReloadShader which is the only place called synchronously
during material conversion.

Fix issue #805.
@lordloki lordloki removed this from In progress in 0.2.4 Oct 1, 2018
youle31 pushed a commit that referenced this issue May 26, 2019
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is
reproduced by using two scenes which both use meshes without material (so using
defmaterial) and the first scene LibLoad and merge the second. What is happening
is that the new created scene will contain a RAS_MaterialBucket of defmaterial
which is also used by the host scene, but defmaterial is not owned by any file
as it's a global default material.
The technique used by LibFree was to tag all ID structs (data, e.g Mesh,
Material, Object) of a Main (the file loaded) and remove them from scenes and
users. In the situation of defmaterial, this struct is never tagged and so never
removed during LibFree. This resulted in a material always existing but all the
light objects used were removed and the function GPU_material_update_lamps
called in material preparation before rendering raise an illegal memory access
as it was iterating on freed lamps.

To solve this issue we have to find a way to remove all game engine data that
were created during the conversion of a libloaded scene. And the minor task is
avoiding end up with only a part of scene materials using all present lights.

The first point is solved by the introduction of a resource base class:
BL_Resource. The goal of this class is to store an identifier of the library
source of converted data. This identifier is opaque type Bl_Resource::Library
and the function BL_Resource::Belong(Library) returns true when the passed
library identifier match the one of the resource.
The classes inheriting from BL_Resource are:
- BL_ConvertObjectInfo
- KX_Mesh
- KX_BlenderMaterial
- BL_ActionData

All these resource types are registered in BL_SceneConverter where all
registering function set the library identifier from the one passed to
BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and
ConvertScene(KX_Scene *scene) (the functions creating a scene converter)
BL_SceneConverter is created using as library identifier the Main pointer of the
current file or the loaded file, this way we also ensure that all linked data of
a file will be owned by the same library. Other than that the loading changed by
the call of the function ReloadShaders to reload all shaders of a merged scene:
the new and old shaders, to benefit of all existing lights.

Concerning LibFree, the first modification is to delay the free to the end of
the frame instead doing it instantly. To achieve it, FreeBlendFile(const
std::string& path) stores the library path to free in m_freeQueue if the library
exists and the function ProcessScheduledLibraries process the merging of the
libloads and the free of libraries, this final function is called in
KX_KetsjiEngine::NextFrame at the end of each logic frame.
The actual library free takes place in FreeBlendFileData. It iterates over all
scenes and objects, if the object convert object info belongs to the free
library the object is removed else KX_GameObject::RemoveResources is called.
Finally the materials, meshes and actions of the library are removed from scene
data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the
meshes that belong to the library or using materials from the library, and do
the same for actions currently played.
Previously BL_ActionManager was also impacted by LibFree as it was using
bAction, now the actuator is using a action name to remove this complexity when
freeing an action.

Some modifications were introduced to ease the libfree. The class BL_ActionData
is used to wrap bAction and link the BL_ScalarInterpolator of the action. All
the actions are converted and registered during scene conversion as the cost is
negligeable.
When a RAS_Texture is free (indirectly by material free while lib free) if the
renderer is non null, then the texture unregister itself from the renderer, this
mechanism of texture users is near to be obsolete.

Shader are now recompiled when merging and freeing a library to ensure that the
lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated
for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or
create a new one if it wasn't initialized.

While reviewing and testing #805, two bugs were noticed. First the animations
were not merged in the targeted scene, second the textures could be initialized
in the conversion thread whithout opengl context.

The first report is fixed by in case of scenes merging creating a converter
which aim the conversion of animations of all scenes to merge, the function
BL_ConvertActions is called with this converter and convert all actions
from a library.
The second issue is resolved by moving the call to InitTextures in
KX_BlenderMaterial::ReloadShader which is the only place called synchronously
during material conversion.

Fix issue #805.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants