Конференция "Прочее" » Двойная буфферизация(выдернуто из "Вакансия Delphi программист")
 
  • Eraser © (23.03.08 21:37) [80]
    > [79] oxffff ©   (23.03.08 21:33)

    вот у него и поинтересуйтесь )
    вот чего он не содержит, так это картинки с изображением окна. Ну не кэширует виндовз это и все тут.. на этом уровне абстракции по крайней мере, уверен, что на более низком уровне растры кэшируются графической подсистемой, но не здесь.
  • Игорь Шевченко © (23.03.08 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 :)

    На этой оптимистической ноте закончим дискуссию ?
  • Игорь Шевченко © (23.03.08 22:01) [82]
    Попытаюсь подвести итог: Большинство операций рисования GDI вызывает обновление буфера растра. В зависимости от возможностей драйвера видеокарты, эти операции обновления отдаются либо драйверу напрямую, чтобы рисование выполнялось с использованием процессора видеокарты, либо GDI рисует по своим алгоритмам, используя процессор собственно компьютера и пересылает сформированное изображение в видеопамять.
    При установленном свойстве DoubleBuffered все рисование с точки зрения GDI выполняется одной операцией BitBlt, поэтому буфер растра обновляется один раз и результаты промежуточных операций на экране не мелькают.
  • 31512 (23.03.08 22:03) [83]
    Сохраню-ка я эту веточку для повышения образованности. Опять же много пользительных ссылок приведено... :-)
  • Eraser © (23.03.08 22:07) [84]
    > [77] Игорь Шевченко ©   (23.03.08 20:38)


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

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

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

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


    читать про Private Device Contexts и их отличие от Common Device Contexts.
  • oxffff © (23.03.08 22:13) [86]

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


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

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

    Важно, что есть буфер который -> копируется в видепамять.
  • oxffff © (23.03.08 22:15) [87]

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


    Именно это мнение я и разделяю.
    Поэтому при double buf буфферов может быть 2 и 3 с учетом front buf video.
  • Eraser © (23.03.08 22:16) [88]
    > [85] oxffff ©   (23.03.08 22:09)

    ну есть отличие, только поясните, какое это отношение имеет к теме, в частности, двойной буфферизации? что-то я не уловил момент..
  • oxffff © (23.03.08 22:21) [89]

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


    [37] [39] [40]
  • Eraser © (23.03.08 22:29) [90]
    > [89] oxffff ©   (23.03.08 22:21)

    вы не путаете кэширование gdi операций с кэшированием готовых растров?
    к слову в висте реализовали системный механизм растровой буфферизации, который успешно применяется в CDS2007, см. BeginBufferedPaint.
  • oxffff © (23.03.08 22:31) [91]

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


    Разговор у нас о DC и DC bitmap.
    Я вас не понял.
  • Дмитрий С (23.03.08 22:38) [92]
    Честно говоря я думал, что под Device (в DC) подразумевается некое устройство (экран, окно, принтер, битмэп, метафайл) для возможности универсально "рисовать" на них. Иначе говоря, я думал, что bitmap в данном случае - лишь один из вариантов того, на чем можно рисовать с помощью DC. И, честно говоря, ранее меня не смущало, что битмэп привязывается к ДЦ с помощью функции SelectObject.
    Поправьте меня, если я не прав.
  • oxffff © (23.03.08 22:40) [93]
    to Eraser

    Offtop

    BeginBufferedPaint

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

    Наш разговор был не об этом. :)
  • Eraser © (23.03.08 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 © (23.03.08 22:59) [95]
    > [92] Дмитрий С   (23.03.08 22:38)

    все правильно, контекст устройство это инструмент для рисования, а не холст. Холст (битмап) к нему можно привязать, но не ко всякому контексту, а только в compatable... BeginBufferedPaint позволяет обойти это ограничение, но только благодаря своим механихмам и для целей буфферизации, хотя возможно как то и можно добраться до внутреннего буффера, используемого этой функцией.
  • Игорь Шевченко © (23.03.08 23:03) [96]
    Кстати, то что оконный DC представляет собой дырку в общий DC объясняет и то, что в оконный DC нельзя выбрать BITMAP - а чего с ним потом делать, с выбранным BITMAP'ом ? :)

    oxffff ©   (23.03.08 22:13) [86]


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


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

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

    Так вот - если драйвер не чего-то поддерживает, то буфер растра будет и GDI будет на нем рисовать и отсылать драйверу в виде внутренней BitBlt - это вроде все поддерживают. А если драйвер поддерживает какие-то операции GDI, то и буфера растра не будет - все рисование будет выполняться видеокартой.
  • oxffff © (23.03.08 23:05) [97]

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


    А что DMClient со стилем CS_OWNDC?
    Перечитай еще раз внимательно. :)
  • oxffff © (23.03.08 23:08) [98]

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


    Это то понятно. Меня больше интересует вопрос более серьезный.
    А как быть если часть операций поддерживается, а часть нет.
    Часть операций видеокартой в VIDEO буфере, а часть в RAM буфере,
    Как  потом смешивать результаты? :)))))))
  • Eraser © (23.03.08 23:10) [99]
    > [97] oxffff ©   (23.03.08 23:05)

    пардон, моя вина.. невнимательность, но суть дела это не поменяло.. даже если заменить WindowName = 'DMClient'; на WindowName = 'Form2'; эффект тот же - скрытая часть окна не копируется.
 
Конференция "Прочее" » Двойная буфферизация(выдернуто из "Вакансия Delphi программист")
Есть новые Нет новых   [134433   +22][b:0.001][p:0.003]