Conversation
Summary of ChangesHello @Alex2772, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly refactors the rendering pipeline by introducing a GPU batching system. The core change involves abstracting rendering operations into a new Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a batching renderer to improve GPU performance by reducing the number of draw calls. The overall approach is solid, but I've found a critical issue with the implementation of stencil mask operations that would break masking functionality. I've provided detailed comments and suggestions to fix this. Additionally, there's a minor inconsistency in the use of std::move that should be addressed for code clarity. A new example for a game inventory UI has been added, which is a great way to showcase the framework's capabilities. I've also found a potential performance issue in the new example where flagRedraw() is called on every frame, which could lead to unnecessary CPU usage.
| void IBatchingRenderer::pushMaskAfter() { | ||
| mCmds.emplace_back(CmdPushMask{}); | ||
| } |
There was a problem hiding this comment.
This is part of a critical bug in the masking implementation. pushMaskAfter() should queue a distinct command (CmdPushMaskAfter) instead of CmdPushMask. Reusing CmdPushMask causes pushMaskAfter() to be handled as pushMaskBefore(), which is incorrect. Please see my other comments on this topic for the full context and fix.
| void IBatchingRenderer::pushMaskAfter() { | |
| mCmds.emplace_back(CmdPushMask{}); | |
| } | |
| void IBatchingRenderer::pushMaskAfter() { | |
| mCmds.emplace_back(CmdPushMaskAfter{}); | |
| } |
| void IBatchingRenderer::popMaskAfter() { | ||
| mCmds.emplace_back(CmdPopMask{}); | ||
| } |
There was a problem hiding this comment.
Similar to pushMaskAfter, popMaskAfter() should queue a distinct command (CmdPopMaskAfter) to differentiate it from popMaskBefore(). Reusing CmdPopMask here is incorrect and will lead to broken masking behavior.
| void IBatchingRenderer::popMaskAfter() { | |
| mCmds.emplace_back(CmdPopMask{}); | |
| } | |
| void IBatchingRenderer::popMaskAfter() { | |
| mCmds.emplace_back(CmdPopMaskAfter{}); | |
| } |
| struct CmdPushMask {}; | ||
| struct CmdPopMask {}; |
There was a problem hiding this comment.
The masking logic is broken because there are no distinct command types for pushMaskAfter and popMaskAfter. This causes them to be handled incorrectly. You should add CmdPushMaskAfter and CmdPopMaskAfter command structs to fix this.
struct CmdPushMask {};
struct CmdPushMaskAfter {};
struct CmdPopMask {};
struct CmdPopMaskAfter {};| using Cmd = std::variant<CmdRectangle, CmdRoundedRectangle, CmdRectangleBorder, CmdRoundedRectangleBorder, | ||
| CmdBoxShadow, CmdBoxShadowInner, CmdString, CmdLines, CmdPoints, CmdLinesPairs, | ||
| CmdSquareSector, CmdPushMask, CmdPopMask, CmdSetBlending, CmdNewRenderViewToTexture, CmdSetWindow>; |
There was a problem hiding this comment.
To complete the fix for the broken masking logic, the Cmd variant needs to be updated to include the new CmdPushMaskAfter and CmdPopMaskAfter types.
using Cmd = std::variant<CmdRectangle, CmdRoundedRectangle, CmdRectangleBorder, CmdRoundedRectangleBorder,
CmdBoxShadow, CmdBoxShadowInner, CmdString, CmdLines, CmdPoints, CmdLinesPairs,
CmdSquareSector, CmdPushMask, CmdPushMaskAfter, CmdPopMask, CmdPopMaskAfter, CmdSetBlending, CmdNewRenderViewToTexture, CmdSetWindow>;| [&](const CmdPushMask&) { renderPushMaskBefore(); }, | ||
| [&](const CmdPopMask&) { renderPopMaskBefore(); }, |
There was a problem hiding this comment.
The handlers for mask commands are incomplete, which will break masking functionality. You are missing handlers for CmdPushMaskAfter and CmdPopMaskAfter. You should add them to call renderPushMaskAfter() and renderPopMaskAfter() respectively.
[&](const CmdPushMask&) { renderPushMaskBefore(); },
[&](const CmdPushMaskAfter&) { renderPushMaskAfter(); },
[&](const CmdPopMask&) { renderPopMaskBefore(); },
[&](const CmdPopMaskAfter&) { renderPopMaskAfter(); },|
|
||
| void render(ARenderContext context) override { | ||
| AWindow::render(context); | ||
| flagRedraw(); |
There was a problem hiding this comment.
Calling flagRedraw() unconditionally in every render call will cause the application to redraw on every frame, even when nothing has changed. This can lead to unnecessary CPU and GPU usage, which is especially problematic on battery-powered devices. You should only flag for a redraw when the state of the UI actually changes.
|
|
||
| void IBatchingRenderer::rectangle(const ABrush& brush, glm::vec2 position, glm::vec2 size) { | ||
| mCmds.emplace_back(CmdRectangle{ | ||
| .brush = std::move(brush), |
There was a problem hiding this comment.
The use of std::move(brush) here is inconsistent with other methods in this file that also take a const ABrush& and simply copy it (e.g., roundedRectangle). Since brush is a const reference, std::move performs a copy anyway, but it can be misleading to future readers of the code. For consistency and clarity, it's better to just use brush for the assignment.
| .brush = std::move(brush), | |
| .brush = brush, |
everything is fine except fonts
No description provided.