CGContextAddArc真的很慢(与用几行绘制的圆相比)

时间:2010-11-14 23:42:20

标签: iphone performance graphics cgcontext

民间,

在编写几个刻度盘和滑块时(例如像一个可以旋转的大音量按钮) - 我发现使用的标准CGContextAddArc()如下:

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();  
    CGContextSetLineWidth(ctx, radius * (KE-KR)+8);
    CGContextSetStrokeColorWithColor(ctx,self.foregroundColor.CGColor);
    .... more some colour/width/etc settings
    ...

    CGContextAddArc(ctx, dx,dy,radius, 0, 2*M_PI, 0);

令人难以置信的缓慢。

在iPad上 - 带有少量填充/描边圆圈,在拖动过程中,不到10个干净[self setNeedsDisplay]更新/秒。手绘圆圈(如下所示)的快速破解速度提高了几个数量级。同样适用于模拟器。

为什么会这样。似乎是正常填充和各种渐变填充的情况。我做错了什么?

DW传递。

// Stupid replacement for CGContectAddArc() which seems to be very slow.
//
void CGContextAddCirlce(CGContextRef ctx, float ox, float oy, float radius)
{
    double len = 2 * M_PI * radius;
    double step = 1.8 / len; // over the top :)

    // translating/scaling would more efficient, etc..
    //
    float x = ox + radius;
    float y = oy;

    // stupid hack - should just do a quadrant and mirror twice.    
    //
    CGContextMoveToPoint(ctx,x,y);
    for(double a = step; a < 2.0 * M_PI -step; a += step) {
        x = ox + radius * cos(a);
        y = oy + radius * sin(a);
        CGContextAddLineToPoint(ctx, x, y);
    };

    CGContextClosePath(ctx);
};

2 个答案:

答案 0 :(得分:3)

Quartz 2D的矢量绘图操作可能很慢,这就是为什么只在需要时重绘一个好主意。

在你的情况下,我建议你绘制一次音量按钮,然后使用旋转变换转换你已经绘制按钮的UIView或CALayer。只需移动,旋转或缩放视图,就不会触发昂贵的重绘。内容已经缓存为纹理,GPU可以快速操作并将此栅格化内容合成到其他视图之上。

你会发现以这种方式避免重绘会提高性能。

答案 1 :(得分:0)

部分问题(主要是已解决)。

  1. 广泛的基准确实表明,与绘制100-200像素半径范围内的圆的矢量/直线路径的完整圆形相比,AddArc确实很慢。对于部分圆圈,效果不太明显;我想知道这是否与beziers的数量有关。
  2. BUT:

    1. 下面的代码没有编译,因为人们会读它;通过包含的定点DSP库(设置为x100)设置为(3.14 ... *((EVP_ARM7_ADJUST [(PLTF)])),M_PI不是实际预期的3.14etc。
    2. 因此它将end-arc double指定为256倍太大。

      后者确实使问题变得如此明显(显然,实施中的实施只是一直四处转转......)。

      现在理解问题(并将保留优化/基准版本)。

      感谢您的帮助!