贝塞尔路径解决性能问题
我的代码如下 -
[[NSColor whiteColor] set];
// `path' is a bezier path with more than 1000 points in it
[path setLineWidth:2];
[path setLineJoinStyle:NSRoundLineJoinStyle];
[path stroke];
// some other stuff...
在 Instruments 中运行时间分析工具,它告诉我我的应用程序花费了 93.5% 的时间来执行最后一行 [路径笔划]
,而 Quartz Debugger 告诉我我的应用程序只是以低于 10 fps 的速度运行(另一个视图在其之上更改位置始终会导致更新)。
我正在寻找提高抚摸贝塞尔曲线路径性能的方法,有时超过 1000 个点的路径会以 >60fps 快速绘制,但是在某些极端情况下,即使点数量相同,也许如果点太多彼此远离(或太密集?),性能变得非常缓慢。
我不知道我能对此做些什么。我认为将视图缓存为位图代表很有帮助,但它对实时调整大小并没有真正的帮助。
编辑:注释掉行 [path setLineWidth:2];
当然有帮助,但路径看起来真的太“细”了。
My code goes as following -
[[NSColor whiteColor] set];
// `path' is a bezier path with more than 1000 points in it
[path setLineWidth:2];
[path setLineJoinStyle:NSRoundLineJoinStyle];
[path stroke];
// some other stuff...
Running the time profiling tool in Instruments it tells me my app is spending 93.5% of the time doing the last line [path stroke]
, and Quartz Debugger tells me my app is only running at less than 10 fps (another view changing position on top of it is always causing the update).
I'm looking for ways to improve the performance of stroking the bezier path, sometimes paths with more than 1000 points draws very quickly with >60fps, however in some extreme cases even with the same number of points, perhaps if the points are too far from each other (or too dense?) the performance becomes really sluggish.
I'm not sure what I can do about this. I think caching the view as a bitmap rep is helpful, but it can't really help with live resize.
Edit: commenting out the line [path setLineWidth:2];
certainly helps, but the path looked really too 'thin'.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用 setFlatness: 方法调整曲线的平坦度,较高的值会提高渲染速度,但会牺牲准确性。例如,您应该在实时调整大小期间使用更高的值。
You can adjust the flatness of the curve using the method setFlatness:, higher values increase the rendering speed at the expense of accuracy. You should use a higher value during live resizes, for example.
当我向 Apple 的 Quartz 2D 团队询问此事时,他们告诉我,影响具有大量点的路径的性能的最大因素是路径与自身相交的次数。为了正确消除交叉点的锯齿,需要做很多工作。
Back when I asked the Quartz 2D team at Apple about this, they told me that the biggest factor in the performance of stroking a path with a large number of points, is how many times the path intersects itself. There's a lot of work that goes into properly anti-aliasing an intersection.
您是否在每次绘制时都构建路径 - 它会随着绘图而变化吗?听起来确实有变化。如果您一遍又一遍地绘制相同的路径,则可能会出现缓存,因此请尝试创建它并保留它,直到它发生变化。这可能有帮助。
您还可以降低一两个 API 级别。也许 CALayer 对象可以做你想做的事。换句话说 - 你真的有一条 1000 个点的线需要弯曲才能连接这些点吗?您可以使用一堆 CALayer 对象来绘制线段。
这些处理器的数学运算速度很快。您也许还可以编写一个数学例程来丢弃不需要的点,将数字从 1000 减少到大约 200 左右。数学会尝试消除靠近的点等。
我的赌注是数学会丢弃不会产生任何视觉差异的点。平坦度的事情听起来也很有趣——可能是通过完全平坦你正在做线段。
Do you build the path at each draw - does it change from drawing to drawing? It sounds like it does change. There may be caching if you draw the same path over and over, so try creating it and keeping it around until it changes. It may help.
You can also drop down an API level or two. Perhaps CALayer objects may do what you want. In other words - do you really have a 1000 point line that needs to be curved to connect the points? You can do a bunch of CALayer objects to draw line segments.
The math on these processors is fast. You could also perhaps write a math routine to throw out unneeded points, to cut the number from 1000 to about 200 or so, say. The math would try to eliminate points that are close together, etc.
My bet is on the math to throw out points that don't make any visual difference. The flatness thing sounds interesting too - it may be that by going totally flat you are doing line segments.
当你说的时候你是什么意思
?
您的意思是您不以 60fps 重绘视图吗?这就是为什么你看不到 60fps 的原因。
什么时候
做某事,这并不意味着“所有可用”时间,而是意味着您的应用消耗了 93.5% 的 cpu 周期。也就是说,可能根本就没有时间。仅仅确定您需要优化是不够的。我并不是说你不需要这样做,或者说抚摸巨大的贝塞尔曲线并不慢。仅此一点并没有多大意义。
What do you mean when you say
??
Do you mean that you are not redrawing the view at 60fps? Then that will be why you are not seeing 60fps then.
When
doing something, it doesn't mean 'all available' time it means 93.5% of the cpu cycles your app consumed. ie, it could be no time at all. It isn't enough to determine that you need to optimise. I'm not saying you don't need to, or that stroking massive beziers isn't dog slow. Just that alone doesn't mean much.