Страниц: [1]
  Печать  
Автор Тема: PgWaitHWIdle  (Прочитано 2715 раз)
lari
Участник
*
Offline Offline

Сообщений: 16


Просмотр профиля
« : Июля 10, 2013, 10:03:51 pm »

Здравствуйте!

Возникла ситуация влияния функции PgWaitHWIdle на отработку функций и утилит работы со временем: clock_gettime, time, date. После вызова PgWaitHWIdle временные результаты этих функций отстают от аппаратного времени(для сравнения использую rtc hw) А при цикличном вызове PgWaitHWIdle расхождение времен накапливается. 
Кусочек кода, где крутится PgWaitHWIdle взят из примера:
...
PgSetFillColor(Pg_WHITE);
PgDrawIRect(0,0,image->size.w - 1,image->size.h - 1,Pg_DRAW_FILL);
PgDrawPhImagemx(NULL,image,0);
PgFlush();
PgWaitHWIdle();
PhDCSetCurrent(dc);
...
Два вопроса:

1) PgWaitHWIdle - практически черный ящик -  по каким причинам она может тормозить функции работы со временем?
2) Если PgWaitHWIdle не использовать при работе с контекстами, к чему это может привести в конечном итоге? (Спрашиваю, потому что комментирую вызов PgWaitHWIdle, все отрисовывается как положено + нет расхождений времен).

Заранее благодарю.
Записан
AG
QOR.Moderator
*****
Offline Offline

Сообщений: 872



Просмотр профиля WWW
« Ответ #1 : Июля 11, 2013, 10:53:24 am »

Нашел пару фрагментов в старом коде. Не знаю поможет ли тебе это.

Код:
int
PgWaitHWIdle( void )
{
struct _Ph_msg_hdr hdr;
iov_t siov[1];
int   ret;

SETIOV( &siov[0], &hdr, sizeof( hdr ) );
hdr.type = _Ph_HW_SYNC;
ret = PhSendGraphicsService(0, siov, 1, NULL, 0);

return ret;
}

Код:
case _Ph_HW_SYNC:{ // Used by PgWaitHWIdle().
if (opt_WaitOnlySpecified) {
if(gf_draw_begin(td->gf_context) == GF_ERR_OK) {
if (gf_draw_finish(td->gf_context) != GF_ERR_OK)
ret_code = EBUSY;
else
ret_code = EOK;

gf_draw_end(td->gf_context);
}
} else {
DISPLAY_INFO_t * display = displays;

while (display != NULL) {
if(gf_draw_begin(display->gf_context) == GF_ERR_OK) {
if (gf_draw_finish(display->gf_context) != GF_ERR_OK)
ret_code = EBUSY;
else
ret_code = EOK;

gf_draw_end(display->gf_context);
}

display = display->next;
}
}
break;
}

Записан

lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #2 : Июля 17, 2013, 09:53:50 pm »

В изначальном примере можно убрать PgWaitHWIdle(), он не нужен как таковой. Его можно заменить на такой код:

1) Отрисовка
2) PgFlush()
3) Рисуем что-то невидимое или ненужный элемент, например точку цвета фона.
4) PgFlush()

Это приведёт к эмуляции PgWaitHWIdle() для любого видеодрайвера.

По поводу отставания времени - я задам вопрос, стало интересно. Вообще PgWaitHWIdle() выполняется в высокоприоритетном потоке и она является блокирующей, т.е. пока драйвер не вернёт управление практически всё висит. Может расхождение по времени связано с этим.
Записан

Страниц: [1]
  Печать  
 
Перейти в: