Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.05.11;
Скачать: CL | DM;

Вниз

Двойная буфферизация(выдернуто из "Вакансия Delphi программист")   Найти похожие ветки 

 
Eraser ©   (2008-03-23 21:37) [80]

> [79] oxffff ©   (23.03.08 21:33)

вот у него и поинтересуйтесь )
вот чего он не содержит, так это картинки с изображением окна. Ну не кэширует виндовз это и все тут.. на этом уровне абстракции по крайней мере, уверен, что на более низком уровне растры кэшируются графической подсистемой, но не здесь.


 
Игорь Шевченко ©   (2008-03-23 21:52) [81]

oxffff ©   (23.03.08 21:33) [79]

Кстати, еще:

Та же программа с небольшими изменениями, перечисляющая окна и пытающаяся вывести кусок с DC

function EnumWindowProc (Wnd: HWND; param: LPARAM): Integer; stdcall;
var
 AClassName: array[0..255] of char;
 CS: DWORD;
begin
 with TForm1(param) do
 begin
   GetClassName(Wnd, AClassName, SizeOf(AClassName));
   CS := GetClassLong(Wnd, GCL_STYLE);
   if (CS and (CS_OWNDC or CS_CLASSDC)) <> 0 then
     ListBox1.Items.AddObject(AClassName, TObject(Wnd));
 end;
 Result := 1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Wnd: HWND;
 ADC: HDC;
begin
 if ListBox1.ItemIndex > -1 then
 begin
   Wnd := HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]);
   if IsWindow(Wnd) then
   begin
//      ADC := GetWindowDC(Wnd);
     ADC := GetDC(Wnd);
     try
       with PaintBox1.ClientRect do
         //StretchBlt(PaintBox1.Canvas.Handle, Left, Top, Right - Left,
//            Bottom - Top,
//            ADC, 0, 0, Right - Left, Bottom - Top, SRCCOPY);
         BitBlt(PaintBox1.Canvas.Handle, Left, Top, Right - Left,
           Bottom - Top,
           ADC, 0, 0, {Right - Left, Bottom - Top, }SRCCOPY);
     finally
       ReleaseDC(Wnd, ADC);
     end;
   end;
 end;
end;


У меня в ListBox три окна - ConsoleWindowClass от Far, MsoCommandBarPopup  от Help по Delphi 2006 и ConsoleWindowClass от Apache, запущенного в консоли.

Окно FAR не полноэкранное и перекрыто нижним краем окна программы.

При нажатии на кнопку в PaintBox рисуется как часть окна Far, так и краешек окна программы, которым перекрыто окно Far.

Меня это приводит к выводу о том, что буфер - он для растра, а не для каждого DC :)

На этой оптимистической ноте закончим дискуссию ?


 
Игорь Шевченко ©   (2008-03-23 22:01) [82]

Попытаюсь подвести итог: Большинство операций рисования GDI вызывает обновление буфера растра. В зависимости от возможностей драйвера видеокарты, эти операции обновления отдаются либо драйверу напрямую, чтобы рисование выполнялось с использованием процессора видеокарты, либо GDI рисует по своим алгоритмам, используя процессор собственно компьютера и пересылает сформированное изображение в видеопамять.
При установленном свойстве DoubleBuffered все рисование с точки зрения GDI выполняется одной операцией BitBlt, поэтому буфер растра обновляется один раз и результаты промежуточных операций на экране не мелькают.


 
31512   (2008-03-23 22:03) [83]

Сохраню-ка я эту веточку для повышения образованности. Опять же много пользительных ссылок приведено... :-)


 
Eraser ©   (2008-03-23 22:07) [84]

> [77] Игорь Шевченко ©   (23.03.08 20:38)


> Но в двух словах. если говорить о DC и об окнах, то буфер
> есть у растра, весьма вероятно, что физически оно живет
> у того самого DC, который по CreateDC("DISPLAY") создается.
> Все оконные DC представляют "окна" (пардон за тавтологию)
> в этот буфер, с границами, определямыми регионами отсечения.

Фэнь с вами согласен.
Вероятно вы достаточно четко представляете себе отличия между контекстом устройства, связанным с конкретным окном, и контекстом, созданным функцией CreateDC. Главное отличие заключается в том, что к числу атрибутов первого относится прямоугольник вывода, являющийся подмножеством поверхности устройства, и объединенный видимый регион, который строится с учетом таких факторов, как регион окна, отсечение соседних и дочерних окон, видимых частей и обновляемого региона окна.


 
oxffff ©   (2008-03-23 22:09) [85]


