-
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
fix: Text
and BitmapText
that doesn't render it's new value on some condition
#11547
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
Conversation
…me condition - `Text` doesn’t update correctly when using WebGPU. This happens because a new texture is created on each text change, replacing the original texture that still being used for rendering. The original texture view isn’t detached -- `.createView()` isn’t called, and the batch bind isn’t refreshed for the new texture. Because of that, the old texture still got rendered even the text already updated. - `BitmapText` doesn't update correctly when it's not visible. This occurs because `_didTextUpdate` already being set to `false` even it's haven't being rendered yet. This was resolved by removing the one inside `validateRenderable` function, since the `addRenderable` function also sets `_didTextUpdate` to false and it correctly render the text
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit ab9eba0:
|
Hi, thanks for the PR @privatestefans ! Hope this gets shipped soon |
@@ -70,6 +70,10 @@ export class GpuTextureSystem implements System, CanvasGenerator | |||
|
|||
public initSource(source: TextureSource): GPUTexture | |||
{ | |||
let gpuTexture = this._gpuSources[source.uid]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
heyhey! whilst this is a fixe, the deeper issue is that initSource should not be called if the texture already exists. would love for us to understand why this is being called each time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup I understand :3
when the text updates, the _updateGpuText
line 41 got called, and then triggering a call to getTexture
function on line 66.
pixijs/src/scene/text/canvas/CanvasTextPipe.ts
Lines 35 to 69 in b19a5b3
public addRenderable(text: Text, instructionSet: InstructionSet) | |
{ | |
const batchableText = this._getGpuText(text); | |
if (text._didTextUpdate) | |
{ | |
this._updateGpuText(text); | |
text._didTextUpdate = false; | |
} | |
this._renderer.renderPipes.batch.addToBatch(batchableText, instructionSet); | |
} | |
public updateRenderable(text: Text) | |
{ | |
const batchableText = this._getGpuText(text); | |
batchableText._batcher.updateElement(batchableText); | |
} | |
private _updateGpuText(text: Text) | |
{ | |
const batchableText = this._getGpuText(text); | |
if (batchableText.texture) | |
{ | |
this._renderer.canvasText.returnTexture(batchableText.texture); | |
} | |
text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution; | |
batchableText.texture = batchableText.texture = this._renderer.canvasText.getTexture(text); | |
updateTextBounds(batchableText, text); | |
} |
inside the getTexture
function, a new texture is created from the updated text, and initSource
function is triggered on line 125 for the new text.
pixijs/src/scene/text/canvas/CanvasTextSystem.ts
Lines 96 to 127 in b19a5b3
const texture = getPo2TextureFromSource(canvasAndContext.canvas, frame.width, frame.height, resolution); | |
if (textureStyle) texture.source.style = textureStyle as TextureStyle; | |
if (style.trim) | |
{ | |
// reapply the padding to the frame | |
frame.pad(style.padding); | |
texture.frame.copyFrom(frame); | |
texture.updateUvs(); | |
} | |
if (style.filters) | |
{ | |
// apply the filters to the texture if required.. | |
// this returns a new texture with the filters applied | |
const filteredTexture = this._applyFilters(texture, style.filters); | |
// return the original texture to the pool so we can reuse the next frame | |
this.returnTexture(texture); | |
CanvasTextGenerator.returnCanvasAndContext(canvasAndContext); | |
// return the new texture with the filters applied | |
return filteredTexture; | |
} | |
this._renderer.texture.initSource(texture._source); | |
CanvasTextGenerator.returnCanvasAndContext(canvasAndContext); | |
return texture; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appreciate the proposed fix @privatestefans! I would like us to figure out why initSource is being called if the texture is already ready.
Sorry to be a pain :P
no worries, I also understand it should not be called every time the text updates. but after digging to the source code, I feel the FPS still drop significantly when we update many text. while this fix improve from 4 FPS to 12FPS, I feel it's better to have cache system for Text -- and I just found having back the cache system like #11505 would actually fix the performance for Text. btw feel free to modify or close this PR in case if #11505 is preferred, I hope you can find something useful here to accelerate the fix anyway :D |
The pixijs/src/rendering/renderers/gl/texture/GlTextureSystem.ts Lines 101 to 104 in b19a5b3
But for WebGPU it replaced the GPU Texture in pixijs/src/rendering/renderers/gpu/texture/GpuTextureSystem.ts Lines 103 to 105 in b19a5b3
|
thanks for the context @privatestefans ! this is all super helpful. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good! I pushed a tiny tweak to bring it inline with the GLTextureSystem
. Thanks for this fix!
pixi.js-base • pixi.js-bunny-mark
commit: |
Description of change
Text
doesn’t update correctly when using WebGPU. This happens because a new texture is created everytime the text changed, and replacing the original texture that still being used for rendering. The new texture doesn't replace the original GPU texture view, and the batch bind doesn't seems refreshed for the new texture. Because of that, the old texture still got rendered although the text already updated.
BitmapText
doesn't update correctly when it's not visible. This occurs because_didTextUpdate
already set tofalse
even it's haven't rendered yet. This can be resolved by removing the one insidevalidateRenderable
function, since theaddRenderable
function also sets_didTextUpdate
to false and it correctly render the text.
Pre-Merge Checklist
npm run lint
)npm run test
)