Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
51
Добавлен:
02.04.2015
Размер:
8.79 Mб
Скачать
      1. Поверхности

Изображение, отображаемое на слое, берется с одного или нескольких внеэкранных контекстов, также называемых поверхностями. Количество поверхностей, необходимых для слоя, определяется его форматом. Так например, для слоя с форматом Pg_LAYER_FORMAT_ARGB888 требуется только одна поверхность, тогда как для слоя с форматом Pg_LAYER_FORMAT_YUV420 требуется три поверхности для получения полного изображения. Формат слоя устанавливается при помощи PgSetLayerArg().

      1. Окна просмотра

окно-источник и отображаемое окно

«Окно-источник» определяет прямоугольную область в данных поверхности. Окно используется для извлечения из данных поверхности того набора, который необходимо отобразить на слое.

«Отображаемое окно» определяет прямоугольную область на экране, где будет отображаться содержимое слоя.

Прокрутка и масштабирование, если поддерживаются слоем, могут осуществляться изменением этих типов «окон». Для перемещения по изображению на поверхности, связанной со слоем необходимо менять координаты «окна-источника». Для масштабирования – менять размеры «окон».

Вам необходимо установить цель действия этих преобразований используя PdSetTargetDevice().

      1. Api слоев

Программный интерфейс слоев состоит из:

PtGetLayerCaps() получить информацию о возможностях слоя

PgCreateLayerSurface() создать внеэкранную поверхность, отображаемую слоем

PgSetLayerSurface() отобразить внеэкранную поверхность на слое

PgSetLayerArg() настроить параметры слоя

PgLockLayer() захватить слой для эксклюзивного использования приложением

PgUnlockLayer() снять захват со слоя

PgLayerCaps_t структура данных, описывающая возможности слоя

API слоев в настоящий момент несовместимо с API оверлеев (PgCreateVideoChannel(), PgConfigScalerChannel(), PgNextVideoFrame(), и так далее). Не запускайте одновременно два приложения использующие эти два программные интерфейса.

Учтите:

  • Photon не может рисовать во внеэкранных поверхностях, формат которых отличен от текущего видеорежима. Таким образом может оказаться невозможно использовать функции рисования Photon на внеэкранном онтексте, полученном при помощи PgCreateLayerSurface(). Вместо этого приложение должно использовать PdGetOffscreenContextPtr(), для получения указателя на видеопамять и записывать данные напрямую.

  • Если приложение изменит внеэкранную поверхность основного экрана при помощи PgSetLayerSurface(), Photon всеравно продолжит рисовать в старую внеэкранную поверхность. Приложению необходимо сохранить указатель на старую поверхность и восстановить её как только оно перестанет использовать слой. Как это сделать показано ниже в примере.

Использование слоев

Чтобы использовать возможности слоев вы обычно должны сделать следующее:

  1. Используйте PgGetLayerCaps() с постоянно увеличивающимся индексом слоя для определения возможностей оборудования (если вы еще их не знаете). Если PgGetLayerCaps() дает ошибку для любых значений – драйвер не поддерживает слои.

  2. Если вы хотите предотвратить использование слоя другими приложениями – используйте PgLockLayer().

  3. Создайте поверхности для отображения на слое и внеэкранные контексты – для отображения данных на поверхность при помощи PgCreateLayerSurface().

  4. Вызовите PgSetLayerArg() с аргументом Pg_LAYER_ARG_LIST_BEGIN.

  5. Вызовите PgSetLayerArg() для установки параметров слоя.

  6. Вызовите PgSetLayerSurface() для отображения внеэкранного контекста поверхности на слое.

  7. Вызовите PgSetLayerArg() для установки параметров слоя. Вы можете использовать Pg_LAYER_ARG_ACTIVE в качестве аргумента для отображения содержимого слоя на экране.

  8. Вызовите PgSetLayerArg() с аргументом Pg_LAYER_ARG_LIST_END.

  9. Если формат слоя RGB или PAL8 установите один из контекстов поверхности слоя текущим а затем используйте Pg* - функции для рисования во внеэкранный контекст.

  10. Если формат слоя YUV, или подобный – вы чаще всего будете записывать данные непосредственно в буфер (например для воспроизведения видеопотока).

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

