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

Optimize TorrentDetail Overview Piece Renderer #1564

Merged
merged 12 commits into from
Mar 12, 2024
Merged

Optimize TorrentDetail Overview Piece Renderer #1564

merged 12 commits into from
Mar 12, 2024

Conversation

fredkilbourn
Copy link
Contributor

@fredkilbourn fredkilbourn commented Mar 9, 2024

Optimize TorrentDetail Overview Piece Renderer [feat/fix/perf]

  • Implement WebGL/WebGPU rendering to better handle larger number of pieces (using pixi.js library)
  • Re-work portion of rendering logic with very poor logarithmic efficiency (using @flatten-js/interval-tree library)

Working smoothly with 717590 pieces:
image

I probably need help reviewing that I've implemented this the right way, used the right conventions. I've not worked with Vue or Typescript before so particularly type specifications and doing garbage collection on onUnmounted should be looked at to make sure I did those things correctly.

PR Checklist

  • I've started from master
  • I've only committed changes related to this PR
  • All tests pass
  • I've removed all commented code

* Implement WebGL/WebGPU rendering to better handle larger number of
  pieces (using pixi.js library)
* Re-work portion of rendering logic with very poor logarithmic
  efficiency (using @flatten-js/interval-tree library)

Signed-off-by: Fred Kilbourn <fred@fredk.com>
@fredkilbourn fredkilbourn requested a review from WDaan as a code owner March 9, 2024 01:14
@fredkilbourn
Copy link
Contributor Author

fredkilbourn commented Mar 9, 2024

Also, take a look at the logic here: https://github.com/VueTorrent/VueTorrent/pull/1564/files#diff-083cbba449da7fcceaf23641d3f3f150bbef59d13c0d3d2691a339b8a173b42eL67-R81

Specifically, changing from this:

if (i > min_piece_range && i < max_piece_range)

To this:

if (pieceSelectedRanges.intersect_any([i, i]))

Which is technically equivalent to i >= min_piece_range && i <= max_piece_range, but I possibly think greater than equal to / less than equal to is correct here, rather than just greater than / less than.

@fredkilbourn
Copy link
Contributor Author

Works on my cell phone even with almost a million pieces.

Assuming everything checks out, you'd probably be able to remove the piece count limits for rendering the canvas, or increase them dramatically.

Copy link
Collaborator

@Larsluph Larsluph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests doesn't pass, please commit the package-lock.json file

Signed-off-by: Fred Kilbourn <fred@fredk.com>
@fredkilbourn
Copy link
Contributor Author

fredkilbourn commented Mar 9, 2024

Tests doesn't pass, please commit the package-lock.json file

My apologies, I thought the All tests pass was related to npm run test, I included package-lock.json just now.

fredkilbourn and others added 2 commits March 9, 2024 08:54
Signed-off-by: Fred Kilbourn <fred@fredk.com>
@fredkilbourn fredkilbourn requested a review from Larsluph March 9, 2024 16:29
@Larsluph
Copy link
Collaborator

Larsluph commented Mar 9, 2024

My apologies, I thought the All tests pass was related to npm run test, I included package-lock.json just now.

It is in fact but merge is blocked without the CI checks. I haven't used the correct words 😅

Signed-off-by: Fred Kilbourn <fred@fredk.com>
Only save piecesApp reference after async init finished

Signed-off-by: Fred Kilbourn <fred@fredk.com>
Signed-off-by: Fred Kilbourn <fred@fredk.com>
Signed-off-by: Fred Kilbourn <fred@fredk.com>
Copy link
Contributor Author

@fredkilbourn fredkilbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed load behavior when refs aren't loaded yet on 'onMounted'

Comment on lines 161 to 170
if (canvas.value) {
canvas.value.width = 4096
if (piecesApp === null) {
const app = new Application()
await app.init({ antialias: true, width: canvas.value.width, height: canvas.value.height })
for (const attr of [...canvas.value.attributes]) app.canvas.setAttribute(attr.nodeName, attr.nodeValue ?? '')
canvas.value.replaceWith(app.canvas)
piecesApp = app
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Larsluph I've been testing my build and this sometimes works and sometimes doesn't work. There is a possibility that the canvas.value is not set yet when this handler fires and if that happens the piecesApp will always be null. Do you know of the correct way to wait for canvas.value to become available?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, note to myself, canvas.value.attribute doesn't need to be wrapped with spread operator, I'll revise next time I'm at my pc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Larsluph I've just pushed changes that wait for refs to load properly, fixes everything mentioned here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know of the correct way to wait for canvas.value to become available?

You can use a watcher on the canvas' ref to do that but I think the onMounted waits for the DOM to load the entities. The canvas may not be loaded because of the current restrictions which sometimes makes it not render.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was doing console.log at the start of onMounted and maybe 1/10 times ref values would be undefined when it fired. Current PR works 100% now compensating for these delayed loads Let me know if I should change it.

Copy link
Collaborator

@Larsluph Larsluph Mar 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let you check that everything is good. My canvas is full black when trying to render it, it seems that I broke something while moving things around... 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let you check that everything is good. My canvas is full black when trying to render it, it seems that I broke something while moving things around... 🤔

I wasn't Immediately able to figure out why it isn't working either. I have to go out for a bit but I'll check later when I can.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did update the canvas width to 4096, this gives maximum details while still maintaining compatibility with nearly all clients.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Larsluph

Figured it out, pushing a fix soon, app doesn't like to be deeply reactive with ref, have to use shallowRef.

Also not the cause but app needs to be saved as a promise so renderCanvas can wait for init to finish before trying to access it. Currently execution can happen like this with graphics being added before init finishes:

22:02:15.530 TorrentDetail-GfvQE6Dx.js:12749 app pre-init
22:02:15.536 TorrentDetail-GfvQE6Dx.js:12705 renderCanvas
22:02:15.850 TorrentDetail-GfvQE6Dx.js:12736 addChild graphics
22:02:15.995 TorrentDetail-GfvQE6Dx.js:12756 app post-init

Copy link
Contributor Author

@fredkilbourn fredkilbourn Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes pushed in #1572

@fredkilbourn
Copy link
Contributor Author

Let me know if there's anything else to be fixed or changed on this PR. I think things are pretty stable now.

WDaan and others added 4 commits March 10, 2024 09:12
Set to 4096 for maximum detail while maintaining compatibility with
majority of clients.

Signed-off-by: Fred Kilbourn <fred@fredk.com>
@WDaan WDaan merged commit 5ed280c into VueTorrent:master Mar 12, 2024
1 check passed
@fredkilbourn
Copy link
Contributor Author

fredkilbourn commented Mar 12, 2024

@WDaan this was still very broken, @Larsluph and I are working on a fix. f42381e caused some issues.

@fredkilbourn
Copy link
Contributor Author

fredkilbourn commented Mar 12, 2024

Fixes pushed in #1572

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

Successfully merging this pull request may close these issues.

3 participants