chromium/components/viz/service/display/overlay_processor_ozone.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "components/viz/service/display/overlay_processor_ozone.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "build/chromeos_buildflags.h"
#include "components/viz/common/buildflags.h"
#include "components/viz/common/features.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "components/viz/service/display/overlay_strategy_fullscreen.h"
#include "components/viz/service/display/overlay_strategy_single_on_top.h"
#include "components/viz/service/display/overlay_strategy_underlay.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
#include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "gpu/config/gpu_finch_features.h"
#include "ui/gl/gl_switches.h"
#endif

#if BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)
#include "components/viz/service/display/overlay_strategy_underlay_cast.h"
#endif

namespace viz {

namespace {

gfx::ColorSpace GetColorSpaceForOzone(gfx::BufferFormat format,
                                      const gfx::ColorSpace& orig_color_space) {}

// TODO(weiliangc): When difference between primary plane and non-primary plane
// can be internalized, merge these two helper functions.
void ConvertToOzoneOverlaySurface(
    const OverlayProcessorInterface::OutputSurfaceOverlayPlane& primary_plane,
    ui::OverlaySurfaceCandidate* ozone_candidate) {}

void ConvertToOzoneOverlaySurface(
    const OverlayCandidate& overlay_candidate,
    ui::OverlaySurfaceCandidate* ozone_candidate) {}

void ConvertToTiledOzoneOverlaySurface(
    const OverlayCandidate& overlay_candidate,
    ui::OverlaySurfaceCandidate* ozone_candidate) {}

uint32_t MailboxToUInt32(const gpu::Mailbox& mailbox) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
bool IsYUVColorSpace(const gfx::ColorSpace& color_space) {
  SkYUVColorSpace yuv_color_space;
  return color_space.ToSkYUVColorSpace(&yuv_color_space);
}

bool AllowColorSpaceCombination(
    SharedImageFormat source_format,
    const gfx::ColorSpace& source_color_space,
    const gfx::ColorSpace& destination_color_space) {
  // Allow invalid source color spaces because the assumption is that the
  // compositor won't do a color space conversion in this case anyway, so it
  // should be consistent with the overlay path.
  if (!source_color_space.IsValid())
    return true;

  // Since https://crrev.com/c/2336347, we force BT.601/narrow for the
  // COLOR_ENCODING and COLOR_RANGE DRM/KMS properties. On the other hand, the
  // compositor is able to handle different YUV encodings and ranges. Therefore,
  // in theory, if we don't want to see a difference between overlays and
  // compositing, we should not promote video frames to overlays unless they
  // actually use BT.601/narrow.
  //
  // In practice, however, we expect to see lots of BT.709 video frames, and we
  // don't want to reject all of them for overlays because the visual difference
  // between BT.601/narrow and BT.709/narrow is not expected to be much.
  // Therefore, in being consistent with the values we provide for
  // EGL_YUV_COLOR_SPACE_HINT_EXT/EGL_SAMPLE_RANGE_HINT_EXT, we'll only allow
  // frames that use non-BT.2020 with non-full range. In those cases, the
  // compositor and the display controller are expected to render the frames
  // equally (and decently - with the understanding that the final result may
  // not be fully correct).
  //
  // TODO(b/233667677): Remove this when we've plumbed the YUV encoding and
  // range to DRM/KMS. At that point, we need to ensure that
  // EGL_YUV_COLOR_SPACE_HINT_EXT/EGL_SAMPLE_RANGE_HINT_EXT would also get the
  // same values as DRM/KMS.
  //
  // TODO(b/243150091): Remove the call to IsYUVColorSpace() or turn it into a
  // DCHECK() once LaCrOS plumbs the correct color space.
  bool is_yuv_color_space = features::IsLacrosColorManagementEnabled() ||
                            IsYUVColorSpace(source_color_space);
  if ((source_format == MultiPlaneFormat::kNV12 ||
       source_format == MultiPlaneFormat::kYV12 ||
       source_format == MultiPlaneFormat::kP010) &&
      is_yuv_color_space &&
      (source_color_space.GetMatrixID() ==
           gfx::ColorSpace::MatrixID::BT2020_NCL ||
       source_color_space.GetRangeID() == gfx::ColorSpace::RangeID::FULL)) {
    return false;
  }

  // Allow color space mismatches as long as either a) the source color space is
  // SRGB; or b) both the source and destination color spaces have the same
  // color usage. It is possible that case (a) still allows for visible color
  // inconsistency between overlays and composition, but we'll address that case
  // if it comes up.
  return source_color_space.GetContentColorUsage() ==
             gfx::ContentColorUsage::kSRGB ||
         source_color_space.GetContentColorUsage() ==
             destination_color_space.GetContentColorUsage();
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

}  // namespace

// |overlay_candidates| is an object used to answer questions about possible
// overlays configurations.
// |available_strategies| is a list of overlay strategies that should be
// initialized by InitializeStrategies.
OverlayProcessorOzone::OverlayProcessorOzone(
    std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates,
    std::vector<OverlayStrategy> available_strategies,
    gpu::SharedImageInterface* shared_image_interface)
    :{}

OverlayProcessorOzone::~OverlayProcessorOzone() = default;

bool OverlayProcessorOzone::IsOverlaySupported() const {}

bool OverlayProcessorOzone::NeedsSurfaceDamageRectList() const {}

bool OverlayProcessorOzone::SupportsFlipRotateTransform() const {}

void OverlayProcessorOzone::NotifyOverlayPromotion(
    DisplayResourceProvider* display_resource_provider,
    const OverlayCandidateList& candidate_list,
    const QuadList& quad_list) {}

void OverlayProcessorOzone::CheckOverlaySupportImpl(
    const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
    OverlayCandidateList* surfaces) {}

void OverlayProcessorOzone::MaybeObserveHardwareCapabilities() {}

void OverlayProcessorOzone::ReceiveHardwareCapabilities(
    ui::HardwareCapabilities hardware_capabilities) {}

gfx::Rect OverlayProcessorOzone::GetOverlayDamageRectForOutputSurface(
    const OverlayCandidate& overlay) const {}

void OverlayProcessorOzone::RegisterOverlayRequirement(bool requires_overlay) {}

void OverlayProcessorOzone::OnSwapBuffersComplete(gfx::SwapResult swap_result) {}

bool OverlayProcessorOzone::SetNativePixmapForCandidate(
    ui::OverlaySurfaceCandidate* candidate,
    const gpu::Mailbox& mailbox,
    bool is_primary) {}

}  // namespace viz