chromium/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.cc

// 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.

#include "gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.h"

#include "base/win/windows_types.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image/dcomp_surface_image_backing.h"
#include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"

namespace gpu {

DCompSurfaceOverlayImageRepresentation::DCompSurfaceOverlayImageRepresentation(
    SharedImageManager* manager,
    SharedImageBacking* backing,
    MemoryTypeTracker* tracker)
    : OverlayImageRepresentation(manager, backing, tracker) {}

DCompSurfaceOverlayImageRepresentation::
    ~DCompSurfaceOverlayImageRepresentation() = default;

std::optional<gl::DCLayerOverlayImage>
DCompSurfaceOverlayImageRepresentation::GetDCLayerOverlayImage() {
  return static_cast<DCompSurfaceImageBacking*>(backing())
      ->GetDCLayerOverlayImage();
}

bool DCompSurfaceOverlayImageRepresentation::BeginReadAccess(
    gfx::GpuFenceHandle& acquire_fence) {
  // DComp surfaces access synchronization happens internally in DWM on commit.
  return true;
}

void DCompSurfaceOverlayImageRepresentation::EndReadAccess(
    gfx::GpuFenceHandle release_fence) {}

DCompSurfaceSkiaGaneshImageRepresentation::
    DCompSurfaceSkiaGaneshImageRepresentation(
        scoped_refptr<SharedContextState> context_state,
        SharedImageManager* manager,
        SharedImageBacking* backing,
        MemoryTypeTracker* tracker)
    : SkiaGaneshImageRepresentation(context_state->gr_context(),
                                    manager,
                                    backing,
                                    tracker),
      context_state_(std::move(context_state)) {
  DCHECK(context_state_);
}

DCompSurfaceSkiaGaneshImageRepresentation::
    ~DCompSurfaceSkiaGaneshImageRepresentation() = default;

std::vector<sk_sp<SkSurface>>
DCompSurfaceSkiaGaneshImageRepresentation::BeginWriteAccess(
    int final_msaa_count,
    const SkSurfaceProps& surface_props,
    const gfx::Rect& update_rect,
    std::vector<GrBackendSemaphore>* begin_semaphores,
    std::vector<GrBackendSemaphore>* end_semaphores,
    std::unique_ptr<skgpu::MutableTextureState>* end_state) {
  DCompSurfaceImageBacking* dcomp_backing =
      static_cast<DCompSurfaceImageBacking*>(backing());
  sk_sp<SkSurface> surface = dcomp_backing->BeginDrawGanesh(
      context_state_.get(), final_msaa_count, surface_props, update_rect);
  if (!surface) {
    return {};
  }

  return {std::move(surface)};
}

void DCompSurfaceSkiaGaneshImageRepresentation::EndWriteAccess() {
  DCompSurfaceImageBacking* dcomp_backing =
      static_cast<DCompSurfaceImageBacking*>(backing());
  dcomp_backing->EndDrawGanesh();
}

std::vector<sk_sp<GrPromiseImageTexture>>
DCompSurfaceSkiaGaneshImageRepresentation::BeginWriteAccess(
    std::vector<GrBackendSemaphore>* begin_semaphores,
    std::vector<GrBackendSemaphore>* end_semaphores,
    std::unique_ptr<skgpu::MutableTextureState>* end_state) {
  NOTREACHED_IN_MIGRATION();
  return {};
}

std::vector<sk_sp<GrPromiseImageTexture>>
DCompSurfaceSkiaGaneshImageRepresentation::BeginReadAccess(
    std::vector<GrBackendSemaphore>* begin_semaphores,
    std::vector<GrBackendSemaphore>* end_semaphores,
    std::unique_ptr<skgpu::MutableTextureState>* end_state) {
  NOTREACHED_IN_MIGRATION();
  return {};
}

void DCompSurfaceSkiaGaneshImageRepresentation::EndReadAccess() {
  NOTREACHED_IN_MIGRATION();
}

DCompSurfaceDawnImageRepresentation::DCompSurfaceDawnImageRepresentation(
    SharedImageManager* manager,
    SharedImageBacking* backing,
    MemoryTypeTracker* tracker,
    const wgpu::Device& device,
    wgpu::BackendType backend_type)
    : DawnImageRepresentation(manager, backing, tracker), device_(device) {}

DCompSurfaceDawnImageRepresentation::~DCompSurfaceDawnImageRepresentation() {
  EndAccess();
}

wgpu::Texture DCompSurfaceDawnImageRepresentation::BeginAccess(
    wgpu::TextureUsage usage,
    wgpu::TextureUsage internal_usage,
    const gfx::Rect& update_rect) {
  DCompSurfaceImageBacking* dcomp_backing =
      static_cast<DCompSurfaceImageBacking*>(backing());
  texture_ =
      dcomp_backing->BeginDrawDawn(device_, usage, internal_usage, update_rect);
  return texture_;
}

wgpu::Texture DCompSurfaceDawnImageRepresentation::BeginAccess(
    wgpu::TextureUsage usage,
    wgpu::TextureUsage internal_usage) {
  NOTREACHED();
}

void DCompSurfaceDawnImageRepresentation::EndAccess() {
  if (!texture_) {
    return;
  }

  // Do this before further operations since those could end up destroying the
  // Dawn device and we want the fence to be duplicated before then.
  DCompSurfaceImageBacking* dcomp_backing =
      static_cast<DCompSurfaceImageBacking*>(backing());
  dcomp_backing->EndDrawDawn(device_, std::move(texture_));
}

}  // namespace gpu