> Eraser ©   (23.03.08 21:37) [80]
> > [79] oxffff ©   (23.03.08 21:33)
>
> вот у него и поинтересуйтесь )
> вот чего он не содержит, так это картинки с изображением
> окна. Ну не кэширует виндовз это и все тут.. на этом уровне
> абстракции по крайней мере, уверен, что на более низком
> уровне растры кэшируются графической подсистемой, но не
> здесь.


читать про Private Device Contexts и их отличие от Common Device Contexts.


 
oxffff ©   (2008-03-23 22:13) [86]


> Меня это приводит к выводу о том, что буфер - он для растра,
>  а не для каждого DC :)
>
> На этой оптимистической ноте закончим дискуссию ?


Так я вам об этом выше написал. см. oxffff ©   (23.03.08 20:10) [68]

Но разговор был о том, есть некий DC SHARED растр, пусть он будет большой и разделяемый не суть важно.

Важно, что есть буфер который -> копируется в видепамять.


 
oxffff ©   (2008-03-23 22:15) [87]


> Игорь Шевченко ©   (23.03.08 22:01) [82]


Именно это мнение я и разделяю.
Поэтому при double buf буфферов может быть 2 и 3 с учетом front buf video.


 
Eraser ©   (2008-03-23 22:16) [88]

> [85] oxffff ©   (23.03.08 22:09)

ну есть отличие, только поясните, какое это отношение имеет к теме, в частности, двойной буфферизации? что-то я не уловил момент..


 
oxffff ©   (2008-03-23 22:21) [89]


> Eraser ©   (23.03.08 22:16) [88]


[37] [39] [40]


 
Eraser ©   (2008-03-23 22:29) [90]

> [89] oxffff ©   (23.03.08 22:21)

вы не путаете кэширование gdi операций с кэшированием готовых растров?
к слову в висте реализовали системный механизм растровой буфферизации, который успешно применяется в CDS2007, см. BeginBufferedPaint.


 
oxffff ©   (2008-03-23 22:31) [91]


> Eraser ©   (23.03.08 22:29) [90]


Разговор у нас о DC и DC bitmap.
Я вас не понял.


 
Дмитрий С   (2008-03-23 22:38) [92]

Честно говоря я думал, что под Device (в DC) подразумевается некое устройство (экран, окно, принтер, битмэп, метафайл) для возможности универсально "рисовать" на них. Иначе говоря, я думал, что bitmap в данном случае - лишь один из вариантов того, на чем можно рисовать с помощью DC. И, честно говоря, ранее меня не смущало, что битмэп привязывается к ДЦ с помощью функции SelectObject.
Поправьте меня, если я не прав.


 
oxffff ©   (2008-03-23 22:40) [93]

to Eraser

Offtop

BeginBufferedPaint

Ну насколько я понял назначение этой функции в том, чтобы обеспечить предварительную отрисовку содержимого в буфере видеокарты, а поскольку скорее всего все операции будут аппаратно поддержаны то сократится количество пересылок RAM -> VIDEO RAM.
Что хорошо скажется на производительности.

Наш разговор был не об этом. :)


 
Eraser ©   (2008-03-23 22:57) [94]

> [89] oxffff ©   (23.03.08 22:21)


> [37] [39] [40]

не пойму в чем "фишка" этого примера?
ведь он только доказывает, то, что уже несколько раз проверял Игорь - копируется только то, что видимо.
вот моя модификация

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm2 = class(TForm)
   Memo1: TMemo;
   Button2: TButton;
   procedure Button2Click(Sender: TObject);
 protected
   procedure CreateParams (var Params: TCreateparams); override;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button2Click(Sender: TObject);
const
 WindowName = "DMClient";
var
 WindowRect: TRect;
 hWnd: THandle;
begin
 hWnd := FindWindow(nil, WindowName);
 GetWindowRect(hWnd, WindowRect);

 StretchBlt(GetDC(Memo1.Handle), 0, 0, Memo1.Width,
   Memo1.Height,
   GetDC(hWnd),
   Memo1.Left, Memo1.Top, Memo1.Width,
   Memo1.Height, SRCCOPY);
end;

procedure TForm2.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;

end.

окно DMClient"а видно только если оно на видимо и только те части, которые не скрыты другими окнами, ч.т.д.


> BeginBufferedPaint
>
> Ну насколько я понял назначение этой функции в том, чтобы
> обеспечить предварительную отрисовку содержимого в буфере
> видеокарты, а поскольку скорее всего все операции будут
> аппаратно поддержаны то сократится количество пересылок
> RAM -> VIDEO RAM.

думаю да, реализация этой функции не многим отличается от того, что реализовано в VCL для более старых версий системы. Там вроде можно указать какой именно тип битмапа применять для кэширования, к примеру BPBF_DIB или BPBF_COMPATIBLEBITMAP.


 
Eraser ©   (2008-03-23 22:59) [95]

> [92] Дмитрий С   (23.03.08 22:38)

все правильно, контекст устройство это инструмент для рисования, а не холст. Холст (битмап) к нему можно привязать, но не ко всякому контексту, а только в compatable... BeginBufferedPaint позволяет обойти это ограничение, но только благодаря своим механихмам и для целей буфферизации, хотя возможно как то и можно добраться до внутреннего буффера, используемого этой функцией.


 
Игорь Шевченко ©   (2008-03-23 23:03) [96]

Кстати, то что оконный DC представляет собой дырку в общий DC объясняет и то, что в оконный DC нельзя выбрать BITMAP - а чего с ним потом делать, с выбранным BITMAP"ом ? :)

oxffff ©   (23.03.08 22:13) [86]


> Важно, что есть буфер который -> копируется в видепамять.


Или не копируется - какой смысл занимать центральный процессор рисованием в этом буфере, если процессор видеокарты поддерживает массу операций GDI ?

Когда GDI (внутри ядра) уже посчитал отсечения и решил, что нужно вызывать драйвер для рисования, он вызывает одну из известных функций. При инициализации видеоподсистемы драйвер видеокарты записывает в адреса этих известных функций те, которые он поддерживает. Которые не поддерживает, остаются для реализации алгоритмов GDI средствами центрального процессора. Фэнь Юань про этот процесс пишет более подробно.

Так вот - если драйвер не чего-то поддерживает, то буфер растра будет и GDI будет на нем рисовать и отсылать драйверу в виде внутренней BitBlt - это вроде все поддерживают. А если драйвер поддерживает какие-то операции GDI, то и буфера растра не будет - все рисование будет выполняться видеокартой.


 
oxffff ©   (2008-03-23 23:05) [97]


> вот моя модификация


А что DMClient со стилем CS_OWNDC?
Перечитай еще раз внимательно. :)


 
oxffff ©   (2008-03-23 23:08) [98]


> Игорь Шевченко ©   (23.03.08 23:03) [96]


Это то понятно. Меня больше интересует вопрос более серьезный.
А как быть если часть операций поддерживается, а часть нет.
Часть операций видеокартой в VIDEO буфере, а часть в RAM буфере,
Как  потом смешивать результаты? :)))))))


 
Eraser ©   (2008-03-23 23:10) [99]

> [97] oxffff ©   (23.03.08 23:05)

пардон, моя вина.. невнимательность, но суть дела это не поменяло.. даже если заменить WindowName = "DMClient"; на WindowName = "Form2"; эффект тот же - скрытая часть окна не копируется.


 
oxffff ©   (2008-03-23 23:11) [100]


> oxffff ©   (23.03.08 23:08) [98]


Или делается копия в этом случае в RAM <--> VIDEO RAM.


 
Игорь Шевченко ©   (2008-03-23 23:15) [101]

oxffff ©   (23.03.08 23:08) [98]


> А как быть если часть операций поддерживается, а часть нет.
>
> Часть операций видеокартой в VIDEO буфере, а часть в RAM
> буфере,
> Как  потом смешивать результаты? :)))))))


То, что не поддерживается, рисуется в буфере растра, потом они смешиваются. Адаптером.


 
oxffff ©   (2008-03-23 23:23) [102]


> Игорь Шевченко ©   (23.03.08 23:15) [101]


Увы это можно сделать только для части операций.
Операции могут иметь зависимости.  :)


 
oxffff ©   (2008-03-23 23:27) [103]


