david-vanderson / dvui

Other
336 stars 26 forks source link

Batching draw calls #86

Open iacore opened 1 month ago

iacore commented 1 month ago

During my work with draw calls (https://github.com/david-vanderson/dvui/issues/83#issuecomment-2267644939), I created the following new API design

Currently:

  1. dvui allocates temporary memory
  2. dvui populates vtx and idx
  3. dvui calls backend.drawClippedTriangles with temporary memory

I propose the following new API:

  1. dvui calls backend.allocDrawCall(vtx_len, idx_len) to allocate memory
  2. dvui populates vtx and idx
  3. dvui calls backend.drawClippedTriangles with temporary memory

benefit: zero copy. backend.allocDrawCall decides the lifetime of memory returned. if no batching, lifetime = until drawClippedTriangles is called if batching, lifetime = until end of frame

iacore commented 1 month ago

@david-vanderson Is scissor/clipping necessary? glScissor is one call to OpenGL. For our use case it doesn't offer performance boost. Windows without scrolling do not need clipping. (if the visual elements still draw outside of the window, that's a different problem)

I want to make the last argument of drawClippedTriangles ?dvui.Rect.

david-vanderson commented 1 month ago

Thanks for the backend improvements!

I'm still trying to wrap my head around whether dvui can interleave drawing with calling the backend directly. The main sticking point is floating subwindows. The dvui draw calls for those happen in the middle of the main window, and are deferred so they draw on top of the main window (and lower subwindows). I think any direct backend drawing would have to be deferred somehow as well (except if it's in the main window).

For clipping, I think that any widget could be in a scroll area where some/all of it is clipped, so the widget doing the drawClippedTriangles() call can't know whether it needs to be clipped or not. Does that answer your question?

In the code you had a comment about checking the clipping rect before creating the triangles, and I think that is a good idea.

What does the comment "TK" mean?

iacore commented 1 month ago

I'm still trying to wrap my head around whether dvui can interleave drawing with calling the backend directly.

I'm not sure what you mean. Please see the rr branch in this repo. zig build sdl-standalone should behave the same. Maybe it will give you some ideas.

For clipping, I think that any widget could be in a scroll area where some/all of it is clipped, so the widget doing the drawClippedTriangles() call can't know whether it needs to be clipped or not. Does that answer your question?

Yes. I'll see if I can make the type ?Rect.

What does the comment "TK" mean?

"To come" in literature writing. It means "todo" but for text content because "TK" sticks out visually.

Please write those. I have little idea how to describe those functions properly.

david-vanderson commented 1 month ago

Okay, it looks like we both hit on the same idea of deferring drawing. This is already done at the one-step-above-triangles level - see renderCommands. Let me add the kind of thing I'm thinking of to the sdl examples and hopefully that will make it more clear.

I'll comment the other functions. Now I know about TK!

iacore commented 1 month ago

what to give to the library user:

RenderCmd: text layout is hard to get right. triangles: easy to draw.

I think the rr branch does not offer any new functionality. Calling window.end() at the right time works too.

david-vanderson commented 1 month ago

Ah okay I think I'm getting it. Yes - if we are passing stuff to the user, then triangles are the way to go.

I think we are talking about different things. See the new direct SDL drawing that I added to sdl-standalone. I'm trying to give the ability to go around dvui for rendering, at least for the main window. I couldn't think of an easy way to make it work for floating subwindows, so I'm punting on that until someone asks.

iacore commented 1 month ago

I couldn't think of an easy way to make it work for floating subwindows

Well uh... you ask the library user to draw on a texture, then render the texture.

The dvui can handle recreating or reuse textures when the bounding box changes.

david-vanderson commented 1 month ago

Yes - the 3 potential ways I know of so far to do subwindow custom drawing are:

Each of them requires some additional cooperation between dvui and the user code. I'm not going to think too hard about this until somebody shows up with a real usecase for it.