Facepunch / garrysmod-requests

Feature requests for Garry's Mod
83 stars 24 forks source link

Make Panel:SetPaintBackgroundEnabled and Panel:SetPaintBorderEnabled on default panel ( aka vgui.Create('PANEL') ), but disabled by default #2366

Closed Jaffies closed 1 month ago

Jaffies commented 2 months ago

The idea is so you won't need to draw background in lua. Panel will draw simple surface.DrawRect( panel:GetBGColor() ) in C, without hooking lua state. Simple. Fast. Needed for performance issues.

Jaffies commented 2 months ago

Right now setting this to true will result in nothing. So if it won't work so ever, then add the default functionality, to make C panels better.

garryspins commented 2 months ago

If you think surface.SetDrawColor(self.Color) surface.DrawRect(0, 0, w, h) in your own paint function is the cause of your performance issues you really need to learn how to use FProfiler buddy...

Jaffies commented 2 months ago

If you think surface.SetDrawColor(self.Color) surface.DrawRect(0, 0, w, h) in your own paint function is the cause of your performance issues you really need to learn how to use FProfiler buddy...

The problem is with C -> Lua API bridge, which calls a lua function to just draw rectangle. 3 C calls (one to call lua function, second/third to call surface functions). All of them cost a lot. Really a lot. If you think that panel.Think = nil and panel.Think = function() end is the same at performance issues, then you need to learn lua C API theory buddy...... That's why SRLion created his own labels, which don't have think function unless it's needed to. Fun fact -> Label:Think will be the most valuable bottleneck in FProfiler because of that, buddy...

garryspins commented 2 months ago

Please just... show benchmarks of the problem you are having

Jaffies commented 2 months ago

Please just... show benchmarks of the problem you are having

Open Fprofiler, make benchmark, then make it again (do not continue it)

You are regurgitating stuff you have just heard in passing without truly understanding what it means, i promise you... your Panel with a Paint function isnt the bane of your existence, you really need to learn Micro-Optimization Theory buddy........

It, fortunately, is. Basically running function 100 times per frame is the problem, which gmod actually does. Making it to not run 100 times per frame is my suggestion. I need to make as less overhead as possible, that's the idea.

garryspins commented 2 months ago

I think if you are having an issue here its because of something else, can you send your code? are you sure its laying out properly? (vgui_visualizelayout 1 to make sure its not being called every frame)

Jaffies commented 2 months ago

I think if you are having an issue here its because of something else, can you send your code? are you sure its laying out properly? (vgui_visualizelayout 1 to make sure its not being called every frame)

I am sure it lays properly. The problem is still with this C API bridge. Basically, if you try to make most performant ui, you use Label panels, not the lua ones that make surface.DrawText()/etc, because of that performance issues. I want that principle with default panels too, especially if rubat could make a rounding for them (like for default source engine panels). You can check that via vgui_lua_paint 0

Jaffies commented 2 months ago

I think if you are having an issue here its because of something else, can you send your code? are you sure its laying out properly? (vgui_visualizelayout 1 to make sure its not being called every frame)

I am sure it lays properly. The problem is still with this C API bridge. Basically, if you try to make most performant ui, you use Label panels, not the lua ones that make surface.DrawText()/etc, because of that performance issues. I want that principle with default panels too, especially if rubat could make a rounding for them (like for default source engine panels). You can check that via vgui_lua_paint 0

The simpliest check is vgui_luapaint 0 on main menu. It works 120 fps without lua paint. With lua paint it drops to 95 fps. Minus 25 fps, which is ~21% fps loss because of lua stuff. Good, huh?

robotboy655 commented 1 month ago
concommand.Add( "test_panel", function(ply,cmd,args)
    local DFrame = vgui.Create("DFrame")
    DFrame:SetSize(520, 520 + 25)
    DFrame:Center()
    DFrame:SetTitle("Derma Frame")
    DFrame:MakePopup()

    local count = 1600
    local rows = 40
    local size = DFrame:GetWide() / rows - 1
    for i=0,count-1 do
        local p = DFrame:Add( "panel" )
        p:SetPos( i % rows * size , 25 + math.floor( i / rows ) * size )
        p:SetSize( size - 1, size - 1 )
        p:SetPaintBackgroundEnabled( true )
        timer.Simple( 0, function() p:SetBGColor( Color( (i / count) * 255, 255, i % rows / rows * 255 ) ) end )
        if ( !args[1] ) then continue end
        p.Paint = function( s, w, h ) draw.RoundedBox( 2, 0, 0, w, h, s:GetBGColor() )  end
    end
end )

It is already possible, so I don't really know what you are asking for?

test_panel for engine paint vs test_panel 1 for Lua paint.

PANEL:ApplySchemeSettings can be used to set the color instead of the timer.