feat: Implement texture caching system with dirty flag optimization (closes #144)
- Add cache_subtree property on Frame for opt-in RenderTexture caching - Add PyTexture::from_rendered() factory for runtime texture creation - Add snapshot= parameter to Sprite for creating sprites from Frame content - Implement content_dirty vs composite_dirty distinction: - markContentDirty(): content changed, invalidate self and ancestors - markCompositeDirty(): position changed, ancestors need recomposite only - Update all UIDrawable position setters to use markCompositeDirty() - Add quick exit workaround for cleanup segfaults Benchmark: deep_nesting_cached is 3.7x faster (0.09ms vs 0.35ms) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8583db7225
commit
68f8349fe8
13 changed files with 220 additions and 56 deletions
|
|
@ -820,19 +820,39 @@ bool UIDrawable::contains_point(float x, float y) const {
|
|||
return global_bounds.contains(x, y);
|
||||
}
|
||||
|
||||
// #116 - Dirty flag propagation up parent chain
|
||||
void UIDrawable::markDirty() {
|
||||
// #144: Content dirty - texture needs rebuild
|
||||
void UIDrawable::markContentDirty() {
|
||||
if (render_dirty) return; // Already dirty, no need to propagate
|
||||
|
||||
render_dirty = true;
|
||||
composite_dirty = true; // If content changed, composite also needs update
|
||||
|
||||
// Propagate to parent
|
||||
// Propagate to parent - parent's composite is dirty (child content changed)
|
||||
auto p = parent.lock();
|
||||
if (p) {
|
||||
p->markDirty();
|
||||
p->markContentDirty(); // Parent also needs to rebuild to include our changes
|
||||
}
|
||||
}
|
||||
|
||||
// #144: Composite dirty - position changed, texture still valid
|
||||
void UIDrawable::markCompositeDirty() {
|
||||
// Don't set render_dirty - our cached texture is still valid
|
||||
// Only mark composite_dirty so parent knows to re-blit us
|
||||
|
||||
// Propagate to parent - parent needs to re-composite
|
||||
auto p = parent.lock();
|
||||
if (p) {
|
||||
p->composite_dirty = true;
|
||||
p->render_dirty = true; // Parent needs to re-render (re-composite children)
|
||||
p->markCompositeDirty(); // Continue propagating up
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy method - calls markContentDirty for backwards compatibility
|
||||
void UIDrawable::markDirty() {
|
||||
markContentDirty();
|
||||
}
|
||||
|
||||
// Python API - get parent drawable
|
||||
PyObject* UIDrawable::get_parent(PyObject* self, void* closure) {
|
||||
PyObjectsEnum objtype = static_cast<PyObjectsEnum>(reinterpret_cast<long>(closure));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue