wasm示例 js canvas 动画示例

3d迷宫移动:https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/A_basic_ray-caster

C:\dev\chromium104\src\third_party\blink\renderer\core\html\canvas\html_canvas_element.cc

HTMLCanvasElement::CreateLayer

HTMLCanvasElement::Paint 和 HTMLCanvasElement::PaintInternal绘制2d,用skp或者image snapshot。需要unacclerate,不用gpu加速。

snapshot = snapshot->MakeUnaccelerated();

webgl:

if (IsWebGL() && PaintsIntoCanvasBuffer())
context_->MarkLayerComposited();

HTMLCanvasElement::Snapshot可以对2d或者webgl快照出 image。

查看代码

&#xA0;scoped_refptr<staticbitmapimage> HTMLCanvasElement::Snapshot(
    SourceDrawingBuffer source_buffer) const {
  if (size_.IsEmpty())
    return nullptr;

  scoped_refptr<staticbitmapimage> image_bitmap;
  if (OffscreenCanvasFrame()) {  // Offscreen Canvas
    DCHECK(OffscreenCanvasFrame()->OriginClean());
    image_bitmap = OffscreenCanvasFrame()->Bitmap();
  } else if (IsWebGL()) {
    if (context_->CreationAttributes().premultiplied_alpha) {
      context_->PaintRenderingResultsToCanvas(source_buffer);
      if (ResourceProvider())
        image_bitmap = ResourceProvider()->Snapshot();
    } else {
      sk_sp<skdata> pixel_data =
          context_->PaintRenderingResultsToDataArray(source_buffer);
      if (pixel_data) {
        // If the accelerated canvas is too big, there is a logic in WebGL code
        // path that scales down the drawing buffer to the maximum supported
        // size. Hence, we need to query the adjusted size of DrawingBuffer.

        gfx::Size adjusted_size = context_->DrawingBufferSize();
        if (!adjusted_size.IsEmpty()) {
          SkColorInfo color_info =
              GetRenderingContextSkColorInfo().makeAlphaType(
                  kUnpremul_SkAlphaType);
          if (color_info.colorType() == kN32_SkColorType)
            color_info = color_info.makeColorType(kRGBA_8888_SkColorType);
          else
            color_info = color_info.makeColorType(kRGBA_F16_SkColorType);
          image_bitmap = StaticBitmapImage::Create(
              std::move(pixel_data),
              SkImageInfo::Make(
                  SkISize::Make(adjusted_size.width(), adjusted_size.height()),
                  color_info));
        }
      }
    }
  } else if (context_) {
    DCHECK(IsRenderingContext2D() || IsImageBitmapRenderingContext() ||
           IsWebGPU());
    image_bitmap = context_->GetImage();
  }

  if (image_bitmap)
    DCHECK(image_bitmap->SupportsDisplayCompositing());
  else
    image_bitmap = CreateTransparentImage(size_);

  return image_bitmap;
}</skdata></staticbitmapimage></staticbitmapimage>

HTMLCanvasElement::toDataURL生成可以在html中写的

HTMLCanvasElement::toBlob 都对应有 canvas的js函数吧。

决定是否cpu or gpu 绘制canvas:

   // If the canvas meets the criteria to use accelerated-GPU rendering, and
    // the user signals that the canvas will not be read frequently through
    // getImageData, which is a slow operation with GPU, the canvas will try to
    // use accelerated-GPU rendering.

    // If any of the two conditions fails, or if the creation of accelerated
    // resource provider fails, the canvas will fallback to CPU rendering.

    UMA_HISTOGRAM_BOOLEAN(
        "Blink.Canvas.2DLayerBridge.WillReadFrequently",
        context_ && context_->CreationAttributes().will_read_frequently);

    if (ShouldAccelerate() && context_ &&
        !context_->CreationAttributes().will_read_frequently) {
      canvas2d_bridge_ = Create2DLayerBridge(RasterMode::kGPU);
    }
    if (!canvas2d_bridge_) {
      canvas2d_bridge_ = Create2DLayerBridge(RasterMode::kCPU);
    }

GetSourceImageForCanvas

