| Index: ui/ozone/platform/drm/host/drm_overlay_manager.cc
|
| diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.cc b/ui/ozone/platform/drm/host/drm_overlay_manager.cc
|
| index 26410b3f94c606e095b36bd42966cda33f33f4ea..9ba5746f75adaf6dad4a4b934ee99d308150f76c 100644
|
| --- a/ui/ozone/platform/drm/host/drm_overlay_manager.cc
|
| +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.cc
|
| @@ -1,87 +1,155 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Copyright 2016 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 "ui/ozone/platform/drm/host/drm_overlay_manager.h"
|
|
|
| +#include <stddef.h>
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "base/command_line.h"
|
| #include "ui/gfx/geometry/rect_conversions.h"
|
| -#include "ui/ozone/common/gpu/ozone_gpu_messages.h"
|
| -#include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
|
| #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h"
|
| #include "ui/ozone/platform/drm/host/drm_window_host.h"
|
| #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
|
| -#include "ui/ozone/public/overlay_candidates_ozone.h"
|
| +#include "ui/ozone/public/ozone_switches.h"
|
|
|
| namespace ui {
|
|
|
| -DrmOverlayManager::DrmOverlayManager(
|
| - DrmGpuPlatformSupportHost* platform_support_host,
|
| - DrmWindowHostManager* window_manager)
|
| - : sender_(new OverlayCandidatesIPC(platform_support_host, this)),
|
| - core_(new DrmOverlayManagerCore(sender_.get(), window_manager)) {}
|
| +typedef OverlayCandidatesOzone::OverlaySurfaceCandidateList
|
| + OverlaySurfaceCandidateList;
|
| +typedef OverlayCandidatesOzone::OverlaySurfaceCandidate OverlaySurfaceCandidate;
|
| +
|
| +namespace {
|
| +const size_t kMaxCacheSize = 200;
|
| +} // namespace
|
| +
|
| +DrmOverlayManager::DrmOverlayManager(GpuThreadAdapter* proxy,
|
| + DrmWindowHostManager* window_manager)
|
| + : proxy_(proxy), window_manager_(window_manager), cache_(kMaxCacheSize) {
|
| + is_supported_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kOzoneTestSingleOverlaySupport);
|
| + proxy_->RegisterHandlerForDrmOverlayManager(this);
|
| +}
|
|
|
| DrmOverlayManager::~DrmOverlayManager() {
|
| + proxy_->UnRegisterHandlerForDrmOverlayManager();
|
| }
|
|
|
| scoped_ptr<OverlayCandidatesOzone> DrmOverlayManager::CreateOverlayCandidates(
|
| gfx::AcceleratedWidget w) {
|
| - return core_->CreateOverlayCandidates(w);
|
| + if (!is_supported_)
|
| + return nullptr;
|
| + return make_scoped_ptr(new DrmOverlayCandidatesHost(this, w));
|
| }
|
|
|
| -void DrmOverlayManager::OnChannelEstablished(
|
| - int host_id,
|
| - scoped_refptr<base::SingleThreadTaskRunner> send_runner,
|
| - const base::Callback<void(IPC::Message*)>& sender) {
|
| - core_->ResetCache();
|
| -}
|
| -
|
| -void DrmOverlayManager::OnChannelDestroyed(int host_id) {}
|
| -
|
| -bool DrmOverlayManager::OnMessageReceived(const IPC::Message& message) {
|
| - bool handled = true;
|
| - IPC_BEGIN_MESSAGE_MAP(DrmOverlayManager, message)
|
| - IPC_MESSAGE_HANDLER(OzoneHostMsg_OverlayCapabilitiesReceived,
|
| - OnOverlayResult)
|
| - IPC_MESSAGE_UNHANDLED(handled = false)
|
| - IPC_END_MESSAGE_MAP()
|
| - return handled;
|
| +void DrmOverlayManager::CheckOverlaySupport(
|
| + OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates,
|
| + gfx::AcceleratedWidget widget) {
|
| + std::vector<OverlayCheck_Params> overlay_params;
|
| + for (auto& candidate : *candidates) {
|
| + // Reject candidates that don't fall on a pixel boundary.
|
| + if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f)) {
|
| + DCHECK(candidate.plane_z_order != 0);
|
| + overlay_params.push_back(OverlayCheck_Params());
|
| + overlay_params.back().is_overlay_candidate = false;
|
| + continue;
|
| + }
|
| +
|
| + // Compositor doesn't have information about the total size of primary
|
| + // candidate. We get this information from display rect.
|
| + if (candidate.plane_z_order == 0)
|
| + candidate.buffer_size = gfx::ToNearestRect(candidate.display_rect).size();
|
| +
|
| + overlay_params.push_back(OverlayCheck_Params(candidate));
|
| + }
|
| +
|
| + const auto& iter = cache_.Get(overlay_params);
|
| + // We are still waiting on results for this candidate list from GPU.
|
| + if (iter != cache_.end() && iter->second)
|
| + return;
|
| +
|
| + size_t size = candidates->size();
|
| +
|
| + if (iter == cache_.end()) {
|
| + // We can skip GPU side validation in case all candidates are invalid.
|
| + bool needs_gpu_validation = false;
|
| + for (size_t i = 0; i < size; i++) {
|
| + if (!overlay_params.at(i).is_overlay_candidate)
|
| + continue;
|
| +
|
| + const OverlaySurfaceCandidate& candidate = candidates->at(i);
|
| + if (!CanHandleCandidate(candidate, widget)) {
|
| + DCHECK(candidate.plane_z_order != 0);
|
| + overlay_params.at(i).is_overlay_candidate = false;
|
| + continue;
|
| + }
|
| +
|
| + needs_gpu_validation = true;
|
| + }
|
| +
|
| + cache_.Put(overlay_params, needs_gpu_validation);
|
| +
|
| + if (needs_gpu_validation)
|
| + SendOverlayValidationRequest(overlay_params, widget);
|
| + } else {
|
| + const std::vector<OverlayCheck_Params>& validated_params = iter->first;
|
| + DCHECK(size == validated_params.size());
|
| +
|
| + for (size_t i = 0; i < size; i++) {
|
| + candidates->at(i).overlay_handled =
|
| + validated_params.at(i).is_overlay_candidate;
|
| + }
|
| + }
|
| }
|
|
|
| void DrmOverlayManager::ResetCache() {
|
| - core_->ResetCache();
|
| -}
|
| -
|
| -void DrmOverlayManager::OnOverlayResult(
|
| - gfx::AcceleratedWidget widget,
|
| - const std::vector<OverlayCheck_Params>& params) {
|
| - core_->GpuSentOverlayResult(widget, params);
|
| + cache_.Clear();
|
| }
|
|
|
| -// TODO(rjkroege): There is a refactoring opportunity in the sender pattern.
|
| -DrmOverlayManager::OverlayCandidatesIPC::OverlayCandidatesIPC(
|
| - DrmGpuPlatformSupportHost* platform_support,
|
| - DrmOverlayManager* parent)
|
| - : platform_support_(platform_support), parent_(parent) {}
|
| +void DrmOverlayManager::SendOverlayValidationRequest(
|
| + const std::vector<OverlayCheck_Params>& new_params,
|
| + gfx::AcceleratedWidget widget) const {
|
| + if (!proxy_->IsConnected())
|
| + return;
|
|
|
| -DrmOverlayManager::OverlayCandidatesIPC::~OverlayCandidatesIPC() {}
|
| -
|
| -void DrmOverlayManager::OverlayCandidatesIPC::UnregisterHandler() {
|
| - platform_support_->UnregisterHandler(parent_);
|
| + proxy_->GpuCheckOverlayCapabilities(widget, new_params);
|
| }
|
|
|
| -void DrmOverlayManager::OverlayCandidatesIPC::RegisterHandler() {
|
| - platform_support_->RegisterHandler(parent_);
|
| -}
|
| -
|
| -bool DrmOverlayManager::OverlayCandidatesIPC::IsConnected() {
|
| - return platform_support_->IsConnected();
|
| +void DrmOverlayManager::GpuSentOverlayResult(
|
| + gfx::AcceleratedWidget widget,
|
| + const std::vector<OverlayCheck_Params>& params) {
|
| + cache_.Put(params, false);
|
| }
|
|
|
| -bool DrmOverlayManager::OverlayCandidatesIPC::CheckOverlayCapabilities(
|
| - gfx::AcceleratedWidget widget,
|
| - const std::vector<OverlayCheck_Params>& new_params) {
|
| - return platform_support_->Send(
|
| - new OzoneGpuMsg_CheckOverlayCapabilities(widget, new_params));
|
| +bool DrmOverlayManager::CanHandleCandidate(
|
| + const OverlaySurfaceCandidate& candidate,
|
| + gfx::AcceleratedWidget widget) const {
|
| + if (candidate.buffer_size.IsEmpty())
|
| + return false;
|
| +
|
| + if (candidate.transform == gfx::OVERLAY_TRANSFORM_INVALID)
|
| + return false;
|
| +
|
| + if (candidate.plane_z_order != 0) {
|
| + // It is possible that the cc rect we get actually falls off the edge of
|
| + // the screen. Usually this is prevented via things like status bars
|
| + // blocking overlaying or cc clipping it, but in case it wasn't properly
|
| + // clipped (since GL will render this situation fine) just ignore it
|
| + // here. This should be an extremely rare occurrance.
|
| + DrmWindowHost* window = window_manager_->GetWindow(widget);
|
| + if (!window->GetBounds().Contains(
|
| + gfx::ToNearestRect(candidate.display_rect))) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + if (candidate.is_clipped &&
|
| + !candidate.clip_rect.Contains(candidate.quad_rect_in_target_space))
|
| + return false;
|
| +
|
| + return true;
|
| }
|
|
|
| } // namespace ui
|
|
|