> Eraser ©   (23.03.08 23:10) [99]
> > [97] oxffff ©   (23.03.08 23:05)
>
> пардон, моя вина.. невнимательность, но суть дела это не
> поменяло.. даже если заменить WindowName = "DMClient"; на
> WindowName = "Form2"; эффект тот же - скрытая часть окна
> не копируется.


Однако если свернуть окно, то копируется начиная с несвернутого положения.
Однако по данному примеру нельзя сделать вывод о количестве буферов или их отсутствии до попадания в front video buf.


 
Игорь Шевченко ©   (2008-03-23 23:32) [104]

oxffff ©   (23.03.08 23:23) [102]


> Увы это можно сделать только для части операций.
> Операции могут иметь зависимости.  :)


GDI тоже не дураки писали и о зависимостях представляют. Очевидно, что если нечто имеет зависимости и это нечто поддерживается аппаратно, а зависимости нет, то выбор делается в пользу целостности. Кроме того, набор функций, которые определяет драйвер, составлялся разработчиками GDI, поэтому зависимости они постарались исключить.


 
Игорь Шевченко ©   (2008-03-23 23:37) [105]

oxffff ©   (23.03.08 23:27) [103]


> Однако если свернуть окно, то копируется начиная с несвернутого
> положения.


Что подтверждает тезис о том, что DC окна является дыркой в DC экрана. Правда, копируется то, что в данный момент видно с этого несвернутого положения. То есть, с того прямоугольника (или региона), который отсекает часть от общего экрана для DC окна.


 
Eraser ©   (2008-03-23 23:37) [106]

> [103] oxffff ©   (23.03.08 23:27)


> Однако если свернуть окно, то копируется начиная с несвернутого
> положения.

у меня копируется опять пустое место.

вот модифицированный пример

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls;

type
 TForm2 = class(TForm)
   Memo1: TMemo;
   Button2: TButton;
   Label1: TLabel;
   Edit1: TEdit;
   Timer1: TTimer;
   procedure Button2Click(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
 protected
   procedure CreateParams (var Params: TCreateparams); override;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button2Click(Sender: TObject);
begin
 Timer1.Enabled := True;
end;

procedure TForm2.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;

procedure TForm2.Timer1Timer(Sender: TObject);
const
 WindowName = "Form2";
var
 //WindowRect: TRect;
 hWnd: THandle;
 bmp: TBitmap;
begin
 Beep;
 Timer1.Enabled := False;
 hWnd := FindWindow(nil, WindowName);
 //GetWindowRect(hWnd, WindowRect);

 bmp := TBitmap.Create;
 try
   bmp.Width := Width;
   bmp.Height := Height;
   StretchBlt(bmp.Canvas.Handle, 0, 0, Memo1.Width,
     Memo1.Height,
     GetDC(hWnd),
     0, 0, Memo1.Width,
     Memo1.Height, SRCCOPY);
   bmp.SaveToFile("test.bmp");
 finally
   bmp.Free;
 end;
end;

end.


> Однако по данному примеру нельзя сделать вывод о количестве
> буферов или их отсутствии до попадания в front video buf.

нет у DC окна никаких буфферов.


 
SPeller (work)   (2008-03-24 04:31) [107]

Ну и спор у вас :) Даже если где-то система что-то и буферизует, то на кой ляд программисту gdi об этом знать? Если содержимое окна надо каждый раз перерисовывать, значит нет буфера :) Если буфер есть, то на кой хрен мы каждый раз перерисовывем? :)


 
31512   (2008-03-24 07:52) [108]

Пора кому-то браться за книжку "О чём спорят на форумах по Delphi".... Я из этой ветки массу новых знаний почерпнул!!!!


 
DVM ©   (2008-03-24 11:43) [109]


> 31512   (24.03.08 07:52) [108]

У Фень Юаня то же самое все гораздо более строго и подробно расписано. Правда без учета висты пока. А здесь спор не ради истины, а ради самого спора скорее.


 
oxffff ©   (2008-03-24 13:34) [110]


> нет у DC окна никаких буфферов.


Игорь Шевченко ©   (23.03.08 22:01) [82]


 
Игорь Шевченко ©   (2008-03-24 14:25) [111]

oxffff ©   (24.03.08 13:34) [110]

Ну все равно ведь нету :) у DC окна...


 
oxffff ©   (2008-03-24 20:17) [112]


> Игорь Шевченко ©   (24.03.08 14:25) [111]


