logo search
Литература_1 / photon_old

Внеэкранная видеопамять

Эти вызовы программного интерфейса приложения позволяют Вам использовать остаточную (leftover) память видеокарты. Когда видеокарта находится в видеорежиме, это обычно остаток видеопамяти, который не используется областью дисплея. Эти области памяти могут использоваться для выполнения различных графических операций, хотя используются ещё акселератором видеокарты. В микроGUI Photon'а они в основном рассматриваются в качестве возможности, аналогичной использованию контекста памяти, но их использование будет более быстрым, поскольку для этих областей имеется аппаратное ускорение. Функции и структуры данных включают:

PdCreateOffscreenContext()

Создание внеэкранного контекста в видеопамяти

PdDupOffscreenContext()

Дублирование внеэкранного контекста

PdGetOffscreenContextPtr()

Создание ссылки на объект совместно используемой памяти внеэкранного контекста

PdOffscreenContext_t

Структура данных, описывающая внеэкранный контекст

PdSetOffscreenTranslation()

Установка преобразования для внеэкранного контекста

PdSetTargetDevice()

Установка целевого устройства

PgContextBlit()

Копирование данных из прямоугольника в одном контексте в другой контекст

PgContextBlitArea()

Копирование данных из области в одном контексте в другой контекст

PgSwapDisplay()

Указать ЭЛТ видеодисплея на заданный контекст

PgWaitHWIdle()

Ожидать, пока видеодрайвер не окажется в простое

PhDCRelease()

Освобождение контекста прорисовки

Вот некий простой код, который создаёт и формирует изображение во внеэкранном буфере, а затем копирует данные на экран. Он создаёт два внеэкранных контекста объёмом 100х100, выполняет какую-то прорисовку, блитинг, и затем блитирует результат в текущую область (т.е. в область, принадлежащую PtWindow). В этом примере предполагается, что Вы уже создали окно и вызвали функцию PgSetRegion(), чтобы указать, что область окна вызывает появление событий прорисовки:

#include <Pt.h>

PtInit( NULL );

/* ... */

PhDrawContext_t *olddc;

PdOffscreenContext_t *context1, *context2;

PhArea_t rsrc,rdst;

/* Создаём область 100x100 в собственном формате экрана */

context1=PdCreateOffscreenContext(0,100,100,0);

if (context1 == NULL)

{

/* Ошибка */

}

/* Делаем её текущим контекстом и рисуем в ней пурпурный прямоугольник */

olddc=PhDCSetCurrent(context1);

PgSetFillColor(Pg_PURPLE);

PgDrawIRect(0,0,99,99,Pg_DRAW_FILL);

PgFlush(); /* Рисование прямоугольника */

PhDCSetCurrent(olddc);

/* Копируем контекст 1 и рисуем белый прямоугольник в середине пурпурного */

context2=PdDupOffscreenContext(context1,0);

if (context2==NULL)

{

/* Ошибка */

}

olddc=PhDCSetCurrent(context2);

PgSetFillColor(Pg_WHITE);

PgDrawIRect(9,9,89,89,Pg_DRAW_FILL);

PgFlush();

PhDCSetCurrent(olddc);

/* Копируем в экранную область пурпурный прямоугольник, изображение которого

сформировано вне экрана в контексте 1 */

rsrc.pos.x = rdst.pos.x = rsrc.pos.y = rdst.pos.y = 0;

rsrc.size.w = rdst.size.w = rsrc.size.h = rdst.size.h = 100;

PgContextBlitArea(context1, &rsrc, NULL, &rdst);

/* Копируем пурпурный и белый прямоугольники из контекста 2

рядом с пурпурным на дисплей */

rdst.pos.x = 100;

PgContextBlitArea(context2, &rsrc, NULL, &rdst);

PgFlush();

/* Очищаем внеэкранный контекст */

PhDCRelease(context1);

PhDCRelease(context2);

context1=NULL;

context2=NULL;

Внеэкранный контекст может быть отвергнут графическим драйвером по целому ряду причин. Когда такое случается, графический драйвер отсылает менеджеру Photon'а событие Ph_EV_INFO с подтипом Ph_OFFSCREEN_INVALID. Данные этого события представляют из себя одно длинное целое, описывающее, почему внеэкранная зона была признана недействительной. Возможными причинами являются следующие:

Pg_VIDEO_MODE_SWITCHED

Графический драйвер сменил видеорежимы

Pg_ENTERED_DIRECT

Приложение вошло в режим прямого доступа

Pg_EXITED_DIRECT

Приложение вышло из режима прямого доступа

Pg_DRIVER_STARTED

Видеодрайвер как раз начал выполнение

Приложение, которое будет использовать внеэкранные контексты, должно быть чувствительным к этим событиям и соответственно реинициализировать свои внеэкранные контексты.