Любой способ ускорить / уменьшить использование процессора при рисовании с Cairo? - PullRequest
4 голосов
/ 31 июля 2011

Я написал приложение, которое использует Cairo для рисования объектов на экране (точнее, в Gtk :: DrawingArea).Нужно все перерисовывать часто.Оказывается, что, несмотря на то, что нарисованные схемы очень просты, X-сервер использует много ЦП при перерисовке, и приложения работают ужасно медленно.Есть ли способ ускорить это?Или, может быть, мне не следует использовать DrawingArea и некоторые другие виджеты?

Я рисую набор прямоугольников, которые пользователь может перемещать, перетаскивая их мышью.Весь рисунок выполняется с помощью on_expose_event, но когда указатель мыши перемещается (при нажатой кнопке), я вызываю queue_draw (), чтобы обновить рисунок.

Ответы [ 4 ]

9 голосов
/ 31 июля 2011

Просто пара вещей, которые нужно проверить:

Сделан ли ваш рисунок в событии экспозиции?

Нарисуйте ваше изображение на Каирской поверхности, а затем в экспозициисобытие просто скопировать с этой поверхности на поверхность виджета.

Вы вырезаете и рисуете только необходимую область?

Событие expose дает вам X, Y, width, height области, которую необходимо перерисовать.В Каире создайте прямоугольник на вашей поверхности с этими размерами и назовите clip, чтобы не тратить время на перерисовку того, что не нужно.

3 голосов
/ 31 июля 2011

Рисование стоит дорого, особенно рисование текста стало самой дорогой задачей графического интерфейса пользователя.

Единственный способ ускорить это - уменьшить количество выпадающих предметов. Проверьте, действительно ли вы рисуете элементы, которые необходимы. Событие expose дает вам прямоугольник. Только обновите эту часть виджета.

Может быть, кешировать элементы в растровом изображении.

Например, для плавной прокрутки это может помочь нарисовать контент в растровом изображении, например, на 500 пикселей больше, так что в большинстве случаев вам просто нужно скопировать изображение и вообще ничего не рисовать (обычно вы получаете прямоугольники высотой всего от 5 до 10 пикселей при прокрутке).

Но вам нужно дать нам больше информации о том, что вы рисуете и какова нагрузка на систему, чтобы получить лучший ответ.

0 голосов
/ 19 августа 2011

Я наконец-то заставил использовать максимально 25 кадров в секунду, используя флаг блокировки.

bool lock = 0;
bool needs_redraw = 0;

void Redraw(){
    if(lock){
        needs_redraw = 1;
        return;
    }

    //draw image to a surface

    needs_redraw = 0;
    lock = 1;
    Glib::signal_timeout().connect(Unlock, 20);

    queue_draw();
}

bool Unlock(){
    lock = 0;
    if(needs_redraw) Redraw();
    return false;
}

void on_expose_event(something){
    //copy image from surface to widget's context
}

Это пример кода, но это идея. Запрет на перерисовку будет выполняться чаще, чем один раз в 20 мс.

0 голосов
/ 31 июля 2011

Я нашел эту статью о резьбовом рисунке в Каире, чтобы решить проблему со скоростью, может быть, это поможет:

http://cairographics.org/threaded_animation_with_cairo/

О высокой загрузке процессора:

У вас установлены правильные аппаратные ускоренные драйверы для X?

...