Как нету?

А как же HBM := GetCurrentObject(DC, OBJ_BITMAP);?

Ведь растр есть. И нет гарантии, что это сразу front поверхность
Так же как и что это back поверхность.


 
oxffff ©   (2008-03-24 20:20) [113]


> Игорь Шевченко ©   (24.03.08 14:25) [111]
> oxffff ©   (24.03.08 13:34) [110]
>
> Ну все равно ведь нету :) у DC окна...


oxffff ©   (22.03.08 14:17) [21]


 
Eraser ©   (2008-03-24 20:24) [114]

> [112] oxffff ©   (24.03.08 20:17)

читаем еще раз литературу, оконный DC не совместим с DC, который может рисовать на битмапах.


 
oxffff ©   (2008-03-24 20:26) [115]


> Eraser ©   (24.03.08 20:24) [114]


Чего???????


 
oxffff ©   (2008-03-24 20:28) [116]


> Eraser ©   (24.03.08 20:24) [114]


Вообще речь во всей ветке шла о количестве буферов перед тем попадет изображение на Front поверхность видеопамяти.


 
oxffff ©   (2008-03-24 20:29) [117]


> Eraser ©   (24.03.08 20:24) [114]
> > [112] oxffff ©   (24.03.08 20:17)
>
> читаем еще раз литературу, оконный DC не совместим с DC,
>  который может рисовать на битмапах.


Ты хочь понял что сказал,
скажи почему есть битмап в оконном DC? И почему функции Bitblt в примерах выше работают?


 
Eraser ©   (2008-03-24 20:39) [118]

> [116] oxffff ©   (24.03.08 20:28)


> Вообще речь во всей ветке шла о количестве буферов перед
> тем попадет изображение на Front поверхность видеопамяти.

давай не будем касаться фронт-буфферов, драйверов и т.п., т.к. это совершенно другая тема, мало пересекающаяся с прикладным уровнем DC.

> скажи почему есть битмап в оконном DC?

не знаю почему он там есть.

> И почему функции Bitblt в примерах выше работают?

как они работают то? копируют ровно то, что есть в экранном контексте, легко доступном через CreateDC(PChar("DISPLAY"), nil, nil, nil);
ни каких бэк-буфферов в этом битмапе или где либо еще на прикладном уровне я не наблюдал.
если знаешь, где этот буффер - покажи, не знаешь - о чем тогда спор?


 
oxffff ©   (2008-03-24 20:54) [119]


> давай не будем касаться фронт-буфферов, драйверов и т.п.
> , т.к. это совершенно другая тема, мало пересекающаяся с
> прикладным уровнем DC.


Речь шла как раз об этом.

> > скажи почему есть битмап в оконном DC?
>
> не знаю почему он там есть.


А чем ты рисуешь?


>
> как они работают то? копируют ровно то, что есть в экранном
> контексте, легко доступном через CreateDC(PChar("DISPLAY"),
>  nil, nil, nil);
> ни каких бэк-буфферов в этом битмапе или где либо еще на
> прикладном уровне я не наблюдал.
> если знаешь, где этот буффер - покажи, не знаешь - о чем
> тогда спор?


Разговор начался в самом самом начале о количестве буферов перед попаданием из MemDC в окно.
То что буфер есть можно узнать по
HBM := GetCurrentObject(DC, OBJ_BITMAP).
А то что он необычный по провалу при вызове GetObject


 
oxffff ©   (2008-03-24 20:55) [120]


> Разговор начался в самом самом начале о количестве буферов
> перед попаданием из MemDC в окно.


Во front buf адаптера



Страницы: 1 2 3 4 5 6 вся ветка

Текущий архив: 2008.05.11;
Скачать: CL | DM;

Наверх




Память: 0.73 MB
Время: 0.037 c
3-1196078709
Тимур
2007-11-26 15:05
2008.05.11
SQL.ADD выдает ошибку


3-1196807687
Евгений Р.
2007-12-05 01:34
2008.05.11
Редактирование в dbGrid для tIbQuery


4-1188571688
istok
2007-08-31 18:48
2008.05.11
получить хендл окна...


2-1207991462
Alex8
2008-04-12 13:11
2008.05.11
Table


15-1206524725
capkoh
2008-03-26 12:45
2008.05.11
Изучение SQL. Сколько времени?