defer texture delete to avoid overwriting the texture during a frame

This commit is contained in:
olebeck 2025-07-15 14:44:05 +02:00
parent 0775db63a6
commit cb895e05c5
7 changed files with 357 additions and 56 deletions

View File

@ -1,13 +1,229 @@
<?xml version="1.0" encoding="utf-8"?>
<resource version="0.1" type="normal" id="sample_plugin">
<?xml-model href="https://raw.githubusercontent.com/olebeck/paf-rcd/refs/heads/master/rco.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
<resource version="0.1" type="normal" id="config_plugin">
<pagetable>
<page id="page_main">
<plane style="style_plane_sample_black" id="plane_sample_black">
<plane style="_common_style_plane_transparent" id="main_plane">
<layout_hint size="960, 544" />
<text style="_common_default_style_text" id="test_strings_id" label="msg_test_text">
<layout_hint adjust="2, 2" anchor="0, 0" align="0, 0" size="0, 0" pos="0, 0" />
</text>
<box> <!-- horizontal -->
<layout_box adjust="1, 1" layout_type="2" />
<plane texture="tex_shark" id="shark_image">
<layout_hint pos="0, 0" size="203, 544" align="1, 0" anchor="1, 0" />
</plane>
<plane texture="tex_settings_bg">
<layout_hint adjust="1, 1" />
<box> <!-- scrollable settings -->
<layout_box adjust="1, 1" layout_type="1" />
<scroll_view style="_common_style_scroll_view_transparent"
w_sbar_v="vertical_scroll_bar" snap_anim_time="0">
<layout_hint adjust="1, 1" />
<box> <!-- vertical scroll -->
<layout_box layout_type="1" space="40" adjust="1, 2" left_margin="20"
right_margin="20" />
<box> <!-- header text -->
<layout_box top_margin="10" />
<text style="_common_default_style_text" label="msg_lego_island_config">
<layout_hint adjust="2, 2" />
</text>
</box>
<box> <!-- Island Texture Quality -->
<layout_box layout_type="1" adjust="2, 2" />
<text label="msg_island_texture">
<layout_hint adjust="2, 2" />
</text>
<radio_box style="_common_default_style_radio_box">
<layout_hint adjust="2, 2" />
<box>
<layout_box layout_type="2" space="15" adjust="2, 2" />
<radio_button style="_common_default_style_radio_button">
<layout_hint size="44, 44" />
</radio_button>
<text label="msg_quality_low">
<layout_hint adjust="2, 2" />
</text>
<radio_button style="_common_default_style_radio_button">
<layout_hint size="44, 44" />
</radio_button>
<text label="msg_quality_medium">
<layout_hint adjust="2, 2" />
</text>
<radio_button style="_common_default_style_radio_button">
<layout_hint size="44, 44" />
</radio_button>
<text label="msg_quality_high">
<layout_hint adjust="2, 2" />
</text>
</box>
</radio_box>
</box>
<box> <!-- Island Model Quality -->
<layout_box layout_type="1" />
<text label="msg_island_quality">
<layout_hint adjust="2, 2" />
</text>
<radio_box style="_common_default_style_radio_box">
<box>
<layout_box layout_type="2" space="15" />
<radio_button style="_common_default_style_radio_button">
<layout_hint size="44, 44" />
</radio_button>
<text label="msg_texture_fast">
<layout_hint adjust="2, 2" />
</text>
<radio_button style="_common_default_style_radio_button">
<layout_hint size="44, 44" />
</radio_button>
<text label="msg_texture_high">
<layout_hint adjust="2, 2" />
</text>
</box>
</radio_box>
</box>
<box> <!-- sliders -->
<layout_box layout_type="2" space="40" />
<box> <!-- Max LOD -->
<layout_box layout_type="1" space="20" />
<text label="msg_max_lod">
<layout_hint adjust="2, 2" />
</text>
<plane>
<layout_hint adjust="2, 2" />
<slidebar style="_common_default_style_slidebar" slider_label_margin="20"
slider_label_mode="1" slider_size="64, 64, 0" slider_label_pos_mode="3"
touch_mode="1" id="_sample_widget_slidebar">
<layout_hint alpha="1" align="0" size="200, 12, 0" />
</slidebar>
</plane>
</box>
<box> <!-- Max Allowed Extras -->
<layout_box layout_type="1" space="20" />
<text label="msg_max_allowed_extras">
<layout_hint adjust="2, 2" />
</text>
<plane>
<layout_hint adjust="2, 2" />
<slidebar style="_common_default_style_slidebar" slider_size="52, 52, 0"
slider_label_pos_mode="3" touch_mode="1" id="_sample_widget_slidebar">
<layout_hint alpha="1" align="0" size="200, 12, 0" />
</slidebar>
</plane>
</box>
</box>
<box> <!-- checkboxes -->
<layout_box layout_type="1" space="20" align="1, 0" anchor="1, 0" />
<box> <!-- 3d sound -->
<layout_box layout_type="2" space="10" align="1" anchor="1" />
<check_box style="_common_style_check_box_scalable">
<layout_hint size="40, 40, 0" />
</check_box>
<text label="msg_3d_sound">
<layout_hint adjust="2, 2" />
</text>
</box>
<box> <!-- music -->
<layout_box layout_type="2" space="10" align="1" anchor="2" />
<check_box style="_common_style_check_box_scalable">
<layout_hint size="40, 40, 0" />
</check_box>
<text label="msg_music">
<layout_hint adjust="2, 2" />
</text>
</box>
<box> <!-- wide view angle -->
<layout_box layout_type="2" space="10" align="1" anchor="1" />
<check_box style="_common_style_check_box_scalable">
<layout_hint size="40, 40, 0" />
</check_box>
<text label="msg_wide_view_angle">
<layout_hint adjust="2, 2" />
</text>
</box>
<box> <!-- texture loader -->
<layout_box layout_type="2" space="10" align="1" anchor="1" />
<check_box style="_common_style_check_box_scalable">
<layout_hint size="40, 40, 0" />
</check_box>
<text label="msg_texture_loader">
<layout_hint adjust="2, 2" />
</text>
</box>
</box>
<plane style="_common_style_plane_transparent"> <!-- spacing for buttons on bottom -->
<layout_hint size="0, 70" adjust="1, 0" />
</plane>
</box>
<scrollbar style="_common_default_style_scrollbar" id="vertical_scroll_bar"
scroll_type="0">
<layout_hint size="5, 0" />
</scrollbar>
</scroll_view>
</box>
<plane style="_common_style_plane_transparent">
<layout_hint adjust="1, 0" size="0, 75" anchor="0, 1" align="0, 1" />
<box style="_common_default_style_box">
<layout_box space="20" layout_type="2" />
<button style="style_save_and_exit_button" id="save_exit_button"
label="msg_save_exit">
<layout_hint adjust="2, 2" />
</button>
<button style="style_save_and_launch_button" id="start_game_button"
label="msg_save_launch">
<layout_hint adjust="2, 2" />
</button>
<button style="style_exit_button" id="exit_button" label="msg_exit">
<layout_hint adjust="2, 2" />
</button>
</box>
</plane>
</plane>
</box>
</plane>
</page>
</pagetable>
@ -16,18 +232,71 @@
</templatetable>
<styletable>
<style_plane color="0, 0, 0, 1" planeobj="plane_obj1" id="style_plane_sample_black">
<planeobj id="plane_obj1" />
</style_plane>
<style_button glow_obj="plane_obj3" color="1, 1, 1, 1" highlight_obj="plane_obj2"
label_obj="text_obj1" bg_obj="plane_obj1" adjust_min_size="170, 54"
id="style_save_and_launch_button">
<planeobj color="0, 0.9, 0.5, 1" texture0="_common_texture_button_white" id="plane_obj1" />
<textobj font_size="20" color="1, 1, 1, 1" align_x="1" align_y="1" adjust_x="1" adjust_y="1"
id="text_obj1" />
<planeobj color="1, 1, 1, 1" texture0="_common_texture_button" id="plane_obj2" />
<planeobj texture0="_common_texture_button_glow" blend="2" id="plane_obj3" />
</style_button>
<style_button glow_obj="plane_obj3" color="1, 1, 1, 1" highlight_obj="plane_obj2"
label_obj="text_obj1" bg_obj="plane_obj1" adjust_min_size="170, 54"
id="style_save_and_exit_button">
<planeobj color="0, 0.5, 0.9, 1" texture0="_common_texture_button_white" id="plane_obj1" />
<textobj font_size="20" color="1, 1, 1, 1" align_x="1" align_y="1" adjust_x="1" adjust_y="1"
id="text_obj1" />
<planeobj color="1, 1, 1, 1" texture0="_common_texture_button" id="plane_obj2" />
<planeobj texture0="_common_texture_button_glow" blend="2" id="plane_obj3" />
</style_button>
<style_button glow_obj="plane_obj3" color="1, 1, 1, 1" highlight_obj="plane_obj2"
label_obj="text_obj1" bg_obj="plane_obj1" adjust_min_size="170, 54" id="style_exit_button">
<planeobj color="0.9, 0.5, 0.0, 1" texture0="_common_texture_button_white" id="plane_obj1" />
<textobj font_size="20" color="1, 1, 1, 1" align_x="1" align_y="1" adjust_x="1" adjust_y="1"
id="text_obj1" />
<planeobj color="1, 1, 1, 1" texture0="_common_texture_button" id="plane_obj2" />
<planeobj texture0="_common_texture_button_glow" blend="2" id="plane_obj3" />
</style_button>
</styletable>
<!-- If the system language is set to a language not listed here, no text will be displayed on the button. -->
<stringtable>
<!--
<locale src_="locale/ja.xml" compress="on" id="ja" />
-->
<locale src="locale/en.xml" compress="on" id="en" />
<!--
<locale src_="locale/en-gb.xml" compress="on" id="en-gb" />
<locale src_="locale/zh-s.xml" compress="on" id="zh-s" />
<locale src_="locale/zh-t.xml" compress="on" id="zh-t" />
<locale src_="locale/da.xml" compress="on" id="da" />
<locale src_="locale/nl.xml" compress="on" id="nl" />
<locale src_="locale/fi.xml" compress="on" id="fi" />
<locale src_="locale/fr.xml" compress="on" id="fr" />
<locale src_="locale/de.xml" compress="on" id="de" />
<locale src_="locale/it.xml" compress="on" id="it" />
<locale src_="locale/ko.xml" compress="on" id="ko" />
<locale src_="locale/no.xml" compress="on" id="no" />
<locale src_="locale/pl.xml" compress="on" id="pl" />
<locale src_="locale/pt.xml" compress="on" id="pt" />
<locale src_="locale/ru.xml" compress="on" id="ru" />
<locale src_="locale/es.xml" compress="on" id="es" />
<locale src_="locale/sv.xml" compress="on" id="sv" />
<locale src_="locale/pt-br.xml" compress="on" id="pt-br" />
<locale src_="locale/tr.xml" compress="on" id="tr" />
-->
</stringtable>
<texturetable>
<texture id="tex_shark" src="textures/shark.png" type="texture/png" />
<texture id="tex_settings_bg" src="textures/tex_settings_bg.gim" type="texture/gim" />
</texturetable>
<filetable>
</filetable>
</resource>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<stringset>
<string id="msg_lego_island_config" src="Lego Island Config"/>
<string id="msg_diskpath" src="isle:diskpath" />
<string id="msg_cdpath" src="isle:cdpath" />
<string id="msg_savepath" src="isle:savepath" />
<string id="msg_wide_view_angle" src="Wide View Angle" />
<string id="msg_3d_sound" src="3D Sound" />
<string id="msg_music" src="Music" />
<string id="msg_cursor_sensitivity" src="Cursor Sensitivity" />
<string id="msg_island_quality" src="Island Quality" />
<string id="msg_quality_low" src="low" />
<string id="msg_quality_medium" src="medium" />
<string id="msg_quality_high" src="high" />
<string id="msg_island_texture" src="Island Texture Quality" />
<string id="msg_texture_fast" src="fast" />
<string id="msg_texture_high" src="high" />
<string id="msg_max_lod" src="Max LOD" />
<string id="msg_max_allowed_extras" src="Max Allowed Extras" />
<string id="msg_transition_type" src="isle:Transition Type" />
<string id="msg_transition_none" src="none" />
<string id="msg_transition_dissolve" src="dissolve" />
<string id="msg_transition_mosaic" src="mosaic" />
<string id="msg_transition_wipe_down" src="wipe down" />
<string id="msg_transition_windows" src="windows" />
<string id="msg_texture_loader" src="Texture Loader Extension" />
<string id="msg_save_exit" src="Save &amp; Exit" />
<string id="msg_save_launch" src="Save &amp; Launch" />
<string id="msg_exit" src="Exit" />
</stringset>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

