Текущий архив: 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]
Кстати, еще:
Та же программа с небольшими изменениями, перечисляющая окна и пытающаяся вывести кусок с DCfunction 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