blob: 900aa8bae88b395e0fb89535e492dcd2b3d6eb51 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/viz/service/display_embedder/overlay_candidate_validator_ozone.h"
#include <stddef.h>
#include <utility>
#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 "components/viz/service/display/overlay_strategy_underlay_cast.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace viz {
namespace {
// TODO(weiliangc): When difference between primary plane and non-primary plane
// can be internalized, merge these two helper functions.
void ConvertToOzoneOverlaySurface(
const OverlayCandidateValidatorOzone::PrimaryPlane& primary_plane,
ui::OverlaySurfaceCandidate* ozone_candidate) {
ozone_candidate->transform = primary_plane.transform;
ozone_candidate->format = primary_plane.format;
ozone_candidate->display_rect = primary_plane.display_rect;
ozone_candidate->crop_rect = gfx::RectF(0.f, 0.f, 1.f, 1.f);
ozone_candidate->clip_rect = gfx::ToEnclosingRect(primary_plane.display_rect);
ozone_candidate->is_clipped = false;
ozone_candidate->plane_z_order = 0;
ozone_candidate->buffer_size = primary_plane.resource_size;
}
void ConvertToOzoneOverlaySurface(
const OverlayCandidate& overlay_candidate,
ui::OverlaySurfaceCandidate* ozone_candidate) {
ozone_candidate->transform = overlay_candidate.transform;
ozone_candidate->format = overlay_candidate.format;
ozone_candidate->display_rect = overlay_candidate.display_rect;
ozone_candidate->crop_rect = overlay_candidate.uv_rect;
ozone_candidate->clip_rect = overlay_candidate.clip_rect;
ozone_candidate->is_clipped = overlay_candidate.is_clipped;
ozone_candidate->plane_z_order = overlay_candidate.plane_z_order;
ozone_candidate->buffer_size = overlay_candidate.resource_size_in_pixels;
}
} // 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.
OverlayCandidateValidatorOzone::OverlayCandidateValidatorOzone(
std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates,
std::vector<OverlayStrategy> available_strategies)
: overlay_candidates_(std::move(overlay_candidates)),
available_strategies_(std::move(available_strategies)) {}
OverlayCandidateValidatorOzone::~OverlayCandidateValidatorOzone() {}
void OverlayCandidateValidatorOzone::InitializeStrategies() {
for (OverlayStrategy strategy : available_strategies_) {
switch (strategy) {
case OverlayStrategy::kFullscreen:
strategies_.push_back(
std::make_unique<OverlayStrategyFullscreen>(this));
break;
case OverlayStrategy::kSingleOnTop:
strategies_.push_back(
std::make_unique<OverlayStrategySingleOnTop>(this));
break;
case OverlayStrategy::kUnderlay:
strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(this));
break;
case OverlayStrategy::kUnderlayCast:
strategies_.push_back(
std::make_unique<OverlayStrategyUnderlayCast>(this));
break;
default:
NOTREACHED();
}
}
}
bool OverlayCandidateValidatorOzone::AllowCALayerOverlays() const {
return false;
}
bool OverlayCandidateValidatorOzone::AllowDCLayerOverlays() const {
return false;
}
bool OverlayCandidateValidatorOzone::NeedsSurfaceOccludingDamageRect() const {
return true;
}
void OverlayCandidateValidatorOzone::CheckOverlaySupport(
const PrimaryPlane* primary_plane,
OverlayCandidateList* surfaces) {
// SW mirroring copies out of the framebuffer, so we can't remove any
// quads for overlaying, otherwise the output is incorrect.
if (software_mirror_active_) {
for (size_t i = 0; i < surfaces->size(); i++) {
surfaces->at(i).overlay_handled = false;
}
return;
}
// This number is depended on what type of strategies we have. Currently we
// only overlay one video.
DCHECK_EQ(1U, surfaces->size());
auto full_size = surfaces->size();
if (primary_plane)
full_size += 1;
ui::OverlayCandidatesOzone::OverlaySurfaceCandidateList ozone_surface_list(
full_size);
// Convert OverlayCandidateList to OzoneSurfaceCandidateList.
{
auto ozone_surface_iterator = ozone_surface_list.begin();
// For ozone-cast, there will not be a primary_plane.
if (primary_plane) {
ConvertToOzoneOverlaySurface(*primary_plane, &(*ozone_surface_iterator));
ozone_surface_iterator++;
}
auto surface_iterator = surfaces->cbegin();
for (; ozone_surface_iterator < ozone_surface_list.end() &&
surface_iterator < surfaces->cend();
ozone_surface_iterator++, surface_iterator++) {
ConvertToOzoneOverlaySurface(*surface_iterator,
&(*ozone_surface_iterator));
}
}
overlay_candidates_->CheckOverlaySupport(&ozone_surface_list);
// Copy information from OzoneSurfaceCandidatelist back to
// OverlayCandidateList.
{
DCHECK_EQ(full_size, ozone_surface_list.size());
auto ozone_surface_iterator = ozone_surface_list.cbegin();
// The primary plane is always handled, and don't need to copy information.
if (primary_plane)
ozone_surface_iterator++;
auto surface_iterator = surfaces->begin();
for (; surface_iterator < surfaces->end() &&
ozone_surface_iterator < ozone_surface_list.cend();
surface_iterator++, ozone_surface_iterator++) {
surface_iterator->overlay_handled =
ozone_surface_iterator->overlay_handled;
surface_iterator->display_rect = ozone_surface_iterator->display_rect;
}
}
}
void OverlayCandidateValidatorOzone::SetSoftwareMirrorMode(bool enabled) {
software_mirror_active_ = enabled;
}
} // namespace viz