简体   繁体   English

来自非常大的位图的Delphi慢Bitblt

[英]Delphi slow bitblt from very large bitmap

I am creating a component, in which one can design tables with drag&drop. 我正在创建一个组件,在其中可以通过拖放来设计表。

I managed to write the drag&drop part and the table rendering, but I have a problem. 我设法编写了拖放部分和表格渲染,但是有一个问题。

I use double buffering, to reduce flickering, by drawing to an in-memory bitmap, then bitblt a portion of it to the screen. 我使用双重缓冲来减少闪烁,方法是绘制到内存中的位图,然后将其一部分bitblt到屏幕上。

Steps: 脚步:

  1. Draw table to in-memory bitmap (this can be very large, up to the maximum). 将表绘制到内存中的位图(这可能非常大,最大)。
  2. partial in-memory bitmap contents on the control canvas. 控制画布上的部分内存中位图内容。

The problem is, that the larger the in-memory bitmap is, the slower the bitblt operation will be (obviously). 问题是,内存中位图越大,bitblt操作(显然)就越慢。

My question is: 我的问题是:

  • How to improve the performance of this? 如何提高这种性能? I'm interested in alternative solutions too. 我也对替代解决方案感兴趣。

Code: 码:

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;

Update: 更新:

Removed "Triple buffering" and UpdateScrollBars from code and question. 从代码和问题中删除了“三重缓冲”和UpdateScrollBars。

  1. Draw table to in-memory bitmap (this can be very large, up to the maximum). 将表绘制到内存中的位图(这可能非常大,最大)。
  2. Blit partial in-memory bitmap contents on the control canvas. 在控件画布上对齐部分内存中位图的内容。

The problem is, that the larger the in-memory bitmap is, the slower the bitblt operation will be (obviously). 问题是,内存中位图越大,bitblt操作(显然)就越慢。

I don't believe that you have correctly diagnosed the problem. 我认为您没有正确诊断问题。 The performance of the blit will be largely determined by the size of the target rectangle. blit的性能将在很大程度上取决于目标矩形的大小。 It is true that for a very large source bitmap, memory access may be less efficient. 的确,对于非常大的源位图,内存访问可能效率较低。 But once the source bitmap is large enough to make each scanline read by the blit reside in a different cache line, then the performance should be constant with target rectangle size. 但是,一旦源位图足够大以使blit读取的每个扫描线驻留在不同的缓存行中,则性能应与目标矩形大小保持恒定。

So, the obvious conclusion to draw from this is that if the performance degrades as the full in-memory bitmap size is increased, then the drawing of that in-memory bitmap is bottleneck. 因此,从中得出的显而易见的结论是,如果性能随着内存中位图的完整大小的增加而降低,则该内存中位图的绘制将成为瓶颈。 You included no details of that so we cannot offer detailed optimisation suggestions. 您没有提供任何详细信息,因此我们无法提供详细的优化建议。 But your next step is to try to work out where the performance bottleneck really is. 但是您的下一步是尝试找出性能瓶颈的真正所在。 If as I believe, the bottleneck is the full in-memory bitmap, then you'll need to find a way to improve performance there. 如果我相信瓶颈是完整的内存位图,那么您将需要找到一种方法来提高性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM