Delphi медленный битблт с очень большой битмап
Я создаю компонент, в котором можно создавать таблицы с помощью перетаскивания.
Мне удалось написать часть перетаскивания и рендеринга таблицы, но у меня есть проблема.
Я использую двойную буферизацию, чтобы уменьшить мерцание, рисуя растровое изображение в памяти, а затем отправляю часть его на экран.
шаги:
- Нарисуйте таблицу в растровое изображение в памяти (это может быть очень большим, вплоть до максимума).
- частичное содержимое растрового изображения в памяти на холсте элемента управления.
Проблема в том, что чем больше растровое изображение в памяти, тем медленнее будет (очевидно) операция bitblt.
Мой вопрос:
- Как улучшить производительность этого? Я тоже заинтересован в альтернативных решениях.
Код:
procedure TCustomGraphicScrollControl.Paint;
var
x,y: Integer;
begin
inherited;
// Rendering is done in the child class. FRender is a 4-bit color depth
// in-memory bitmap.
if HorzScrollBar.Visible then x := HorzScrollBar.Position else x:=0;
if VertScrollBar.Visible then y := VertScrollBar.Position else y:=0;
// We will create a second in-memory bitmap, with the same dimensions as the control
// and the same color depth as FRender. This way BitBlt will be a little faster, as it won't be needed to do any conversion.
// bitblt part of the large in-memory bitmap to screen
BitBlt(
FCanvas.Handle,
0,
0,
Width,
Height,
FRender.Canvas.Handle,
x,
y,
SRCCOPY
);
end;
Обновить:
Удалены "Тройная буферизация" и UpdateScrollBars из кода и вопроса.
1 ответ
- Нарисуйте таблицу в растровое изображение в памяти (это может быть очень большим, вплоть до максимума).
- Blit частичное содержимое растрового изображения в памяти на холсте элемента управления.
Проблема в том, что чем больше растровое изображение в памяти, тем медленнее будет (очевидно) операция bitblt.
Я не верю, что вы правильно диагностировали проблему. Производительность блита будет в значительной степени определяться размером целевого прямоугольника. Это правда, что для очень большого исходного растрового изображения доступ к памяти может быть менее эффективным. Но если исходное растровое изображение достаточно велико, чтобы каждая строка развертки, считываемая блитом, находилась в другой строке кэша, тогда производительность должна быть постоянной с целевым размером прямоугольника.
Итак, очевидный вывод, который можно сделать из этого, заключается в том, что если производительность снижается при увеличении полного размера растрового изображения в памяти, то отрисовка этого растрового изображения в памяти является узким местом. Вы не указали детали этого, поэтому мы не можем предложить подробные предложения по оптимизации. Но ваш следующий шаг - попытаться понять, где на самом деле существует узкое место в производительности. Если, как я полагаю, узким местом является полное растровое изображение в памяти, то вам нужно найти способ повысить производительность там.