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

Api слоев

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

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

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

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

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

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

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

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

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

Учтите:

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

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

  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);

}

Yandex.RTB R-A-252273-3
Yandex.RTB R-A-252273-4