Текущий архив: 2008.05.11;
Скачать: CL | DM;
Вниз
Двойная буфферизация(выдернуто из "Вакансия Delphi программист") Найти похожие ветки
← →
oxffff © (2008-03-23 17:24) [40]
> Игорь Шевченко © (23.03.08 17:09) [39]
Снимайте значок МАСТЕРА и передавайте его мне.
Убедитесь, что картинка есть.
Поправьте
with PaintBox1.ClientRect do
StretchBlt(PaintBox1.Canvas.Handle, Left, Top, Right - Left,
Bottom - Top,
ADC, 0, 0, Right - Left, Bottom - Top, SRCCOPY);
на
with Memo1.ClientRect do
StretchBlt(GETDC(Memo1.Handle), Left, Top, Right - Left,
Bottom - Top,
ADC, 0, 0, Right - Left, Bottom - Top, SRCCOPY);
← →
Игорь Шевченко © (2008-03-23 18:20) [41]oxffff © (23.03.08 17:24) [40]
А как же буфер, который в каждом DC ? Мой вариант тоже должен работать - ему ж без разницы. Кроме того, регулярно народ спрашивает, как ему получить изображение окна, если оно закрыто другими. В случае наличия буфера такой проблемы быть не должно, верно ?
← →
Дмитрий С (2008-03-23 18:33) [42]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
ApplicationEvents1: TApplicationEvents;
procedure ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = wm_paint then ListBox1.Items.Add(DateTimeToStr(Now));
end;
end.
Этот пример в Висте дает неожиданный интересный результат.
← →
Игорь Шевченко © (2008-03-23 19:05) [43]oxffff © (23.03.08 17:24) [40]
Кстати, о чем мы вообще спорим ?
Вот из Borland"овской справки: "Double buffering reduces the amount of flicker when the control repaints, but is more memory intensive."
Если у DC есть свой буфер, откуда вообще flicker возникает ?
← →
oxffff © (2008-03-23 19:10) [44]
> А как же буфер, который в каждом DC ?
Common device con
texts are display DCs maintained in a special cache by the system. Common device contexts are used in applications that perform infrequent drawing operations. Before the system returns the DC handle, it initializes the common device context with default objects, attributes, and modes. Any drawing operations performed by the application use these defaults unless one of the GDI functions is called to select a new object, change the attributes of an existing object, or select a new mode.
Because only a limited number of common device contexts exist, an application should release them after it has finished drawing. When the application releases a common device context, any changes to the default data are lost.
← →
oxffff © (2008-03-23 19:19) [45]
> Если у DC есть свой буфер, откуда вообще flicker возникает
> ?
Если после каждой графической операции DC пересылать подвергнутый операции RECT в VIDEO FRONT Buffer, то будет вам тот же flip.
Другое дело, что видеокарта может брать на себя часть операций поддерживаемых аппаратно, причем формировать изображение тоже в буфере возможно в своей области. Вообщем без DDK спецификации к видеодрайверу уже не обойтись. :)
>Кстати, о чем мы вообще спорим ?
Честно говоря общение куда свалилось не туда.
← →
Игорь Шевченко © (2008-03-23 19:19) [46]oxffff © (23.03.08 19:10) [44]
> When the application releases a common device context, any
> changes to the default data are lost.
Ну и нафига такой буфер нужен ? :)
Что по-твоему получается - в оконной процедуре по BeginPaint или по GetDC получается общий DC из кэша, на нем чего-то рисуется функциями GDI (надо понимать, в буфер ? ), а после ReleaseDC весь этот буфер пропадает ?
А теперь смотри: В системе масса окон, количество DC (всех, не только общих), всяко меньше количества окон, как они с буферами-то справляются ? Особенно, когда куча потоков лезет за DC в кэш.
← →
oxffff © (2008-03-23 19:22) [47]
> Если у DC есть свой буфер, откуда вообще flicker возникает
> ?
Вопрос в другом, а что если видеокарта не поддерживает часть GDI операций, тогда изображение будет сформировано средствами Windows в буфере и растр просто будет передан в front буфер.
← →
Игорь Шевченко © (2008-03-23 19:22) [48]
> Если после каждой графической операции DC пересылать подвергнутый
> операции RECT в VIDEO FRONT Buffer, то будет вам тот же
> flip.
Ну да. Я об том же. Вот Борланд (и не только он), сделал возможность формировать изображение в памяти, чтобы потом его одним чохом пересылать в контекст устройства (независимо от аппаратной буферизации, буферизации в ядре, и т.п.)
← →
Игорь Шевченко © (2008-03-23 19:25) [49]oxffff © (23.03.08 19:22) [47]
> Вопрос в другом, а что если видеокарта не поддерживает часть
> GDI операций, тогда изображение будет сформировано средствами
> Windows в буфере и растр просто будет передан в front буфер.
>
Собственно, по-другому просто нельзя. Разумеется, растр где-то формируется, это еще со времен Windows 3.1 в DDK подробно расписано.
Но из этого не следует, что свой буфер есть у каждого DC, об чем собственно, большевики неоднократно заявляли.
← →
oxffff © (2008-03-23 19:26) [50]
> А теперь смотри: В системе масса окон, количество DC (всех,
> не только общих), всяко меньше количества окон, как они
> с буферами-то справляются ?
Ничего не мешает Windows поступать очень просто,
не слать WM_PAINT при отсутствии ресурса.
Но тем менее почти 100% окон как раз и являются Common Device Contexts.
Ведь работает же.
← →
oxffff © (2008-03-23 19:28) [51]
> а после ReleaseDC весь этот буфер пропадает ?
Почему пропадает? Вы делаете EraseBackground и вперед с новой песней.
← →
oxffff © (2008-03-23 19:29) [52]
> oxffff © (23.03.08 19:28) [51]
В смысле просто очищаете труды предудущей оконной процедуры и заполняете своим контенком
← →
oxffff © (2008-03-23 19:32) [53]
> Но из этого не следует, что свой буфер есть у каждого DC,
> об чем собственно, большевики неоднократно заявляли.
Во всяком случае bitmap obj есть для display DC. Разговор начался ведь с этого.
← →
Игорь Шевченко © (2008-03-23 19:33) [54]oxffff © (23.03.08 19:26) [50]
> Ничего не мешает Windows поступать очень просто,
> не слать WM_PAINT при отсутствии ресурса.
Он так не поступает. Он просто не знает в момент посылки WM_PAINT, есть ресурсы или нету, потому что WM_PAINT всегда асинхронно посылается, да еще в очереди находится с низким приоритетом.
> Но тем менее почти 100% окон как раз и являются Common Device
> Contexts.
> Ведь работает же.
Ну да, работает. Потому что операции обрабатываются сами по себе, формируя растр (с учетом всех отсечений), без буфера в каждом DC :)
Собственно, почти вся ядерная часть GDI занимается по преимуществу отсечениями.
← →
Eraser © (2008-03-23 19:36) [55]нет у окна никаких встроенных битмапов по-умолчанию и точка.
← →
oxffff © (2008-03-23 19:38) [56]
> Eraser © (23.03.08 19:36) [55]
Ссылочку на документацию в студию.
← →
@!!ex © (2008-03-23 19:39) [57]> Ссылочку на документацию в студию.
Каку. документацию?? Сказано же: Нет и точка!
← →
oxffff © (2008-03-23 19:45) [58]
> Eraser © (23.03.08 19:36) [55]
> нет у окна никаких встроенных битмапов по-умолчанию и точка.
>
procedure TForm1.Button1Click(Sender: TObject);
var Hobj:HGDIOBJ;
HDC:Thandle;
begin
HDC:=GetDC(Handle);
Hobj:=GetCurrentObject(HDC,OBJ_BITMAP);
if Hobj<>0 then SHOWMESSAGE("ERASER садись. Двойка.");
ReleaseDC(Handle,HDC);
end;
← →
oxffff © (2008-03-23 19:46) [59]
>
> Он так не поступает. Он просто не знает в момент посылки
> WM_PAINT, есть ресурсы или нету, потому что WM_PAINT всегда
> асинхронно посылается, да еще в очереди находится с низким
> приоритетом.
Ну не проблема это. :)
← →
oxffff © (2008-03-23 19:48) [60]
> без буфера в каждом DC :)
oxffff © (23.03.08 19:45) [58]
← →
Игорь Шевченко © (2008-03-23 19:52) [61]oxffff © (23.03.08 19:32) [53]
> Во всяком случае bitmap obj есть для display DC. Разговор
> начался ведь с этого.
Про display dc разговора не было вообще. Был разговор про DC окна.
Что есть у Display DC - то совершенно другой случай.
Вот скажи, когда в моем и в твоем примере делался StrectBlt куда биты пересылались ? В буфер конкретного DC (формы в данном случае) или в буфер растра после всех отсечений ?
А если бы часть окна, где расположен PaintBox была бы закрыта, куда бы биты пересылались (или не пересылались)
← →
oxffff © (2008-03-23 19:57) [62]
> Про display dc разговора не было вообще. Был разговор про
> DC окна.
>Что есть у Display DC - то совершенно другой случай.
А как же это? :)
Display Device Contexts
An application obtains a display DC by calling the BeginPaint, GetDC, or GetDCEx function and identifying the window in which the corresponding output will appear. Typically, an application obtains a display DC only when it must draw in the client area. When the application is finished drawing, it must release the DC by calling the EndPaint or ReleaseDC function.
There are three types of DCs for video displays:
Class
Common
Private
← →
oxffff © (2008-03-23 20:00) [63]
> Вот скажи, когда в моем и в твоем примере делался StrectBlt
> куда биты пересылались ? В буфер конкретного DC (формы в
> данном случае) или в буфер растра после всех отсечений ?
>
Это зависит от того, эмулирует ли Windows операции, и если ДА, то какие.
← →
Дмитрий С (2008-03-23 20:02) [64]
> oxffff
А если, к примеру, окно отображается через терминал RDP, то буферов еще больше?
Все же, я думаю, что понятие DoubleBuffered VCL не включает в себя буферы системы.
← →
oxffff © (2008-03-23 20:04) [65]
> Игорь Шевченко © (23.03.08 19:52) [61]
Скажите если по вашему все операции GDI идут без буфера к видеопамять.
Зачем придумали DIRECTDRAW?
← →
oxffff © (2008-03-23 20:06) [66]
> А если, к примеру, окно отображается через терминал RDP,
> то буферов еще больше?
см Common Device Contexts
← →
Игорь Шевченко © (2008-03-23 20:07) [67]oxffff © (23.03.08 19:57) [62]
Продолжим дальше ?
var
DC: HDC;
HBM: HBitmap;
Info: tagBITMAP;
begin
.....
HBM := GetCurrentObject(DC, OBJ_BITMAP);
GetObject(HBM, Sizeof(Info), @Info);
ShowMessageFmt("Bitmap is %d x %d", [Info.bmWidth, Info.bmHeight]);
...
end;
oxffff © (23.03.08 19:57) [62]
> А как же это? :)
Давайте отличать DC, созданные по CreateDC ("DISPLAY", ...) и оконные.
Дабы не было путаницы, договоримся, что Display dc - это то, что создается по CreateDC
← →
oxffff © (2008-03-23 20:10) [68]
> Игорь Шевченко © (23.03.08 19:52) [61]
и КАК ЖЕ [58]?
Один Буфер c рабочий стол или несколько, но он есть.
Вы посмотрите внимательно на ваш пример с CS_OWNDC, можно скопировать даже больше, чем окно с CS_OWNDC.
← →
Eraser © (2008-03-23 20:10) [69]> [64] Дмитрий С (23.03.08 20:02)
> А если, к примеру, окно отображается через терминал RDP,
> то буферов еще больше?
ребята создавшие RDP проделали отличную работу в плане кэширования, вот там многое, даже почти все, действиетельно кэшируется.. подобие такого механизма реализовано и в моем продукте, но примитивнее.
попробуйте отключить кэширования и посмотрите каким плачевным станет результат.
> oxffff ©
отвечу чуть позже.
← →
Игорь Шевченко © (2008-03-23 20:13) [70]oxffff © (23.03.08 20:00) [63]
> Это зависит от того, эмулирует ли Windows операции, и если
> ДА, то какие.
Хорошо, русть не StretchBlt, пусть BitBlt, которую операцию умеет каждый драйвер.
Куда биты будут пересылаться в случае, когда часть окна закрыта и в случае, когда она открыта ?
И почему при изменении перекрытия окна другими окнами Windows посылает WM_PAINT тому окну, часть которого стала видимой, если оно уже было отрисовано в DC (OWN_DC) ?unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
ListBox1: TListBox;
procedure WMPaint (var Message: TWMPaint); message WM_PAINT;
protected
procedure CreateParams (var Params: TCreateparams); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;
procedure TForm1.WMPaint(var Message: TWMPaint);
begin
ListBox1.Items.Add("WM_PAINT");
inherited;
end;
end.
Если поверх этого окна перемещать другое, то видна последовательность WM_PAINT.
Нафига их выдают ?
← →
Игорь Шевченко © (2008-03-23 20:14) [71]oxffff © (23.03.08 20:10) [68]
> и КАК ЖЕ [58]?
А ты посмотри, какие характеристики у этого BITMAP
← →
oxffff © (2008-03-23 20:15) [72]
> Игорь Шевченко © (23.03.08 20:07) [67]
> oxffff © (23.03.08 19:57) [62]
>
> Продолжим дальше ?
> var
> DC: HDC;
> HBM: HBitmap;
> Info: tagBITMAP;
> begin
> .....
> HBM := GetCurrentObject(DC, OBJ_BITMAP);
> GetObject(HBM, Sizeof(Info), @Info);
> ShowMessageFmt("Bitmap is %d x %d", [Info.bmWidth, Info.
> bmHeight]);
> ...
> end;
OK. Ваш код не работает.
Только исправляйте свой код на
if GetObject(Hobj, Sizeof(Info), @Info)<>0 then
ShowMessageFmt("Bitmap is %d x %d", [Info.bmWidth, Info.bmHeight]);
← →
oxffff © (2008-03-23 20:20) [73]
> Если поверх этого окна перемещать другое, то видна последовательность
> WM_PAINT.
>
> Нафига их выдают ?
А что при установке CS_OWNDC семантика поведения окна меняется?
Почему вы связываете вид DC и ОКНО?
← →
oxffff © (2008-03-23 20:22) [74]
> Куда биты будут пересылаться в случае, когда часть окна
> закрыта и в случае, когда она открыта ?
А что насчет CLIP RECT и regions?
← →
oxffff © (2008-03-23 20:24) [75]Игорь Шевченко © (23.03.08 20:14) [71]
Сформулируйте точно вашу точку зрения.
Как происходит работа GDI словами.
← →
Игорь Шевченко © (2008-03-23 20:33) [76]oxffff © (23.03.08 20:15) [72]
> OK. Ваш код не работает.
Э...а почему ? :) Вроде как битмап вынутый из DC.. (И действительно, битмап, проверено. Только вот вызов GetObject говорит A call to OS function failed)
oxffff © (23.03.08 20:20) [73]
> А что при установке CS_OWNDC семантика поведения окна меняется?
Так рисовать-то по твоей логике не надо.
При CS_SAVEBITS, например, рисование меняется.
oxffff © (23.03.08 20:22) [74]
> А что насчет CLIP RECT и regions?
так они на что действуют-то ? На буфер DC или на буфер растра ?
← →
Игорь Шевченко © (2008-03-23 20:38) [77]oxffff © (23.03.08 20:24) [75]
> Сформулируйте точно вашу точку зрения.
> Как происходит работа GDI словами.
Это хорошая просьба, боюсь, что для ответа на нее у меня не хватит ни знаний, ни времени, ни места на форуме.
Но в двух словах. если говорить о DC и об окнах, то буфер есть у растра, весьма вероятно, что физически оно живет у того самого DC, который по CreateDC("DISPLAY") создается. Все оконные DC представляют "окна" (пардон за тавтологию) в этот буфер, с границами, определямыми регионами отсечения.
← →
Eraser © (2008-03-23 20:40) [78]> [58] oxffff © (23.03.08 19:45)
ну привязан какой-то битмап к контексту для непонятных целей и что дальше, это не значит, что в этом битмапе хранится картинка окна.
http://img201.imageshack.us/my.php?image=compatabedcec7.gif (с) Фэнь Юань.
вообще очень советую почитать 5 главу этой книги, там все подробно описано.
← →
oxffff © (2008-03-23 21:33) [79]
> ну привязан какой-то битмап к контексту для непонятных целей
> и что дальше, это не значит, что в этом битмапе хранится
> картинка окна.
А для каких целей он нужен?
И что говорит Фэнь Юань?
← →
Eraser © (2008-03-23 21:37) [80]> [79] oxffff © (23.03.08 21:33)
вот у него и поинтересуйтесь )
вот чего он не содержит, так это картинки с изображением окна. Ну не кэширует виндовз это и все тут.. на этом уровне абстракции по крайней мере, уверен, что на более низком уровне растры кэшируются графической подсистемой, но не здесь.
Страницы: 1 2 3 4 5 6 вся ветка
Текущий архив: 2008.05.11;
Скачать: CL | DM;
Память: 0.65 MB
Время: 0.024 c