View File

@ -12,11 +12,15 @@ void loadPluginCB(paf::Plugin* plugin)
paf::Plugin::PageOpenParam pageOpenParam;
pageOpenParam.option = paf::Plugin::PageOption_None;
plugin->SetLocale(Locale_EN);
paf::ui::Scene* pScene = plugin->PageOpen("page_main", pageOpenParam);
g_rootPage = pScene;
paf::ui::Widget* pText = (paf::ui::Text*) pScene->FindChild("test_strings_id");
pText->SetString(L"Test Text");
pScene->SetDebugMode(paf::ui::Scene::DEBUG_AUTH_LAYOUT_RULER);
//paf::ui::Widget* pText = (paf::ui::Text*) pScene->FindChild("title_text");
//pText->SetString(L"Test Text");
}
int paf_main(void)

View File

@ -80,12 +80,16 @@ typedef struct GXMVertex {
typedef struct GXMDisplayData {
void* address;
int index;
} GXMDisplayData;
static void display_callback(const void* callback_data)
{
const GXMDisplayData* display_data = (const GXMDisplayData*) callback_data;
GXMRenderer* renderer = static_cast<GXMRenderer*>(DDRenderer);
renderer->DeleteTextures(display_data->index);
SceDisplayFrameBuf framebuf;
SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf));
framebuf.size = sizeof(SceDisplayFrameBuf);
@ -154,7 +158,7 @@ int gxm_library_init()
return 0;
}
#ifdef WITH_RAZOR
#ifdef GXM_WITH_RAZOR
load_razor();
#endif
@ -654,6 +658,7 @@ void GXMContext::swap_display()
// display
GXMDisplayData displayData;
displayData.address = this->displayBuffers[this->backBufferIndex];
displayData.index = this->backBufferIndex;
sceGxmDisplayQueueAddEntry(
this->displayBuffersSync[this->frontBufferIndex],
this->displayBuffersSync[this->backBufferIndex],
@ -913,21 +918,24 @@ void GXMRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* textu
[](IDirect3DRMObject* obj, void* arg) {
auto* ctx = static_cast<TextureDestroyContextGXM*>(arg);
auto& cache = ctx->renderer->m_textures[ctx->textureId];
for (int i = 0; i < cache.bufferCount; i++) {
if (cache.notifications[i]) {
sceGxmNotificationWait(cache.notifications[i]);
}
void* textureData = sceGxmTextureGetData(&cache.gxmTexture[i]);
gxm->free(textureData);
memset(&cache.gxmTexture[i], 0, sizeof(SceGxmTexture));
}
ctx->renderer->m_textures_delete[gxm->backBufferIndex].push_back(cache.gxmTexture);
cache.texture = nullptr;
memset(&cache.gxmTexture, 0, sizeof(SceGxmTexture));
delete ctx;
},
ctx
);
}
void GXMRenderer::DeleteTextures(int index)
{
for(auto& del : this->m_textures_delete[index]) {
void* textureData = sceGxmTextureGetData(&del);
gxm->free(textureData);
}
this->m_textures_delete[index].clear();
}
static void convertTextureMetadata(
SDL_Surface* surface,
bool* supportedFormat,
@ -1046,22 +1054,9 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi, float
auto& tex = m_textures[i];
if (tex.texture == texture) {
if (tex.version != texture->m_version) {
if (tex.bufferCount != GXM_TEXTURE_BUFFER_COUNT) {
for (int i = 1; i < GXM_TEXTURE_BUFFER_COUNT; i++) {
tex.gxmTexture[i] = tex.gxmTexture[0];
uint8_t* textureData = (uint8_t*) gxm->alloc(textureSize, textureAlignment);
sceGxmTextureSetData(&tex.gxmTexture[i], textureData);
}
tex.bufferCount = GXM_TEXTURE_BUFFER_COUNT;
}
if (tex.bufferCount > 1) {
tex.currentIndex = (tex.currentIndex + 1) % GXM_TEXTURE_BUFFER_COUNT;
}
if (tex.notifications[tex.currentIndex]) {
sceGxmNotificationWait(tex.notifications[tex.currentIndex]);
}
tex.notifications[tex.currentIndex] = &this->fragmentNotifications[this->currentFragmentBufferIndex];
uint8_t* textureData = (uint8_t*) sceGxmTextureGetData(&tex.gxmTexture[tex.currentIndex]);
sceGxmNotificationWait(tex.notification);
tex.notification = &this->fragmentNotifications[this->currentFragmentBufferIndex];
uint8_t* textureData = (uint8_t*) sceGxmTextureGetData(&tex.gxmTexture);
copySurfaceToGxm(surface, textureData, textureStride, textureSize);
tex.version = texture->m_version;
}
@ -1107,10 +1102,8 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi, float
memset(&tex, 0, sizeof(tex));
tex.texture = texture;
tex.version = texture->m_version;
tex.bufferCount = 1;
tex.currentIndex = 0;
tex.gxmTexture[0] = gxmTexture;
tex.notifications[0] = &this->fragmentNotifications[this->currentFragmentBufferIndex];
tex.gxmTexture = gxmTexture;
tex.notification = &this->fragmentNotifications[this->currentFragmentBufferIndex];
AddTextureDestroyCallback(i, texture);
return i;
}
@ -1120,16 +1113,20 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi, float
memset(&tex, 0, sizeof(tex));
tex.texture = texture;
tex.version = texture->m_version;
tex.bufferCount = 1;
tex.currentIndex = 0;
tex.gxmTexture[0] = gxmTexture;
tex.notifications[0] = &this->fragmentNotifications[this->currentFragmentBufferIndex];
tex.gxmTexture = gxmTexture;
tex.notification = &this->fragmentNotifications[this->currentFragmentBufferIndex];
m_textures.push_back(tex);
Uint32 textureId = (Uint32) (m_textures.size() - 1);
AddTextureDestroyCallback(textureId, texture);
return textureId;
}
const SceGxmTexture* GXMRenderer::UseTexture(GXMTextureCacheEntry& texture) {
texture.notification = &this->fragmentNotifications[this->currentFragmentBufferIndex];
sceGxmSetFragmentTexture(gxm->context, 0, &texture.gxmTexture);
return &texture.gxmTexture;
}
GXMMeshCacheEntry GXMRenderer::GXMUploadMesh(const MeshGroup& meshGroup)
{
GXMMeshCacheEntry cache{&meshGroup, meshGroup.version};

View File

@ -16,17 +16,14 @@ DEFINE_GUID(GXM_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00,
#define GXM_VERTEX_BUFFER_COUNT 2
#define GXM_FRAGMENT_BUFFER_COUNT 3
#define GXM_TEXTURE_BUFFER_COUNT 2
#define GXM_WITH_RAZOR DEBUG
struct GXMTextureCacheEntry {
IDirect3DRMTexture* texture;
Uint32 version;
int bufferCount;
int currentIndex;
SceGxmTexture gxmTexture[GXM_TEXTURE_BUFFER_COUNT];
SceGxmNotification* notifications[GXM_TEXTURE_BUFFER_COUNT];
SceGxmTexture gxmTexture;
SceGxmNotification* notification; // latest frame it was used in
};
struct GXMMeshCacheEntry {
@ -81,6 +78,7 @@ class GXMRenderer : public Direct3DRMRenderer {
void Download(SDL_Surface* target) override;
void SetDither(bool dither) override;
void DeleteTextures(int index);
private:
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
void AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh);
@ -88,13 +86,7 @@ class GXMRenderer : public Direct3DRMRenderer {
GXMMeshCacheEntry GXMUploadMesh(const MeshGroup& meshGroup);
void StartScene();
inline const SceGxmTexture* UseTexture(GXMTextureCacheEntry& texture)
{
texture.notifications[texture.currentIndex] = &this->fragmentNotifications[this->currentFragmentBufferIndex];
const SceGxmTexture* gxmTexture = &texture.gxmTexture[texture.currentIndex];
sceGxmSetFragmentTexture(gxm->context, 0, gxmTexture);
return gxmTexture;
}
const SceGxmTexture* UseTexture(GXMTextureCacheEntry& texture);
inline GXMVertex2D* QuadVerticesBuffer()
{
@ -113,6 +105,7 @@ class GXMRenderer : public Direct3DRMRenderer {
std::vector<GXMMeshCacheEntry> m_meshes;
D3DRMMATRIX4D m_projection;
std::vector<SceneLight> m_lights;
std::vector<SceGxmTexture> m_textures_delete[GXM_FRAGMENT_BUFFER_COUNT];
bool transparencyEnabled = false;