【问题标题】:Canvas API implementation画布 API 实现
【发布时间】:2022-01-25 03:22:16
【问题描述】:

我最近开始了解 javascript 如何在底层工作,并开始了解(在 chrome 的上下文中)v8 引擎和 Web API 是不同的。以下是我对画布 API 的一些具体问题:

  1. 为什么每次要访问给定画布的像素时都需要使用getImageData()?既然画布是基于像素的,难道不应该有一个像素数组供画布 API 在您每次绘制时都会对其进行操作,从而使其静态可用?
  2. 有没有办法了解具体的 API 是如何实现的?例如——ctx.fillRect() 是如何在内部完成的?我尝试通过更改特定的像素颜色来手动执行此操作,但结果速度要慢得多。也许是因为我是用 javascript 做的,而且它通常是在 c++ 内部完成的?实现是在他们自己的源代码中,没有办法找出来吗?

我可能会混淆很多概念,因为我仍然不太了解 Web API 或 v8 的工作原理,因此感谢您提供任何澄清。

【问题讨论】:

    标签: javascript canvas html5-canvas v8 webapi


    【解决方案1】:

    为什么每次我们想要访问给定画布的像素时都需要使用 getImageData() ?既然画布是基于像素的,难道不应该有一个像素数组供画布 API 每次绘制时都会对其进行操作,从而使其静态可用吗?

    你是对的,它本来可以这样制作的,甚至有 active discussions 直接访问像素缓冲区,允许零拷贝读取和写入操作。
    然而,在最初的设计中,人们认为有必要将像素缓冲区与当前上下文执行完全分离。例如,这允许使用基于 GPU 的实现,其中所有绘图都由 GPU 执行,而后备缓冲区存储在 GPU 的内存中,因此脚本无法访问。
    还要注意的是,大多数实现都使用双缓冲,在前缓冲区和后缓冲区之间交换,以避免撕裂。

    有没有办法了解具体的 API 是如何实现的?例如,ctx.fillRect() 在内部是如何完成的?

    您总是可以尝试浏览源代码,Chrome 有方便的https://source.chromium.org/,Firefox 有https://searchfox.org 然而,对于 Canvas 2D API,真正看的地方有点复杂。 每个浏览器都至少有一个渲染引擎,在这个引擎中将包含所有 API 包装器,然后调用另一个图形引擎来生成图形。
    在基于 Chromium 的浏览器中,渲染引擎称为 Blink,而图形引擎 Skia,在 Safari 中,它们使用 WebKit(Blink 从中分叉)和 Core Graphics,在Firefox、IIRC Gecko 使用基于平台(Cairo、Core Graphics 或 Skia)的各种渲染和图形引擎,因此在此浏览器中查看实际图形操作的位置并不容易。
    为了增添乐趣,所有这些图形引擎都将支持“软件渲染”(CPU)路径或“硬件加速”(GPU)路径。

    但为了帮助您开始您的旅程,Blink 的 fillRect() 实现从这里开始:https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc;l=1075


    注意事项:JavaScript 引擎(例如 v8)在这一切上几乎没有什么可做的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 2020-07-02
      • 2014-02-21
      • 1970-01-01
      • 2011-09-27
      • 2016-05-15
      • 2012-12-07
      相关资源
      最近更新 更多