1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133

gpu / command_buffer / service / shared_image / dxgi_swap_chain_image_backing.h [blame]

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_DXGI_SWAP_CHAIN_IMAGE_BACKING_H_
#define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_DXGI_SWAP_CHAIN_IMAGE_BACKING_H_

#include <windows.h>

#include <d3d11.h>
#include <dxgi1_2.h>
#include <wrl/client.h>

#include <utility>

#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/service/shared_image/d3d_image_backing.h"
#include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/gpu/ganesh/GrTypes.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gl/buildflags.h"

namespace gpu {

class D3DImageBacking;
class SharedContextState;
class SharedImageManager;
class MemoryTypeTracker;

class GPU_GLES2_EXPORT DXGISwapChainImageBacking
    : public ClearTrackingSharedImageBacking {
 public:
  static std::unique_ptr<DXGISwapChainImageBacking> Create(
      Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device,
      const Mailbox& mailbox,
      viz::SharedImageFormat format,
      DXGI_FORMAT internal_format,
      const gfx::Size& size,
      const gfx::ColorSpace& color_space,
      GrSurfaceOrigin surface_origin,
      SkAlphaType alpha_type,
      gpu::SharedImageUsageSet usage,
      std::string debug_label);

  DXGISwapChainImageBacking(const DXGISwapChainImageBacking&) = delete;
  DXGISwapChainImageBacking& operator=(const DXGISwapChainImageBacking&) =
      delete;

  ~DXGISwapChainImageBacking() override;

  // SharedImageBacking implementation.
  SharedImageBackingType GetType() const override;
  void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;

 protected:
  std::unique_ptr<OverlayImageRepresentation> ProduceOverlay(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker) override;

  std::unique_ptr<SkiaGaneshImageRepresentation> ProduceSkiaGanesh(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker,
      scoped_refptr<SharedContextState> context_state) override;

  std::unique_ptr<SkiaGraphiteImageRepresentation> ProduceSkiaGraphite(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker,
      scoped_refptr<SharedContextState> context_state) override;

 private:
  DXGISwapChainImageBacking(
      const Mailbox& mailbox,
      viz::SharedImageFormat format,
      const gfx::Size& size,
      const gfx::ColorSpace& color_space,
      GrSurfaceOrigin surface_origin,
      SkAlphaType alpha_type,
      gpu::SharedImageUsageSet usage,
      std::string debug_label,
      Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device,
      Microsoft::WRL::ComPtr<IDXGISwapChain1> dxgi_swap_chain,
      int buffers_need_alpha_initialization_count);

  friend class DXGISwapChainOverlayImageRepresentation;
  bool Present(bool should_synchronize_present_with_vblank);
  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
    return std::make_optional<gl::DCLayerOverlayImage>(size(),
                                                       dxgi_swap_chain_);
  }

  friend class SkiaGLImageRepresentationDXGISwapChain;
  // Called by the Skia representation to indicate where it intends to draw.
  bool DidBeginWriteAccess(const gfx::Rect& swap_rect);

  friend class DawnRepresentationDXGISwapChain;
  wgpu::Texture BeginAccessDawn(const wgpu::Device& device,
                                wgpu::TextureUsage usage,
                                wgpu::TextureUsage internal_usage,
                                const gfx::Rect& update_rect);
  void EndAccessDawn(const wgpu::Device& device, wgpu::Texture texture);

  std::optional<gfx::Rect> pending_swap_rect_;

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
  Microsoft::WRL::ComPtr<IDXGISwapChain1> dxgi_swap_chain_;

  // Holds a gles2::TexturePassthrough and corresponding egl image.
  scoped_refptr<D3DImageBacking::GLTextureHolder> gl_texture_holder_;

  // SharedTextureMemory is created from DXGISwapChain's backbuffer texture.
  // This |shared_texture_memory_| wraps the ComPtr<ID3D11Texture> instead of
  // creating from a share HANDLE.
  wgpu::SharedTextureMemory shared_texture_memory_;

  // Count of buffers in |dxgi_swap_chain_| that need to have their alpha
  // channels be cleared to opaque before use. If positive at the start of write
  // access, this count will be decremented and the back buffer cleared.
  // This value should be initialized to 0 or the swap chain's buffer count. It
  // assumes DXGI swap chains cycle through its buffers in order, so after
  // calling present |buffer_count - 1| times, |GetBuffer(0)| will have referred
  // to every buffer once.
  int buffers_need_alpha_initialization_count_ = 0;

  bool first_swap_ = true;
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_DXGI_SWAP_CHAIN_IMAGE_BACKING_H_