Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2

BitBlt


MinGW   (20.04.17 20:46[20]

У вас DIB-секция - грубо говоря просто массив байт в памяти. Каким же образом GDI обязана "блокировать" доступ к ней? И зачем ей это?

Это вопрос не функций GDI, а синхронизации потоков.

Вы что, не имеете в своей многопоточной системе событий/сигналов типа "отрисовка кадра началась", "отрисовка кадра закончилась", "пора начать рисовать новый кадр"? Молотите как попало на максимуме процессора? Это как бы нехорошо.


dmk ©   (21.04.17 12:42[21]

>пора начать рисовать новый кадр
Суть потоков в том, что в совокупности они настолько быстрые, что после вызова BitBlt они начинают рисовать в буфере который еще выводится. Т.е. система не успевает дорисовать до конца буфер, а потоки уже успевают в нем нарисовать новое. Флага в системе что отрисовка окончена нет. В одном потоке нет проблем.


D7   (24.04.17 11:32[22]

Вообще вроде логично что надо дождаться пока кадр выведется, и тока потом продолжать рисование на этом кадре.
Дак может сделаете свой?

...
IsDrawing:=True;
BitBlt(...);
IsDrawing:=False;
...


Как бы логически аналог Lock/Unlock из TCanvas.


dmk ©   (24.04.17 17:23[23]

Вы странный человек. Это потоки. У меня рисует только один поток с ID=0.
Остальные ждут пока он отрисует. Именно такой флаг и стоит. Только когда делается вызов BitBlt, поток ID=0 сразу после вызова функции выходит и возвращается в цикл где ждут остальные потоки, чтобы продолжить отрисовку, но сама BitBlt еще не успевает дорисовать!!! Сама функция еще не выполнена!!! Может она драйверу дает отрисовывать, может еще кому. Факт в том, что она не успевает дорисовать, а потоки уже рисуют в буфере. 20 потоков (в моем случае) это очень быстро!!!! BitBlt просто не потокобезопасна. Она жизнеспособна только в одном потоке. У меня и Synchronize стоит и флаги. Результат один и тот же.

Еще раз привожу код:


//Это процедура вывода на экран
procedure TTestForm.UpdateThreads;
var
 dp: TDrawParams;

begin
 if (not gThreadsUpdating) then
 begin
   gThreadsUpdating := true;

   if bZBuffer then sBmp.DrawZBuffer;

   //Информация и контролы
   sBmp.DrawSmallText(Rgn.X + 10, Rgn.Y + 10, Ansistring('Рисует ID: ' + HexToStr(Word(gFirstID)) + 'h'), 1, crWhite, 255, 64);
   dp.Angle := gAngle;
   if bInfo then TestForm.DrawCenterInfo(dp);
   RepaintControls;
   DrawProgress(gProgress, false);
   UpdateWindow; // <-Здесь находитя BitBlt

   if b3D then sBmp.ClearZBuffer;

   //Очищаем фон
   ClearBack;

   //Счетчик обновлений
   Inc(gNumBufferUpdates);

   gThreadsUpdating := false;
 end;
end;

//Это цикл отрисовки
procedure QThread.Execute;
var
 cP: TFloatPoint;
 Params: TDrawParams;

label
 StopDraw;

begin
 //Параметры по умолчанию
 Params := FillParams;

 //Центр вращения
 cP.fX := cX;
 cP.fY := cY;

 //Порядковый номер потока
 NumberID := GetFreeID(ThreadID);

 //Заполняем параметры
 Params.cX := cX;
 Params.cY := cY;
 Params.ThreadID := NumberID;
 Params.Angle := gAngle;

 //Отсечение всего региона
 if bClip then
   Params.R := lmR else
   Params.R := Rgn;

 //Цикл отрисовки
 while (gDrawCounter <= gNumDrawCycles) do
 begin
   //Превышение индекса объектов
   //учитывается в программе отрисовки
   //Рисуем ...
   gDrawProc(Params);

   //Обновляет буфер самый шустрый поток
   if (ThreadID = gFirstID) then
   begin
     //Обновляем буфер
     Synchronize(TestForm.UpdateThreads); //<-- Synchronize не обязательно, но может моргать!
     //TestForm.UpdateThreads;
     //Прогресс
     gProgress := Round(gDrawCounter / (gNumDrawCycles - 1) * 100);
     //Кол-во циклов отрисовки
     Inc(gDrawCounter);
     //Следующий угол
     gAngle := RorAngle(gAngle, gAngleInc);
     //Сброс кол-ва отрисованных объектов
     gObjectIndex := 0;
   end;//if (gNumEntered)

   //Устанавливаем флаг завершения отрисовки
   FPaints[NumberID] := True;

   //Остальные потоки ждут здесь
   //пока первый поток не отрисует буфер
   //или все потоки не соберутся здесь
   while (not PaintsFinished) do
   begin
     //Проверка на превышение циклов отрисовки
     if (gDrawCounter >= gNumDrawCycles) then goto StopDraw;
   end;

   //Проверка на ESC
   if gESC then goto StopDraw;
 end;//while

StopDraw:

 //Устанавливаем флаг завершения отрисовки
 FPaints[NumberID] := True;

 //Ждем здесь пока остальные потоки не закончат отрисовку
 while (not PaintsFinished) do
 begin
 end;
end;


dmk ©   (24.04.17 17:40[24]

Короче добавил CriticalSection в UpdateThreads - скорость снизилась, но глюки исчезли.
Значит Игорь Шевченко ©   (09.02.17 21:39) [4] был прав.


Страницы: 1 2 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо