Двойная буферизация: различия между версиями
Cool-T (обсуждение | вклад) («Двойная буферизация» переименована в «Предотвращение мерцания»: Не соответствует названию.) | G-XaD (обсуждение | вклад) (Ссылка вику и подкорректировал определение) | ||
(не показано 6 промежуточных версий 1 участника) | |||
Строка 1: | Строка 1: | ||
− | # | + | Двойная буферизация ({{lang-en|Double Buffering}}) — метод вывода графики на экран через драйвер, который применяется в приложениях, активно использующих вывод графики через [[AHI|драйвер дисплея]] в полноэкранном режиме. Используется как метод повышения производительности за счет избыточного использования [[видеопамяти]]. |
+ | |||
+ | == Описание == | ||
+ | |||
+ | При использовании метода "двойной буферизации", графика сначала выводится во вторичный буфер (в данном случае на [[AHI#Поверхности|поверхность]]), а затем первичный буфер подменяется на вторичный. | ||
+ | |||
+ | == Применение == | ||
+ | |||
+ | Перед началом вывода графики необходимо чтобы у нас был [[AHI#Контекст устройства|контекст устройства]] ('''dCtx'''), на которое будем выводить графику и две [[AHI#Поверхности|поверхности]] - экранная поверхность ('''sDisp''') и внеэкранная поверхность ('''sDraw'''). Если у нас их нет - смотрим [[AHI#Инициализация|здесь]] как их получить. Как только получены поверхности, мы сохраняем их в дополнительные переменные '''sRealDisp''' и '''sRealDraw''', т.к. они нам ещё понадобятся. | ||
+ | |||
+ | Итак, графика инициализирована. Можем приступать к работе. | ||
+ | |||
+ | <ol> | ||
+ | <li>'''Перед выводом графики мы меняем поверхность, на которой будем рисовать'''<br> | ||
+ | По-умолчанию этой поверхностью является экранная поверхность. Но для наших целей она не подходит. Переключаем поверхность с помощью функции [[AhiDrawSurfDstSet]]: | ||
+ | <pre> | ||
+ | AhiDrawSurfDstSet(dCtx, sDraw, 0); | ||
+ | </pre> | ||
+ | </li> | ||
+ | |||
+ | <li>'''Собственно, выводим графику'''<br> | ||
+ | Выводим графику. Не забываем устанавливать [[Raster Operations|растровую операцию]] и цвет кисти: | ||
+ | <pre> | ||
+ | // Вспомогательная переменная для указания области экрана | ||
+ | AHIRECT_T rect; | ||
+ | |||
+ | // Устанавливаем растровую операцию на применение кисти | ||
+ | AhiDrawRopSet(dCtx, AHIROP3(AHIROP_PATCOPY)); | ||
+ | |||
+ | // Установим цвет кисти. Этим цветом будут выводиться наши графические примитивы | ||
+ | AhiDrawBrushFgColorSet(dCtx, ATI_565RGB(0,0,255)); // Ярко-синий | ||
+ | |||
+ | // Зададим прямоугольник на экране, который будет залит нашим цветом | ||
+ | rect.x1 = 0; | ||
+ | rect.y1 = 0; | ||
+ | rect.x2 = 64; | ||
+ | rect.y2 = 64; | ||
+ | |||
+ | // Нарисуем прямоугольник rect | ||
+ | AhiDrawSpans(dCtx, &rect, 1, 0); | ||
+ | </pre> | ||
+ | </li> | ||
+ | |||
+ | <li>'''Заменяем экранную поверхность'''<br> | ||
+ | Графика выведена во внеэкранную поверхность, но теперь её нужно вывести на экран. Для этого мы устанавливаем '''sDraw''' экранной поверхностью, а '''sDisp''' - поверхностью для рисования и меняем местами значения переменных '''sDisp''' и '''sDraw''': | ||
+ | <pre> | ||
+ | AHISURFACE_T tSurface; | ||
+ | |||
+ | // Установка экранной поверхности | ||
+ | AhiDispSurfSet(dCtx, sDraw, 0); | ||
+ | // Установка поверхности для рисования | ||
+ | AhiDrawSurfDstSet(dCtx, sDisp, 0); | ||
+ | |||
+ | // Изображение получено на экране | ||
+ | |||
+ | // Меняем поверхности местами | ||
+ | tSurface = sDisp; | ||
+ | sDisp = sDraw; | ||
+ | sDraw = tSurface; | ||
+ | </pre> | ||
+ | |||
+ | Далее повторяем все действия с первого пункта, пока необходимо выводить графику | ||
+ | </li> | ||
+ | |||
+ | <li>'''Возвращаем значения sDisp и sDraw'''<br> | ||
+ | Перед выходом из эльфа '''ОБЯЗАТЕЛЬНО''' необходимо вернуть их значения, которые были выданы телефоном. Т.к. не известно, в какой из двух переменных ('''sDisp''' или '''sDraw''') находится реальная экранная поверхность, мы воспользуемся переменными '''sRealDisp''' и '''sRealDraw''', о которых говорилось в самом начале. | ||
+ | <pre> | ||
+ | // Установка экранной поверхности | ||
+ | AhiDispSurfSet(dCtx, sRealDisp, 0); | ||
+ | // Установка поверхности для рисования | ||
+ | AhiDrawSurfDstSet(dCtx, sRealDraw, 0); | ||
+ | </pre> | ||
+ | |||
+ | И только тогда выходим из эльфа. | ||
+ | </li> | ||
+ | |||
+ | </ol> | ||
+ | |||
+ | == См. также == | ||
+ | |||
+ | * [[AHI]] - драйвер для чипов ATI | ||
+ | * [[LdrDisplayCbkReg]] - функция для создания callback'ов для рисования поверх [[UIS]] | ||
+ | * [[LdrDisplayCbkUnReg]] - функция для удаления callback'ов, созданных с помощью [[LdrDisplayCbkReg]] | ||
+ | * [[Предотвращение мерцания]] - Классический метод предотвращения мерцания при выводе графики | ||
+ | |||
+ | == Ссылки == | ||
+ | [http://ru.wikipedia.org/wiki/Двойная_буферизация Wikipedia(RU): Двойная буферизация] | ||
+ | |||
+ | |||
+ | [[Категория:Эльфостроение]] |
Текущая версия на 16:52, 12 июня 2010
Двойная буферизация (англ. Double Buffering) — метод вывода графики на экран через драйвер, который применяется в приложениях, активно использующих вывод графики через драйвер дисплея в полноэкранном режиме. Используется как метод повышения производительности за счет избыточного использования видеопамяти.
Описание
При использовании метода "двойной буферизации", графика сначала выводится во вторичный буфер (в данном случае на поверхность), а затем первичный буфер подменяется на вторичный.
Применение
Перед началом вывода графики необходимо чтобы у нас был контекст устройства (dCtx), на которое будем выводить графику и две поверхности - экранная поверхность (sDisp) и внеэкранная поверхность (sDraw). Если у нас их нет - смотрим здесь как их получить. Как только получены поверхности, мы сохраняем их в дополнительные переменные sRealDisp и sRealDraw, т.к. они нам ещё понадобятся.
Итак, графика инициализирована. Можем приступать к работе.
- Перед выводом графики мы меняем поверхность, на которой будем рисовать
По-умолчанию этой поверхностью является экранная поверхность. Но для наших целей она не подходит. Переключаем поверхность с помощью функции AhiDrawSurfDstSet:AhiDrawSurfDstSet(dCtx, sDraw, 0);
- Собственно, выводим графику
Выводим графику. Не забываем устанавливать растровую операцию и цвет кисти:// Вспомогательная переменная для указания области экрана AHIRECT_T rect; // Устанавливаем растровую операцию на применение кисти AhiDrawRopSet(dCtx, AHIROP3(AHIROP_PATCOPY)); // Установим цвет кисти. Этим цветом будут выводиться наши графические примитивы AhiDrawBrushFgColorSet(dCtx, ATI_565RGB(0,0,255)); // Ярко-синий // Зададим прямоугольник на экране, который будет залит нашим цветом rect.x1 = 0; rect.y1 = 0; rect.x2 = 64; rect.y2 = 64; // Нарисуем прямоугольник rect AhiDrawSpans(dCtx, &rect, 1, 0);
- Заменяем экранную поверхность
Графика выведена во внеэкранную поверхность, но теперь её нужно вывести на экран. Для этого мы устанавливаем sDraw экранной поверхностью, а sDisp - поверхностью для рисования и меняем местами значения переменных sDisp и sDraw:AHISURFACE_T tSurface; // Установка экранной поверхности AhiDispSurfSet(dCtx, sDraw, 0); // Установка поверхности для рисования AhiDrawSurfDstSet(dCtx, sDisp, 0); // Изображение получено на экране // Меняем поверхности местами tSurface = sDisp; sDisp = sDraw; sDraw = tSurface;
Далее повторяем все действия с первого пункта, пока необходимо выводить графику
- Возвращаем значения sDisp и sDraw
Перед выходом из эльфа ОБЯЗАТЕЛЬНО необходимо вернуть их значения, которые были выданы телефоном. Т.к. не известно, в какой из двух переменных (sDisp или sDraw) находится реальная экранная поверхность, мы воспользуемся переменными sRealDisp и sRealDraw, о которых говорилось в самом начале.// Установка экранной поверхности AhiDispSurfSet(dCtx, sRealDisp, 0); // Установка поверхности для рисования AhiDrawSurfDstSet(dCtx, sRealDraw, 0);
И только тогда выходим из эльфа.
См. также
- AHI - драйвер для чипов ATI
- LdrDisplayCbkReg - функция для создания callback'ов для рисования поверх UIS
- LdrDisplayCbkUnReg - функция для удаления callback'ов, созданных с помощью LdrDisplayCbkReg
- Предотвращение мерцания - Классический метод предотвращения мерцания при выводе графики