Действительно ли CGContextAddArc настолько медленный (по сравнению с кругом, нарисованным с несколькими линиями? - PullRequest
4 голосов
/ 15 ноября 2010

Люди,

При кодировании нескольких циферблатов и ползунков (например, как большая кнопка громкости, которую можно вращать) - я обнаружил, что стандартный 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 ]

3 голосов
/ 15 ноября 2010

Операции векторного рисования в Quartz 2D могут быть медленными, поэтому рекомендуется перерисовывать их только при необходимости.

В вашем случае я бы предложил один раз нарисовать кнопку громкости, а затем преобразоватьUIView или CALayer, в который вы нарисовали кнопку, используя вращательное преобразование.Простое перемещение, вращение или масштабирование вида не приводит к дорогостоящему перерисовыванию.Контент уже кэшируется как текстура, и графический процессор может быстро манипулировать и комбинировать этот растеризованный контент поверх ваших других представлений.

Вы обнаружите, что избегая перерисовки таким способом, вы получите значительно улучшенную производительность.1005 *

0 голосов
/ 15 ноября 2010

Проблема частично (в основном разрешена).

  1. Обширный сравнительный анализ действительно показывает, что AddArc действительно медленный по сравнению с рисованием полного круга с векторной / прямой линией для кругов в 100-200 пикселейрадиус радиусДля частичных кругов эффект гораздо менее выражен;мне интересно, связано ли это с числом безье.

НО:

  1. Приведенный ниже код не скомпилировался так, как читается;M_PI не был 3.14etc, как на самом деле ожидалось, если установить значение (3.14 ... * ((EVP_ARM7_ADJUST [(PLTF)])) включенной библиотекой DSP с фиксированной точкой (установленной в x100).

Следовательно, он определил двойную конечную дугу в 256 раз слишком большим.

И именно последний сделал проблему настолько заметной (очевидно, лежащая в основе реализация просто продолжает вращаться и округляться).).

Итак, проблема теперь понятна (и будет поддерживать оптимизированную / проверенную версию).

Спасибо за помощь!

...