通知image变化:HTMLCanvasElement::NotifyListenersCanvasChanged()

阻止不支持webgl:HTMLCanvasElement::IsWebGLBlocked()

webgl代码:src\third_party\blink\renderer\modules\webgl

canvas代码:src\third_party\blink\renderer\modules\canvas 这个目录的 README.md

C:\dev\chromium104\src\third_party\blink\renderer\core\paint\html_canvas_painter.cc

RecordForeignLayer

c:\dev\chromium104\src\third_party\blink\renderer\platform\graphics\paint\foreign_layer_display_item.cc

chrome在headless模式,是不启动gpu模式的。可以通过chrome://inspect 打开监控的无头浏览器,输入 chrome://gpu查看,全是软渲染。

  • canvas 2d时:

在软渲染时,canvas的绘制指令通过cpu生成成了 layer的picture, 即skp,可以获取skp将其显示。

而在gpu绘制时,生成layer是textureLayer, 通过外部gpu绘制,这时是没有绘制指令的。无法通过skp重现。(可能是直接gpu绘制了?)

canvas webgl (canvas.getContext(“webgl”) 获得。有2d,3d api。

在canvas是获取的3d webgl上下文画笔时,会需要swiftshader软渲染。是必现生成texturelayer的。

Canvas 是 HTML5 提供的一个特性,你可以把它当做一个载体,简单的说就是一张白纸。而 Canvas 2D 相当于获取了内置的二维图形接口,也就是二维画笔。Canvas 3D 是获取基于 WebGL的图形接口,相当于三维画笔。你可以选择不同的画笔在上面作画。
OpenGL是 底层的驱动级的图形接口(是显卡有直接关系的) 类似于 DirectX. 但是这种底层的 OpenGL 是 寄生于浏览器的JavaScript无法涉及的。但是为了让 Web 拥有更强大的 图形处理能力 2010年时候WebGL被推出来。WebGL 允许工程师使用JS 去调用部分封装过的 OpenGL ES2.0 标准接口去 提供硬件级别的3D图形加速功能。
Skia 是一个开源的2D图形库。 SwiftShader是一个高性能的,基于CPU的OpenGLES和Direct3D图形APIs的实现。它的目标是为高级3D图形提供硬件独立性。

https://threejs.org/ webgl 3d 封装库

创建canvas和测试进入加速模式:

TEST_F(HTMLCanvasPainterTest, Canvas2DLayerAppearsInLayerTree) {
  // Insert a <canvas> and force it into accelerated mode.

  // Not using SetBodyInnerHTML() because we need to test before document
  // lifecyle update.

  GetDocument().body()->setInnerHTML("<canvas width="300" height="200">");
  auto* element = To<htmlcanvaselement>(GetDocument().body()->firstChild());
  CanvasContextCreationAttributesCore attributes;
  attributes.alpha = true;
  CanvasRenderingContext* context =
      element->GetCanvasRenderingContext("2d", attributes);
  gfx::Size size(300, 200);
  std::unique_ptr<canvas2dlayerbridge> bridge = MakeCanvas2DLayerBridge(size);
  element->SetResourceProviderForTesting(nullptr, std::move(bridge), size);
  ASSERT_EQ(context, element->RenderingContext());
  ASSERT_TRUE(context->IsComposited());
  ASSERT_TRUE(element->IsAccelerated());

  // Force the page to paint.

  element->PreFinalizeFrame();
  context->FinalizeFrame();
  element->PostFinalizeFrame();
  UpdateAllLifecyclePhasesForTest();

  // Fetch the layer associated with the <canvas>, and check that it was
  // correctly configured in the layer tree.

  const cc::Layer* layer = context->CcLayer();
  ASSERT_TRUE(layer);
  EXPECT_TRUE(HasLayerAttached(*layer));
  EXPECT_EQ(gfx::Size(300, 200), layer->bounds());
}</canvas></canvas2dlayerbridge></htmlcanvaselement></canvas></canvas>

Original: https://www.cnblogs.com/bigben0123/p/15988053.html
Author: Bigben
Title: wasm示例 js canvas 动画示例

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/551317/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球