问题标签 [doublebuffered]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java AWT drawImage 竞争条件 - 如何使用同步来避免它
经过数小时的调试和分析,我终于设法找出了竞态条件的原因。解决它是另一回事!
为了查看实际的竞态条件,我在调试过程中录制了一段视频。从那以后,我加深了对这种情况的理解,因此请原谅糟糕的评论和作为调试过程的一部分实施的愚蠢机制。
http://screencast.com/t/aTAk1NOVanjR
因此,情况是:我们有一个表面的双缓冲实现(即 java.awt.Frame 或 Window),其中有一个正在进行的线程基本上连续循环,调用渲染进程(执行 UI 布局并将其渲染到后台缓冲区) ) 然后,在渲染后,将渲染区域从后缓冲区传送到屏幕。
这是双缓冲渲染的伪代码版本(Surface.java的完整版本第 824 行):
与任何 AWT 表面实现一样,它还实现(AWT.java 中的第 507 行 -链接限制 :( - 使用 Surface.java 链接,将 core/Surface.java 替换为 plat/AWT.java)绘制/更新覆盖也 blit从后台缓冲区到屏幕:
使用 drawImage() 函数实现了 Blitting(AWT.java 中的第 371 行):
(警告:这是我开始做假设的地方!)
这里的问题似乎是 drawImage 是异步的,并且首先调用来自 refreshBackBuffer() 通过绘制/更新的 blit,但随后发生。
所以... blit 已经同步了。防止竞争条件的明显方法不起作用。:(
到目前为止,我已经提出了两种解决方案,但它们都不是理想的:
在下一个渲染过程中重新 blit
缺点:性能下降,遇到竞争条件时仍然会出现一些闪烁(有效屏幕 -> 无效屏幕 -> 有效屏幕)不要在绘制/更新时进行 blit,而是设置刷新边界并在下一次渲染过程中使用这些
边界
这里(1)似乎是两害相权取其轻。 编辑:并且(2)不起作用,出现空白屏幕......(1)工作正常,但只是掩盖了可能仍然存在的问题。
我所希望的,并且由于我对同步以及如何使用它的理解不足而似乎无法想象的是一种锁定机制,它以某种方式解释了 drawImage() 的异步性质。
或者也许使用 ImageObserver?
请注意,由于应用程序的性质(Vexi,对于那些感兴趣的人,网站已过时,我只能使用 2 个超链接)渲染线程必须在绘制/更新之外 - 它具有单线程脚本模型和布局过程(渲染的子过程)调用脚本。
c# - DrawReversibleLine() 和双缓冲
我正在使用 curstom 双缓冲,并想用DrawReversibleLine()
. 但这怎么能做到呢?此方法直接绘制到屏幕上,所以我看不出如何在背景缓冲区上绘制。你会怎么办?
c# - Double Buffer Compact Framework 中的自定义控件
我有一个继承自Panel
. 我最终在这个面板上放置了几个 DataGrids 和 Labels。当它变得太长时,它会自动为我滚动。
我真的需要滚动,因为它是一个扫描对象列表,它会变得比屏幕上允许的空间更大。
但是当我滚动它时,它会闪烁很多。我很想让它给我一些平滑的滚动。
我已经看过几个“Compact Framework”双缓冲示例,但它们都是双缓冲绘制方法(即graphics.DrawString
)。我的自定义控件本身不做任何绘画。它只是将正常的网格和标签放在面板上,然后让面板绘制它们。
有没有办法双缓冲正常控件(同样不是自定义绘画)?
c# - C#,WinForms中的双缓冲区?
然而,我认为我将 DoubleBuffered 设置为 true,图像仍然闪烁。任何想法我做错了什么?谢谢!
c# - 可滚动图片框 c# .net 使用双缓冲停止闪烁
我创建了一个引用此链接的可滚动图片框。
它工作正常。但是当我滚动时图像闪烁。
Windows 窗体具有 DoubleBuffered 属性。但是图片框没有。我想如果我可以在图片框上使用 DoubleBuffered 那么我的问题可能会解决。
请帮助解决这个问题
谢谢你哟
scroll - 如何在滚动时消除 wxListCtrl 闪烁?
我在 wxWidgets 应用程序中使用 wxListCtrl,似乎无法消除快速滚动大量项目列表时发生的闪烁(例如,按住“向下翻页”键)。列表控件创建为虚拟/报告列表,我目前正在Win7下测试。
似乎背景清除导致闪烁,但我不能简单地覆盖它,因为文本/边框正确显示是必需的。
我相信我需要的是一种进行双缓冲的方法,其中列表不会在视觉上更新,直到背景被清除并且项目被绘制(屏幕外)。有谁知道如何在 wxWidgets 中做到这一点?或者,还有更好的方法?
非常感谢...
delphi - 如何消除TPaintBox右边缘的闪烁(例如调整大小时)
总结:
假设我有一个 TForm 和两个面板。面板对齐 alTop 和 alClient。alClient 面板包含一个 TPaintBox,其 OnPaint 涉及绘图代码。
组件上 DoubleBuffered 的默认值为 false。
在绘图过程中,闪烁很明显,因为表格,面板都绘制了它们的背景。
因为表单被面板覆盖,所以截取它的 WM_ERASEBKGND 消息可能没问题。如果不是这样,当窗体调整大小时,可能会在面板上看到闪烁,并在面板的右边缘闪烁,因为窗体绘制了它的背景。
其次,因为 alTop 面板旨在成为某些按钮的容器,所以最好将其 DoubleBuffered 设置为 true 以让 Delphi 确保其上没有闪烁。它可能不会带来太多的性能负担。
第三,由于 alClient 面板仅作为另一个绘图组件的容器,因此该面板很可能不参与最终绘图的组成。在这方面,使用 TPanel 后代而不是标准 TPanel 可能会更好。在这个 TPanel 后代中,覆盖受保护的过程 Paint 并且在过程内部不做任何事情,尤其是不要继承调用以避免基类 TCustomPanel.Paint 中的 FillRect 调用。此外,拦截 WM_ERASEBKGND 消息并且在里面什么也不做。这是因为当TPanel.ParentBackground为False时,Delphi负责重绘背景,为True时,ThemeService负责。
最后,要在 TPaintBox 中进行无闪烁绘制:
(1) 使用 VCL 内置的绘图例程,最好...
(2) 使用 OpenGL,启用 OpenGL 的双缓冲区。
(3) ...
===Q:如何消除TPaintBox右边缘的闪烁?===
假设对于一个 TForm,我有两个面板。顶部相对于表单对齐 alTop 并被视为按钮的容器。另一个是 alClient 相对于窗体对齐,并被视为绘制组件的容器(例如 VCL 中的 TPaintBox,或 Graphics32 中的 TPaintBox32)。对于后一个面板,它的 WM_ERASEBKGND 消息被截获。
现在,我在下面的示例代码中使用了一个 TPaintBox 实例。在它的 OnPaint 处理程序中,我有两种选择来绘制我希望没有闪烁的绘图。选项 1 是在填充矩形后绘制。因为它的父面板不应该擦除背景,所以绘图应该是无闪烁的。选择 2 是在 TBitmap 上绘图,然后将其 Canvas 复制回油漆盒。
但是,两个选项都在闪烁,第二个选项尤其闪烁。我主要关心的是选项 1。如果您调整表单的大小,您会看到闪烁的主要部分发生在右边缘。为什么会这样?有人可以帮助评论原因和可能的解决方案吗?(注意,如果我在这里使用 TPaintBox32 而不是 TPaintBox,右边缘根本不会闪烁。)
我的第二个担心是,当使用选项 1 时,闪烁的小部分随机发生在颜料盒上。如果您快速调整表单大小,这不是很明显但仍然可以观察到。此外,当使用选项 2 时,这种闪烁变得更加严重。我没有找到这个的原因。有人可以帮助评论可能的原因和解决方案吗?
任何建议表示赞赏!
===问:如何正确拦截面板重绘背景?===
(如果我应该在一个单独的问题中问这个问题,请直接说出来,我将删除它。)
新建一个VCL应用,粘贴示例代码,附上FormCreate,运行debug。现在将鼠标悬停在表单上,您可以看到面板正在重新绘制其背景。但是,如示例代码所示,我应该已经通过拦截 WM_ERASEBKGND 消息来拦截此行为。
注意,如果我注释掉这三行,
然后可以捕获 WM_ERASEBKGND 消息。我不知道这种差异。
有人可以帮助评论这种行为的原因,以及如何正确拦截 WM_ERASEBKGND 消息(当 ParentBackground := False 时)?
java - 使用覆盖更新方法的 Java 双缓冲区引发堆栈溢出
我试图通过覆盖我的 JPanel 的更新方法来实现我的游戏在 Java 中的双缓冲,我做了所有常用的代码等,但它仍然无法工作,它会引发堆栈溢出错误,以下是具体错误:
我的代码也不是特别复杂:
我希望有人能指出我哪里出错了,我在想可能与更新被调用太多次有关,或者可能更新是错误的方法?
c - 双缓冲设计 I/O 同步
如果我的应用程序生成数据缓慢但消耗数据很快,那么它是否适合双缓冲区实现?基本思想是让生产者填充后缓冲区,而消费者处理前缓冲区。我不希望客户端看起来好像在等待数据。我想平衡生产和消费。我怎样才能实现这个功能?即使我有一个后台缓冲区线程....它也必须与前台缓冲区线程同步,以便前台缓冲区知道何时有新数据(缓冲区已交换)。如果后台缓冲区线程花费太长时间来生成其数据,那么前台缓冲区将不得不等待处理它。
c# - 双缓冲控制导致出现灰色
我有一个接受 aControl
并将生成的图像绘制到它的类。在我的应用程序代码中,我为此使用了一个Panel
控件——这似乎工作得很好,除了当图像被重绘时我在控件上得到了很多闪烁。我认为解决方案是在控件上启用双缓冲。我正在使用以下代码执行此操作:
添加此代码后,图像被绘制,然后立即替换为默认的灰色按钮背景颜色 - 就好像系统正在绘制我自己的内容。
我记得在某处看到了一个属性,它告诉系统永远不要绘制控件(这对我来说是完美的,因为我正在用内容填充整个控件),但现在我找不到它。是否有这样的属性,如果有,我该如何启用它?
我将 C# 与 .NET 框架 4.0 版一起使用。