4

伙计们,

在编写几个刻度盘和滑块(例如,一个可以旋转的大音量按钮)时 - 我发现标准 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] 更新/秒。一个非常快速的手绘圆圈(如下所示)的破解速度要快几个数量级。同样适用于模拟器。

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

德。

// 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);
};
4

2 回答 2

3

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

在您的情况下,我建议您绘制一次音量按钮,然后使用旋转变换将您绘制按钮的 UIView 或 CALayer 转换为该按钮。通过简单地移动、旋转或缩放视图,您不会触发代价高昂的重绘。内容已作为纹理缓存,GPU 可以快速操作并在您的其他视图之上合成此光栅化内容。

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

于 2010-11-15T17:53:28.150 回答
0

部分问题(大部分已解决)。

  1. 广泛的基准测试确实表明,与为 100-200 像素半径范围内的圆绘制带有矢量/直线路径的完整圆相比,AddArc 确实很慢。对于部分圆圈,效果不那么明显;我想知道这是否与贝塞尔曲线的数量有关。

但:

  1. 下面的代码没有像人们阅读它那样编译;通过包含的定点 DSP 库(设置为 x100)设置为 (3.14... * ((EVP_ARM7_ADJUST[(PLTF)])),M_PI 不是 3.14etc 的实际预期。

因此,它以 256 倍大的倍数指定了端弧双倍。

正是后者确实使问题如此引人注目(显然底层实现只是不断地转来转去......)。

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

谢谢您的帮助!

于 2010-11-15T20:59:44.297 回答