diff options
author | achaulk <achaulk@chromium.org> | 2015-06-05 09:57:30 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-05 16:57:52 +0000 |
commit | ad89643990d9b2320960d1912695cc1418a3fdab (patch) | |
tree | ae3b7e0d61d6c4c344ab16953558a40054671efc /ui | |
parent | d21062b6325cd91effe187dd7a9aa87be3f599bc (diff) | |
download | chromium_src-ad89643990d9b2320960d1912695cc1418a3fdab.zip chromium_src-ad89643990d9b2320960d1912695cc1418a3fdab.tar.gz chromium_src-ad89643990d9b2320960d1912695cc1418a3fdab.tar.bz2 |
ozone: Add overlay candidate implementation that queries support via IPC
Querying is done asynchronously, with a browser-side cache of responses.
GPU will try out the requested overlay configuration and report if it was
successful. Response delay is typically 1 frame but could be more in
rare situations. A maximum cache size is imposed so that a video that's being
moved/resized won't cause memory consumption to explode
TBR=danakj (trivial enum change)
Review URL: https://codereview.chromium.org/1157793004
Cr-Commit-Position: refs/heads/master@{#333073}
Diffstat (limited to 'ui')
18 files changed, 370 insertions, 56 deletions
diff --git a/ui/gfx/overlay_transform.h b/ui/gfx/overlay_transform.h index 382d5c3..252fc73 100644 --- a/ui/gfx/overlay_transform.h +++ b/ui/gfx/overlay_transform.h @@ -17,6 +17,7 @@ enum OverlayTransform { OVERLAY_TRANSFORM_ROTATE_90, OVERLAY_TRANSFORM_ROTATE_180, OVERLAY_TRANSFORM_ROTATE_270, + OVERLAY_TRANSFORM_LAST = OVERLAY_TRANSFORM_ROTATE_270 }; } // namespace gfx diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/ui/ozone/common/gpu/ozone_gpu_message_params.cc index de90c80..100f208 100644 --- a/ui/ozone/common/gpu/ozone_gpu_message_params.cc +++ b/ui/ozone/common/gpu/ozone_gpu_message_params.cc @@ -4,6 +4,9 @@ #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/ipc/gfx_param_traits.h" + namespace ui { DisplayMode_Params::DisplayMode_Params() @@ -29,4 +32,22 @@ DisplaySnapshot_Params::DisplaySnapshot_Params() DisplaySnapshot_Params::~DisplaySnapshot_Params() {} +OverlayCheck_Params::OverlayCheck_Params() + : transform(gfx::OVERLAY_TRANSFORM_INVALID), + format(SurfaceFactoryOzone::UNKNOWN), + plane_z_order(0) { +} + +OverlayCheck_Params::OverlayCheck_Params( + const OverlayCandidatesOzone::OverlaySurfaceCandidate& candidate) + : buffer_size(candidate.buffer_size), + transform(candidate.transform), + format(candidate.format), + display_rect(gfx::ToNearestRect(candidate.display_rect)), + plane_z_order(candidate.plane_z_order) { +} + +OverlayCheck_Params::~OverlayCheck_Params() { +} + } // namespace ui diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.h b/ui/ozone/common/gpu/ozone_gpu_message_params.h index a2d543a..cc0eb0a 100644 --- a/ui/ozone/common/gpu/ozone_gpu_message_params.h +++ b/ui/ozone/common/gpu/ozone_gpu_message_params.h @@ -11,7 +11,10 @@ #include "ui/display/types/display_constants.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/overlay_transform.h" #include "ui/ozone/ozone_export.h" +#include "ui/ozone/public/overlay_candidates_ozone.h" +#include "ui/ozone/public/surface_factory_ozone.h" namespace ui { @@ -44,6 +47,19 @@ struct OZONE_EXPORT DisplaySnapshot_Params { std::string string_representation; }; +struct OZONE_EXPORT OverlayCheck_Params { + OverlayCheck_Params(); + OverlayCheck_Params( + const OverlayCandidatesOzone::OverlaySurfaceCandidate& candidate); + ~OverlayCheck_Params(); + + gfx::Size buffer_size; + gfx::OverlayTransform transform; + SurfaceFactoryOzone::BufferFormat format; + gfx::Rect display_rect; + int plane_z_order; +}; + } // namespace ui #endif // UI_OZONE_COMMON_GPU_OZONE_GPU_MESSAGE_PARAMS_H_ diff --git a/ui/ozone/common/gpu/ozone_gpu_messages.h b/ui/ozone/common/gpu/ozone_gpu_messages.h index b58af6a..77cd70e 100644 --- a/ui/ozone/common/gpu/ozone_gpu_messages.h +++ b/ui/ozone/common/gpu/ozone_gpu_messages.h @@ -29,8 +29,12 @@ IPC_ENUM_TRAITS_MAX_VALUE(ui::DisplayConnectionType, IPC_ENUM_TRAITS_MAX_VALUE(ui::HDCPState, ui::HDCP_STATE_LAST) -// clang-format off +IPC_ENUM_TRAITS_MAX_VALUE(gfx::OverlayTransform, gfx::OVERLAY_TRANSFORM_LAST) + +IPC_ENUM_TRAITS_MAX_VALUE(ui::SurfaceFactoryOzone::BufferFormat, + ui::SurfaceFactoryOzone::BUFFER_FORMAT_LAST) +// clang-format off IPC_STRUCT_TRAITS_BEGIN(ui::DisplayMode_Params) IPC_STRUCT_TRAITS_MEMBER(size) IPC_STRUCT_TRAITS_MEMBER(is_interlaced) @@ -60,6 +64,14 @@ IPC_STRUCT_TRAITS_BEGIN(ui::GammaRampRGBEntry) IPC_STRUCT_TRAITS_MEMBER(b) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ui::OverlayCheck_Params) + IPC_STRUCT_TRAITS_MEMBER(buffer_size) + IPC_STRUCT_TRAITS_MEMBER(transform) + IPC_STRUCT_TRAITS_MEMBER(format) + IPC_STRUCT_TRAITS_MEMBER(display_rect) + IPC_STRUCT_TRAITS_MEMBER(plane_z_order) +IPC_STRUCT_TRAITS_END() + // clang-format on //------------------------------------------------------------------------------ @@ -128,6 +140,10 @@ IPC_MESSAGE_CONTROL2(OzoneGpuMsg_SetGammaRamp, int64_t, // display ID, std::vector<ui::GammaRampRGBEntry>) // lut +IPC_MESSAGE_CONTROL2(OzoneGpuMsg_CheckOverlayCapabilities, + gfx::AcceleratedWidget /* widget */, + std::vector<ui::OverlayCheck_Params> /* overlays */) + //------------------------------------------------------------------------------ // Browser Messages // These messages are from the GPU to the browser process. @@ -157,3 +173,8 @@ IPC_MESSAGE_CONTROL1(OzoneHostMsg_DisplayControlTaken, bool /* success */) // Response to OzoneGpuMsg_RelinquishDisplayControl. IPC_MESSAGE_CONTROL1(OzoneHostMsg_DisplayControlRelinquished, bool /* success */) + +// Response for OzoneGpuMsg_CheckOverlayCapabilities +IPC_MESSAGE_CONTROL2(OzoneHostMsg_OverlayCapabilitiesReceived, + gfx::AcceleratedWidget /* widget */, + bool /* result */) diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn index 6429e6b..9f447a2 100644 --- a/ui/ozone/platform/drm/BUILD.gn +++ b/ui/ozone/platform/drm/BUILD.gn @@ -75,6 +75,8 @@ source_set("drm_common") { "host/drm_gpu_platform_support_host.h", "host/drm_native_display_delegate.cc", "host/drm_native_display_delegate.h", + "host/drm_overlay_candidates_host.cc", + "host/drm_overlay_candidates_host.h", "host/drm_overlay_manager.cc", "host/drm_overlay_manager.h", "host/drm_window_host.cc", diff --git a/ui/ozone/platform/drm/drm.gypi b/ui/ozone/platform/drm/drm.gypi index dc8ef0d..dd427a9 100644 --- a/ui/ozone/platform/drm/drm.gypi +++ b/ui/ozone/platform/drm/drm.gypi @@ -96,6 +96,8 @@ 'host/drm_gpu_platform_support_host.h', 'host/drm_native_display_delegate.cc', 'host/drm_native_display_delegate.h', + 'host/drm_overlay_candidates_host.cc', + 'host/drm_overlay_candidates_host.h', 'host/drm_overlay_manager.cc', 'host/drm_overlay_manager.h', 'host/drm_window_host.cc', diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc index 92df322..a94d308 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc +++ b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc @@ -13,6 +13,7 @@ #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" #include "ui/ozone/platform/drm/gpu/drm_window.h" +#include "ui/ozone/platform/drm/gpu/scanout_buffer.h" #include "ui/ozone/platform/drm/gpu/screen_manager.h" namespace ui { @@ -167,10 +168,12 @@ class DrmGpuPlatformSupportMessageFilter : public IPC::MessageFilter { DrmGpuPlatformSupport::DrmGpuPlatformSupport( DrmDeviceManager* drm_device_manager, ScreenManager* screen_manager, + ScanoutBufferGenerator* buffer_generator, scoped_ptr<DrmGpuDisplayManager> display_manager) : sender_(NULL), drm_device_manager_(drm_device_manager), screen_manager_(screen_manager), + buffer_generator_(buffer_generator), display_manager_(display_manager.Pass()) { filter_ = new DrmGpuPlatformSupportMessageFilter( screen_manager, base::Bind(&DrmGpuPlatformSupport::SetIOTaskRunner, @@ -217,6 +220,8 @@ bool DrmGpuPlatformSupport::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(OzoneGpuMsg_GetHDCPState, OnGetHDCPState) IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetHDCPState, OnSetHDCPState) IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetGammaRamp, OnSetGammaRamp); + IPC_MESSAGE_HANDLER(OzoneGpuMsg_CheckOverlayCapabilities, + OnCheckOverlayCapabilities) IPC_MESSAGE_UNHANDLED(handled = false); IPC_END_MESSAGE_MAP() @@ -260,6 +265,14 @@ void DrmGpuPlatformSupport::OnCursorMove(gfx::AcceleratedWidget widget, screen_manager_->GetWindow(widget)->MoveCursor(location); } +void DrmGpuPlatformSupport::OnCheckOverlayCapabilities( + gfx::AcceleratedWidget widget, + const std::vector<OverlayCheck_Params>& overlays) { + sender_->Send(new OzoneHostMsg_OverlayCapabilitiesReceived( + widget, screen_manager_->GetWindow(widget) + ->TestPageFlip(overlays, buffer_generator_))); +} + void DrmGpuPlatformSupport::OnRefreshNativeDisplays() { sender_->Send( new OzoneHostMsg_UpdateNativeDisplays(display_manager_->GetDisplays())); diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h index 27e84e1..bd735a6 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h +++ b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h @@ -33,15 +33,18 @@ class DrmGpuDisplayManager; class DrmSurfaceFactory; class DrmWindow; class ScreenManager; +class ScanoutBufferGenerator; struct DisplayMode_Params; struct DisplaySnapshot_Params; +struct OverlayCheck_Params; struct GammaRampRGBEntry; class DrmGpuPlatformSupport : public GpuPlatformSupport { public: DrmGpuPlatformSupport(DrmDeviceManager* drm_device_manager, ScreenManager* screen_manager, + ScanoutBufferGenerator* buffer_generator, scoped_ptr<DrmGpuDisplayManager> display_manager); ~DrmGpuPlatformSupport() override; @@ -65,6 +68,9 @@ class DrmGpuPlatformSupport : public GpuPlatformSupport { const gfx::Point& location, int frame_delay_ms); void OnCursorMove(gfx::AcceleratedWidget widget, const gfx::Point& location); + void OnCheckOverlayCapabilities( + gfx::AcceleratedWidget widget, + const std::vector<OverlayCheck_Params>& overlays); // Display related IPC handlers. void OnRefreshNativeDisplays(); @@ -87,6 +93,7 @@ class DrmGpuPlatformSupport : public GpuPlatformSupport { IPC::Sender* sender_; // Not owned. DrmDeviceManager* drm_device_manager_; // Not owned. ScreenManager* screen_manager_; // Not owned. + ScanoutBufferGenerator* buffer_generator_; // Not owned. scoped_ptr<DrmGpuDisplayManager> display_manager_; ScopedVector<GpuPlatformSupport> handlers_; diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc index b2f7a46..81756f7 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.cc +++ b/ui/ozone/platform/drm/gpu/drm_window.cc @@ -8,9 +8,11 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkSurface.h" +#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" #include "ui/ozone/platform/drm/gpu/drm_buffer.h" #include "ui/ozone/platform/drm/gpu/drm_device.h" #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" +#include "ui/ozone/platform/drm/gpu/scanout_buffer.h" #include "ui/ozone/platform/drm/gpu/screen_manager.h" namespace ui { @@ -25,6 +27,9 @@ namespace { #define DRM_CAP_CURSOR_HEIGHT 0x9 #endif +void EmptyFlipCallback(gfx::SwapResult) { +} + void UpdateCursorImage(DrmBuffer* cursor, const SkBitmap& image) { SkRect damage; image.getBounds(&damage); @@ -139,6 +144,36 @@ bool DrmWindow::SchedulePageFlip(bool is_sync, return true; } +bool DrmWindow::TestPageFlip(const std::vector<OverlayCheck_Params>& overlays, + ScanoutBufferGenerator* buffer_generator) { + if (!controller_) + return true; + for (const auto& overlay : overlays) { + // 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. + if (overlay.plane_z_order != 0 && !bounds().Contains(overlay.display_rect)) + return false; + } + + scoped_refptr<DrmDevice> drm = controller_->GetAllocationDrmDevice(); + OverlayPlaneList planes; + for (const auto& overlay : overlays) { + gfx::Size size = + (overlay.plane_z_order == 0) ? bounds().size() : overlay.buffer_size; + scoped_refptr<ScanoutBuffer> buffer = buffer_generator->Create(drm, size); + if (!buffer) + return false; + planes.push_back(OverlayPlane(buffer, overlay.plane_z_order, + overlay.transform, overlay.display_rect, + gfx::RectF(gfx::Size(1, 1)))); + } + return controller_->SchedulePageFlip(planes, true, true, + base::Bind(&EmptyFlipCallback)); +} + const OverlayPlane* DrmWindow::GetLastModesetBuffer() { return OverlayPlane::GetPrimaryPlane(last_submitted_planes_); } diff --git a/ui/ozone/platform/drm/gpu/drm_window.h b/ui/ozone/platform/drm/gpu/drm_window.h index 1164f17..36d3b5b 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.h +++ b/ui/ozone/platform/drm/gpu/drm_window.h @@ -29,6 +29,8 @@ namespace ui { class DrmBuffer; class DrmDeviceManager; class HardwareDisplayController; +struct OverlayCheck_Params; +class ScanoutBufferGenerator; class ScreenManager; // A delegate of the platform window (DrmWindow) on the GPU process. This is @@ -84,6 +86,8 @@ class OZONE_EXPORT DrmWindow { void QueueOverlayPlane(const OverlayPlane& plane); bool SchedulePageFlip(bool is_sync, const SwapCompletionCallback& callback); + bool TestPageFlip(const std::vector<OverlayCheck_Params>& planes, + ScanoutBufferGenerator* buffer_generator); // Returns the last buffer associated with this window. const OverlayPlane* GetLastModesetBuffer(); diff --git a/ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc b/ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc new file mode 100644 index 0000000..52e31b1 --- /dev/null +++ b/ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc @@ -0,0 +1,141 @@ +// Copyright 2015 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_candidates_host.h" + +#include <algorithm> + +#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" + +namespace ui { + +namespace { +const size_t kMaxCacheSize = 100; +} // namespace + +bool DrmOverlayCandidatesHost::OverlayCompare::operator()( + const OverlayCheck_Params& l, + const OverlayCheck_Params& r) { + if (l.plane_z_order < r.plane_z_order) + return true; + if (l.plane_z_order > r.plane_z_order) + return false; + if (l.display_rect < r.display_rect) + return true; + if (l.display_rect != r.display_rect) + return false; + if (l.format < r.format) + return true; + if (l.format > r.format) + return false; + if (l.transform < r.transform) + return true; + if (l.transform > r.transform) + return false; + if (l.buffer_size.width() < r.buffer_size.width()) + return true; + if (l.buffer_size.width() > r.buffer_size.width()) + return false; + return l.buffer_size.height() < r.buffer_size.height(); +} + +DrmOverlayCandidatesHost::DrmOverlayCandidatesHost( + gfx::AcceleratedWidget widget, + DrmGpuPlatformSupportHost* platform_support) + : widget_(widget), + platform_support_(platform_support), + cache_(kMaxCacheSize) { + platform_support_->RegisterHandler(this); +} + +DrmOverlayCandidatesHost::~DrmOverlayCandidatesHost() { + platform_support_->UnregisterHandler(this); +} + +void DrmOverlayCandidatesHost::CheckOverlaySupport( + OverlaySurfaceCandidateList* candidates) { + if (candidates->size() == 2) + CheckSingleOverlay(candidates); +} + +void DrmOverlayCandidatesHost::CheckSingleOverlay( + OverlaySurfaceCandidateList* candidates) { + OverlayCandidatesOzone::OverlaySurfaceCandidate* first = &(*candidates)[0]; + OverlayCandidatesOzone::OverlaySurfaceCandidate* second = &(*candidates)[1]; + OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay; + if (first->plane_z_order == 0) { + overlay = second; + } else if (second->plane_z_order == 0) { + overlay = first; + } else { + return; + } + // 0.01 constant chosen to match DCHECKs in gfx::ToNearestRect and avoid + // that code asserting on quads that we accept. + if (!gfx::IsNearestRectWithinDistance(overlay->display_rect, 0.01f)) + return; + if (overlay->transform == gfx::OVERLAY_TRANSFORM_INVALID) + return; + + OverlayCheck_Params lookup(*overlay); + auto iter = cache_.Get(lookup); + if (iter == cache_.end()) { + cache_.Put(lookup, false); + SendRequest(*candidates, lookup); + } else { + overlay->overlay_handled = iter->second; + } +} + +void DrmOverlayCandidatesHost::OnChannelEstablished( + int host_id, + scoped_refptr<base::SingleThreadTaskRunner> send_runner, + const base::Callback<void(IPC::Message*)>& sender) { +} + +void DrmOverlayCandidatesHost::OnChannelDestroyed(int host_id) { +} + +bool DrmOverlayCandidatesHost::OnMessageReceived(const IPC::Message& message) { + bool handled = false; + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(DrmOverlayCandidatesHost, message, &handled) + IPC_MESSAGE_FORWARD(OzoneHostMsg_OverlayCapabilitiesReceived, this, + DrmOverlayCandidatesHost::OnOverlayResult) + IPC_END_MESSAGE_MAP() + return handled; +} + +void DrmOverlayCandidatesHost::SendRequest( + const OverlaySurfaceCandidateList& candidates, + const OverlayCheck_Params& check) { + if (!platform_support_->IsConnected()) + return; + pending_checks_.push_back(check); + std::vector<OverlayCheck_Params> list; + for (const auto& candidate : candidates) + list.push_back(OverlayCheck_Params(candidate)); + platform_support_->Send( + new OzoneGpuMsg_CheckOverlayCapabilities(widget_, list)); +} + +void DrmOverlayCandidatesHost::OnOverlayResult(bool* handled, + gfx::AcceleratedWidget widget, + bool result) { + if (widget != widget_) + return; + *handled = true; + DCHECK(!pending_checks_.empty()); + ProcessResult(pending_checks_.front(), result); + pending_checks_.pop_front(); +} + +void DrmOverlayCandidatesHost::ProcessResult(const OverlayCheck_Params& check, + bool result) { + if (result) + cache_.Put(check, true); +} + +} // namespace ui diff --git a/ui/ozone/platform/drm/host/drm_overlay_candidates_host.h b/ui/ozone/platform/drm/host/drm_overlay_candidates_host.h new file mode 100644 index 0000000..2f00cac --- /dev/null +++ b/ui/ozone/platform/drm/host/drm_overlay_candidates_host.h @@ -0,0 +1,85 @@ +// Copyright 2015 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. + +#ifndef UI_OZONE_PLATFORM_DRM_HOST_OVERLAY_CANDIDATES_H_ +#define UI_OZONE_PLATFORM_DRM_HOST_OVERLAY_CANDIDATES_H_ + +#include <deque> +#include <map> +#include <vector> + +#include "base/containers/mru_cache.h" +#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" +#include "ui/ozone/public/gpu_platform_support_host.h" +#include "ui/ozone/public/overlay_candidates_ozone.h" + +namespace ui { + +class DrmGpuPlatformSupportHost; + +// This is an implementation of OverlayCandidatesOzone where the driver is asked +// about overlay capabilities via IPC. We have no way of querying abstract +// capabilities, only if a particular configuration is supported or not. +// Each time we we are asked if a particular configuration is supported, if we +// have not seen that configuration before, it is IPCed to the GPU via +// OzoneGpuMsg_CheckOverlayCapabilities; a test commit is then performed and +// the result is returned in OzoneHostMsg_OverlayCapabilitiesReceived. Testing +// is asynchronous, until the reply arrives that configuration will be failed. +// +// There is a many:1 relationship between this class and +// DrmGpuPlatformSupportHost, each compositor will own one of these objects. +// Each request has a unique request ID, which is assigned from a shared +// sequence number so that replies can be routed to the correct object. +class DrmOverlayCandidatesHost : public OverlayCandidatesOzone, + public GpuPlatformSupportHost { + struct OverlayCompare { + bool operator()(const OverlayCheck_Params& l, const OverlayCheck_Params& r); + }; + + public: + DrmOverlayCandidatesHost(gfx::AcceleratedWidget widget, + DrmGpuPlatformSupportHost* platform_support); + ~DrmOverlayCandidatesHost() override; + + // OverlayCandidatesOzone: + void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) override; + + // GpuPlatformSupportHost: + void OnChannelEstablished( + int host_id, + scoped_refptr<base::SingleThreadTaskRunner> send_runner, + const base::Callback<void(IPC::Message*)>& sender) override; + void OnChannelDestroyed(int host_id) override; + bool OnMessageReceived(const IPC::Message& message) override; + + private: + void SendRequest(const OverlaySurfaceCandidateList& candidates, + const OverlayCheck_Params& check); + void OnOverlayResult(bool* handled, + gfx::AcceleratedWidget widget, + bool result); + void ProcessResult(const OverlayCheck_Params& check, bool result); + + void CheckSingleOverlay(OverlaySurfaceCandidateList* candidates); + + gfx::AcceleratedWidget widget_; + DrmGpuPlatformSupportHost* platform_support_; // Not owned. + + std::deque<OverlayCheck_Params> pending_checks_; + + template <class KeyType, class ValueType> + struct OverlayMap { + typedef std::map<KeyType, ValueType, OverlayCompare> Type; + }; + base::MRUCacheBase<OverlayCheck_Params, + bool, + base::MRUCacheNullDeletor<bool>, + OverlayMap> cache_; + + DISALLOW_COPY_AND_ASSIGN(DrmOverlayCandidatesHost); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRM_HOST_OVERLAY_CANDIDATES_H_ diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.cc b/ui/ozone/platform/drm/host/drm_overlay_manager.cc index 7143001..4f101cc 100644 --- a/ui/ozone/platform/drm/host/drm_overlay_manager.cc +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.cc @@ -6,59 +6,17 @@ #include "base/command_line.h" #include "ui/gfx/geometry/rect_conversions.h" +#include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h" #include "ui/ozone/public/overlay_candidates_ozone.h" #include "ui/ozone/public/ozone_switches.h" namespace ui { -namespace { -class SingleOverlay : public OverlayCandidatesOzone { - public: - SingleOverlay() {} - ~SingleOverlay() override {} - - void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) override { - if (candidates->size() == 2) { - OverlayCandidatesOzone::OverlaySurfaceCandidate* first = - &(*candidates)[0]; - OverlayCandidatesOzone::OverlaySurfaceCandidate* second = - &(*candidates)[1]; - OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay; - if (first->plane_z_order == 0) { - overlay = second; - } else if (second->plane_z_order == 0) { - overlay = first; - } else { - NOTREACHED(); - return; - } - // 0.01 constant chosen to match DCHECKs in gfx::ToNearestRect and avoid - // that code asserting on quads that we accept. - if (overlay->plane_z_order > 0 && - IsTransformSupported(overlay->transform) && - gfx::IsNearestRectWithinDistance(overlay->display_rect, 0.01f)) { - overlay->overlay_handled = true; - } - } - } - - private: - bool IsTransformSupported(gfx::OverlayTransform transform) { - switch (transform) { - case gfx::OVERLAY_TRANSFORM_NONE: - return true; - default: - return false; - } - } - - DISALLOW_COPY_AND_ASSIGN(SingleOverlay); -}; - -} // namespace - -DrmOverlayManager::DrmOverlayManager(bool allow_surfaceless) - : allow_surfaceless_(allow_surfaceless) { +DrmOverlayManager::DrmOverlayManager( + bool allow_surfaceless, + DrmGpuPlatformSupportHost* platform_support_host) + : platform_support_host_(platform_support_host), + allow_surfaceless_(allow_surfaceless) { is_supported_ = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kOzoneTestSingleOverlaySupport); } @@ -70,7 +28,8 @@ scoped_ptr<OverlayCandidatesOzone> DrmOverlayManager::CreateOverlayCandidates( gfx::AcceleratedWidget w) { if (!is_supported_) return nullptr; - return make_scoped_ptr(new SingleOverlay()); + return make_scoped_ptr( + new DrmOverlayCandidatesHost(w, platform_support_host_)); } bool DrmOverlayManager::CanShowPrimaryPlaneAsOverlay() { diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.h b/ui/ozone/platform/drm/host/drm_overlay_manager.h index 91bdd51..fcaf621 100644 --- a/ui/ozone/platform/drm/host/drm_overlay_manager.h +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.h @@ -5,14 +5,16 @@ #ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_H_ #define UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_H_ -#include "base/memory/scoped_ptr.h" #include "ui/ozone/public/overlay_manager_ozone.h" namespace ui { +class DrmGpuPlatformSupportHost; + class DrmOverlayManager : public OverlayManagerOzone { public: - DrmOverlayManager(bool allow_surfaceless); + DrmOverlayManager(bool allow_surfaceless, + DrmGpuPlatformSupportHost* platform_support_host); ~DrmOverlayManager() override; // OverlayManagerOzone: @@ -21,6 +23,7 @@ class DrmOverlayManager : public OverlayManagerOzone { bool CanShowPrimaryPlaneAsOverlay() override; private: + DrmGpuPlatformSupportHost* platform_support_host_; bool allow_surfaceless_; bool is_supported_; diff --git a/ui/ozone/platform/drm/ozone_platform_drm.cc b/ui/ozone/platform/drm/ozone_platform_drm.cc index c0a6ce7..3c4a623 100644 --- a/ui/ozone/platform/drm/ozone_platform_drm.cc +++ b/ui/ozone/platform/drm/ozone_platform_drm.cc @@ -95,13 +95,13 @@ class OzonePlatformDrm : public OzonePlatform { scoped_ptr<DrmDeviceGenerator>(new DrmDeviceGenerator()))); window_manager_.reset(new DrmWindowHostManager()); cursor_.reset(new DrmCursor(window_manager_.get())); - overlay_manager_.reset(new DrmOverlayManager(false)); + overlay_manager_.reset(new DrmOverlayManager(false, nullptr)); surface_factory_ozone_.reset(new DrmSurfaceFactory(screen_manager_.get())); scoped_ptr<DrmGpuDisplayManager> display_manager(new DrmGpuDisplayManager( screen_manager_.get(), drm_device_manager_.get())); gpu_platform_support_.reset(new DrmGpuPlatformSupport( drm_device_manager_.get(), screen_manager_.get(), - display_manager.Pass())); + buffer_generator_.get(), display_manager.Pass())); gpu_platform_support_host_.reset( new DrmGpuPlatformSupportHost(cursor_.get())); display_manager_.reset(new DrmDisplayHostManager( diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index d7b85a3..d70490e 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc @@ -158,7 +158,8 @@ class OzonePlatformGbm : public OzonePlatform { display_manager_.reset(new DrmDisplayHostManager( gpu_platform_support_host_.get(), device_manager_.get())); cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone); - overlay_manager_.reset(new DrmOverlayManager(use_surfaceless_)); + overlay_manager_.reset(new DrmOverlayManager( + use_surfaceless_, gpu_platform_support_host_.get())); #if defined(USE_XKBCOMMON) KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(make_scoped_ptr( new XkbKeyboardLayoutEngine(xkb_evdev_code_converter_))); @@ -185,7 +186,7 @@ class OzonePlatformGbm : public OzonePlatform { screen_manager_.get(), drm_device_manager_.get())); gpu_platform_support_.reset(new DrmGpuPlatformSupport( drm_device_manager_.get(), screen_manager_.get(), - display_manager.Pass())); + buffer_generator_.get(), display_manager.Pass())); } private: diff --git a/ui/ozone/public/overlay_candidates_ozone.h b/ui/ozone/public/overlay_candidates_ozone.h index c573330..2ae0d12 100644 --- a/ui/ozone/public/overlay_candidates_ozone.h +++ b/ui/ozone/public/overlay_candidates_ozone.h @@ -27,6 +27,8 @@ class OZONE_BASE_EXPORT OverlayCandidatesOzone { gfx::OverlayTransform transform; // Format of the buffer to composite. SurfaceFactoryOzone::BufferFormat format; + // Size of the buffer, in pixels. + gfx::Size buffer_size; // Rect on the display to position the overlay to. Input rectangle may // not have integer coordinates, but when accepting for overlay, must // be modified by CheckOverlaySupport to output integer values. diff --git a/ui/ozone/public/surface_factory_ozone.h b/ui/ozone/public/surface_factory_ozone.h index 678976b..f5ddc59 100644 --- a/ui/ozone/public/surface_factory_ozone.h +++ b/ui/ozone/public/surface_factory_ozone.h @@ -60,6 +60,7 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone { BGRA_8888, RGBX_8888, RGB_888, + BUFFER_FORMAT_LAST = RGB_888 }; enum BufferUsage { |