Is my script fully optimized? (Convert Frame with UICorner to buffer)

Include a standalone, bare-bones rbxl file with only the code you want reviewed.

Provide an overview of:

  • What does the code do and what are you not satisfied with?
    Simply recreate pixel to pixel perfect to how UICorner render on Frame
  • What potential improvements have you considered?
    I haven’t figured out yet.
  • How (specifically) do you want to improve the code?
    I just want it to be as fast as possible.
--!optimize 2
--!native

--taken from imagedocs
-- 47: mul r0.xyzw, r0.xyzw, v2.xyzw
-- 48: mad r1.xy, v1.xyxx, CB1.UvDesc.xzxx, CB1.UvDesc.ywyy
-- 49: add r1.xy, abs(r1.xyxx), -CB1.RcDesc.xyxx
-- 50: max r1.zw, r1.xxxy, l(0, 0, 0, 0)
-- 51: dp2 r1.z, r1.zwzz, r1.zwzz
-- 52: sqrt r1.z, r1.z
-- 53: max r1.x, r1.y, r1.x
-- 54: min r1.x, r1.x, l(0)
-- 55: add r1.x, r1.x, r1.z
-- 56: add_sat r1.y, -r1.x, CB1.RcDesc.z
-- 57: mul r0.w, r0.w, r1.y
-- 58: add_sat r1.x, r1.x, -CB1.RcDesc.w
-- 59: mul o0.w, r0.w, r1.x
-- 60: mov o0.xyz, r0.xyzx

local round, min, max, clamp, abs, sqrt = math.round, math.min, math.max, math.clamp, math.abs, math.sqrt
local UDim_new = UDim.new()
local writeu8 = buffer.writeu8

return function(Frame: Frame & any)
	local CornerRadius = if Frame.UICorner then Frame.UICorner.CornerRadius else UDim_new
	local Size = Frame.AbsoluteSize
	local Rad = round(min(min(Size.X, Size.Y) / 2, CornerRadius.Scale * min(Size.X, Size.Y) + CornerRadius.Offset))

	local Rad2 = Rad * 2
	local Buffer = buffer.create(Rad2 ^ 2 * 4)

	for y = 0, Rad2 - 1 do
		local ry = abs(y - Rad + 0.5) - 0.5
		local ryMaxSqrd = max(ry, 0) ^ 2
		local CursorY = y * Rad2

		for x = 0, Rad2 - 1 do
			local Cursor = (CursorY + x) * 4

			local rx = abs(x - Rad + 0.5) - 0.5
			rx = min(max(ry, rx), 0) + sqrt(max(rx, 0) ^ 2 + ryMaxSqrd)

			writeu8(Buffer, Cursor, 255)
			writeu8(Buffer, Cursor + 1, 255)
			writeu8(Buffer, Cursor + 2, 255)
			writeu8(Buffer, Cursor + 3, round((clamp(-rx + Rad, 0, 1)) * 254.94))
		end
	end

	return Buffer, Rad
end

Your script is pretty solid, but you might be able to make it faster by caching min(Size.X, Size.Y) since it’s used multiple times, which would reduce redundant calculations. Also, try to minimize the use of abs and sqrt by caching their results when possible. If buffer.writeu8 allows it, batching writes could help reduce overhead.

1 Like

Thanks you after some profiling I got the finale result also credit to Rounding a number without lua math. thingy - #4 by MrMouse2405 for the faster rounding alternative

The finale code:

--!native
--!optimize 2

local min, max, clamp, abs = math.min, math.max, math.clamp, math.abs
local UDim_new = UDim.new()
local writeu32, create = buffer.writeu32, buffer.create

return function(Frame: Frame & any)
	local CorRad = if Frame.UICorner then Frame.UICorner.CornerRadius else UDim_new
	local SizeXYmin = min(Frame.AbsoluteSize.X, Frame.AbsoluteSize.Y)
	local Rad = min(SizeXYmin * 0.5, CorRad.Scale * SizeXYmin + CorRad.Offset) + 6755399441055740 - 6755399441055740

	if Rad > 512 then
		error("Radius can't be larger than 512 pixels due to the limit of EditableImage only being 1024x1024 pixels.")
	end

	local Rad2 = Rad * 2
	local Buffer = create(Rad2 ^ 2 * 4)
	local RadMinusHalf = Rad - 0.5

	for y = 0, Rad2 - 1 do
		local CursorY = y * Rad2

		local ry = abs(y - RadMinusHalf) - 0.5
		local ryMaxSqrd = max(ry, 0) ^ 2

		for x = 0, Rad2 - 1 do
			local Cursor = (CursorY + x) * 4

			local rx = abs(x - RadMinusHalf) - 0.5
			local rxMaxSqrd = max(rx, 0) ^ 2
			local Distance = (rxMaxSqrd + ryMaxSqrd) ^ 0.5
			local rxyMinMax = min(max(ry, rx), 0)
			rx = Rad - (rxyMinMax + Distance)

			local rxClamp = clamp(rx, 0, 1)
			local RoundedAlpha = rxClamp * 254.94 + 6755399441055740 - 6755399441055740
			local AlphaToByte = RoundedAlpha * 16777216
			local Value = 16777215 + AlphaToByte

			writeu32(Buffer, Cursor, Value)
		end
	end

	return Buffer, Rad
end

There is probably some more squeezing, but I guess this is it for now