多平面覆盖硬件要求

支持多平面覆盖不需要显示驱动程序和硬件。 但是,若要提供多平面覆盖支持,硬件必须满足以下要求:

  • 硬件必须支持非重叠平面:
    • 一个平面可以覆盖屏幕的一部分,而另一个平面可以覆盖屏幕的一个不同的、相互排斥的部分。
    • 如果屏幕的任何部分没有被平面覆盖,则硬件必须扫描出该区域的黑色。 硬件可以假定在最底部的 z 顺序中有一个虚拟平面,该平面填充了黑色。
  • 硬件必须支持重叠平面:
    • 硬件必须能够按平面启用或禁用 alpha 混合。 (Alpha 混合是一种技术,其中源位图中的颜色与目标位图中的颜色相结合,以生成新的目标位图。)
    • 必须使用预乘 alpha 在平面之间混合。
  • 如果只有一个输出目标处于活动状态,则活动输出必须支持多平面覆盖。 在克隆模式下,如果多个输出同时处于活动状态,硬件不应报告它支持多平面覆盖,除非所有活动输出都支持多平面覆盖。
  • 桌面窗口管理器 (DWM) 的交换链 (平面 0) 必须能够与其他覆盖平面交互。
  • 必须能够启用和禁用所有平面,包括平面 0 (DWM 的交换链) 。
  • 所有平面都必须支持源和目标剪辑,包括平面 0 (DWM 的交换链) 。
  • 至少一个平面必须支持收缩和拉伸,独立于可能启用的其他平面。
  • 支持缩放的平面必须同时支持比双线性更好的双线性筛选和筛选质量。
  • 至少一个平面必须支持这些 YUV 格式 (有关详细信息,请参阅 Windows 8.1) 中的 YUV 格式范围
    • 对于 YUV 格式,将ITU BT.601 和 BT.709 YUV 转换为 RGB 矩阵。
    • 正常 (或工作室) 范围 YUV 亮度 (16 - 235) 和扩展范围的 YUV 亮度 (0 - 255) 。
  • 硬件必须处理以下寄存器闩锁方案:
    • ) (缓冲区地址、剪切、缩放等的所有单平面属性必须在垂直回溯期间以原子方式发布。 更新寄存器块时,它们必须全部以原子方式发布 ,例如,如果在写入与覆盖平面相关的 20 个寄存器中的 10 个寄存器后发生 VSync,则它们都不会发布到下一个 VSync,因为它们不能全部发布到当前 Vsync) 。
    • 每个平面都可以独立于其他平面进行更新。 例如,如果平面 0 寄存器在 VSync 之前已更新,之后在 VSync 发生时更新了平面 1 寄存器,则平面 1 更新可能会等到下一个 VSync,但平面 0 更新应按时进行。
    • 在单个当前调用期间更新多个平面时,更新应以原子方式发生。 例如,如果单个当前调用正在更新平面 0 并启用平面 1,则平面 0 寄存器不应在 VSync 上发布,除非平面 1 寄存器也发布在同一 VSync 上。
  • 转换、缩放和混合应按以下顺序进行:
    1. 根据指定的源矩形剪裁源分配。 源矩形保证在源分配的大小范围内进行绑定。

    2. 应用水平图像翻转,然后应用垂直图像翻转(如果请求)。

    3. 根据目标矩形应用缩放,根据剪辑矩形应用剪裁,并在缩放时应用适当的筛选。

    4. 与其他层的分配混合。 应从上到下执行混合 (或直到按 z 顺序) 命中不透明层。 如果请求 alpha 混合,硬件必须遵循每像素 alpha,并且颜色值将预先乘以 alpha。 以下伪代码从上到下重复执行源对目标操作, ( ( (Layer[0] over layer[1]) over Layer[2]) over ¦ Layer[n]) 。 在目标矩形之外,每个层都必须被视为透明 (0,0,0,0) 。

      Color = Color[0]; // Layer 0 is topmost.
      Alpha = Color[0].Alpha;
      for (i = 1; Alpha < 1 && i < LayersToBlend; i++)
      {
          Color += ((1 - Alpha) * Color[i]);
          Alpha += ((1 - Alpha) * Color[i].Alpha);
      }
      Output Color;
      

      只要输出结果相同,硬件就可以从下到上混合。 在这种情况下,应使用以下混合算法:

      Color = Color[LayersToBlend-1];  // Bottom-most layer
      Alpha = Color[LayersToBlend-1].Alpha;
      if (LayersToBlend > 1)
      {
          for (i = LayersToBlend - 2; Alpha < 1 && i >= 0; i--)
          {
              Color = Color[i] + ((1 - Color[i].Alpha) * Color;
              Alpha = Color[i].Alpha + (1 - Color[i].Alpha) * Alpha;
          }
      }
      Output Color;
      
    5. 必须在未覆盖任何层的任何目标矩形的区域显示黑色。 硬件可以假设有一个概念性的虚拟最底层黑层,即屏幕的大小。