Delphi从非常大的位图缓慢bitblt

时间:2014-06-18 10:48:21

标签: performance delphi bitblt

我正在创建一个组件,其中可以使用拖放设计表。

我设法编写了拖放部分和表格渲染,但我遇到了问题。

我使用双缓冲,通过绘制到内存中的位图来减少闪烁,然后将其中的一部分bitblt到屏幕。

步骤:

  1. 将表绘制到内存中的位图(这可能非常大,最大可达)。
  2. 控制画布上的部分内存中位图内容。
  3. 问题是,内存位图越大,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 个答案:

答案 0 :(得分:2)

  
      
  1. 将表绘制到内存中的位图(这可能非常大,最大可达)。
  2.   
  3. 在控制画布上Blit部分内存中的位图内容。
  4.         

    问题是,内存位图越大,bitblt操作就越慢(显然)。

我不相信你已经正确诊断出这个问题。 blit的性能很大程度上取决于目标矩形的大小。确实,对于非常大的源位图,存储器访问可能效率较低。但是一旦源位图足够大以使blit读取的每个扫描线位于不同的高速缓存行中,那么性能应该与目标矩形大小保持不变。

因此,从中得出的明显结论是,如果性能随着内存中位图大小的增加而降低,则该内存中位图的绘制是瓶颈。您没有详细说明,因此我们无法提供详细的优化建议。但是,下一步是尝试找出性能瓶颈的确切位置。如果我认为瓶颈是完整的内存位图,那么你需要找到一种方法来提高性能。