1

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

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

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

脚步:

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

问题是,内存中的位图越大,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。

4

1 回答 1

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

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

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

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

于 2014-06-18T11:54:58.560 回答