1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_SWAP_BUFFER_PROVIDER_H_
6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_SWAP_BUFFER_PROVIDER_H_
7 
8 #include "cc/layers/texture_layer.h"
9 #include "cc/layers/texture_layer_client.h"
10 #include "gpu/command_buffer/common/mailbox.h"
11 #include "gpu/command_buffer/common/sync_token.h"
12 #include "third_party/blink/renderer/platform/geometry/int_size.h"
13 #include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h"
14 #include "third_party/blink/renderer/platform/platform_export.h"
15 #include "third_party/blink/renderer/platform/wtf/functional.h"
16 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
17 
18 namespace blink {
19 
20 // WebGPUSwapBufferProvider contains the cc::Layer used by the swapchain as well
21 // as the resources used for the layer. It is separate from GPUSwapChain so that
22 // it can be kept alive via refcounting instead of garbage collection and so it
23 // can live in blink_platform and use gpu:: or viz:: types.
24 class PLATFORM_EXPORT WebGPUSwapBufferProvider
25     : public cc::TextureLayerClient,
26       public RefCounted<WebGPUSwapBufferProvider> {
27  public:
28   class Client {
29    public:
30     // Called to make the WebGPU/Dawn stop accessing the texture prior to its
31     // transfer to the compositor.
32     virtual void OnTextureTransferred() = 0;
33   };
34 
35   WebGPUSwapBufferProvider(
36       Client* client,
37       scoped_refptr<DawnControlClientHolder> dawn_control_client,
38       uint64_t device_client_id,
39       WGPUTextureUsage usage,
40       WGPUTextureFormat format);
41   ~WebGPUSwapBufferProvider() override;
42 
43   cc::Layer* CcLayer();
44   void Neuter();
45   WGPUTexture GetNewTexture(const IntSize& size);
46 
47   // cc::TextureLayerClient implementation.
48   bool PrepareTransferableResource(
49       cc::SharedBitmapIdRegistrar* bitmap_registrar,
50       viz::TransferableResource* out_resource,
51       std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback)
52       override;
53 
54  private:
55   // Holds resources and synchronization for one of the swapchain images.
56   struct SwapBuffer : public RefCounted<SwapBuffer> {
57     SwapBuffer(WebGPUSwapBufferProvider*,
58                gpu::Mailbox mailbox,
59                gpu::SyncToken creation_token,
60                gfx::Size size);
61     ~SwapBuffer();
62 
63     gfx::Size size;
64     gpu::Mailbox mailbox;
65 
66     // A reference back to the swap buffers to keep it alive while this image
67     // is in flight so that the destructor can access data in the swap
68     // buffers.
69     scoped_refptr<WebGPUSwapBufferProvider> swap_buffers;
70 
71     // A token signaled when the previous user of the image is finished using
72     // it. It could be WebGPU, the compositor or the shared image creation.
73     gpu::SyncToken access_finished_token;
74 
75    private:
76     DISALLOW_COPY_AND_ASSIGN(SwapBuffer);
77   };
78 
79   void MailboxReleased(scoped_refptr<SwapBuffer> swap_buffer,
80                        const gpu::SyncToken& sync_token,
81                        bool lost_resource);
82 
83   scoped_refptr<DawnControlClientHolder> dawn_control_client_;
84   Client* client_;
85   uint64_t device_client_id_;
86   scoped_refptr<cc::TextureLayer> layer_;
87   bool neutered_ = false;
88 
89   WGPUTextureUsage usage_;
90 
91   uint32_t wire_texture_id_ = 0;
92   uint32_t wire_texture_generation_ = 0;
93   scoped_refptr<SwapBuffer> current_swap_buffer_;
94   viz::ResourceFormat format_;
95 };
96 
97 }  // namespace blink
98 
99 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_SWAP_BUFFER_PROVIDER_H_
100