summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorachaulk <achaulk@chromium.org>2015-06-05 09:57:30 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-05 16:57:52 +0000
commitad89643990d9b2320960d1912695cc1418a3fdab (patch)
treeae3b7e0d61d6c4c344ab16953558a40054671efc /ui
parentd21062b6325cd91effe187dd7a9aa87be3f599bc (diff)
downloadchromium_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')
-rw-r--r--ui/gfx/overlay_transform.h1
-rw-r--r--ui/ozone/common/gpu/ozone_gpu_message_params.cc21
-rw-r--r--ui/ozone/common/gpu/ozone_gpu_message_params.h16
-rw-r--r--ui/ozone/common/gpu/ozone_gpu_messages.h23
-rw-r--r--ui/ozone/platform/drm/BUILD.gn2
-rw-r--r--ui/ozone/platform/drm/drm.gypi2
-rw-r--r--ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc13
-rw-r--r--ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h7
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window.cc35
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window.h4
-rw-r--r--ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc141
-rw-r--r--ui/ozone/platform/drm/host/drm_overlay_candidates_host.h85
-rw-r--r--ui/ozone/platform/drm/host/drm_overlay_manager.cc57
-rw-r--r--ui/ozone/platform/drm/host/drm_overlay_manager.h7
-rw-r--r--ui/ozone/platform/drm/ozone_platform_drm.cc4
-rw-r--r--ui/ozone/platform/drm/ozone_platform_gbm.cc5
-rw-r--r--ui/ozone/public/overlay_candidates_ozone.h2
-rw-r--r--ui/ozone/public/surface_factory_ozone.h1
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 {