Программа, приведенная ниже показывает использование программного интерфейса слоев.

      1. Пример

#include <errno.h>

#include <stdio.h>

#include <Ph.h>

int

FindFormatIndex(int layer, unsigned int format)

{

PgLayerCaps_t caps;

int format_idx = 0;

while (PgGetLayerCaps(layer, format_idx, &caps) != -1) {

if (caps.format == format)

return format_idx;

format_idx++;

}

return -1;

}

int

main(int argc, char **argv)

{

/*

* For best results, these values should match your video mode.

*/

#define LAYER_FORMAT Pg_LAYER_FORMAT_ARGB8888

#define SURFACE_WIDTH 1024

#define SURFACE_HEIGHT 768

struct _Ph_ctrl *ph;

PgLayerCaps_t caps;

PdOffscreenContext_t *surf;

PdOffscreenContext_t *scr = NULL;

PhDrawContext_t *olddc;

PhRid_t driver_rid = -1;

int layer_idx = -1;

int format_idx = -1;

int active = 1;

int i;

/*

* Arguments:

* -d <driver region>

* -l <layer index>

*/

while ((i = getopt(argc, argv, "d:l:")) != -1) {

switch(i) {

case 'd': /* driver region */

driver_rid = atol(optarg);

break;

case 'l': /* layer index */

layer_idx = atoi(optarg);

break;

default:

break;

}

}

if (layer_idx == -1) {

printf("Specify layer index.\n");

exit(-1);

}

if (driver_rid == -1) {

printf("Specify graphics driver region.\n");

exit(-1);

}

ph = PhAttach(NULL, NULL);

if (ph == NULL) {

perror("PhAttach");

exit(-1);

}

if (-1 == PdSetTargetDevice(PhDCGetCurrent(), driver_rid)) {

perror("PdSetTargetDevice");

exit(-1);

}

/* Check if the layer supports the required format */

format_idx = FindFormatIndex(layer_idx, LAYER_FORMAT);

if (format_idx == -1) {

printf("Layer does not support format\n");

exit(-1);

}

/* Get the layer capabilities */

PgGetLayerCaps(layer_idx, format_idx, &caps);

if (caps.caps & Pg_LAYER_CAP_MAIN_DISPLAY) {

/* Save a reference to the current display surface */

scr = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);

}

/* Allocate a surface for the layer */

surf = PgCreateLayerSurface(layer_idx, 0, format_idx,

SURFACE_WIDTH, SURFACE_HEIGHT, Pg_OSC_MEM_PAGE_ALIGN);

if (surf == NULL)

exit(-1);

/* Draw some stuff on the surface */

olddc = PhDCSetCurrent(surf);

PgSetFillColor(Pg_BLACK);

PgDrawIRect(0, 0, SURFACE_WIDTH-1, SURFACE_HEIGHT-1, Pg_DRAW_FILL);

PgSetFillColor(Pg_YELLOW);

PgDrawIRect(0, 0, 100, 100, Pg_DRAW_FILL);

PgSetFillColor(PgRGB(255,180, 0));

PgDrawIRect(70, 80, 600, 500, Pg_DRAW_FILL);

PhDCSetCurrent(olddc);

/* Lock the layer */

if (-1 == PgLockLayer(layer_idx))

exit(-1);

/* Start configuring arguments */

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);

/* Select the layer format */

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_FORMAT_INDEX,

&format_idx, sizeof(int));

/* This changes the current display surface */

PgSetLayerSurface(layer_idx, 0, surf);

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_ACTIVE,

&active, sizeof(int));

/* Configure other arguments ... */

/* End configuration */

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_END, 0, 0);

/* Application continues ... */

sleep(3);

/* Finished using layer; Restore the current display surface */

if (caps.caps & Pg_LAYER_CAP_MAIN_DISPLAY) {

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);

PgSetLayerSurface(layer_idx, 0, scr);

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_END, 0, 0);

}

PgUnlockLayer(layer_idx);

if (scr) PhDCRelease(scr);

PhDCRelease(surf);

PhDetach(ph);

exit(0);

}

Соседние файлы в папке Литература