Производительность при частом рисовании CGPaths

Я работаю над приложением для iOS, которое визуализирует данные в виде линейного графика. График рисуется как CGPath в полноэкранном пользовательском UIView и содержит не более 320 точек данных. Данные часто обновляются, и график должен перерисовываться соответствующим образом - частота обновления 10/сек была бы хорошей.

Пока все просто. Однако, похоже, что мой подход требует много процессорного времени. Обновление графика с 320 сегментами со скоростью 10 раз в секунду приводит к загрузке процессора на 45% на iPhone 4S.

Возможно, я недооцениваю графическую работу под капотом, но мне кажется, что загрузка процессора для этой задачи очень велика.

Ниже приведена моя функция drawRect(), которая вызывается каждый раз, когда готов новый набор данных. N содержит количество точек, а points - вектор CGPoint* с координатами для рисования.

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    // set attributes
    CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
    CGContextSetLineWidth(context, 1.f);

    // create path
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddLines(path, NULL, points, N+1);

    // stroke path
    CGContextAddPath(context, path);
    CGContextStrokePath(context);

    // clean up
    CGPathRelease(path); 
}

Я попробовал сначала отрисовать контур в автономный CGContext, прежде чем добавить его в текущий слой, как было предложено здесь, но без положительного результата. Я также пробовал рисовать в CALayer напрямую, но это тоже ничего не дало.

Есть предложения, как улучшить производительность для этой задачи? Или рендеринг - это просто больше работы для CPU, чем я думаю? Может ли OpenGL иметь какой-то смысл/разницу?

Спасибо /Andi

Update: Я также попробовал использовать UIBezierPath вместо CGPath. В этом сообщении здесь дается хорошее объяснение, почему это не помогло. Подстройка CGContextSetMiterLimit и др. также не принесла большого облегчения.

Обновление #2: В конце концов я перешел на OpenGL. Это была крутая и разочаровывающая кривая обучения, но прирост производительности просто невероятный. Однако, алгоритмы сглаживания CoreGraphics делают более приятную работу, чем та, которая может быть достигнута с 4x-мультисэмплингом в OpenGL.

13
задан Community 23 May 2017 в 12:24
поделиться