| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_CANVAS_CONTEXT_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_CANVAS_CONTEXT_H_ |
| |
| #include "base/containers/heap_array.h" |
| #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_alpha_mode.h" |
| #include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h" |
| #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" |
| #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h" |
| #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" |
| #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_cpp.h" |
| #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h" |
| #include "third_party/blink/renderer/platform/graphics/graphics_types.h" |
| #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" |
| |
| namespace blink { |
| |
| class ExceptionState; |
| class GPUDevice; |
| class GPUCanvasConfiguration; |
| class GPUSwapChain; |
| class GPUTexture; |
| class WebGPUTextureAlphaClearer; |
| class V8UnionHTMLCanvasElementOrOffscreenCanvas; |
| |
| // A GPUCanvasContext does little by itself and basically just binds a canvas |
| // and a GPUSwapChain together and forwards calls from one to the other. |
| class GPUCanvasContext : public CanvasRenderingContext, |
| public WebGPUSwapBufferProvider::Client { |
| DEFINE_WRAPPERTYPEINFO(); |
| |
| public: |
| class Factory : public CanvasRenderingContextFactory { |
| public: |
| Factory() = default; |
| |
| Factory(const Factory&) = delete; |
| Factory& operator=(const Factory&) = delete; |
| |
| ~Factory() override; |
| |
| CanvasRenderingContext* Create( |
| CanvasRenderingContextHost*, |
| const CanvasContextCreationAttributesCore&) override; |
| CanvasRenderingContext::CanvasRenderingAPI GetRenderingAPI() const override; |
| }; |
| |
| GPUCanvasContext(CanvasRenderingContextHost*, |
| const CanvasContextCreationAttributesCore&); |
| |
| GPUCanvasContext(const GPUCanvasContext&) = delete; |
| GPUCanvasContext& operator=(const GPUCanvasContext&) = delete; |
| |
| ~GPUCanvasContext() override; |
| |
| void Trace(Visitor*) const override; |
| |
| // CanvasRenderingContext implementation |
| V8RenderingContext* AsV8RenderingContext() final; |
| V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final; |
| SkColorInfo CanvasRenderingContextSkColorInfo() const override; |
| // Produces a snapshot of the current contents of the swap chain if possible. |
| // If that texture has already been sent to the compositor, will produce a |
| // snapshot of the just released texture associated to this gpu context. |
| // todo(crbug/1267243) Make snapshot always return the current frame. |
| scoped_refptr<StaticBitmapImage> GetImage(FlushReason) final; |
| bool PaintRenderingResultsToCanvas(SourceDrawingBuffer) final; |
| // Copies the back buffer to given shared image resource provider which must |
| // be webgpu compatible. Returns true on success. |
| bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*, |
| SourceDrawingBuffer) final; |
| bool CopyRenderingResultsToVideoFrame( |
| WebGraphicsContext3DVideoFramePool* frame_pool, |
| SourceDrawingBuffer src_buffer, |
| const gfx::ColorSpace& dst_color_space, |
| VideoFrameCopyCompletedCallback callback) override; |
| void PageVisibilityChanged() override {} |
| bool isContextLost() const override { return false; } |
| bool IsComposited() const final { return true; } |
| bool IsOriginTopLeft() const final { return true; } |
| void SetFilterQuality(cc::PaintFlags::FilterQuality) override; |
| bool IsPaintable() const final { return true; } |
| int ExternallyAllocatedBufferCountPerPixel() final { return 1; } |
| void Stop() final; |
| cc::Layer* CcLayer() const final; |
| void Reshape(int width, int height) override; |
| |
| // OffscreenCanvas-specific methods |
| bool PushFrame() final; |
| // Returns a StaticBitmapImage backed by a texture containing the current |
| // contents of the front buffer. This is done without any pixel copies. The |
| // texture in the ImageBitmap is from the active ContextProvider on the |
| // WebGPUSwapBufferProvider. |
| ImageBitmap* TransferToImageBitmap(ScriptState*, ExceptionState&) final; |
| |
| bool IsOffscreenCanvas() const { |
| if (Host()) |
| return Host()->IsOffscreenCanvas(); |
| return false; |
| } |
| |
| // gpu_presentation_context.idl |
| V8UnionHTMLCanvasElementOrOffscreenCanvas* getHTMLOrOffscreenCanvas() const; |
| |
| void configure(const GPUCanvasConfiguration* descriptor, ExceptionState&); |
| void unconfigure(); |
| GPUTexture* getCurrentTexture(ScriptState*, ExceptionState&); |
| |
| // WebGPUSwapBufferProvider::Client implementation |
| void OnTextureTransferred() override; |
| void SetNeedsCompositingUpdate() override; |
| |
| private: |
| void DetachSwapBuffers(); |
| void ReplaceDrawingBuffer(bool destroy_swap_buffers); |
| void InitializeAlphaModePipeline(wgpu::TextureFormat format); |
| |
| void FinalizeFrame(FlushReason) override; |
| |
| scoped_refptr<StaticBitmapImage> SnapshotInternal( |
| const wgpu::Texture& texture, |
| const gfx::Size& size) const; |
| |
| bool CopyTextureToResourceProvider( |
| const wgpu::Texture& texture, |
| const gfx::Size& size, |
| CanvasResourceProvider* resource_provider) const; |
| |
| void CopyToSwapTexture(); |
| |
| base::WeakPtr<WebGraphicsContext3DProviderWrapper> GetContextProviderWeakPtr() |
| const; |
| |
| cc::PaintFlags::FilterQuality filter_quality_ = |
| cc::PaintFlags::FilterQuality::kLow; |
| Member<GPUDevice> device_; |
| |
| // If the system doesn't support the requested format but it's one that WebGPU |
| // is required to offer, a texture_ will be allocated separately with the |
| // desired format and the will be copied to swap_texture_, allocated by the |
| // swap buffer provider with the system-supported format, when we're ready to |
| // present. Otherwise texture_ and swap_texture_ will point to the same |
| // texture, allocated by the swap buffer provider. |
| Member<GPUTexture> texture_; |
| Member<GPUTexture> swap_texture_; |
| |
| PredefinedColorSpace color_space_ = PredefinedColorSpace::kSRGB; |
| V8GPUCanvasAlphaMode::Enum alpha_mode_; |
| scoped_refptr<WebGPUTextureAlphaClearer> alpha_clearer_; |
| scoped_refptr<WebGPUSwapBufferProvider> swap_buffers_; |
| |
| bool new_texture_required_ = true; |
| bool copy_to_swap_texture_required_ = false; |
| bool suppress_preferred_format_warning_ = false; |
| bool stopped_ = false; |
| |
| // Matches [[configuration]] != null in the WebGPU specification. |
| bool configured_ = false; |
| // Matches [[texture_descriptor]] in the WebGPU specification except that it |
| // never becomes null. |
| wgpu::TextureDescriptor texture_descriptor_; |
| // The texture descriptor for the swap_texture is tracked separately, since |
| // it may have different usage in the case that a copy is required. |
| wgpu::TextureDescriptor swap_texture_descriptor_; |
| wgpu::DawnTextureInternalUsageDescriptor texture_internal_usage_; |
| base::HeapArray<wgpu::TextureFormat> view_formats_; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_CANVAS_CONTEXT_H_ |