diff options
Diffstat (limited to 'chromium/ui/ozone')
80 files changed, 1289 insertions, 1044 deletions
diff --git a/chromium/ui/ozone/common/BUILD.gn b/chromium/ui/ozone/common/BUILD.gn index f079f53ef07..cc1ee3f2e29 100644 --- a/chromium/ui/ozone/common/BUILD.gn +++ b/chromium/ui/ozone/common/BUILD.gn @@ -8,8 +8,6 @@ assert(use_ozone) source_set("common") { sources = [ - "display_snapshot_proxy.cc", - "display_snapshot_proxy.h", "egl_util.cc", "egl_util.h", "gl_ozone_egl.cc", diff --git a/chromium/ui/ozone/common/display_snapshot_proxy.cc b/chromium/ui/ozone/common/display_snapshot_proxy.cc deleted file mode 100644 index 88ef6cc377f..00000000000 --- a/chromium/ui/ozone/common/display_snapshot_proxy.cc +++ /dev/null @@ -1,61 +0,0 @@ -// 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 "ui/ozone/common/display_snapshot_proxy.h" - -#include <stddef.h> - -#include "base/memory/ptr_util.h" -#include "ui/display/types/display_mode.h" -#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" - -namespace ui { - -namespace { - -bool SameModes(const DisplayMode_Params& lhs, const DisplayMode_Params& rhs) { - return lhs.size == rhs.size && lhs.is_interlaced == rhs.is_interlaced && - lhs.refresh_rate == rhs.refresh_rate; -} - -} // namespace - -DisplaySnapshotProxy::DisplaySnapshotProxy(const DisplaySnapshot_Params& params) - : DisplaySnapshotMojo( - params.display_id, - params.origin, - params.physical_size, - params.type, - params.is_aspect_preserving_scaling, - params.has_overscan, - params.has_color_correction_matrix, - params.display_name, - params.sys_path, - std::vector<std::unique_ptr<const display::DisplayMode>>(), - params.edid, - nullptr, - nullptr, - params.string_representation) { - for (size_t i = 0; i < params.modes.size(); ++i) { - modes_.push_back(base::MakeUnique<display::DisplayMode>( - params.modes[i].size, params.modes[i].is_interlaced, - params.modes[i].refresh_rate)); - - if (params.has_current_mode && - SameModes(params.modes[i], params.current_mode)) - current_mode_ = modes_.back().get(); - - if (params.has_native_mode && - SameModes(params.modes[i], params.native_mode)) - native_mode_ = modes_.back().get(); - } - - product_id_ = params.product_id; - maximum_cursor_size_ = params.maximum_cursor_size; -} - -DisplaySnapshotProxy::~DisplaySnapshotProxy() { -} - -} // namespace ui diff --git a/chromium/ui/ozone/common/display_snapshot_proxy.h b/chromium/ui/ozone/common/display_snapshot_proxy.h deleted file mode 100644 index a53e2121f67..00000000000 --- a/chromium/ui/ozone/common/display_snapshot_proxy.h +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -#ifndef UI_OZONE_COMMON_DISPLAY_SNAPSHOT_PROXY_H_ -#define UI_OZONE_COMMON_DISPLAY_SNAPSHOT_PROXY_H_ - -#include "base/macros.h" -#include "ui/display/types/display_snapshot_mojo.h" - -namespace ui { - -struct DisplaySnapshot_Params; - -class DisplaySnapshotProxy : public display::DisplaySnapshotMojo { - public: - DisplaySnapshotProxy(const DisplaySnapshot_Params& params); - ~DisplaySnapshotProxy() override; - - private: - DISALLOW_COPY_AND_ASSIGN(DisplaySnapshotProxy); -}; - -} // namespace ui - -#endif // UI_OZONE_COMMON_DISPLAY_SNAPSHOT_PROXY_H_ diff --git a/chromium/ui/ozone/common/gl_ozone_osmesa.cc b/chromium/ui/ozone/common/gl_ozone_osmesa.cc index 2ee4dbba2d6..e7ccc733f59 100644 --- a/chromium/ui/ozone/common/gl_ozone_osmesa.cc +++ b/chromium/ui/ozone/common/gl_ozone_osmesa.cc @@ -4,6 +4,7 @@ #include "ui/ozone/common/gl_ozone_osmesa.h" +#include "build/build_config.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_context_osmesa.h" @@ -27,7 +28,14 @@ bool GLOzoneOSMesa::InitializeGLOneOffPlatform() { bool GLOzoneOSMesa::InitializeStaticGLBindings( gl::GLImplementation implementation) { +#if defined(OS_FUCHSIA) + // TODO(fuchsia): Enable this once there's EGL available, see + // https://crbug.com/750943. + NOTIMPLEMENTED(); + return false; +#else return gl::InitializeStaticGLBindingsOSMesaGL(); +#endif } void GLOzoneOSMesa::InitializeDebugGLBindings() { diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc index 29692cacea4..79ddb77c77c 100644 --- a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc @@ -31,23 +31,12 @@ OverlayCheck_Params::OverlayCheck_Params( format(candidate.format), display_rect(gfx::ToNearestRect(candidate.display_rect)), crop_rect(candidate.crop_rect), - plane_z_order(candidate.plane_z_order) {} + plane_z_order(candidate.plane_z_order), + is_overlay_candidate(candidate.overlay_handled) {} OverlayCheck_Params::OverlayCheck_Params(const OverlayCheck_Params& other) = default; OverlayCheck_Params::~OverlayCheck_Params() {} -bool OverlayCheck_Params::operator<(const OverlayCheck_Params& param) const { - int lwidth = buffer_size.width(); - int lheight = buffer_size.height(); - int rwidth = param.buffer_size.width(); - int rheight = param.buffer_size.height(); - - return std::tie(plane_z_order, format, display_rect, lwidth, lheight, - transform) < std::tie(param.plane_z_order, param.format, - param.display_rect, rwidth, rheight, - param.transform); -} - } // namespace ui diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h index 67d138ee680..204051857d5 100644 --- a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h @@ -52,7 +52,6 @@ struct DisplaySnapshot_Params { bool has_native_mode = false; DisplayMode_Params native_mode; int64_t product_id = 0; - std::string string_representation; gfx::Size maximum_cursor_size; }; @@ -62,7 +61,6 @@ struct OverlayCheck_Params { OverlayCheck_Params(const OverlayCheck_Params& other); ~OverlayCheck_Params(); - bool operator<(const OverlayCheck_Params& plane) const; gfx::Size buffer_size; gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE; diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h b/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h index c20cc0813a5..b97616c4e65 100644 --- a/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h @@ -60,7 +60,6 @@ IPC_STRUCT_TRAITS_BEGIN(ui::DisplaySnapshot_Params) IPC_STRUCT_TRAITS_MEMBER(has_native_mode) IPC_STRUCT_TRAITS_MEMBER(native_mode) IPC_STRUCT_TRAITS_MEMBER(product_id) - IPC_STRUCT_TRAITS_MEMBER(string_representation) IPC_STRUCT_TRAITS_MEMBER(maximum_cursor_size) IPC_STRUCT_TRAITS_END() diff --git a/chromium/ui/ozone/demo/gl_renderer.cc b/chromium/ui/ozone/demo/gl_renderer.cc index 970a299bb50..53f5e96b9f9 100644 --- a/chromium/ui/ozone/demo/gl_renderer.cc +++ b/chromium/ui/ozone/demo/gl_renderer.cc @@ -30,7 +30,7 @@ bool GlRenderer::Initialize() { return false; } - surface_->Resize(size_, 1.f, true); + surface_->Resize(size_, 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true); if (!context_->MakeCurrent(surface_.get())) { LOG(ERROR) << "Failed to make GL context current"; diff --git a/chromium/ui/ozone/demo/ozone_demo.cc b/chromium/ui/ozone/demo/ozone_demo.cc index bf9aa69977e..d5879e685d0 100644 --- a/chromium/ui/ozone/demo/ozone_demo.cc +++ b/chromium/ui/ozone/demo/ozone_demo.cc @@ -80,7 +80,7 @@ class RendererFactory { class WindowManager : public display::NativeDisplayObserver { public: - WindowManager(const base::Closure& quit_closure); + explicit WindowManager(const base::Closure& quit_closure); ~WindowManager() override; void Quit(); @@ -285,7 +285,6 @@ void WindowManager::OnConfigurationChanged() { } is_configuring_ = true; - delegate_->GrabServer(); delegate_->GetDisplays( base::Bind(&WindowManager::OnDisplaysAquired, base::Unretained(this))); } @@ -310,7 +309,6 @@ void WindowManager::OnDisplaysAquired( gfx::Rect(origin, display->native_mode()->size()))); origin.Offset(display->native_mode()->size().width(), 0); } - delegate_->UngrabServer(); is_configuring_ = false; if (should_configure_) { diff --git a/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc b/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc index f68bd5ddd70..2708ffc6085 100644 --- a/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc +++ b/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc @@ -24,6 +24,36 @@ namespace ui { +namespace { + +OverlaySurfaceCandidate MakeOverlayCandidate(int z_order, + gfx::Rect bounds_rect, + gfx::RectF crop_rect) { + // The overlay checking interface is designed to satisfy the needs of CC which + // will be producing RectF target rectangles. But we use the bounds produced + // in RenderFrame for GLSurface::ScheduleOverlayPlane. + gfx::RectF display_rect(bounds_rect.x(), bounds_rect.y(), bounds_rect.width(), + bounds_rect.height()); + + OverlaySurfaceCandidate overlay_candidate; + + // The bounds rectangle of the candidate overlay buffer. + overlay_candidate.buffer_size = bounds_rect.size(); + // The same rectangle in floating point coordinates. + overlay_candidate.display_rect = display_rect; + + // Show the entire buffer by setting the crop to a unity square. + overlay_candidate.crop_rect = gfx::RectF(0, 0, 1, 1); + + // The demo overlay instance is always ontop and not clipped. Clipped quads + // cannot be placed in overlays. + overlay_candidate.is_clipped = false; + + return overlay_candidate; +} + +} // namespace + SurfacelessGlRenderer::BufferWrapper::BufferWrapper() { } @@ -107,66 +137,58 @@ bool SurfacelessGlRenderer::Initialize() { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch("enable-overlay")) { gfx::Size overlay_size = gfx::Size(size_.width() / 8, size_.height() / 8); - overlay_buffer_.reset(new BufferWrapper()); - overlay_buffer_->Initialize(gfx::kNullAcceleratedWidget, overlay_size); - - glViewport(0, 0, overlay_size.width(), overlay_size.height()); - glClearColor(1.0, 1.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + for (size_t i = 0; i < arraysize(overlay_buffer_); ++i) { + overlay_buffer_[i].reset(new BufferWrapper()); + overlay_buffer_[i]->Initialize(gfx::kNullAcceleratedWidget, overlay_size); + + glViewport(0, 0, overlay_size.width(), overlay_size.height()); + glClearColor(i, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } } + disable_primary_plane_ = command_line->HasSwitch("disable-primary-plane"); PostRenderFrameTask(gfx::SwapResult::SWAP_ACK); return true; } -// OverlayChecker demonstrates how to use the -// OverlayCandidatesOzone::CheckOverlaySupport to determine if a given overlay -// can be successfully displayed. -void SurfacelessGlRenderer::OverlayChecker(int z_order, - gfx::Rect bounds_rect, - gfx::RectF crop_rect) { - // The overlay checking interface is designed to satisfy the needs of CC which - // will be producing RectF target rectangles. But we use the bounds produced - // in RenderFrame for GLSurface::ScheduleOverlayPlane. - gfx::RectF display_rect(bounds_rect.x(), bounds_rect.y(), bounds_rect.width(), - bounds_rect.height()); - - OverlaySurfaceCandidate overlay_candidate; - - // The bounds rectangle of the candidate overlay buffer. - overlay_candidate.buffer_size = bounds_rect.size(); - // The same rectangle in floating point coordinates. - overlay_candidate.display_rect = display_rect; - - // Show the entire buffer by setting the crop to a unity square. - overlay_candidate.crop_rect = gfx::RectF(0, 0, 1, 1); - - // The clip region is the entire screen. - overlay_candidate.clip_rect = gfx::Rect(size_); - - // The demo overlay instance is always ontop and not clipped. Clipped quads - // cannot be placed in overlays. - overlay_candidate.is_clipped = false; - - OverlayCandidatesOzone::OverlaySurfaceCandidateList list; - list.push_back(overlay_candidate); - - // Ask ozone platform to determine if this rect can be placed in an overlay. - // Ozone will update the list and return it. - overlay_checker_->CheckOverlaySupport(&list); - - // Note what the checker decided. - // say more about it. - TRACE_EVENT2("hwoverlays", "SurfacelessGlRenderer::OverlayChecker", "canihaz", - list[0].overlay_handled, "display_rect", - list[0].display_rect.ToString()); -} - void SurfacelessGlRenderer::RenderFrame() { TRACE_EVENT0("ozone", "SurfacelessGlRenderer::RenderFrame"); float fraction = NextFraction(); + gfx::Rect overlay_rect; + + OverlayCandidatesOzone::OverlaySurfaceCandidateList overlay_list; + if (!disable_primary_plane_) { + overlay_list.push_back( + MakeOverlayCandidate(1, gfx::Rect(size_), gfx::RectF(0, 0, 1, 1))); + // We know at least the primary plane can be scanned out. + overlay_list.back().overlay_handled = true; + } + if (overlay_buffer_[0]) { + overlay_rect = gfx::Rect(overlay_buffer_[0]->size()); + + float steps_num = 5.0f; + float stepped_fraction = + std::floor((fraction + 0.5f / steps_num) * steps_num) / steps_num; + gfx::Vector2d offset( + stepped_fraction * (size_.width() - overlay_rect.width()), + (size_.height() - overlay_rect.height()) / 2); + overlay_rect += offset; + overlay_list.push_back( + MakeOverlayCandidate(1, overlay_rect, gfx::RectF(0, 0, 1, 1))); + } + + // The actual validation for a specific overlay configuration is done + // asynchronously and then cached inside overlay_checker_ once a reply + // is sent back. + // This means that the first few frames we call this method for a specific + // overlay_list, all the overlays but the primary plane, that we explicitly + // marked as handled, will be rejected even if they might be handled at a + // later time. + overlay_checker_->CheckOverlaySupport(&overlay_list); + context_->MakeCurrent(surface_.get()); buffers_[back_buffer_]->BindFramebuffer(); @@ -174,23 +196,17 @@ void SurfacelessGlRenderer::RenderFrame() { glClearColor(1 - fraction, 0.0, fraction, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - surface_->ScheduleOverlayPlane(0, gfx::OVERLAY_TRANSFORM_NONE, - buffers_[back_buffer_]->image(), - gfx::Rect(size_), gfx::RectF(0, 0, 1, 1)); - - if (overlay_buffer_) { - gfx::Rect overlay_rect(overlay_buffer_->size()); - gfx::Vector2d offset(fraction * (size_.width() - overlay_rect.width()), - (size_.height() - overlay_rect.height()) / 2); - overlay_rect += offset; - - // TODO(rjkroege): Overlay checking should gate the following and will - // be added after solving http://crbug.com/735640 - OverlayChecker(1, overlay_rect, gfx::RectF(0, 0, 1, 1)); + if (!disable_primary_plane_) { + CHECK(overlay_list.front().overlay_handled); + surface_->ScheduleOverlayPlane(0, gfx::OVERLAY_TRANSFORM_NONE, + buffers_[back_buffer_]->image(), + gfx::Rect(size_), gfx::RectF(0, 0, 1, 1)); + } + if (overlay_buffer_[0] && overlay_list.back().overlay_handled) { surface_->ScheduleOverlayPlane(1, gfx::OVERLAY_TRANSFORM_NONE, - overlay_buffer_->image(), overlay_rect, - gfx::RectF(0, 0, 1, 1)); + overlay_buffer_[back_buffer_]->image(), + overlay_rect, gfx::RectF(0, 0, 1, 1)); } back_buffer_ ^= 1; diff --git a/chromium/ui/ozone/demo/surfaceless_gl_renderer.h b/chromium/ui/ozone/demo/surfaceless_gl_renderer.h index 5467435c7f3..20e75cdee5b 100644 --- a/chromium/ui/ozone/demo/surfaceless_gl_renderer.h +++ b/chromium/ui/ozone/demo/surfaceless_gl_renderer.h @@ -32,7 +32,6 @@ class SurfacelessGlRenderer : public GlRenderer { // GlRenderer: void RenderFrame() override; void PostRenderFrameTask(gfx::SwapResult result) override; - void OverlayChecker(int z_order, gfx::Rect bounds_rect, gfx::RectF crop_rect); class BufferWrapper { public: @@ -57,7 +56,8 @@ class SurfacelessGlRenderer : public GlRenderer { std::unique_ptr<BufferWrapper> buffers_[2]; - std::unique_ptr<BufferWrapper> overlay_buffer_; + std::unique_ptr<BufferWrapper> overlay_buffer_[2]; + bool disable_primary_plane_ = false; std::unique_ptr<OverlayCandidatesOzone> overlay_checker_; diff --git a/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc index 525ba66bb94..3b3eb346de5 100644 --- a/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc +++ b/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc @@ -40,7 +40,8 @@ class GLImageNativePixmapTestDelegate { surface_factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size, format, usage); DCHECK(pixmap); - if (usage == gfx::BufferUsage::GPU_READ_CPU_READ_WRITE) { + if (usage == gfx::BufferUsage::GPU_READ_CPU_READ_WRITE || + usage == gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE) { auto client_pixmap = client_pixmap_factory_->ImportFromHandle( pixmap->ExportHandle(), size, usage); bool mapped = client_pixmap->Map(); @@ -67,7 +68,8 @@ class GLImageNativePixmapTestDelegate { const uint8_t* GetImageColor() { if (format == gfx::BufferFormat::R_8) { return kRed; - } else if (format == gfx::BufferFormat::YVU_420) { + } else if (format == gfx::BufferFormat::YVU_420 || + format == gfx::BufferFormat::YUV_420_BIPLANAR) { return kYvuColor; } return kGreen; @@ -87,7 +89,9 @@ INSTANTIATE_TYPED_TEST_CASE_P(GLImageNativePixmapScanout, using GLImageReadWriteType = testing::Types< GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferFormat::R_8>>; + gfx::BufferFormat::R_8>, + GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, + gfx::BufferFormat::YUV_420_BIPLANAR>>; using GLImageBindTestTypes = testing::Types< GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, @@ -97,6 +101,8 @@ using GLImageBindTestTypes = testing::Types< GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::BufferFormat::YVU_420>, GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, + gfx::BufferFormat::YUV_420_BIPLANAR>, + GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, gfx::BufferFormat::YUV_420_BIPLANAR>>; // These tests are disabled since the trybots are running with Ozone X11 diff --git a/chromium/ui/ozone/platform/cast/DEPS b/chromium/ui/ozone/platform/cast/DEPS index a967e61a1a2..ffc9eafa338 100644 --- a/chromium/ui/ozone/platform/cast/DEPS +++ b/chromium/ui/ozone/platform/cast/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+chromecast/base/cast_features.h", "+chromecast/base/chromecast_switches.h", "+chromecast/chromecast_features.h", "+chromecast/public" diff --git a/chromium/ui/ozone/platform/cast/gl_surface_cast.cc b/chromium/ui/ozone/platform/cast/gl_surface_cast.cc index 04d7d64c2d1..28822a35841 100644 --- a/chromium/ui/ozone/platform/cast/gl_surface_cast.cc +++ b/chromium/ui/ozone/platform/cast/gl_surface_cast.cc @@ -4,16 +4,25 @@ #include "ui/ozone/platform/cast/gl_surface_cast.h" +#include "base/feature_list.h" #include "base/memory/ptr_util.h" +#include "chromecast/base/cast_features.h" #include "ui/gfx/vsync_provider.h" #include "ui/ozone/common/egl_util.h" #include "ui/ozone/platform/cast/gl_ozone_egl_cast.h" namespace { -// Target fixed 30fps. +// Target fixed 30fps, or 60fps if doing triple-buffer 720p. // TODO(halliwell): We might need to customize this value on various devices // or make it dynamic that throttles framerate if device is overheating. -const base::TimeDelta kVSyncInterval = base::TimeDelta::FromSeconds(2) / 59.9; +base::TimeDelta GetVSyncInterval() { + if (base::FeatureList::IsEnabled(chromecast::kTripleBuffer720)) { + return base::TimeDelta::FromSeconds(1) / 59.9; + } else { + return base::TimeDelta::FromSeconds(2) / 59.9; + } +} + } // namespace namespace ui { @@ -23,7 +32,7 @@ GLSurfaceCast::GLSurfaceCast(gfx::AcceleratedWidget widget, : NativeViewGLSurfaceEGL( parent->GetNativeWindow(), base::MakeUnique<gfx::FixedVSyncProvider>(base::TimeTicks(), - kVSyncInterval)), + GetVSyncInterval())), widget_(widget), parent_(parent), supports_swap_buffer_with_bounds_( @@ -66,9 +75,11 @@ gfx::SwapResult GLSurfaceCast::SwapBuffersWithBounds( bool GLSurfaceCast::Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) { return parent_->ResizeDisplay(size) && - NativeViewGLSurfaceEGL::Resize(size, scale_factor, has_alpha); + NativeViewGLSurfaceEGL::Resize(size, scale_factor, color_space, + has_alpha); } bool GLSurfaceCast::ScheduleOverlayPlane(int z_order, diff --git a/chromium/ui/ozone/platform/cast/gl_surface_cast.h b/chromium/ui/ozone/platform/cast/gl_surface_cast.h index 2fb3fe98fcb..e93119af556 100644 --- a/chromium/ui/ozone/platform/cast/gl_surface_cast.h +++ b/chromium/ui/ozone/platform/cast/gl_surface_cast.h @@ -28,6 +28,7 @@ class GLSurfaceCast : public gl::NativeViewGLSurfaceEGL { const std::vector<gfx::Rect>& rects) override; bool Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) override; bool ScheduleOverlayPlane(int z_order, gfx::OverlayTransform transform, diff --git a/chromium/ui/ozone/platform/cast/surface_factory_cast.cc b/chromium/ui/ozone/platform/cast/surface_factory_cast.cc index 6cc1392991a..522a837c062 100644 --- a/chromium/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/chromium/ui/ozone/platform/cast/surface_factory_cast.cc @@ -29,8 +29,8 @@ class DummySurface : public SurfaceOzoneCanvas { sk_sp<SkSurface> GetSurface() override { return surface_; } void ResizeCanvas(const gfx::Size& viewport_size) override { - surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul( - viewport_size.width(), viewport_size.height())); + surface_ = + SkSurface::MakeNull(viewport_size.width(), viewport_size.height()); } void PresentCanvas(const gfx::Rect& damage) override {} diff --git a/chromium/ui/ozone/platform/drm/BUILD.gn b/chromium/ui/ozone/platform/drm/BUILD.gn index 05f649dac31..732e2d52f39 100644 --- a/chromium/ui/ozone/platform/drm/BUILD.gn +++ b/chromium/ui/ozone/platform/drm/BUILD.gn @@ -16,8 +16,6 @@ source_set("gbm") { "common/drm_util.h", "common/scoped_drm_types.cc", "common/scoped_drm_types.h", - "cursor_proxy_mojo.cc", - "cursor_proxy_mojo.h", "gpu/crtc_controller.cc", "gpu/crtc_controller.h", "gpu/drm_buffer.cc", @@ -103,8 +101,10 @@ source_set("gbm") { "host/drm_window_host_manager.h", "host/gpu_thread_adapter.h", "host/gpu_thread_observer.h", - "mus_thread_proxy.cc", - "mus_thread_proxy.h", + "host/host_cursor_proxy.cc", + "host/host_cursor_proxy.h", + "host/host_drm_device.cc", + "host/host_drm_device.h", "ozone_platform_gbm.cc", "ozone_platform_gbm.h", ] diff --git a/chromium/ui/ozone/platform/drm/OWNERS b/chromium/ui/ozone/platform/drm/OWNERS index 0d77c0eae94..363a93a5f95 100644 --- a/chromium/ui/ozone/platform/drm/OWNERS +++ b/chromium/ui/ozone/platform/drm/OWNERS @@ -1 +1,2 @@ +dcastagna@chromium.org dnicoara@chromium.org diff --git a/chromium/ui/ozone/platform/drm/common/display_types.h b/chromium/ui/ozone/platform/drm/common/display_types.h index 5d0b1acf653..da8b5c07533 100644 --- a/chromium/ui/ozone/platform/drm/common/display_types.h +++ b/chromium/ui/ozone/platform/drm/common/display_types.h @@ -6,13 +6,13 @@ #define UI_OZONE_PLATFORM_DRM_COMMON_DISPLAY_TYPES_H_ namespace display { -class DisplaySnapshotMojo; +class DisplaySnapshot; } // namespace display namespace ui { using MovableDisplaySnapshots = - std::vector<std::unique_ptr<display::DisplaySnapshotMojo>>; + std::vector<std::unique_ptr<display::DisplaySnapshot>>; } // namespace ui diff --git a/chromium/ui/ozone/platform/drm/common/drm_util.cc b/chromium/ui/ozone/platform/drm/common/drm_util.cc index 97130378d93..b452b33122b 100644 --- a/chromium/ui/ozone/platform/drm/common/drm_util.cc +++ b/chromium/ui/ozone/platform/drm/common/drm_util.cc @@ -16,9 +16,8 @@ #include "base/containers/flat_map.h" #include "base/memory/ptr_util.h" #include "ui/display/types/display_mode.h" -#include "ui/display/types/display_snapshot_mojo.h" +#include "ui/display/types/display_snapshot.h" #include "ui/display/util/edid_parser.h" -#include "ui/ozone/common/display_snapshot_proxy.h" #if !defined(DRM_FORMAT_R16) // TODO(riju): crbug.com/733703 @@ -204,6 +203,12 @@ bool HasColorCorrectionMatrix(int fd, drmModeCrtc* crtc) { return false; } +bool DisplayModeEquals(const DisplayMode_Params& lhs, + const DisplayMode_Params& rhs) { + return lhs.size == rhs.size && lhs.is_interlaced == rhs.is_interlaced && + lhs.refresh_rate == rhs.refresh_rate; +} + } // namespace DisplayMode_Params GetDisplayModeParams(const display::DisplayMode& mode) { @@ -427,7 +432,6 @@ std::vector<DisplaySnapshot_Params> CreateParamsFromSnapshot( } p.product_id = d->product_id(); - p.string_representation = d->ToString(); p.maximum_cursor_size = d->maximum_cursor_size(); params.push_back(p); @@ -435,6 +439,29 @@ std::vector<DisplaySnapshot_Params> CreateParamsFromSnapshot( return params; } +std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshotFromParams( + const DisplaySnapshot_Params& params) { + display::DisplaySnapshot::DisplayModeList modes; + const display::DisplayMode* current_mode = nullptr; + const display::DisplayMode* native_mode = nullptr; + + // Find pointers to current and native mode in the copied data. + for (auto& mode : params.modes) { + modes.push_back(CreateDisplayModeFromParams(mode)); + if (params.has_current_mode && DisplayModeEquals(mode, params.current_mode)) + current_mode = modes.back().get(); + if (params.has_native_mode && DisplayModeEquals(mode, params.native_mode)) + native_mode = modes.back().get(); + } + + return std::make_unique<display::DisplaySnapshot>( + params.display_id, params.origin, params.physical_size, params.type, + params.is_aspect_preserving_scaling, params.has_overscan, + params.has_color_correction_matrix, params.display_name, params.sys_path, + std::move(modes), params.edid, current_mode, native_mode, + params.product_id, params.maximum_cursor_size); +} + int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format) { switch (format) { case gfx::BufferFormat::R_8: @@ -522,8 +549,57 @@ MovableDisplaySnapshots CreateMovableDisplaySnapshotsFromParams( const std::vector<DisplaySnapshot_Params>& displays) { MovableDisplaySnapshots snapshots; for (const auto& d : displays) - snapshots.push_back(base::MakeUnique<DisplaySnapshotProxy>(d)); + snapshots.push_back(CreateDisplaySnapshotFromParams(d)); return snapshots; } +OverlaySurfaceCandidateList CreateOverlaySurfaceCandidateListFrom( + const std::vector<OverlayCheck_Params>& params) { + OverlaySurfaceCandidateList candidates; + for (auto& p : params) { + OverlaySurfaceCandidate osc; + osc.transform = p.transform; + osc.buffer_size = p.buffer_size; + osc.format = p.format; + osc.display_rect = gfx::RectF(p.display_rect); + osc.crop_rect = p.crop_rect; + osc.plane_z_order = p.plane_z_order; + osc.overlay_handled = p.is_overlay_candidate; + candidates.push_back(osc); + } + + return candidates; +} + +std::vector<OverlayCheck_Params> CreateParamsFromOverlaySurfaceCandidate( + const OverlaySurfaceCandidateList& candidates) { + std::vector<OverlayCheck_Params> overlay_params; + for (auto& candidate : candidates) { + overlay_params.push_back(OverlayCheck_Params(candidate)); + } + + return overlay_params; +} + +OverlayStatusList CreateOverlayStatusListFrom( + const std::vector<OverlayCheckReturn_Params>& params) { + OverlayStatusList returns; + for (auto& p : params) { + returns.push_back(p.status); + } + + return returns; +} + +std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList( + const OverlayStatusList& returns) { + std::vector<OverlayCheckReturn_Params> params; + for (auto& s : returns) { + OverlayCheckReturn_Params p; + p.status = s; + params.push_back(p); + } + return params; +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/drm/common/drm_util.h b/chromium/ui/ozone/platform/drm/common/drm_util.h index 9fdfb016244..593be0c7333 100644 --- a/chromium/ui/ozone/platform/drm/common/drm_util.h +++ b/chromium/ui/ozone/platform/drm/common/drm_util.h @@ -12,7 +12,6 @@ #include "base/files/file_path.h" #include "base/macros.h" -#include "ui/display/types/display_mode.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" #include "ui/ozone/platform/drm/common/display_types.h" #include "ui/ozone/platform/drm/common/scoped_drm_types.h" @@ -21,6 +20,7 @@ typedef struct _drmModeModeInfo drmModeModeInfo; namespace display { class DisplayMode; +class DisplaySnapshot; } // namespace display namespace gfx { @@ -72,6 +72,9 @@ DisplaySnapshot_Params CreateDisplaySnapshotParams( std::vector<DisplaySnapshot_Params> CreateParamsFromSnapshot( const MovableDisplaySnapshots& displays); +std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshotFromParams( + const DisplaySnapshot_Params& params); + int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format); gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format); @@ -96,6 +99,18 @@ bool ModeIsInterlaced(const drmModeModeInfo& mode); MovableDisplaySnapshots CreateMovableDisplaySnapshotsFromParams( const std::vector<DisplaySnapshot_Params>& displays); +OverlaySurfaceCandidateList CreateOverlaySurfaceCandidateListFrom( + const std::vector<OverlayCheck_Params>& params); + +std::vector<OverlayCheck_Params> CreateParamsFromOverlaySurfaceCandidate( + const OverlaySurfaceCandidateList& candidates); + +OverlayStatusList CreateOverlayStatusListFrom( + const std::vector<OverlayCheckReturn_Params>& params); + +std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList( + const OverlayStatusList& returns); + } // namespace ui #endif // UI_OZONE_PLATFORM_DRM_COMMON_DRM_UTIL_H_ diff --git a/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc b/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc index f8a4f5e1a04..88835c29d4e 100644 --- a/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc +++ b/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc @@ -4,8 +4,10 @@ #include "ui/ozone/platform/drm/common/drm_util.h" +#include <map> + #include "testing/gtest/include/gtest/gtest.h" -#include "ui/display/types/display_snapshot_mojo.h" +#include "ui/display/types/display_snapshot.h" #include "ui/gfx/geometry/size.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" @@ -31,7 +33,6 @@ bool operator==(const ui::DisplaySnapshot_Params& a, a.current_mode == b.current_mode && a.has_native_mode == b.has_native_mode && a.native_mode == b.native_mode && a.product_id == b.product_id && - a.string_representation == b.string_representation && a.maximum_cursor_size == b.maximum_cursor_size; } @@ -63,7 +64,6 @@ void DetailedCompare(const ui::DisplaySnapshot_Params& a, EXPECT_EQ(a.has_native_mode, b.has_native_mode); EXPECT_EQ(a.native_mode, b.native_mode); EXPECT_EQ(a.product_id, b.product_id); - EXPECT_EQ(a.string_representation, b.string_representation); EXPECT_EQ(a.maximum_cursor_size, b.maximum_cursor_size); } @@ -104,7 +104,6 @@ TEST_F(DrmUtilTest, RoundTripDisplaySnapshot) { fp.has_native_mode = true; fp.native_mode = MakeDisplay(1.1); fp.product_id = 7; - fp.string_representation = "bending glass display"; fp.maximum_cursor_size = gfx::Size(103, 44); sp.display_id = 1002; @@ -123,7 +122,6 @@ TEST_F(DrmUtilTest, RoundTripDisplaySnapshot) { sp.has_native_mode = true; sp.native_mode = MakeDisplay(500.2); sp.product_id = 8; - sp.string_representation = "rigid glass display"; sp.maximum_cursor_size = gfx::Size(500, 44); ep.display_id = 2002; @@ -142,7 +140,6 @@ TEST_F(DrmUtilTest, RoundTripDisplaySnapshot) { ep.current_mode = MakeDisplay(1000.2); ep.has_native_mode = false; ep.product_id = 9; - ep.string_representation = "fluted glass display"; ep.maximum_cursor_size = gfx::Size(1000, 44); orig_params.push_back(fp); @@ -162,4 +159,46 @@ TEST_F(DrmUtilTest, RoundTripDisplaySnapshot) { EXPECT_EQ(ep, roundtrip_params[2]); } +TEST_F(DrmUtilTest, OverlaySurfaceCandidate) { + OverlaySurfaceCandidateList input; + + OverlaySurfaceCandidate input_osc; + input_osc.transform = gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL; + input_osc.format = gfx::BufferFormat::YUV_420_BIPLANAR; + input_osc.buffer_size = gfx::Size(100, 50); + input_osc.display_rect = gfx::RectF(1., 2., 3., 4.); + input_osc.crop_rect = gfx::RectF(10., 20., 30., 40.); + input_osc.clip_rect = gfx::Rect(10, 20, 30, 40); + input_osc.is_clipped = true; + input_osc.plane_z_order = 42; + input_osc.overlay_handled = true; + + input.push_back(input_osc); + + // Roundtrip the conversions. + auto output = CreateOverlaySurfaceCandidateListFrom( + CreateParamsFromOverlaySurfaceCandidate(input)); + + EXPECT_EQ(input.size(), output.size()); + OverlaySurfaceCandidate output_osc = output[0]; + + EXPECT_EQ(input_osc.transform, output_osc.transform); + EXPECT_EQ(input_osc.format, output_osc.format); + EXPECT_EQ(input_osc.buffer_size, output_osc.buffer_size); + EXPECT_EQ(input_osc.display_rect, output_osc.display_rect); + EXPECT_EQ(input_osc.crop_rect, output_osc.crop_rect); + EXPECT_EQ(input_osc.plane_z_order, output_osc.plane_z_order); + EXPECT_EQ(input_osc.overlay_handled, output_osc.overlay_handled); + + EXPECT_FALSE(input < output); + EXPECT_FALSE(output < input); + + std::map<OverlaySurfaceCandidateList, int> map; + map[input] = 42; + const auto& iter = map.find(output); + + EXPECT_NE(map.end(), iter); + EXPECT_EQ(42, iter->second); +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc index 68d504aaecd..ae4f9b02266 100644 --- a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc +++ b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc @@ -81,20 +81,19 @@ bool CrtcController::SchedulePageFlip( DCHECK(!page_flip_request_.get() || test_only); DCHECK(!is_disabled_); const OverlayPlane* primary = OverlayPlane::GetPrimaryPlane(overlays); - if (!primary) { - LOG(ERROR) << "No primary plane to display on crtc " << crtc_; - page_flip_request->Signal(gfx::SwapResult::SWAP_ACK); - return true; - } - DCHECK(primary->buffer.get()); - - if (primary->buffer->GetSize() != gfx::Size(mode_.hdisplay, mode_.vdisplay)) { - VLOG(2) << "Trying to pageflip a buffer with the wrong size. Expected " - << mode_.hdisplay << "x" << mode_.vdisplay << " got " - << primary->buffer->GetSize().ToString() << " for" - << " crtc=" << crtc_ << " connector=" << connector_; - page_flip_request->Signal(gfx::SwapResult::SWAP_ACK); - return true; + if (primary) { + DCHECK(primary->buffer.get()); + // TODO(dcastagna): Get rid of this. Scaling on the primary plane is + // supported on all the devices. + if (primary->buffer->GetSize() != + gfx::Size(mode_.hdisplay, mode_.vdisplay)) { + VLOG(2) << "Trying to pageflip a buffer with the wrong size. Expected " + << mode_.hdisplay << "x" << mode_.vdisplay << " got " + << primary->buffer->GetSize().ToString() << " for" + << " crtc=" << crtc_ << " connector=" << connector_; + page_flip_request->Signal(gfx::SwapResult::SWAP_ACK); + return true; + } } if (!drm_->plane_manager()->AssignOverlayPlanes(plane_list, overlays, crtc_, @@ -125,12 +124,8 @@ std::vector<uint64_t> CrtcController::GetFormatModifiers(uint32_t format) { } void CrtcController::OnPageFlipEvent(unsigned int frame, - unsigned int seconds, - unsigned int useconds) { - time_of_last_flip_ = - static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + - useconds; - + base::TimeTicks timestamp) { + time_of_last_flip_ = timestamp; SignalPageFlipRequest(gfx::SwapResult::SWAP_ACK); } diff --git a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h index 1bdae0385b0..5222b63ee36 100644 --- a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h +++ b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h @@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/time/time.h" #include "ui/gfx/swap_result.h" #include "ui/ozone/platform/drm/common/scoped_drm_types.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h" @@ -39,7 +40,7 @@ class CrtcController : public base::SupportsWeakPtr<CrtcController> { uint32_t connector() const { return connector_; } const scoped_refptr<DrmDevice>& drm() const { return drm_; } bool is_disabled() const { return is_disabled_; } - uint64_t time_of_last_flip() const { return time_of_last_flip_; } + base::TimeTicks time_of_last_flip() const { return time_of_last_flip_; } // Perform the initial modesetting operation using |plane| as the buffer for // the primary plane. The CRTC configuration is specified by |mode|. @@ -76,12 +77,7 @@ class CrtcController : public base::SupportsWeakPtr<CrtcController> { // Called when the page flip event occurred. The event is provided by the // kernel when a VBlank event finished. This allows the controller to // update internal state and propagate the update to the surface. - // The tuple (seconds, useconds) represents the event timestamp. |seconds| - // represents the number of seconds while |useconds| represents the - // microseconds (< 1 second) in the timestamp. - void OnPageFlipEvent(unsigned int frame, - unsigned int seconds, - unsigned int useconds); + void OnPageFlipEvent(unsigned int frame, base::TimeTicks timestamp); bool SetCursor(const scoped_refptr<ScanoutBuffer>& buffer); bool MoveCursor(const gfx::Point& location); @@ -110,7 +106,7 @@ class CrtcController : public base::SupportsWeakPtr<CrtcController> { bool is_disabled_ = true; // The time of the last page flip event as reported by the kernel callback. - uint64_t time_of_last_flip_ = 0; + base::TimeTicks time_of_last_flip_; DISALLOW_COPY_AND_ASSIGN(CrtcController); }; diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_device.cc b/chromium/ui/ozone/platform/drm/gpu/drm_device.cc index ed132f15e55..315b1c0879e 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_device.cc +++ b/chromium/ui/ozone/platform/drm/gpu/drm_device.cc @@ -30,10 +30,9 @@ namespace ui { namespace { -typedef base::Callback<void(uint32_t /* frame */, - uint32_t /* seconds */, - uint32_t /* useconds */, - uint64_t /* id */)> DrmEventHandler; +using DrmEventHandler = base::Callback<void(uint32_t /* frame */, + base::TimeTicks /* timestamp */, + uint64_t /* id */)>; bool DrmCreateDumbBuffer(int fd, const SkImageInfo& info, @@ -97,8 +96,17 @@ bool ProcessDrmEvent(int fd, const DrmEventHandler& callback) { TRACE_EVENT_INSTANT1("benchmark,drm", "DrmEventFlipComplete", TRACE_EVENT_SCOPE_THREAD, "data", std::move(drm_data)); - callback.Run(vblank.sequence, vblank.tv_sec, vblank.tv_usec, - vblank.user_data); + // Warning: It is generally unsafe to manufacture TimeTicks values; but + // here it is required for interfacing with libdrm. Assumption: libdrm + // is providing the timestamp from the CLOCK_MONOTONIC POSIX clock. + DCHECK_EQ(base::TimeTicks::GetClock(), + base::TimeTicks::Clock::LINUX_CLOCK_MONOTONIC); + const base::TimeTicks timestamp = + base::TimeTicks() + base::TimeDelta::FromMicroseconds( + static_cast<int64_t>(vblank.tv_sec) * + base::Time::kMicrosecondsPerSecond + + vblank.tv_usec); + callback.Run(vblank.sequence, timestamp, vblank.user_data); } break; case DRM_EVENT_VBLANK: break; @@ -298,10 +306,7 @@ class DrmDevice::PageFlipManager { PageFlipManager() : next_id_(0) {} ~PageFlipManager() {} - void OnPageFlip(uint32_t frame, - uint32_t seconds, - uint32_t useconds, - uint64_t id) { + void OnPageFlip(uint32_t frame, base::TimeTicks timestamp, uint64_t id) { auto it = std::find_if(callbacks_.begin(), callbacks_.end(), FindCallback(id)); if (it == callbacks_.end()) { @@ -315,7 +320,7 @@ class DrmDevice::PageFlipManager { return; callbacks_.erase(it); - callback.Run(frame, seconds, useconds); + callback.Run(frame, timestamp); } uint64_t GetNextId() { return next_id_++; } diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_device.h b/chromium/ui/ozone/platform/drm/gpu/drm_device.h index 132b5dc5ec2..4e197848279 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_device.h +++ b/chromium/ui/ozone/platform/drm/gpu/drm_device.h @@ -15,6 +15,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/time/time.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/overlay_transform.h" @@ -39,9 +40,9 @@ class HardwareDisplayPlaneManager; // would be called. In unit tests this interface would be stubbed. class DrmDevice : public base::RefCountedThreadSafe<DrmDevice> { public: - typedef base::Callback<void(unsigned int /* frame */, - unsigned int /* seconds */, - unsigned int /* useconds */)> PageFlipCallback; + using PageFlipCallback = + base::Callback<void(unsigned int /* frame */, + base::TimeTicks /* timestamp */)>; DrmDevice(const base::FilePath& device_path, base::File file, diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.cc b/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.cc index 6b8142bc7df..da86d3bde63 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.cc +++ b/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.cc @@ -38,8 +38,7 @@ DrmDeviceManager::~DrmDeviceManager() { } bool DrmDeviceManager::AddDrmDevice(const base::FilePath& path, - const base::FileDescriptor& fd) { - base::File file(fd.fd); + base::File file) { auto it = std::find_if(devices_.begin(), devices_.end(), FindByDevicePath(path)); if (it != devices_.end()) { diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.h b/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.h index 52f59ad845b..a1241b7d92d 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.h +++ b/chromium/ui/ozone/platform/drm/gpu/drm_device_manager.h @@ -9,13 +9,13 @@ #include <memory> #include <vector> +#include "base/files/file.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "ui/gfx/native_widget_types.h" namespace base { class FilePath; -struct FileDescriptor; } namespace ui { @@ -33,7 +33,7 @@ class DrmDeviceManager { ~DrmDeviceManager(); // The first device registered is assumed to be the primary device. - bool AddDrmDevice(const base::FilePath& path, const base::FileDescriptor& fd); + bool AddDrmDevice(const base::FilePath& path, base::File file); void RemoveDrmDevice(const base::FilePath& path); // Updates the device associated with |widget|. diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc index eb333ee7d06..f8d5daa2aeb 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc @@ -14,8 +14,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "ui/display/types/display_mode.h" -#include "ui/display/types/display_snapshot_mojo.h" -#include "ui/ozone/common/display_snapshot_proxy.h" +#include "ui/display/types/display_snapshot.h" #include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/drm_buffer.h" #include "ui/ozone/platform/drm/gpu/drm_device_generator.h" @@ -77,7 +76,7 @@ class GbmDeviceGenerator : public DrmDeviceGenerator { } // namespace -DrmThread::DrmThread() : base::Thread("DrmThread") {} +DrmThread::DrmThread() : base::Thread("DrmThread"), binding_(this) {} DrmThread::~DrmThread() { Stop(); @@ -117,16 +116,24 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget, uint32_t flags = 0; switch (usage) { case gfx::BufferUsage::GPU_READ: + flags = GBM_BO_USE_TEXTURING; break; case gfx::BufferUsage::SCANOUT: - flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; + flags = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; + break; + case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: + flags = GBM_BO_USE_LINEAR | GBM_BO_USE_CAMERA_WRITE | GBM_BO_USE_SCANOUT | + GBM_BO_USE_TEXTURING; break; case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: - flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR; + flags = GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; + break; + case gfx::BufferUsage::SCANOUT_VDA_WRITE: + flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; break; case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: - flags = GBM_BO_USE_LINEAR; + flags = GBM_BO_USE_LINEAR | GBM_BO_USE_TEXTURING; break; } @@ -140,11 +147,21 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget, if (window && window->GetController()) modifiers = window->GetController()->GetFormatModifiers(fourcc_format); - if (modifiers.size() > 0 && !(flags & GBM_BO_USE_LINEAR)) - *buffer = GbmBuffer::CreateBufferWithModifiers(gbm, fourcc_format, size, - flags, modifiers); - else - *buffer = GbmBuffer::CreateBuffer(gbm, fourcc_format, size, flags); + // NOTE: BufferUsage::SCANOUT is used to create buffers that will be + // explicitly set via kms on a CRTC (e.g: BufferQueue buffers), therefore + // allocation should fail if it's not possible to allocate a BO_USE_SCANOUT + // buffer in that case. + bool retry_without_scanout = usage != gfx::BufferUsage::SCANOUT; + do { + if (modifiers.size() > 0 && !(flags & GBM_BO_USE_LINEAR)) + *buffer = GbmBuffer::CreateBufferWithModifiers(gbm, fourcc_format, size, + flags, modifiers); + else + *buffer = GbmBuffer::CreateBuffer(gbm, fourcc_format, size, flags); + retry_without_scanout = + retry_without_scanout && !*buffer && (flags & GBM_BO_USE_SCANOUT); + flags &= ~GBM_BO_USE_SCANOUT; + } while (retry_without_scanout); } void DrmThread::CreateBufferFromFds( @@ -189,19 +206,19 @@ void DrmThread::GetVSyncParameters( window->GetVSyncParameters(callback); } -void DrmThread::CreateWindow(gfx::AcceleratedWidget widget) { +void DrmThread::CreateWindow(const gfx::AcceleratedWidget& widget) { std::unique_ptr<DrmWindow> window( new DrmWindow(widget, device_manager_.get(), screen_manager_.get())); window->Initialize(buffer_generator_.get()); screen_manager_->AddWindow(widget, std::move(window)); } -void DrmThread::DestroyWindow(gfx::AcceleratedWidget widget) { +void DrmThread::DestroyWindow(const gfx::AcceleratedWidget& widget) { std::unique_ptr<DrmWindow> window = screen_manager_->RemoveWindow(widget); window->Shutdown(); } -void DrmThread::SetWindowBounds(gfx::AcceleratedWidget widget, +void DrmThread::SetWindowBounds(const gfx::AcceleratedWidget& widget, const gfx::Rect& bounds) { screen_manager_->GetWindow(widget)->SetBounds(bounds); } @@ -220,17 +237,18 @@ void DrmThread::MoveCursor(const gfx::AcceleratedWidget& widget, } void DrmThread::CheckOverlayCapabilities( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays, - base::OnceCallback<void(gfx::AcceleratedWidget, - const std::vector<OverlayCheck_Params>&, - const std::vector<OverlayCheckReturn_Params>&)> - callback) { + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + base::OnceCallback<void(const gfx::AcceleratedWidget&, + const OverlaySurfaceCandidateList&, + const OverlayStatusList&)> callback) { TRACE_EVENT0("drm,hwoverlays", "DrmThread::CheckOverlayCapabilities"); + auto params = CreateParamsFromOverlaySurfaceCandidate(overlays); std::move(callback).Run( widget, overlays, - screen_manager_->GetWindow(widget)->TestPageFlip(overlays)); + CreateOverlayStatusListFrom( + screen_manager_->GetWindow(widget)->TestPageFlip(params))); } void DrmThread::RefreshNativeDisplays( @@ -265,9 +283,8 @@ void DrmThread::RelinquishDisplayControl( std::move(callback).Run(true); } -void DrmThread::AddGraphicsDevice(const base::FilePath& path, - const base::FileDescriptor& fd) { - device_manager_->AddDrmDevice(path, fd); +void DrmThread::AddGraphicsDevice(const base::FilePath& path, base::File file) { + device_manager_->AddDrmDevice(path, std::move(file)); } void DrmThread::RemoveGraphicsDevice(const base::FilePath& path) { @@ -298,10 +315,24 @@ void DrmThread::SetColorCorrection( correction_matrix); } +void DrmThread::StartDrmDevice(StartDrmDeviceCallback callback) { + // We currently assume that |Init| always succeeds so return true to indicate + // when the DRM thread has completed launching. In particular, the invocation + // of the callback in the client triggers the invocation of DRM thread + // readiness observers. + std::move(callback).Run(true); +} + // DrmThread requires a BindingSet instead of a simple Binding because it will // be used from multiple threads in multiple processes. -void DrmThread::AddBinding(ozone::mojom::DeviceCursorRequest request) { +void DrmThread::AddBindingCursorDevice( + ozone::mojom::DeviceCursorRequest request) { bindings_.AddBinding(this, std::move(request)); } +void DrmThread::AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request) { + TRACE_EVENT0("drm", "DrmThread::AddBindingDrmDevice"); + binding_.Bind(std::move(request)); +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread.h index 8fdecc94db7..973409b073d 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_thread.h +++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread.h @@ -9,6 +9,7 @@ #include <memory> +#include "base/files/file.h" #include "base/files/scoped_file.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -20,10 +21,11 @@ #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" #include "ui/ozone/platform/drm/common/display_types.h" #include "ui/ozone/public/interfaces/device_cursor.mojom.h" +#include "ui/ozone/public/interfaces/drm_device.mojom.h" #include "ui/ozone/public/swap_completion_callback.h" namespace base { -struct FileDescriptor; +class FilePath; } namespace display { @@ -53,14 +55,17 @@ struct OverlayPlane; // (for example jank in the cursor if the GPU main thread is performing heavy // operations). The inverse is also true as blocking operations on the DRM // thread (such as modesetting) no longer block the GPU main thread. -class DrmThread : public base::Thread, public ozone::mojom::DeviceCursor { +class DrmThread : public base::Thread, + public ozone::mojom::DeviceCursor, + public ozone::mojom::DrmDevice { public: DrmThread(); ~DrmThread() override; void Start(); - // Must be called on the DRM thread. + // Must be called on the DRM thread. All methods for use from the GPU thread. + // DrmThreadProxy (on GPU)thread) is the client for these methods. void CreateBuffer(gfx::AcceleratedWidget widget, const gfx::Size& size, gfx::BufferFormat format, @@ -72,9 +77,12 @@ class DrmThread : public base::Thread, public ozone::mojom::DeviceCursor { std::vector<base::ScopedFD>&& fds, const std::vector<gfx::NativePixmapPlane>& planes, scoped_refptr<GbmBuffer>* buffer); - void GetScanoutFormats(gfx::AcceleratedWidget widget, std::vector<gfx::BufferFormat>* scanout_formats); + void AddBindingCursorDevice(ozone::mojom::DeviceCursorRequest request); + void AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request); + + // DrmWindowProxy (on GPU thread) is the client for these methods. void SchedulePageFlip(gfx::AcceleratedWidget widget, const std::vector<OverlayPlane>& planes, SwapCompletionOnceCallback callback); @@ -82,53 +90,56 @@ class DrmThread : public base::Thread, public ozone::mojom::DeviceCursor { gfx::AcceleratedWidget widget, const gfx::VSyncProvider::UpdateVSyncCallback& callback); - void CreateWindow(gfx::AcceleratedWidget widget); - void DestroyWindow(gfx::AcceleratedWidget widget); - void SetWindowBounds(gfx::AcceleratedWidget widget, const gfx::Rect& bounds); - void SetCursor(const gfx::AcceleratedWidget& widget, - const std::vector<SkBitmap>& bitmaps, - const gfx::Point& location, - int32_t frame_delay_ms) override; - void MoveCursor(const gfx::AcceleratedWidget& widget, - const gfx::Point& location) override; - void CheckOverlayCapabilities( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays, - base::OnceCallback<void(gfx::AcceleratedWidget, - const std::vector<OverlayCheck_Params>&, - const std::vector<OverlayCheckReturn_Params>&)> - callback); + // ozone::mojom::DrmDevice + void StartDrmDevice(StartDrmDeviceCallback callback) override; + void CreateWindow(const gfx::AcceleratedWidget& widget) override; + void DestroyWindow(const gfx::AcceleratedWidget& widget) override; + void SetWindowBounds(const gfx::AcceleratedWidget& widget, + const gfx::Rect& bounds) override; + void TakeDisplayControl(base::OnceCallback<void(bool)> callback) override; + void RelinquishDisplayControl( + base::OnceCallback<void(bool)> callback) override; void RefreshNativeDisplays( - base::OnceCallback<void(MovableDisplaySnapshots)> callback); - void ConfigureNativeDisplay(int64_t id, - std::unique_ptr<display::DisplayMode> mode, - const gfx::Point& origin, - base::OnceCallback<void(int64_t, bool)> callback); - void DisableNativeDisplay(int64_t id, - base::OnceCallback<void(int64_t, bool)> callback); - void TakeDisplayControl(base::OnceCallback<void(bool)> callback); - void RelinquishDisplayControl(base::OnceCallback<void(bool)> callback); - void AddGraphicsDevice(const base::FilePath& path, - const base::FileDescriptor& fd); - void RemoveGraphicsDevice(const base::FilePath& path); - void GetHDCPState( - int64_t display_id, - base::OnceCallback<void(int64_t, bool, display::HDCPState)> callback); + base::OnceCallback<void(MovableDisplaySnapshots)> callback) override; + void AddGraphicsDevice(const base::FilePath& path, base::File file) override; + void RemoveGraphicsDevice(const base::FilePath& path) override; + void DisableNativeDisplay( + int64_t id, + base::OnceCallback<void(int64_t, bool)> callback) override; + void ConfigureNativeDisplay( + int64_t id, + std::unique_ptr<display::DisplayMode> mode, + const gfx::Point& origin, + base::OnceCallback<void(int64_t, bool)> callback) override; + void GetHDCPState(int64_t display_id, + base::OnceCallback<void(int64_t, bool, display::HDCPState)> + callback) override; void SetHDCPState(int64_t display_id, display::HDCPState state, - base::OnceCallback<void(int64_t, bool)> callback); + base::OnceCallback<void(int64_t, bool)> callback) override; void SetColorCorrection( int64_t display_id, const std::vector<display::GammaRampRGBEntry>& degamma_lut, const std::vector<display::GammaRampRGBEntry>& gamma_lut, - const std::vector<float>& correction_matrix); + const std::vector<float>& correction_matrix) override; + void CheckOverlayCapabilities( + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + base::OnceCallback<void(const gfx::AcceleratedWidget&, + const OverlaySurfaceCandidateList&, + const OverlayStatusList&)> callback) override; + + // ozone::mojom::DeviceCursor + void SetCursor(const gfx::AcceleratedWidget& widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int32_t frame_delay_ms) override; + void MoveCursor(const gfx::AcceleratedWidget& widget, + const gfx::Point& location) override; // base::Thread: void Init() override; - // Mojo support for DeviceCursorRequest. - void AddBinding(ozone::mojom::DeviceCursorRequest request); - private: std::unique_ptr<DrmDeviceManager> device_manager_; std::unique_ptr<ScanoutBufferGenerator> buffer_generator_; @@ -139,6 +150,9 @@ class DrmThread : public base::Thread, public ozone::mojom::DeviceCursor { // requests from two different client threads. mojo::BindingSet<ozone::mojom::DeviceCursor> bindings_; + // The mojo implementation of DrmDevice can use a simple binding. + mojo::Binding<ozone::mojom::DrmDevice> binding_; + DISALLOW_COPY_AND_ASSIGN(DrmThread); }; diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc index b1add6a3d74..fb46660ae63 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc +++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc @@ -8,7 +8,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sender.h" -#include "ui/display/types/display_snapshot_mojo.h" +#include "ui/display/types/display_snapshot.h" #include "ui/ozone/common/gpu/ozone_gpu_messages.h" #include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/drm_thread_proxy.h" @@ -109,8 +109,9 @@ void DrmThreadMessageProxy::OnCursorMove(gfx::AcceleratedWidget widget, void DrmThreadMessageProxy::OnCheckOverlayCapabilities( gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays) { + const std::vector<OverlayCheck_Params>& param_overlays) { DCHECK(drm_thread_->IsRunning()); + auto overlays = CreateOverlaySurfaceCandidateListFrom(param_overlays); auto callback = base::BindOnce(&DrmThreadMessageProxy::OnCheckOverlayCapabilitiesCallback, weak_ptr_factory_.GetWeakPtr()); @@ -191,9 +192,11 @@ void DrmThreadMessageProxy::OnAddGraphicsDevice( const base::FilePath& path, const base::FileDescriptor& fd) { DCHECK(drm_thread_->IsRunning()); + base::File file(fd.fd); drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::AddGraphicsDevice, - base::Unretained(drm_thread_), path, fd)); + FROM_HERE, + base::Bind(&DrmThread::AddGraphicsDevice, base::Unretained(drm_thread_), + path, Passed(&file))); } void DrmThreadMessageProxy::OnRemoveGraphicsDevice(const base::FilePath& path) { @@ -239,11 +242,13 @@ void DrmThreadMessageProxy::OnSetColorCorrection( } void DrmThreadMessageProxy::OnCheckOverlayCapabilitiesCallback( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays, - const std::vector<OverlayCheckReturn_Params>& returns) const { - sender_->Send( - new OzoneHostMsg_OverlayCapabilitiesReceived(widget, overlays, returns)); + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& candidates, + const OverlayStatusList& returns) const { + auto param_overlays = CreateParamsFromOverlaySurfaceCandidate(candidates); + auto param_returns = CreateParamsFromOverlayStatusList(returns); + sender_->Send(new OzoneHostMsg_OverlayCapabilitiesReceived( + widget, param_overlays, param_returns)); } void DrmThreadMessageProxy::OnRefreshNativeDisplaysCallback( diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h index da749ed08e9..c1ec3150c6f 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h +++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h @@ -15,6 +15,7 @@ #include "ui/gfx/native_widget_types.h" #include "ui/ozone/platform/drm/common/display_types.h" #include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h" +#include "ui/ozone/public/overlay_surface_candidate.h" namespace base { struct FileDescriptor; @@ -30,7 +31,6 @@ namespace ui { class DrmThread; struct DisplayMode_Params; struct OverlayCheck_Params; -struct OverlayCheckReturn_Params; class DrmThreadMessageProxy : public IPC::MessageFilter, public InterThreadMessagingProxy { @@ -80,9 +80,9 @@ class DrmThreadMessageProxy : public IPC::MessageFilter, const std::vector<float>& correction_matrix); void OnCheckOverlayCapabilitiesCallback( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays, - const std::vector<OverlayCheckReturn_Params>& returns) const; + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + const OverlayStatusList& returns) const; void OnRefreshNativeDisplaysCallback(MovableDisplaySnapshots displays) const; void OnConfigureNativeDisplayCallback(int64_t display_id, bool success) const; void OnDisableNativeDisplayCallback(int64_t display_id, bool success) const; diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc index dccef01e783..8d15f12294c 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc +++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc @@ -22,6 +22,10 @@ void DrmThreadProxy::BindThreadIntoMessagingProxy( messaging_proxy->SetDrmThread(&drm_thread_); } +void DrmThreadProxy::StartDrmThread() { + drm_thread_.Start(); +} + std::unique_ptr<DrmWindowProxy> DrmThreadProxy::CreateDrmWindowProxy( gfx::AcceleratedWidget widget) { return base::MakeUnique<DrmWindowProxy>(widget, &drm_thread_); @@ -63,11 +67,20 @@ void DrmThreadProxy::GetScanoutFormats( widget, scanout_formats)); } -void DrmThreadProxy::AddBinding(ozone::mojom::DeviceCursorRequest request) { +void DrmThreadProxy::AddBindingCursorDevice( + ozone::mojom::DeviceCursorRequest request) { + drm_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&DrmThread::AddBindingCursorDevice, + base::Unretained(&drm_thread_), base::Passed(&request))); +} + +void DrmThreadProxy::AddBindingDrmDevice( + ozone::mojom::DrmDeviceRequest request) { drm_thread_.task_runner()->PostTask( FROM_HERE, - base::Bind(&DrmThread::AddBinding, base::Unretained(&drm_thread_), - base::Passed(&request))); + base::Bind(&DrmThread::AddBindingDrmDevice, + base::Unretained(&drm_thread_), base::Passed(&request))); } } // namespace ui diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h index 4ae9ca2de11..c8a0b4b9c0b 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h +++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h @@ -27,6 +27,8 @@ class DrmThreadProxy { void BindThreadIntoMessagingProxy(InterThreadMessagingProxy* messaging_proxy); + void StartDrmThread(); + std::unique_ptr<DrmWindowProxy> CreateDrmWindowProxy( gfx::AcceleratedWidget widget); @@ -45,7 +47,8 @@ class DrmThreadProxy { void GetScanoutFormats(gfx::AcceleratedWidget widget, std::vector<gfx::BufferFormat>* scanout_formats); - void AddBinding(ozone::mojom::DeviceCursorRequest request); + void AddBindingCursorDevice(ozone::mojom::DeviceCursorRequest request); + void AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request); private: DrmThread drm_thread_; diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_window.cc b/chromium/ui/ozone/platform/drm/gpu/drm_window.cc index 29447bc6307..82b86176fe6 100644 --- a/chromium/ui/ozone/platform/drm/gpu/drm_window.cc +++ b/chromium/ui/ozone/platform/drm/gpu/drm_window.cc @@ -162,18 +162,11 @@ void DrmWindow::GetVSyncParameters( // If we're in mirror mode the 2 CRTCs should have similar modes with the same // refresh rates. CrtcController* crtc = controller_->crtc_controllers()[0].get(); - // The value is invalid, so we can't update the parameters. - if (controller_->GetTimeOfLastFlip() == 0 || crtc->mode().vrefresh == 0) - return; - - // Stores the time of the last refresh. - base::TimeTicks timebase = - base::TimeTicks::FromInternalValue(controller_->GetTimeOfLastFlip()); - // Stores the refresh rate. - base::TimeDelta interval = - base::TimeDelta::FromSeconds(1) / crtc->mode().vrefresh; - - callback.Run(timebase, interval); + const base::TimeTicks last_flip = controller_->GetTimeOfLastFlip(); + if (last_flip == base::TimeTicks() || crtc->mode().vrefresh == 0) + return; // The value is invalid, so we can't update the parameters. + callback.Run(last_flip, + base::TimeDelta::FromSeconds(1) / crtc->mode().vrefresh); } void DrmWindow::ResetCursor(bool bitmap_only) { diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_buffer.cc b/chromium/ui/ozone/platform/drm/gpu/gbm_buffer.cc index d9b42c934b7..624bcc99d48 100644 --- a/chromium/ui/ozone/platform/drm/gpu/gbm_buffer.cc +++ b/chromium/ui/ozone/platform/drm/gpu/gbm_buffer.cc @@ -259,8 +259,9 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( DCHECK_EQ(planes[0].offset, 0); // Try to use scanout if supported. - bool try_scanout = gbm_device_is_format_supported( - gbm->device(), format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + int gbm_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; + bool try_scanout = + gbm_device_is_format_supported(gbm->device(), format, gbm_flags); gbm_bo* bo = nullptr; if (try_scanout) { @@ -280,18 +281,18 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( // The fd passed to gbm_bo_import is not ref-counted and need to be // kept open for the lifetime of the buffer. bo = gbm_bo_import(gbm->device(), GBM_BO_IMPORT_FD_PLANAR, &fd_data, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + gbm_flags); if (!bo) { LOG(ERROR) << "nullptr returned from gbm_bo_import"; return nullptr; } + } else { + gbm_flags &= ~GBM_BO_USE_SCANOUT; } - uint32_t flags = GBM_BO_USE_RENDERING; - if (try_scanout) - flags |= GBM_BO_USE_SCANOUT; - scoped_refptr<GbmBuffer> buffer(new GbmBuffer( - gbm, bo, format, flags, 0, 0, std::move(fds), size, std::move(planes))); + scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, format, gbm_flags, 0, + 0, std::move(fds), size, + std::move(planes))); return buffer; } diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_surface.cc b/chromium/ui/ozone/platform/drm/gpu/gbm_surface.cc index 649f4b051fb..a0cebe6ab50 100644 --- a/chromium/ui/ozone/platform/drm/gpu/gbm_surface.cc +++ b/chromium/ui/ozone/platform/drm/gpu/gbm_surface.cc @@ -46,12 +46,14 @@ bool GbmSurface::OnMakeCurrent(gl::GLContext* context) { bool GbmSurface::Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) { if (size == GetSize()) return true; // Alpha value isn't actually used in allocating buffers yet, so always use // true instead. - return GbmSurfaceless::Resize(size, scale_factor, true) && CreatePixmaps(); + return GbmSurfaceless::Resize(size, scale_factor, color_space, true) && + CreatePixmaps(); } bool GbmSurface::SupportsPostSubBuffer() { diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_surface.h b/chromium/ui/ozone/platform/drm/gpu/gbm_surface.h index ba38c01ac0d..fedff501c49 100644 --- a/chromium/ui/ozone/platform/drm/gpu/gbm_surface.h +++ b/chromium/ui/ozone/platform/drm/gpu/gbm_surface.h @@ -31,6 +31,7 @@ class GbmSurface : public GbmSurfaceless { bool OnMakeCurrent(gl::GLContext* context) override; bool Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) override; bool SupportsPostSubBuffer() override; void SwapBuffersAsync(const SwapCompletionCallback& callback) override; diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc index 46218658981..37f9b17c6c6 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc @@ -72,6 +72,13 @@ void HardwareDisplayController::Disable() { for (const auto& controller : crtc_controllers_) controller->Disable(); + for (const auto& planes : owned_hardware_planes_) { + DrmDevice* drm = planes.first; + HardwareDisplayPlaneList* plane_list = planes.second.get(); + bool ret = drm->plane_manager()->DisableOverlayPlanes(plane_list); + LOG_IF(ERROR, !ret) << "Can't disable overlays when disabling HDC."; + } + is_disabled_ = true; } @@ -107,7 +114,7 @@ bool HardwareDisplayController::ActualSchedulePageFlip( [](const OverlayPlane& l, const OverlayPlane& r) { return l.z_order < r.z_order; }); - if (pending_planes.front().z_order != 0) { + if (pending_planes.front().z_order < 0) { std::move(callback).Run(gfx::SwapResult::SWAP_FAILED); return false; } @@ -283,8 +290,8 @@ gfx::Size HardwareDisplayController::GetModeSize() const { crtc_controllers_[0]->mode().vdisplay); } -uint64_t HardwareDisplayController::GetTimeOfLastFlip() const { - uint64_t time = 0; +base::TimeTicks HardwareDisplayController::GetTimeOfLastFlip() const { + base::TimeTicks time; for (const auto& controller : crtc_controllers_) { if (time < controller->time_of_last_flip()) time = controller->time_of_last_flip(); diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h index 31777d2c932..c80aba42352 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h @@ -17,6 +17,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/time/time.h" #include "ui/gfx/swap_result.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h" #include "ui/ozone/platform/drm/gpu/overlay_plane.h" @@ -149,7 +150,7 @@ class HardwareDisplayController { gfx::Point origin() const { return origin_; } void set_origin(const gfx::Point& origin) { origin_ = origin; } - uint64_t GetTimeOfLastFlip() const; + base::TimeTicks GetTimeOfLastFlip() const; const std::vector<std::unique_ptr<CrtcController>>& crtc_controllers() const { return crtc_controllers_; diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc index 0dbd989f9c8..05da38c50f3 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc @@ -400,7 +400,7 @@ TEST_F(HardwareDisplayControllerTest, FailPageFlipping) { EXPECT_EQ(1, page_flips_); } -TEST_F(HardwareDisplayControllerTest, FailPageFlippingDueToNoPrimaryPlane) { +TEST_F(HardwareDisplayControllerTest, CheckNoPrimaryPlane) { ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( new ui::MockScanoutBuffer(kDefaultModeSize)), 1, gfx::OVERLAY_TRANSFORM_NONE, @@ -413,7 +413,7 @@ TEST_F(HardwareDisplayControllerTest, FailPageFlippingDueToNoPrimaryPlane) { base::Unretained(this))); drm_->RunCallbacks(); - EXPECT_EQ(gfx::SwapResult::SWAP_FAILED, last_swap_result_); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(1, page_flips_); } @@ -452,3 +452,33 @@ TEST_F(HardwareDisplayControllerTest, RemoveCrtcMidPageFlip) { EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(1, page_flips_); } + +TEST_F(HardwareDisplayControllerTest, Disable) { + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new ui::MockScanoutBuffer(kDefaultModeSize))); + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + + ui::OverlayPlane plane2(new ui::MockScanoutBuffer(kOverlaySize), 1, + gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(kOverlaySize), + gfx::RectF(kDefaultModeSizeF)); + std::vector<ui::OverlayPlane> planes; + planes.push_back(plane1); + planes.push_back(plane2); + + controller_->SchedulePageFlip( + planes, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this))); + drm_->RunCallbacks(); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); + EXPECT_EQ(1, page_flips_); + + controller_->Disable(); + + int planes_in_use = 0; + for (const auto& plane : drm_->plane_manager()->planes()) { + if (plane->in_use()) + planes_in_use++; + } + // Only the primary plane is in use. + ASSERT_EQ(1, planes_in_use); +} diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane.h index 90050f98a89..0cf28072e60 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane.h +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane.h @@ -45,6 +45,7 @@ class HardwareDisplayPlane { uint32_t plane_id() const { return plane_id_; } Type type() const { return type_; } + void set_type(const Type type) { type_ = type; } void set_owning_crtc(uint32_t crtc) { owning_crtc_ = crtc; } uint32_t owning_crtc() const { return owning_crtc_; } diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h index 15538c5e85f..2a9f0bd1246 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h @@ -89,6 +89,10 @@ class HardwareDisplayPlaneManager { virtual bool Commit(HardwareDisplayPlaneList* plane_list, bool test_only) = 0; + // Disable all the overlay planes previously submitted and now stored in + // plane_list->old_plane_list. + virtual bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) = 0; + const std::vector<std::unique_ptr<HardwareDisplayPlane>>& planes() { return planes_; } diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc index 67bea1230f5..eb0655d9a58 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc @@ -17,12 +17,11 @@ namespace { void AtomicPageFlipCallback(std::vector<base::WeakPtr<CrtcController>> crtcs, unsigned int frame, - unsigned int seconds, - unsigned int useconds) { + base::TimeTicks timestamp) { for (auto& crtc : crtcs) { auto* crtc_ptr = crtc.get(); if (crtc_ptr) - crtc_ptr->OnPageFlipEvent(frame, seconds, useconds); + crtc_ptr->OnPageFlipEvent(frame, timestamp); } } @@ -75,8 +74,12 @@ bool HardwareDisplayPlaneManagerAtomic::Commit( if (!drm_->CommitProperties(plane_list->atomic_property_set.get(), flags, crtcs.size(), base::Bind(&AtomicPageFlipCallback, crtcs))) { - PLOG(ERROR) << "Failed to commit properties. test_only:" << std::boolalpha - << test_only << " error"; + if (!test_only) { + PLOG(ERROR) << "Failed to commit properties for page flip."; + } else { + VPLOG(2) << "Failed to commit properties for MODE_ATOMIC_TEST_ONLY."; + } + ResetCurrentPlaneList(plane_list); return false; } @@ -86,6 +89,33 @@ bool HardwareDisplayPlaneManagerAtomic::Commit( return true; } +bool HardwareDisplayPlaneManagerAtomic::DisableOverlayPlanes( + HardwareDisplayPlaneList* plane_list) { + for (HardwareDisplayPlane* plane : plane_list->old_plane_list) { + if (plane->type() != HardwareDisplayPlane::kOverlay) + continue; + plane->set_in_use(false); + plane->set_owning_crtc(0); + + HardwareDisplayPlaneAtomic* atomic_plane = + static_cast<HardwareDisplayPlaneAtomic*>(plane); + atomic_plane->SetPlaneData(plane_list->atomic_property_set.get(), 0, 0, + gfx::Rect(), gfx::Rect(), + gfx::OVERLAY_TRANSFORM_NONE); + } + // The list of crtcs is only useful if flags contains DRM_MODE_PAGE_FLIP_EVENT + // to get the pageflip callback. In this case we don't need to be notified + // at the next page flip, so the list of crtcs can be empty. + std::vector<base::WeakPtr<CrtcController>> crtcs; + bool ret = drm_->CommitProperties(plane_list->atomic_property_set.get(), + DRM_MODE_ATOMIC_NONBLOCK, crtcs.size(), + base::Bind(&AtomicPageFlipCallback, crtcs)); + PLOG_IF(ERROR, !ret) << "Failed to commit properties for page flip."; + + plane_list->atomic_property_set.reset(drmModeAtomicAlloc()); + return ret; +} + bool HardwareDisplayPlaneManagerAtomic::SetPlaneData( HardwareDisplayPlaneList* plane_list, HardwareDisplayPlane* hw_plane, diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h index 7847d43700c..968ff37897e 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h @@ -20,6 +20,7 @@ class HardwareDisplayPlaneManagerAtomic : public HardwareDisplayPlaneManager { // HardwareDisplayPlaneManager: bool Commit(HardwareDisplayPlaneList* plane_list, bool test_only) override; + bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override; private: bool SetPlaneData(HardwareDisplayPlaneList* plane_list, diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc index 501dfabcf6d..50d4334dc1e 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc @@ -98,6 +98,17 @@ bool HardwareDisplayPlaneManagerLegacy::Commit( return ret; } +bool HardwareDisplayPlaneManagerLegacy::DisableOverlayPlanes( + HardwareDisplayPlaneList* plane_list) { + // We're never going to ship legacy pageflip with overlays enabled. + DCHECK(std::find_if(plane_list->old_plane_list.begin(), + plane_list->old_plane_list.end(), + [](HardwareDisplayPlane* plane) { + return plane->type() == HardwareDisplayPlane::kOverlay; + }) == plane_list->old_plane_list.end()); + return true; +} + bool HardwareDisplayPlaneManagerLegacy::SetPlaneData( HardwareDisplayPlaneList* plane_list, HardwareDisplayPlane* hw_plane, diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h index 56c55766e0f..1f9786028b7 100644 --- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h +++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h @@ -20,6 +20,7 @@ class HardwareDisplayPlaneManagerLegacy : public HardwareDisplayPlaneManager { // HardwareDisplayPlaneManager: bool Commit(HardwareDisplayPlaneList* plane_list, bool test_only) override; + bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override; protected: bool SetPlaneData(HardwareDisplayPlaneList* plane_list, diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc index c294771a5f5..c3845221469 100644 --- a/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc +++ b/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc @@ -126,7 +126,7 @@ bool MockDrmDevice::PageFlip(uint32_t crtc_id, current_framebuffer_ = framebuffer; if (page_flip_expectation_) { if (use_sync_flips_) - callback.Run(0, 0, 0); + callback.Run(0, base::TimeTicks()); else callbacks_.push(callback); } @@ -241,7 +241,7 @@ void MockDrmDevice::RunCallbacks() { while (!callbacks_.empty()) { PageFlipCallback callback = callbacks_.front(); callbacks_.pop(); - callback.Run(0, 0, 0); + callback.Run(0, base::TimeTicks()); } } diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.cc b/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.cc index ec26ff89a11..68e7659b836 100644 --- a/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.cc +++ b/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.cc @@ -28,6 +28,8 @@ MockHardwareDisplayPlaneManager::MockHardwareDisplayPlaneManager( plane->Initialize(drm, std::vector<uint32_t>(1, DRM_FORMAT_XRGB8888), std::vector<drm_format_modifier>(1, linear_modifier), false, true); + plane->set_type(i ? HardwareDisplayPlane::kOverlay + : HardwareDisplayPlane::kPrimary); planes_.push_back(std::move(plane)); } } @@ -99,6 +101,18 @@ void MockHardwareDisplayPlaneManager::SetCrtcInfo( ResetPlaneCount(); } +bool MockHardwareDisplayPlaneManager::DisableOverlayPlanes( + HardwareDisplayPlaneList* plane_list) { + for (HardwareDisplayPlane* plane : plane_list->old_plane_list) { + if (plane->type() != HardwareDisplayPlane::kOverlay) + continue; + plane->set_in_use(false); + plane->set_owning_crtc(0); + } + + return true; +} + bool MockHardwareDisplayPlaneManager::SetPlaneData( HardwareDisplayPlaneList* plane_list, HardwareDisplayPlane* hw_plane, diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.h b/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.h index 60f159e517f..dc567a9f4a0 100644 --- a/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.h +++ b/chromium/ui/ozone/platform/drm/gpu/mock_hardware_display_plane_manager.h @@ -33,6 +33,7 @@ class MockHardwareDisplayPlaneManager void SetPlaneProperties(const std::vector<FakePlaneInfo>& planes); void SetCrtcInfo(const std::vector<uint32_t>& crtcs); + bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override; bool SetPlaneData(HardwareDisplayPlaneList* plane_list, HardwareDisplayPlane* hw_plane, const OverlayPlane& overlay, diff --git a/chromium/ui/ozone/platform/drm/host/drm_display_host.cc b/chromium/ui/ozone/platform/drm/host/drm_display_host.cc index 463c108f9c2..824287f2382 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_display_host.cc +++ b/chromium/ui/ozone/platform/drm/host/drm_display_host.cc @@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" #include "ui/display/types/display_mode.h" -#include "ui/ozone/common/display_snapshot_proxy.h" +#include "ui/display/types/display_snapshot.h" #include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/host/gpu_thread_adapter.h" @@ -19,7 +19,7 @@ DrmDisplayHost::DrmDisplayHost(GpuThreadAdapter* sender, const DisplaySnapshot_Params& params, bool is_dummy) : sender_(sender), - snapshot_(new DisplaySnapshotProxy(params)), + snapshot_(CreateDisplaySnapshotFromParams(params)), is_dummy_(is_dummy) { sender_->AddGpuThreadObserver(this); } @@ -31,7 +31,7 @@ DrmDisplayHost::~DrmDisplayHost() { void DrmDisplayHost::UpdateDisplaySnapshot( const DisplaySnapshot_Params& params) { - snapshot_ = base::MakeUnique<DisplaySnapshotProxy>(params); + snapshot_ = CreateDisplaySnapshotFromParams(params); } void DrmDisplayHost::Configure(const display::DisplayMode* mode, diff --git a/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc index 8411915dfde..f160a2ce760 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc +++ b/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc @@ -288,8 +288,7 @@ void DrmDisplayHostManager::OnAddGraphicsDevice( std::unique_ptr<DrmDeviceHandle> handle) { if (handle->IsValid()) { drm_devices_[dev_path] = sys_path; - proxy_->GpuAddGraphicsDevice(sys_path, - base::FileDescriptor(handle->PassFD())); + proxy_->GpuAddGraphicsDevice(sys_path, handle->PassFD()); NotifyDisplayDelegate(); } @@ -332,7 +331,7 @@ void DrmDisplayHostManager::OnGpuProcessLaunched() { // Send the primary device first since this is used to initialize graphics // state. proxy_->GpuAddGraphicsDevice(drm_devices_[primary_graphics_card_path_], - base::FileDescriptor(handle->PassFD())); + handle->PassFD()); } void DrmDisplayHostManager::OnGpuThreadReady() { diff --git a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc index ccbcbeb21c7..52e08ed5cc4 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc +++ b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc @@ -9,6 +9,7 @@ #include "base/trace_event/trace_event.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" #include "ui/ozone/common/gpu/ozone_gpu_messages.h" +#include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/host/drm_cursor.h" #include "ui/ozone/platform/drm/host/drm_display_host_manager.h" #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h" @@ -244,10 +245,10 @@ bool DrmGpuPlatformSupportHost::GpuRelinquishDisplayControl() { return Send(new OzoneGpuMsg_RelinquishDisplayControl()); } -bool DrmGpuPlatformSupportHost::GpuAddGraphicsDevice( - const base::FilePath& path, - const base::FileDescriptor& fd) { - IPC::Message* message = new OzoneGpuMsg_AddGraphicsDevice(path, fd); +bool DrmGpuPlatformSupportHost::GpuAddGraphicsDevice(const base::FilePath& path, + base::ScopedFD fd) { + IPC::Message* message = new OzoneGpuMsg_AddGraphicsDevice( + path, base::FileDescriptor(std::move(fd))); // This function may be called from two places: // - DrmDisplayHostManager::OnGpuProcessLaunched() invoked synchronously @@ -294,14 +295,17 @@ bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmOverlayManager( void DrmGpuPlatformSupportHost::OnOverlayResult( gfx::AcceleratedWidget widget, const std::vector<OverlayCheck_Params>& params, - const std::vector<OverlayCheckReturn_Params>& returns) { - overlay_manager_->GpuSentOverlayResult(widget, params, returns); + const std::vector<OverlayCheckReturn_Params>& param_returns) { + auto candidates = CreateOverlaySurfaceCandidateListFrom(params); + auto returns = CreateOverlayStatusListFrom(param_returns); + overlay_manager_->GpuSentOverlayResult(widget, candidates, returns); } bool DrmGpuPlatformSupportHost::GpuCheckOverlayCapabilities( gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& new_params) { - return Send(new OzoneGpuMsg_CheckOverlayCapabilities(widget, new_params)); + const OverlaySurfaceCandidateList& candidates) { + auto params = CreateParamsFromOverlaySurfaceCandidate(candidates); + return Send(new OzoneGpuMsg_CheckOverlayCapabilities(widget, params)); } // DrmDisplayHost diff --git a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h index 5611b961d74..826e09d949c 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h +++ b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h @@ -63,7 +63,7 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost, bool GpuRefreshNativeDisplays() override; bool GpuRelinquishDisplayControl() override; bool GpuAddGraphicsDevice(const base::FilePath& path, - const base::FileDescriptor& fd) override; + base::ScopedFD fd) override; bool GpuRemoveGraphicsDevice(const base::FilePath& path) override; // Methods needed for DrmOverlayManager. @@ -74,7 +74,7 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost, // Services needed by DrmOverlayManager bool GpuCheckOverlayCapabilities( gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& new_params) override; + const OverlaySurfaceCandidateList& new_params) override; // Services needed by DrmDisplayHost bool GpuConfigureNativeDisplay(int64_t display_id, diff --git a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc index ffaad3c5107..f96d2d9bbd9 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc +++ b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc @@ -34,12 +34,6 @@ void DrmNativeDisplayDelegate::Initialize() { display_manager_->AddDelegate(this); } -void DrmNativeDisplayDelegate::GrabServer() { -} - -void DrmNativeDisplayDelegate::UngrabServer() { -} - void DrmNativeDisplayDelegate::TakeDisplayControl( const display::DisplayControlCallback& callback) { display_manager_->TakeDisplayControl(callback); @@ -50,23 +44,11 @@ void DrmNativeDisplayDelegate::RelinquishDisplayControl( display_manager_->RelinquishDisplayControl(callback); } -void DrmNativeDisplayDelegate::SyncWithServer() { -} - -void DrmNativeDisplayDelegate::SetBackgroundColor(uint32_t color_argb) { -} - -void DrmNativeDisplayDelegate::ForceDPMSOn() { -} - void DrmNativeDisplayDelegate::GetDisplays( const display::GetDisplaysCallback& callback) { display_manager_->UpdateDisplays(callback); } -void DrmNativeDisplayDelegate::AddMode(const display::DisplaySnapshot& output, - const display::DisplayMode* mode) {} - void DrmNativeDisplayDelegate::Configure( const display::DisplaySnapshot& output, const display::DisplayMode* mode, @@ -76,9 +58,6 @@ void DrmNativeDisplayDelegate::Configure( display->Configure(mode, origin, callback); } -void DrmNativeDisplayDelegate::CreateFrameBuffer(const gfx::Size& size) { -} - void DrmNativeDisplayDelegate::GetHDCPState( const display::DisplaySnapshot& output, const display::GetHDCPStateCallback& callback) { @@ -94,19 +73,6 @@ void DrmNativeDisplayDelegate::SetHDCPState( display->SetHDCPState(state, callback); } -std::vector<display::ColorCalibrationProfile> -DrmNativeDisplayDelegate::GetAvailableColorCalibrationProfiles( - const display::DisplaySnapshot& output) { - return std::vector<display::ColorCalibrationProfile>(); -} - -bool DrmNativeDisplayDelegate::SetColorCalibrationProfile( - const display::DisplaySnapshot& output, - display::ColorCalibrationProfile new_profile) { - NOTIMPLEMENTED(); - return false; -} - bool DrmNativeDisplayDelegate::SetColorCorrection( const display::DisplaySnapshot& output, const std::vector<display::GammaRampRGBEntry>& degamma_lut, diff --git a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h index e37a37366b9..0b1d5336aff 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h +++ b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h @@ -17,7 +17,7 @@ class DrmDisplayHostManager; class DrmNativeDisplayDelegate : public display::NativeDisplayDelegate { public: - DrmNativeDisplayDelegate(DrmDisplayHostManager* display_manager); + explicit DrmNativeDisplayDelegate(DrmDisplayHostManager* display_manager); ~DrmNativeDisplayDelegate() override; void OnConfigurationChanged(); @@ -25,34 +25,20 @@ class DrmNativeDisplayDelegate : public display::NativeDisplayDelegate { // display::NativeDisplayDelegate overrides: void Initialize() override; - void GrabServer() override; - void UngrabServer() override; void TakeDisplayControl( const display::DisplayControlCallback& callback) override; void RelinquishDisplayControl( const display::DisplayControlCallback& callback) override; - void SyncWithServer() override; - void SetBackgroundColor(uint32_t color_argb) override; - void ForceDPMSOn() override; void GetDisplays(const display::GetDisplaysCallback& callback) override; - void AddMode(const display::DisplaySnapshot& output, - const display::DisplayMode* mode) override; void Configure(const display::DisplaySnapshot& output, const display::DisplayMode* mode, const gfx::Point& origin, const display::ConfigureCallback& callback) override; - void CreateFrameBuffer(const gfx::Size& size) override; void GetHDCPState(const display::DisplaySnapshot& output, const display::GetHDCPStateCallback& callback) override; void SetHDCPState(const display::DisplaySnapshot& output, display::HDCPState state, const display::SetHDCPStateCallback& callback) override; - std::vector<display::ColorCalibrationProfile> - GetAvailableColorCalibrationProfiles( - const display::DisplaySnapshot& output) override; - bool SetColorCalibrationProfile( - const display::DisplaySnapshot& output, - display::ColorCalibrationProfile new_profile) override; bool SetColorCorrection( const display::DisplaySnapshot& output, const std::vector<display::GammaRampRGBEntry>& degamma_lut, diff --git a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.cc b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.cc index 2d144393cb4..34099f1cc3e 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.cc +++ b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.cc @@ -12,6 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "ui/gfx/geometry/rect_conversions.h" +#include "ui/ozone/platform/drm/common/drm_util.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" @@ -49,13 +50,14 @@ void DrmOverlayManager::CheckOverlaySupport( OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates, gfx::AcceleratedWidget widget) { TRACE_EVENT0("hwoverlays", "DrmOverlayManager::CheckOverlaySupport"); - std::vector<OverlayCheck_Params> overlay_params; + + OverlaySurfaceCandidateList result_candidates; 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; + result_candidates.push_back(OverlaySurfaceCandidate()); + result_candidates.back().overlay_handled = false; continue; } @@ -64,29 +66,29 @@ void DrmOverlayManager::CheckOverlaySupport( if (candidate.plane_z_order == 0) candidate.buffer_size = gfx::ToNearestRect(candidate.display_rect).size(); - overlay_params.push_back(OverlayCheck_Params(candidate)); + result_candidates.push_back(OverlaySurfaceCandidate(candidate)); + // Start out hoping that we can have an overlay. + result_candidates.back().overlay_handled = true; if (!CanHandleCandidate(candidate, widget)) { DCHECK(candidate.plane_z_order != 0); - overlay_params.back().is_overlay_candidate = false; + result_candidates.back().overlay_handled = false; } } size_t size = candidates->size(); - auto iter = cache_.Get(overlay_params); + auto iter = cache_.Get(result_candidates); if (iter == cache_.end()) { // We can skip GPU side validation in case all candidates are invalid. bool needs_gpu_validation = std::any_of( - overlay_params.begin(), overlay_params.end(), - [](OverlayCheck_Params& c) { return c.is_overlay_candidate; }); + result_candidates.begin(), result_candidates.end(), + [](OverlaySurfaceCandidate& c) { return c.overlay_handled; }); OverlayValidationCacheValue value; value.request_num = 0; - value.returns.resize(overlay_params.size()); - for (size_t i = 0; i < value.returns.size(); ++i) { - value.returns[i].status = - needs_gpu_validation ? OVERLAY_STATUS_PENDING : OVERLAY_STATUS_NOT; - } - iter = cache_.Put(overlay_params, value); + value.status.resize(result_candidates.size(), needs_gpu_validation + ? OVERLAY_STATUS_PENDING + : OVERLAY_STATUS_NOT); + iter = cache_.Put(result_candidates, value); } OverlayValidationCacheValue& value = iter->second; @@ -94,20 +96,19 @@ void DrmOverlayManager::CheckOverlaySupport( value.request_num++; } else if (value.request_num == kThrottleRequestSize) { value.request_num++; - if (value.returns.back().status == OVERLAY_STATUS_PENDING) - SendOverlayValidationRequest(overlay_params, widget); + if (value.status.back() == OVERLAY_STATUS_PENDING) + SendOverlayValidationRequest(result_candidates, widget); } else { // We haven't received an answer yet. - if (value.returns.back().status == OVERLAY_STATUS_PENDING) + if (value.status.back() == OVERLAY_STATUS_PENDING) return; - const std::vector<OverlayCheckReturn_Params>& returns = value.returns; - DCHECK(size == returns.size()); + const std::vector<OverlayStatus>& status = value.status; + DCHECK(size == status.size()); for (size_t i = 0; i < size; i++) { - DCHECK(returns[i].status == OVERLAY_STATUS_ABLE || - returns[i].status == OVERLAY_STATUS_NOT); - candidates->at(i).overlay_handled = - returns[i].status == OVERLAY_STATUS_ABLE; + DCHECK(status[i] == OVERLAY_STATUS_ABLE || + status[i] == OVERLAY_STATUS_NOT); + candidates->at(i).overlay_handled = status[i] == OVERLAY_STATUS_ABLE; } } } @@ -125,25 +126,25 @@ DrmOverlayManager::OverlayValidationCacheValue::~OverlayValidationCacheValue() = default; void DrmOverlayManager::SendOverlayValidationRequest( - const std::vector<OverlayCheck_Params>& new_params, + const OverlaySurfaceCandidateList& candidates, gfx::AcceleratedWidget widget) const { if (!proxy_->IsConnected()) return; TRACE_EVENT_ASYNC_BEGIN0( "hwoverlays", "DrmOverlayManager::SendOverlayValidationRequest", this); - proxy_->GpuCheckOverlayCapabilities(widget, new_params); + proxy_->GpuCheckOverlayCapabilities(widget, candidates); } void DrmOverlayManager::GpuSentOverlayResult( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& params, - const std::vector<OverlayCheckReturn_Params>& returns) { + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& candidates, + const OverlayStatusList& returns) { TRACE_EVENT_ASYNC_END0( "hwoverlays", "DrmOverlayManager::SendOverlayValidationRequest response", this); - auto iter = cache_.Peek(params); + auto iter = cache_.Peek(candidates); if (iter != cache_.end()) { - iter->second.returns = returns; + iter->second.status = returns; } } diff --git a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h index 6ad846997a2..c1915d5714e 100644 --- a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h +++ b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h @@ -35,10 +35,9 @@ class DrmOverlayManager : public OverlayManagerOzone { // Communication-free implementations of actions performed in response to // messages from the GPU thread. - void GpuSentOverlayResult( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& params, - const std::vector<OverlayCheckReturn_Params>& returns); + void GpuSentOverlayResult(const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& params, + const OverlayStatusList& returns); // Service method for DrmOverlayCandidatesHost void CheckOverlaySupport( @@ -54,11 +53,11 @@ class DrmOverlayManager : public OverlayManagerOzone { OverlayValidationCacheValue(const OverlayValidationCacheValue&); ~OverlayValidationCacheValue(); int request_num = 0; - std::vector<OverlayCheckReturn_Params> returns; + std::vector<OverlayStatus> status; }; void SendOverlayValidationRequest( - const std::vector<OverlayCheck_Params>& new_params, + const OverlaySurfaceCandidateList& candidates, gfx::AcceleratedWidget widget) const; bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate, gfx::AcceleratedWidget widget) const; @@ -66,9 +65,9 @@ class DrmOverlayManager : public OverlayManagerOzone { GpuThreadAdapter* proxy_; // Not owned. DrmWindowHostManager* window_manager_; // Not owned. - // List of all OverlayCheck_Params instances which have been requested + // List of all OverlaySurfaceCandidate instances which have been requested // for validation and/or validated. - base::MRUCache<std::vector<OverlayCheck_Params>, OverlayValidationCacheValue> + base::MRUCache<OverlaySurfaceCandidateList, OverlayValidationCacheValue> cache_; DISALLOW_COPY_AND_ASSIGN(DrmOverlayManager); diff --git a/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h b/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h index 4d63d010dfd..f275e66709a 100644 --- a/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h +++ b/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h @@ -38,7 +38,7 @@ class GpuThreadAdapter { virtual bool GpuRefreshNativeDisplays() = 0; virtual bool GpuRelinquishDisplayControl() = 0; virtual bool GpuAddGraphicsDevice(const base::FilePath& path, - const base::FileDescriptor& fd) = 0; + base::ScopedFD fd) = 0; virtual bool GpuRemoveGraphicsDevice(const base::FilePath& path) = 0; // Methods for DrmOverlayManager. @@ -49,7 +49,7 @@ class GpuThreadAdapter { // Services needed by DrmOverlayManager virtual bool GpuCheckOverlayCapabilities( gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& new_params) = 0; + const OverlaySurfaceCandidateList& overlays) = 0; // Services needed by DrmDisplayHost virtual bool GpuConfigureNativeDisplay( diff --git a/chromium/ui/ozone/platform/drm/cursor_proxy_mojo.cc b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc index c48ddcad7c4..ba5baeec450 100644 --- a/chromium/ui/ozone/platform/drm/cursor_proxy_mojo.cc +++ b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc @@ -2,7 +2,7 @@ // 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/cursor_proxy_mojo.h" +#include "ui/ozone/platform/drm/host/host_cursor_proxy.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/interfaces/constants.mojom.h" @@ -10,15 +10,15 @@ namespace ui { // We assume that this is invoked only on the UI thread. -CursorProxyMojo::CursorProxyMojo(service_manager::Connector* connector) +HostCursorProxy::HostCursorProxy(service_manager::Connector* connector) : connector_(connector->Clone()) { ui_thread_ref_ = base::PlatformThread::CurrentRef(); connector->BindInterface(ui::mojom::kServiceName, &main_cursor_ptr_); } -CursorProxyMojo::~CursorProxyMojo() {} +HostCursorProxy::~HostCursorProxy() {} -void CursorProxyMojo::CursorSet(gfx::AcceleratedWidget widget, +void HostCursorProxy::CursorSet(gfx::AcceleratedWidget widget, const std::vector<SkBitmap>& bitmaps, const gfx::Point& location, int frame_delay_ms) { @@ -30,7 +30,7 @@ void CursorProxyMojo::CursorSet(gfx::AcceleratedWidget widget, } } -void CursorProxyMojo::Move(gfx::AcceleratedWidget widget, +void HostCursorProxy::Move(gfx::AcceleratedWidget widget, const gfx::Point& location) { InitializeOnEvdevIfNecessary(); if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) { @@ -40,12 +40,12 @@ void CursorProxyMojo::Move(gfx::AcceleratedWidget widget, } } -// Evdev runs this method on starting. But if a CursorProxyMojo is created long +// Evdev runs this method on starting. But if a HostCursorProxy is created long // after Evdev has started (e.g. if the Viz process crashes (and the -// |CursorProxyMojo| self-destructs and then a new |CursorProxyMojo| is built +// |HostCursorProxy| self-destructs and then a new |HostCursorProxy| is built // when the GpuThread/DrmThread pair are once again running), we need to run it // on cursor motions. -void CursorProxyMojo::InitializeOnEvdevIfNecessary() { +void HostCursorProxy::InitializeOnEvdevIfNecessary() { if (ui_thread_ref_ != base::PlatformThread::CurrentRef()) { connector_->BindInterface(ui::mojom::kServiceName, &evdev_cursor_ptr_); } diff --git a/chromium/ui/ozone/platform/drm/cursor_proxy_mojo.h b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h index e1bceff9208..42feece0e0e 100644 --- a/chromium/ui/ozone/platform/drm/cursor_proxy_mojo.h +++ b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h @@ -2,11 +2,10 @@ // 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_CURSOR_PROXY_MOJO_H_ -#define UI_OZONE_PLATFORM_DRM_CURSOR_PROXY_MOJO_H_ +#ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ +#define UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ #include "ui/gfx/native_widget_types.h" -#include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h" #include "ui/ozone/platform/drm/host/drm_cursor.h" #include "ui/ozone/public/interfaces/device_cursor.mojom.h" @@ -21,10 +20,10 @@ namespace ui { // pointer control via Mojo-style IPC. This code runs only in the mus-ws (i.e. // it's the client) and sends mouse pointer control messages to a less // priviledged process. -class CursorProxyMojo : public DrmCursorProxy { +class HostCursorProxy : public DrmCursorProxy { public: - explicit CursorProxyMojo(service_manager::Connector* connector); - ~CursorProxyMojo() override; + explicit HostCursorProxy(service_manager::Connector* connector); + ~HostCursorProxy() override; private: // DrmCursorProxy. @@ -42,9 +41,9 @@ class CursorProxyMojo : public DrmCursorProxy { ui::ozone::mojom::DeviceCursorPtr evdev_cursor_ptr_; base::PlatformThreadRef ui_thread_ref_; - DISALLOW_COPY_AND_ASSIGN(CursorProxyMojo); + DISALLOW_COPY_AND_ASSIGN(HostCursorProxy); }; } // namespace ui -#endif // UI_OZONE_PLATFORM_DRM_CURSOR_PROXY_MOJO_H_ +#endif // UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_ diff --git a/chromium/ui/ozone/platform/drm/host/host_drm_device.cc b/chromium/ui/ozone/platform/drm/host/host_drm_device.cc new file mode 100644 index 00000000000..628b3c23a16 --- /dev/null +++ b/chromium/ui/ozone/platform/drm/host/host_drm_device.cc @@ -0,0 +1,348 @@ +// 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/host_drm_device.h" + +#include "base/bind.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/ui/public/interfaces/constants.mojom.h" +#include "ui/display/types/display_snapshot.h" +#include "ui/ozone/platform/drm/common/drm_util.h" +#include "ui/ozone/platform/drm/host/drm_display_host_manager.h" +#include "ui/ozone/platform/drm/host/drm_overlay_manager.h" +#include "ui/ozone/platform/drm/host/host_cursor_proxy.h" + +namespace ui { + +HostDrmDevice::HostDrmDevice(DrmCursor* cursor, + service_manager::Connector* connector) + : cursor_(cursor), connector_(connector), weak_ptr_factory_(this) { + // Bind the viz process pointer here. + // TODO(rjkroege): Reconnect on error as that would indicate that the Viz + // process has failed. + connector->BindInterface(ui::mojom::kServiceName, &drm_device_ptr_); +} + +HostDrmDevice::~HostDrmDevice() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + for (GpuThreadObserver& observer : gpu_thread_observers_) + observer.OnGpuThreadRetired(); +} + +void HostDrmDevice::AsyncStartDrmDevice() { + auto callback = base::BindOnce(&HostDrmDevice::OnDrmServiceStartedCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->StartDrmDevice(std::move(callback)); +} + +void HostDrmDevice::BlockingStartDrmDevice() { + // Wait until startup related tasks posted to this thread that must precede + // blocking on + base::RunLoop().RunUntilIdle(); + + bool success; + drm_device_ptr_->StartDrmDevice(&success); + CHECK(success) + << "drm thread failed to successfully start in single process mode."; + if (!connected_) + OnDrmServiceStartedCallback(true); + return; +} + +void HostDrmDevice::OnDrmServiceStartedCallback(bool success) { + // This can be called multiple times in the course of single-threaded startup. + if (connected_) + return; + if (success == true) { + connected_ = true; + RunObservers(); + } + // TODO(rjkroege): Handle failure of launching a viz process. +} + +void HostDrmDevice::ProvideManagers(DrmDisplayHostManager* display_manager, + DrmOverlayManager* overlay_manager) { + display_manager_ = display_manager; + overlay_manager_ = overlay_manager; +} + +void HostDrmDevice::RunObservers() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + for (GpuThreadObserver& observer : gpu_thread_observers_) { + observer.OnGpuProcessLaunched(); + observer.OnGpuThreadReady(); + } + + // The cursor is special since it will process input events on the IO thread + // and can by-pass the UI thread. This means that we need to special case it + // and notify it after all other observers/handlers are notified. + cursor_->SetDrmCursorProxy(base::MakeUnique<HostCursorProxy>(connector_)); + + // TODO(rjkroege): Call ResetDrmCursorProxy when the mojo connection to the + // DRM thread is broken. +} + +void HostDrmDevice::AddGpuThreadObserver(GpuThreadObserver* observer) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + gpu_thread_observers_.AddObserver(observer); + if (IsConnected()) { + observer->OnGpuProcessLaunched(); + observer->OnGpuThreadReady(); + } +} + +void HostDrmDevice::RemoveGpuThreadObserver(GpuThreadObserver* observer) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + gpu_thread_observers_.RemoveObserver(observer); +} + +bool HostDrmDevice::IsConnected() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + + // TODO(rjkroege): Need to set to connected_ to false when we lose the Viz + // process connection. + return connected_; +} + +// Services needed for DrmDisplayHostMananger. +void HostDrmDevice::RegisterHandlerForDrmDisplayHostManager( + DrmDisplayHostManager* handler) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_ = handler; +} + +void HostDrmDevice::UnRegisterHandlerForDrmDisplayHostManager() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_ = nullptr; +} + +bool HostDrmDevice::GpuCreateWindow(gfx::AcceleratedWidget widget) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->CreateWindow(widget); + return true; +} + +bool HostDrmDevice::GpuDestroyWindow(gfx::AcceleratedWidget widget) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->DestroyWindow(widget); + return true; +} + +bool HostDrmDevice::GpuWindowBoundsChanged(gfx::AcceleratedWidget widget, + const gfx::Rect& bounds) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->SetWindowBounds(widget, bounds); + return true; +} + +// Services needed for DrmOverlayManager. +void HostDrmDevice::RegisterHandlerForDrmOverlayManager( + DrmOverlayManager* handler) { + // TODO(rjkroege): Permit overlay manager to run in viz when the display + // compositor runs in viz. + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + overlay_manager_ = handler; +} + +void HostDrmDevice::UnRegisterHandlerForDrmOverlayManager() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + overlay_manager_ = nullptr; +} + +bool HostDrmDevice::GpuCheckOverlayCapabilities( + gfx::AcceleratedWidget widget, + const OverlaySurfaceCandidateList& overlays) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + auto callback = + base::BindOnce(&HostDrmDevice::GpuCheckOverlayCapabilitiesCallback, + weak_ptr_factory_.GetWeakPtr()); + + drm_device_ptr_->CheckOverlayCapabilities(widget, overlays, + std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuRefreshNativeDisplays() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = + base::BindOnce(&HostDrmDevice::GpuRefreshNativeDisplaysCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->RefreshNativeDisplays(std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuConfigureNativeDisplay(int64_t id, + const DisplayMode_Params& pmode, + const gfx::Point& origin) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + // TODO(rjkroege): Remove the use of mode here. + auto mode = CreateDisplayModeFromParams(pmode); + auto callback = + base::BindOnce(&HostDrmDevice::GpuConfigureNativeDisplayCallback, + weak_ptr_factory_.GetWeakPtr()); + + drm_device_ptr_->ConfigureNativeDisplay(id, std::move(mode), origin, + std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuDisableNativeDisplay(int64_t id) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = + base::BindOnce(&HostDrmDevice::GpuDisableNativeDisplayCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->DisableNativeDisplay(id, std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuTakeDisplayControl() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = base::BindOnce(&HostDrmDevice::GpuTakeDisplayControlCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->TakeDisplayControl(std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuRelinquishDisplayControl() { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = + base::BindOnce(&HostDrmDevice::GpuRelinquishDisplayControlCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->TakeDisplayControl(std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuAddGraphicsDevice(const base::FilePath& path, + base::ScopedFD fd) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + base::File file(fd.release()); + drm_device_ptr_->AddGraphicsDevice(path, std::move(file)); + return true; +} + +bool HostDrmDevice::GpuRemoveGraphicsDevice(const base::FilePath& path) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + drm_device_ptr_->RemoveGraphicsDevice(std::move(path)); + return true; +} + +bool HostDrmDevice::GpuGetHDCPState(int64_t display_id) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = base::BindOnce(&HostDrmDevice::GpuGetHDCPStateCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->GetHDCPState(display_id, std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuSetHDCPState(int64_t display_id, + display::HDCPState state) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + auto callback = base::BindOnce(&HostDrmDevice::GpuSetHDCPStateCallback, + weak_ptr_factory_.GetWeakPtr()); + drm_device_ptr_->SetHDCPState(display_id, state, std::move(callback)); + return true; +} + +bool HostDrmDevice::GpuSetColorCorrection( + int64_t id, + const std::vector<display::GammaRampRGBEntry>& degamma_lut, + const std::vector<display::GammaRampRGBEntry>& gamma_lut, + const std::vector<float>& correction_matrix) { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + if (!IsConnected()) + return false; + + drm_device_ptr_->SetColorCorrection(id, degamma_lut, gamma_lut, + correction_matrix); + + return true; +} + +void HostDrmDevice::GpuCheckOverlayCapabilitiesCallback( + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + const OverlayStatusList& returns) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + overlay_manager_->GpuSentOverlayResult(widget, overlays, returns); +} + +void HostDrmDevice::GpuConfigureNativeDisplayCallback(int64_t display_id, + bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuConfiguredDisplay(display_id, success); +} + +// TODO(rjkroege): Remove the unnecessary conversion back into params. +void HostDrmDevice::GpuRefreshNativeDisplaysCallback( + std::vector<std::unique_ptr<display::DisplaySnapshot>> displays) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuHasUpdatedNativeDisplays( + CreateParamsFromSnapshot(displays)); +} + +void HostDrmDevice::GpuDisableNativeDisplayCallback(int64_t display_id, + bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuConfiguredDisplay(display_id, success); +} + +void HostDrmDevice::GpuTakeDisplayControlCallback(bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuTookDisplayControl(success); +} + +void HostDrmDevice::GpuRelinquishDisplayControlCallback(bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuRelinquishedDisplayControl(success); +} + +void HostDrmDevice::GpuGetHDCPStateCallback(int64_t display_id, + bool success, + display::HDCPState state) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuReceivedHDCPState(display_id, success, state); +} + +void HostDrmDevice::GpuSetHDCPStateCallback(int64_t display_id, + bool success) const { + DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_); + display_manager_->GpuUpdatedHDCPState(display_id, success); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/drm/mus_thread_proxy.h b/chromium/ui/ozone/platform/drm/host/host_drm_device.h index 63350ba6a54..47c5b18170d 100644 --- a/chromium/ui/ozone/platform/drm/mus_thread_proxy.h +++ b/chromium/ui/ozone/platform/drm/host/host_drm_device.h @@ -2,26 +2,23 @@ // 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_MUS_THREAD_PROXY_H_ -#define UI_OZONE_PLATFORM_DRM_MUS_THREAD_PROXY_H_ +#ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ +#define UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" #include "ui/gfx/native_widget_types.h" -#include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h" #include "ui/ozone/platform/drm/host/drm_cursor.h" #include "ui/ozone/platform/drm/host/gpu_thread_adapter.h" #include "ui/ozone/public/interfaces/device_cursor.mojom.h" - -namespace base { -class SingleThreadTaskRunner; -} +#include "ui/ozone/public/interfaces/drm_device.mojom.h" namespace display { -class DisplaySnapshotMojo; +class DisplaySnapshot; } namespace service_manager { @@ -29,32 +26,30 @@ class Connector; } namespace ui { - class DrmDisplayHostManager; class DrmOverlayManager; -class DrmThread; class GpuThreadObserver; -class MusThreadProxy; - -// In Mus, the window server thread (analogous to Chrome's UI thread), GPU and -// DRM threads coexist in a single Mus process. The |MusThreadProxy| connects -// these threads together via cross-thread calls. -class MusThreadProxy : public GpuThreadAdapter, - public InterThreadMessagingProxy, - public DrmCursorProxy { + +// This is the Viz host-side library for the DRM device service provided by the +// viz process. +class HostDrmDevice : public GpuThreadAdapter { public: - MusThreadProxy(DrmCursor* cursor, service_manager::Connector* connector); - ~MusThreadProxy() override; + HostDrmDevice(DrmCursor* cursor, service_manager::Connector* connector); + ~HostDrmDevice() override; + + // Start the DRM service. Runs the |OnDrmServiceStartedCallback| when the + // service has launched and initiates the remaining startup. + void AsyncStartDrmDevice(); + + // Blocks until the DRM service has come up. Use this entry point only when + // supporting launch of the service where the ozone UI and GPU + // reponsibilities are performed by the same underlying thread. + void BlockingStartDrmDevice(); - void StartDrmThread(); void ProvideManagers(DrmDisplayHostManager* display_manager, DrmOverlayManager* overlay_manager); - // InterThreadMessagingProxy. - void SetDrmThread(DrmThread* thread) override; - - // This is the core functionality. They are invoked when we have a main - // thread, a gpu thread and we have called initialize on both. + // GpuThreadAdapter void AddGpuThreadObserver(GpuThreadObserver* observer) override; void RemoveGpuThreadObserver(GpuThreadObserver* observer) override; bool IsConnected() override; @@ -68,16 +63,15 @@ class MusThreadProxy : public GpuThreadAdapter, bool GpuRefreshNativeDisplays() override; bool GpuRelinquishDisplayControl() override; bool GpuAddGraphicsDevice(const base::FilePath& path, - const base::FileDescriptor& fd) override; + base::ScopedFD fd) override; bool GpuRemoveGraphicsDevice(const base::FilePath& path) override; // Services needed for DrmOverlayManager. void RegisterHandlerForDrmOverlayManager(DrmOverlayManager* handler) override; void UnRegisterHandlerForDrmOverlayManager() override; - bool GpuCheckOverlayCapabilities( gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& new_params) override; + const OverlaySurfaceCandidateList& new_params) override; // Services needed by DrmDisplayHost bool GpuConfigureNativeDisplay(int64_t display_id, @@ -98,29 +92,21 @@ class MusThreadProxy : public GpuThreadAdapter, bool GpuWindowBoundsChanged(gfx::AcceleratedWidget widget, const gfx::Rect& bounds) override; - // DrmCursorProxy. - void CursorSet(gfx::AcceleratedWidget window, - const std::vector<SkBitmap>& bitmaps, - const gfx::Point& point, - int frame_delay_ms) override; - void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override; - void InitializeOnEvdevIfNecessary() override; - private: + void OnDrmServiceStartedCallback(bool success); + void PollForSingleThreadReady(int previous_delay); void RunObservers(); - void DispatchObserversFromDrmThread(); void GpuCheckOverlayCapabilitiesCallback( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays, - const std::vector<OverlayCheckReturn_Params>& returns) const; + const gfx::AcceleratedWidget& widget, + const OverlaySurfaceCandidateList& overlays, + const OverlayStatusList& returns) const; void GpuConfigureNativeDisplayCallback(int64_t display_id, bool success) const; void GpuRefreshNativeDisplaysCallback( - std::vector<std::unique_ptr<display::DisplaySnapshotMojo>> displays) - const; + std::vector<std::unique_ptr<display::DisplaySnapshot>> displays) const; void GpuDisableNativeDisplayCallback(int64_t display_id, bool success) const; void GpuTakeDisplayControlCallback(bool success) const; void GpuRelinquishDisplayControlCallback(bool success) const; @@ -129,28 +115,24 @@ class MusThreadProxy : public GpuThreadAdapter, display::HDCPState state) const; void GpuSetHDCPStateCallback(int64_t display_id, bool success) const; - scoped_refptr<base::SingleThreadTaskRunner> ws_task_runner_; - - DrmThread* drm_thread_; // Not owned. - - // Guards for multi-theaded access to drm_thread_. - base::Lock lock_; + // Mojo implementation of the DrmDevice. + ui::ozone::mojom::DrmDevicePtr drm_device_ptr_; DrmDisplayHostManager* display_manager_; // Not owned. DrmOverlayManager* overlay_manager_; // Not owned. DrmCursor* cursor_; // Not owned. service_manager::Connector* connector_; + THREAD_CHECKER(on_window_server_thread_); + bool connected_ = false; base::ObserverList<GpuThreadObserver> gpu_thread_observers_; - base::ThreadChecker on_window_server_thread_; - - base::WeakPtrFactory<MusThreadProxy> weak_ptr_factory_; + base::WeakPtrFactory<HostDrmDevice> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(MusThreadProxy); + DISALLOW_COPY_AND_ASSIGN(HostDrmDevice); }; } // namespace ui -#endif // UI_OZONE_PLATFORM_DRM_MUS_THREAD_PROXY_H_ +#endif // UI_OZONE_PLATFORM_DRM_HOST_HOST_DRM_DEVICE_H_ diff --git a/chromium/ui/ozone/platform/drm/mus_thread_proxy.cc b/chromium/ui/ozone/platform/drm/mus_thread_proxy.cc deleted file mode 100644 index 5a15795de7e..00000000000 --- a/chromium/ui/ozone/platform/drm/mus_thread_proxy.cc +++ /dev/null @@ -1,444 +0,0 @@ -// 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/mus_thread_proxy.h" - -#include "base/bind.h" -#include "base/single_thread_task_runner.h" -#include "base/task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "ui/display/types/display_snapshot_mojo.h" -#include "ui/ozone/platform/drm/common/drm_util.h" -#include "ui/ozone/platform/drm/cursor_proxy_mojo.h" -#include "ui/ozone/platform/drm/gpu/drm_thread.h" -#include "ui/ozone/platform/drm/gpu/proxy_helpers.h" -#include "ui/ozone/platform/drm/host/drm_display_host_manager.h" -#include "ui/ozone/platform/drm/host/drm_overlay_manager.h" - -namespace ui { - -namespace { - -// Forwarding proxy to handle ownership semantics. -class CursorProxyThread : public DrmCursorProxy { - public: - explicit CursorProxyThread(MusThreadProxy* mus_thread_proxy); - ~CursorProxyThread() override; - - private: - // DrmCursorProxy. - void CursorSet(gfx::AcceleratedWidget window, - const std::vector<SkBitmap>& bitmaps, - const gfx::Point& point, - int frame_delay_ms) override; - void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override; - void InitializeOnEvdevIfNecessary() override; - MusThreadProxy* const mus_thread_proxy_; // Not owned. - DISALLOW_COPY_AND_ASSIGN(CursorProxyThread); -}; - -CursorProxyThread::CursorProxyThread(MusThreadProxy* mus_thread_proxy) - : mus_thread_proxy_(mus_thread_proxy) {} -CursorProxyThread::~CursorProxyThread() {} - -void CursorProxyThread::CursorSet(gfx::AcceleratedWidget window, - const std::vector<SkBitmap>& bitmaps, - const gfx::Point& point, - int frame_delay_ms) { - mus_thread_proxy_->CursorSet(window, bitmaps, point, frame_delay_ms); -} -void CursorProxyThread::Move(gfx::AcceleratedWidget window, - const gfx::Point& point) { - mus_thread_proxy_->Move(window, point); -} -void CursorProxyThread::InitializeOnEvdevIfNecessary() { - mus_thread_proxy_->InitializeOnEvdevIfNecessary(); -} - -} // namespace - -MusThreadProxy::MusThreadProxy(DrmCursor* cursor, - service_manager::Connector* connector) - : ws_task_runner_(base::ThreadTaskRunnerHandle::Get()), - drm_thread_(nullptr), - cursor_(cursor), - connector_(connector), - weak_ptr_factory_(this) {} - -MusThreadProxy::~MusThreadProxy() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - for (GpuThreadObserver& observer : gpu_thread_observers_) - observer.OnGpuThreadRetired(); -} - -// This is configured on the GPU thread. -void MusThreadProxy::SetDrmThread(DrmThread* thread) { - base::AutoLock acquire(lock_); - drm_thread_ = thread; -} - -void MusThreadProxy::ProvideManagers(DrmDisplayHostManager* display_manager, - DrmOverlayManager* overlay_manager) { - display_manager_ = display_manager; - overlay_manager_ = overlay_manager; -} - -// Runs on Gpu thread. -void MusThreadProxy::StartDrmThread() { - DCHECK(drm_thread_); - drm_thread_->Start(); - - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&MusThreadProxy::DispatchObserversFromDrmThread, - base::Unretained(this))); -} - -void MusThreadProxy::DispatchObserversFromDrmThread() { - ws_task_runner_->PostTask(FROM_HERE, base::Bind(&MusThreadProxy::RunObservers, - base::Unretained(this))); -} - -void MusThreadProxy::RunObservers() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - for (GpuThreadObserver& observer : gpu_thread_observers_) { - // TODO(rjkroege): This needs to be different when gpu process split - // happens. - observer.OnGpuProcessLaunched(); - observer.OnGpuThreadReady(); - } - - // The cursor is special since it will process input events on the IO thread - // and can by-pass the UI thread. This means that we need to special case it - // and notify it after all other observers/handlers are notified. - if (connector_ == nullptr) { - // CursorProxyThread does not need to use delegate because the non-mojo - // MusThreadProxy is only used in tests that do not operate the cursor. - // Future refactoring will unify the mojo and in-process modes. - cursor_->SetDrmCursorProxy(base::MakeUnique<CursorProxyThread>(this)); - } else { - cursor_->SetDrmCursorProxy(base::MakeUnique<CursorProxyMojo>(connector_)); - } - - // TODO(rjkroege): Call ResetDrmCursorProxy when the mojo connection to the - // DRM thread is broken. -} - -void MusThreadProxy::AddGpuThreadObserver(GpuThreadObserver* observer) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - - gpu_thread_observers_.AddObserver(observer); - if (IsConnected()) { - // TODO(rjkroege): This needs to be different when gpu process split - // happens. - observer->OnGpuProcessLaunched(); - observer->OnGpuThreadReady(); - } -} - -void MusThreadProxy::RemoveGpuThreadObserver(GpuThreadObserver* observer) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - gpu_thread_observers_.RemoveObserver(observer); -} - -bool MusThreadProxy::IsConnected() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - base::AutoLock acquire(lock_); - if (drm_thread_) - return drm_thread_->IsRunning(); - return false; -} - -// Services needed for DrmDisplayHostMananger. -void MusThreadProxy::RegisterHandlerForDrmDisplayHostManager( - DrmDisplayHostManager* handler) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_ = handler; -} - -void MusThreadProxy::UnRegisterHandlerForDrmDisplayHostManager() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_ = nullptr; -} - -bool MusThreadProxy::GpuCreateWindow(gfx::AcceleratedWidget widget) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::CreateWindow, - base::Unretained(drm_thread_), widget)); - return true; -} - -bool MusThreadProxy::GpuDestroyWindow(gfx::AcceleratedWidget widget) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::DestroyWindow, - base::Unretained(drm_thread_), widget)); - return true; -} - -bool MusThreadProxy::GpuWindowBoundsChanged(gfx::AcceleratedWidget widget, - const gfx::Rect& bounds) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::SetWindowBounds, - base::Unretained(drm_thread_), widget, bounds)); - return true; -} - -// Services needed for DrmCursorProxy. -void MusThreadProxy::CursorSet(gfx::AcceleratedWidget widget, - const std::vector<SkBitmap>& bitmaps, - const gfx::Point& location, - int frame_delay_ms) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return; - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::Bind(&DrmThread::SetCursor, base::Unretained(drm_thread_), widget, - bitmaps, location, frame_delay_ms)); -} - -void MusThreadProxy::Move(gfx::AcceleratedWidget widget, - const gfx::Point& location) { - // NOTE: Input events skip the main thread to avoid jank. - if (!drm_thread_ || !drm_thread_->IsRunning()) - return; - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::MoveCursor, - base::Unretained(drm_thread_), widget, location)); -} - -void MusThreadProxy::InitializeOnEvdevIfNecessary() {} - -// Services needed for DrmOverlayManager. -void MusThreadProxy::RegisterHandlerForDrmOverlayManager( - DrmOverlayManager* handler) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - overlay_manager_ = handler; -} - -void MusThreadProxy::UnRegisterHandlerForDrmOverlayManager() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - overlay_manager_ = nullptr; -} - -bool MusThreadProxy::GpuCheckOverlayCapabilities( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuCheckOverlayCapabilitiesCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&DrmThread::CheckOverlayCapabilities, - base::Unretained(drm_thread_), widget, overlays, - std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuRefreshNativeDisplays() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuRefreshNativeDisplaysCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DrmThread::RefreshNativeDisplays, - base::Unretained(drm_thread_), std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuConfigureNativeDisplay(int64_t id, - const DisplayMode_Params& pmode, - const gfx::Point& origin) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - - auto mode = CreateDisplayModeFromParams(pmode); - auto callback = - base::BindOnce(&MusThreadProxy::GpuConfigureNativeDisplayCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DrmThread::ConfigureNativeDisplay, - base::Unretained(drm_thread_), id, std::move(mode), origin, - std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuDisableNativeDisplay(int64_t id) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuDisableNativeDisplayCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&DrmThread::DisableNativeDisplay, - base::Unretained(drm_thread_), id, - std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuTakeDisplayControl() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = base::BindOnce(&MusThreadProxy::GpuTakeDisplayControlCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DrmThread::TakeDisplayControl, - base::Unretained(drm_thread_), std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuRelinquishDisplayControl() { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = - base::BindOnce(&MusThreadProxy::GpuRelinquishDisplayControlCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DrmThread::RelinquishDisplayControl, - base::Unretained(drm_thread_), std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuAddGraphicsDevice(const base::FilePath& path, - const base::FileDescriptor& fd) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::AddGraphicsDevice, - base::Unretained(drm_thread_), path, fd)); - return true; -} - -bool MusThreadProxy::GpuRemoveGraphicsDevice(const base::FilePath& path) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - drm_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&DrmThread::RemoveGraphicsDevice, - base::Unretained(drm_thread_), path)); - return true; -} - -bool MusThreadProxy::GpuGetHDCPState(int64_t display_id) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = base::BindOnce(&MusThreadProxy::GpuGetHDCPStateCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DrmThread::GetHDCPState, base::Unretained(drm_thread_), - display_id, std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuSetHDCPState(int64_t display_id, - display::HDCPState state) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - auto callback = base::BindOnce(&MusThreadProxy::GpuSetHDCPStateCallback, - weak_ptr_factory_.GetWeakPtr()); - auto safe_callback = CreateSafeOnceCallback(std::move(callback)); - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&DrmThread::SetHDCPState, base::Unretained(drm_thread_), - display_id, state, std::move(safe_callback))); - return true; -} - -bool MusThreadProxy::GpuSetColorCorrection( - int64_t id, - const std::vector<display::GammaRampRGBEntry>& degamma_lut, - const std::vector<display::GammaRampRGBEntry>& gamma_lut, - const std::vector<float>& correction_matrix) { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - if (!drm_thread_ || !drm_thread_->IsRunning()) - return false; - drm_thread_->task_runner()->PostTask( - FROM_HERE, - base::Bind(&DrmThread::SetColorCorrection, base::Unretained(drm_thread_), - id, degamma_lut, gamma_lut, correction_matrix)); - return true; -} - -void MusThreadProxy::GpuCheckOverlayCapabilitiesCallback( - gfx::AcceleratedWidget widget, - const std::vector<OverlayCheck_Params>& overlays, - const std::vector<OverlayCheckReturn_Params>& returns) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - overlay_manager_->GpuSentOverlayResult(widget, overlays, returns); -} - -void MusThreadProxy::GpuConfigureNativeDisplayCallback(int64_t display_id, - bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuConfiguredDisplay(display_id, success); -} - -void MusThreadProxy::GpuRefreshNativeDisplaysCallback( - std::vector<std::unique_ptr<display::DisplaySnapshotMojo>> displays) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuHasUpdatedNativeDisplays( - CreateParamsFromSnapshot(displays)); -} - -void MusThreadProxy::GpuDisableNativeDisplayCallback(int64_t display_id, - bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuConfiguredDisplay(display_id, success); -} - -void MusThreadProxy::GpuTakeDisplayControlCallback(bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuTookDisplayControl(success); -} - -void MusThreadProxy::GpuRelinquishDisplayControlCallback(bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuRelinquishedDisplayControl(success); -} - -void MusThreadProxy::GpuGetHDCPStateCallback(int64_t display_id, - bool success, - display::HDCPState state) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuReceivedHDCPState(display_id, success, state); -} - -void MusThreadProxy::GpuSetHDCPStateCallback(int64_t display_id, - bool success) const { - DCHECK(on_window_server_thread_.CalledOnValidThread()); - display_manager_->GpuUpdatedHDCPState(display_id, success); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc b/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc index 109c5a97ed2..cc0bb2f5720 100644 --- a/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc @@ -17,6 +17,8 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" @@ -25,7 +27,6 @@ #include "ui/events/ozone/evdev/event_factory_evdev.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/ozone/platform/drm/common/drm_util.h" -#include "ui/ozone/platform/drm/cursor_proxy_mojo.h" #include "ui/ozone/platform/drm/gpu/drm_device_generator.h" #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" @@ -42,7 +43,7 @@ #include "ui/ozone/platform/drm/host/drm_overlay_manager.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/platform/drm/mus_thread_proxy.h" +#include "ui/ozone/platform/drm/host/host_drm_device.h" #include "ui/ozone/public/cursor_factory_ozone.h" #include "ui/ozone/public/gpu_platform_support_host.h" #include "ui/ozone/public/ozone_platform.h" @@ -81,7 +82,8 @@ class GlApiLoader { class OzonePlatformGbm : public OzonePlatform { public: - OzonePlatformGbm() : using_mojo_(false), single_process_(false) {} + OzonePlatformGbm() + : using_mojo_(false), single_process_(false), weak_factory_(this) {} ~OzonePlatformGbm() override {} // OzonePlatform: @@ -106,26 +108,45 @@ class OzonePlatformGbm : public OzonePlatform { std::unique_ptr<SystemInputInjector> CreateSystemInputInjector() override { return event_factory_ozone_->CreateSystemInputInjector(); } + void AddInterfaces( service_manager::BinderRegistryWithArgs< const service_manager::BindSourceInfo&>* registry) override { registry->AddInterface<ozone::mojom::DeviceCursor>( - base::Bind(&OzonePlatformGbm::Create, base::Unretained(this)), + base::Bind(&OzonePlatformGbm::CreateDeviceCursorBinding, + weak_factory_.GetWeakPtr()), + gpu_task_runner_); + + registry->AddInterface<ozone::mojom::DrmDevice>( + base::Bind(&OzonePlatformGbm::CreateDrmDeviceBinding, + weak_factory_.GetWeakPtr()), gpu_task_runner_); } - void Create(ozone::mojom::DeviceCursorRequest request, - const service_manager::BindSourceInfo& source_info) { + void CreateDeviceCursorBinding( + ozone::mojom::DeviceCursorRequest request, + const service_manager::BindSourceInfo& source_info) { if (drm_thread_proxy_) - drm_thread_proxy_->AddBinding(std::move(request)); + drm_thread_proxy_->AddBindingCursorDevice(std::move(request)); else pending_cursor_requests_.push_back(std::move(request)); } + + // service_manager::InterfaceFactory<ozone::mojom::DrmDevice>: + void CreateDrmDeviceBinding( + ozone::mojom::DrmDeviceRequest request, + const service_manager::BindSourceInfo& source_info) { + if (drm_thread_proxy_) + drm_thread_proxy_->AddBindingDrmDevice(std::move(request)); + else + pending_gpu_adapter_requests_.push_back(std::move(request)); + } + std::unique_ptr<PlatformWindow> CreatePlatformWindow( PlatformWindowDelegate* delegate, const gfx::Rect& bounds) override { GpuThreadAdapter* adapter = gpu_platform_support_host_.get(); if (using_mojo_ || single_process_) { - adapter = mus_thread_proxy_.get(); + adapter = host_drm_device_.get(); } std::unique_ptr<DrmWindowHost> platform_window(new DrmWindowHost( @@ -140,18 +161,18 @@ class OzonePlatformGbm : public OzonePlatform { } void InitializeUI(const InitParams& args) override { // Ozone drm can operate in three modes configured at runtime: - // 1. legacy mode where browser and gpu components communicate + // 1. legacy mode where host and viz components communicate // via param traits IPC. - // 2. single-process mode where browser and gpu components - // communicate via PostTask. - // 3. mojo mode where browser and gpu components communicate + // 2. single-process mode where host and viz components + // communicate via in-process mojo. + // 3. multi-process mode where host and viz components communicate // via mojo IPC. - // Currently, mojo mode uses mojo in a single process but this is - // an interim implementation detail that will be eliminated in a - // future CL. single_process_ = args.single_process; using_mojo_ = args.connector != nullptr; - DCHECK(!(using_mojo_ && single_process_)); + host_thread_ = base::PlatformThread::CurrentRef(); + + DCHECK(!(using_mojo_ && !single_process_)) + << "Multiprocess Mojo is not supported yet."; device_manager_ = CreateDeviceManager(); window_manager_.reset(new DrmWindowHostManager()); @@ -170,18 +191,13 @@ class OzonePlatformGbm : public OzonePlatform { GpuThreadAdapter* adapter; - // TODO(rjkroege): Once mus is split, only do this for single_process. - if (single_process_ || using_mojo_) + if (single_process_) gl_api_loader_.reset(new GlApiLoader()); if (using_mojo_) { - mus_thread_proxy_ = - base::MakeUnique<MusThreadProxy>(cursor_.get(), args.connector); - adapter = mus_thread_proxy_.get(); - } else if (single_process_) { - mus_thread_proxy_ = - base::MakeUnique<MusThreadProxy>(cursor_.get(), nullptr); - adapter = mus_thread_proxy_.get(); + host_drm_device_ = + base::MakeUnique<HostDrmDevice>(cursor_.get(), args.connector); + adapter = host_drm_device_.get(); } else { gpu_platform_support_host_.reset( new DrmGpuPlatformSupportHost(cursor_.get())); @@ -195,24 +211,27 @@ class OzonePlatformGbm : public OzonePlatform { event_factory_ozone_->input_controller())); cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone); - if (using_mojo_ || single_process_) { - mus_thread_proxy_->ProvideManagers(display_manager_.get(), - overlay_manager_.get()); + if (using_mojo_) { + host_drm_device_->ProvideManagers(display_manager_.get(), + overlay_manager_.get()); + host_drm_device_->AsyncStartDrmDevice(); } } + void InitializeGPU(const InitParams& args) override { // TODO(rjkroege): services/ui should initialize this with a connector. // However, in-progress refactorings in services/ui make it difficult to // require this at present. Set using_mojo_ like below once this is // complete. + // TODO(rjk): Make it possible to turn this on. // using_mojo_ = args.connector != nullptr; - gpu_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - InterThreadMessagingProxy* itmp; - if (using_mojo_ || single_process_) { - itmp = mus_thread_proxy_.get(); - } else { + + if (!single_process_) gl_api_loader_.reset(new GlApiLoader()); + + InterThreadMessagingProxy* itmp; + if (!using_mojo_) { scoped_refptr<DrmThreadMessageProxy> message_proxy( new DrmThreadMessageProxy()); itmp = message_proxy.get(); @@ -222,40 +241,77 @@ class OzonePlatformGbm : public OzonePlatform { // NOTE: Can't start the thread here since this is called before sandbox // initialization in multi-process Chrome. In mus, we start the DRM thread. drm_thread_proxy_.reset(new DrmThreadProxy()); - drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp); surface_factory_.reset(new GbmSurfaceFactory(drm_thread_proxy_.get())); - if (using_mojo_ || single_process_) { - mus_thread_proxy_->StartDrmThread(); + if (!using_mojo_) { + drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp); + } else { + drm_thread_proxy_->StartDrmThread(); } + + // When the viz process (and hence the gpu portion of ozone/gbm) is + // operating in a single process, the AddInterfaces method is best + // invoked before the GPU thread launches. As a result, requests to add + // mojom bindings to the as yet un-launched service will fail so we queue + // incoming binding requests until the GPU thread is running and play them + // back here. for (auto& request : pending_cursor_requests_) - drm_thread_proxy_->AddBinding(std::move(request)); + drm_thread_proxy_->AddBindingCursorDevice(std::move(request)); pending_cursor_requests_.clear(); + for (auto& request : pending_gpu_adapter_requests_) + drm_thread_proxy_->AddBindingDrmDevice(std::move(request)); + pending_gpu_adapter_requests_.clear(); + + // If InitializeGPU and InitializeUI are invoked on the same thread, startup + // sequencing is complicated because tasks are queued on the unbound mojo + // pipe connecting the UI (the host) to the DRM thread before the DRM thread + // is launched above. Special case this sequence vis the + // BlockingStartDrmDevice API. + // TODO(rjkroege): In a future when we have completed splitting Viz, it will + // be possible to simplify this logic. + if (using_mojo_ && single_process_ && + host_thread_ == base::PlatformThread::CurrentRef()) { + CHECK(host_drm_device_) + << "Mojo single-process mode requires a HostDrmDevice."; + host_drm_device_->BlockingStartDrmDevice(); + } } private: bool using_mojo_; bool single_process_; - - // Bridges the DRM, GPU and main threads in mus. This must be destroyed last. - std::unique_ptr<MusThreadProxy> mus_thread_proxy_; + base::PlatformThreadRef host_thread_; // Objects in the GPU process. std::unique_ptr<DrmThreadProxy> drm_thread_proxy_; std::unique_ptr<GlApiLoader> gl_api_loader_; std::unique_ptr<GbmSurfaceFactory> surface_factory_; scoped_refptr<IPC::MessageFilter> gpu_message_filter_; - // TODO(sad): Once the mus gpu process split happens, this can go away. - std::vector<ozone::mojom::DeviceCursorRequest> pending_cursor_requests_; scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; + // TODO(rjkroege,sadrul): Provide a more elegant solution for this issue when + // running in single process mode. + std::vector<ozone::mojom::DeviceCursorRequest> pending_cursor_requests_; + std::vector<ozone::mojom::DrmDeviceRequest> pending_gpu_adapter_requests_; + + // gpu_platform_support_host_ is the IPC bridge to the GPU process while + // host_drm_device_ is the mojo bridge to the Viz process. Only one can be in + // use at any time. + // TODO(rjkroege): Remove gpu_platform_support_host_ once ozone/drm with mojo + // has reached the stable channel. + // A raw pointer to either |gpu_platform_support_host_| or |host_drm_device_| + // is passed to |display_manager_| and |overlay_manager_| in IntializeUI. + // To avoid a use after free, the following two members should be declared + // before the two managers, so that they're deleted after them. + std::unique_ptr<DrmGpuPlatformSupportHost> gpu_platform_support_host_; + std::unique_ptr<HostDrmDevice> host_drm_device_; + // Objects in the Browser process. std::unique_ptr<DeviceManager> device_manager_; std::unique_ptr<BitmapCursorFactoryOzone> cursor_factory_ozone_; std::unique_ptr<DrmWindowHostManager> window_manager_; std::unique_ptr<DrmCursor> cursor_; std::unique_ptr<EventFactoryEvdev> event_factory_ozone_; - std::unique_ptr<DrmGpuPlatformSupportHost> gpu_platform_support_host_; std::unique_ptr<DrmDisplayHostManager> display_manager_; std::unique_ptr<DrmOverlayManager> overlay_manager_; @@ -263,6 +319,8 @@ class OzonePlatformGbm : public OzonePlatform { XkbEvdevCodes xkb_evdev_code_converter_; #endif + base::WeakPtrFactory<OzonePlatformGbm> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(OzonePlatformGbm); }; diff --git a/chromium/ui/ozone/platform/headless/headless_surface_factory.cc b/chromium/ui/ozone/platform/headless/headless_surface_factory.cc index d3c9f35a05f..40583a3527a 100644 --- a/chromium/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/chromium/ui/ozone/platform/headless/headless_surface_factory.cc @@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/task_scheduler/post_task.h" +#include "build/build_config.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/gfx/codec/png_codec.h" @@ -108,14 +109,21 @@ HeadlessSurfaceFactory::HeadlessSurfaceFactory() HeadlessSurfaceFactory::HeadlessSurfaceFactory( HeadlessWindowManager* window_manager) - : window_manager_(window_manager), - osmesa_implementation_(base::MakeUnique<GLOzoneOSMesa>()) {} + : window_manager_(window_manager) { +#if !defined(OS_FUCHSIA) + osmesa_implementation_ = base::MakeUnique<GLOzoneOSMesa>(); +#endif +} HeadlessSurfaceFactory::~HeadlessSurfaceFactory() {} std::vector<gl::GLImplementation> HeadlessSurfaceFactory::GetAllowedGLImplementations() { +#if defined(OS_FUCHSIA) + return std::vector<gl::GLImplementation>{gl::kGLImplementationStubGL}; +#else return std::vector<gl::GLImplementation>{gl::kGLImplementationOSMesaGL}; +#endif } GLOzone* HeadlessSurfaceFactory::GetGLOzone( diff --git a/chromium/ui/ozone/platform/headless/headless_window_manager.h b/chromium/ui/ozone/platform/headless/headless_window_manager.h index d57f091e888..f0ee9120034 100644 --- a/chromium/ui/ozone/platform/headless/headless_window_manager.h +++ b/chromium/ui/ozone/platform/headless/headless_window_manager.h @@ -9,8 +9,8 @@ #include <memory> +#include "base/containers/id_map.h" #include "base/files/file_path.h" -#include "base/id_map.h" #include "base/macros.h" #include "base/threading/thread_checker.h" #include "ui/gfx/native_widget_types.h" @@ -43,7 +43,7 @@ class HeadlessWindowManager { private: base::FilePath location_; - IDMap<HeadlessWindow*> windows_; + base::IDMap<HeadlessWindow*> windows_; base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(HeadlessWindowManager); diff --git a/chromium/ui/ozone/platform/wayland/gl_surface_wayland.cc b/chromium/ui/ozone/platform/wayland/gl_surface_wayland.cc index d1e64cc216c..5827383eefe 100644 --- a/chromium/ui/ozone/platform/wayland/gl_surface_wayland.cc +++ b/chromium/ui/ozone/platform/wayland/gl_surface_wayland.cc @@ -35,6 +35,7 @@ GLSurfaceWayland::GLSurfaceWayland(WaylandEglWindowPtr egl_window) bool GLSurfaceWayland::Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) { if (size_ == size) return true; diff --git a/chromium/ui/ozone/platform/wayland/gl_surface_wayland.h b/chromium/ui/ozone/platform/wayland/gl_surface_wayland.h index ca27fbf7133..27b81f0e192 100644 --- a/chromium/ui/ozone/platform/wayland/gl_surface_wayland.h +++ b/chromium/ui/ozone/platform/wayland/gl_surface_wayland.h @@ -34,6 +34,7 @@ class GLSurfaceWayland : public gl::NativeViewGLSurfaceEGL { // gl::GLSurface: bool Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) override; EGLConfig GetConfig() override; diff --git a/chromium/ui/ozone/platform/wayland/wayland_window.cc b/chromium/ui/ozone/platform/wayland/wayland_window.cc index 85cfee522e4..a7f4313bd13 100644 --- a/chromium/ui/ozone/platform/wayland/wayland_window.cc +++ b/chromium/ui/ozone/platform/wayland/wayland_window.cc @@ -96,7 +96,7 @@ gfx::Rect WaylandWindow::GetBounds() { void WaylandWindow::SetTitle(const base::string16& title) { DCHECK(xdg_surface_); - xdg_surface_set_title(xdg_surface_.get(), UTF16ToUTF8(title).c_str()); + xdg_surface_set_title(xdg_surface_.get(), base::UTF16ToUTF8(title).c_str()); connection_->ScheduleFlush(); } diff --git a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc index 0fc232ee590..ea4348778d7 100644 --- a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc +++ b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc @@ -80,6 +80,7 @@ EGLConfig GLSurfaceEGLOzoneX11::GetConfig() { bool GLSurfaceEGLOzoneX11::Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) { if (size == GetSize()) return true; diff --git a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h index ec044651872..dcb419083b9 100644 --- a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h +++ b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h @@ -21,6 +21,7 @@ class GLSurfaceEGLOzoneX11 : public gl::NativeViewGLSurfaceEGL { EGLConfig GetConfig() override; bool Resize(const gfx::Size& size, float scale_factor, + ColorSpace color_space, bool has_alpha) override; private: diff --git a/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc b/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc index 072c5b02551..58176cc0fbc 100644 --- a/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc +++ b/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc @@ -9,7 +9,6 @@ #include <memory> #include <utility> -#include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" @@ -32,16 +31,6 @@ namespace ui { namespace { -// Returns true if a flag is present that will cause Ozone UI and GPU to run in -// the same process. -// TODO(kylechar): Remove --mojo-platform-channel-handle when mus-ws process -// split happens. -bool HasSingleProcessFlag() { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - return command_line->HasSwitch("mojo-platform-channel-handle") || - command_line->HasSwitch("single-process"); -} - // Singleton OzonePlatform implementation for X11 platform. class OzonePlatformX11 : public OzonePlatform { public: @@ -106,7 +95,7 @@ class OzonePlatformX11 : public OzonePlatform { // In single process mode either the UI thread will create an event source // or it's a test and an event source isn't desired. - if (!params.single_process && !HasSingleProcessFlag()) + if (!params.single_process) CreatePlatformEventSource(); surface_factory_ozone_ = base::MakeUnique<X11SurfaceFactory>(); @@ -127,7 +116,7 @@ class OzonePlatformX11 : public OzonePlatform { return; // In single process mode XInitThreads() must be the first Xlib call. - if (params.single_process || HasSingleProcessFlag()) + if (params.single_process) XInitThreads(); ui::SetDefaultX11ErrorHandlers(); diff --git a/chromium/ui/ozone/public/input_controller.cc b/chromium/ui/ozone/public/input_controller.cc index 5aa300240b4..7ee1a3712b6 100644 --- a/chromium/ui/ozone/public/input_controller.cc +++ b/chromium/ui/ozone/public/input_controller.cc @@ -40,6 +40,7 @@ class StubInputController : public InputController { void SetNaturalScroll(bool enabled) override; void SetMouseSensitivity(int value) override; void SetPrimaryButtonRight(bool right) override; + void SetMouseReverseScroll(bool enabled) override; void SetTapToClickPaused(bool state) override; void GetTouchDeviceStatus(GetTouchDeviceStatusReply reply) override; void GetTouchEventLog(const base::FilePath& out_dir, @@ -121,6 +122,9 @@ void StubInputController::SetMouseSensitivity(int value) { void StubInputController::SetPrimaryButtonRight(bool right) { } +void StubInputController::SetMouseReverseScroll(bool enabled) { +} + void StubInputController::SetTapToClickPaused(bool state) { } diff --git a/chromium/ui/ozone/public/input_controller.h b/chromium/ui/ozone/public/input_controller.h index cdec1d54b65..f791a8b5022 100644 --- a/chromium/ui/ozone/public/input_controller.h +++ b/chromium/ui/ozone/public/input_controller.h @@ -65,6 +65,7 @@ class OZONE_BASE_EXPORT InputController { // Mouse settings. virtual void SetMouseSensitivity(int value) = 0; virtual void SetPrimaryButtonRight(bool right) = 0; + virtual void SetMouseReverseScroll(bool enabled) = 0; // Touch log collection. virtual void GetTouchDeviceStatus(GetTouchDeviceStatusReply reply) = 0; diff --git a/chromium/ui/ozone/public/interfaces/BUILD.gn b/chromium/ui/ozone/public/interfaces/BUILD.gn index 48221f5185c..f66bf8a1248 100644 --- a/chromium/ui/ozone/public/interfaces/BUILD.gn +++ b/chromium/ui/ozone/public/interfaces/BUILD.gn @@ -7,11 +7,14 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("interfaces") { sources = [ "device_cursor.mojom", + "drm_device.mojom", "overlay_surface_candidate.mojom", ] public_deps = [ + "//mojo/common:common_custom_types", "//skia/public/interfaces:interfaces", + "//ui/display/mojo:interfaces", "//ui/gfx/geometry/mojo", "//ui/gfx/mojo", ] diff --git a/chromium/ui/ozone/public/interfaces/drm_device.mojom b/chromium/ui/ozone/public/interfaces/drm_device.mojom new file mode 100644 index 00000000000..eede42437b0 --- /dev/null +++ b/chromium/ui/ozone/public/interfaces/drm_device.mojom @@ -0,0 +1,86 @@ +// Copyright 2017 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. + +module ui.ozone.mojom; + +import "mojo/common/file.mojom"; +import "mojo/common/file_path.mojom"; +import "ui/display/mojo/display_constants.mojom"; +import "ui/display/mojo/display_mode.mojom"; +import "ui/display/mojo/display_snapshot.mojom"; +import "ui/display/mojo/gamma_ramp_rgb_entry.mojom"; +import "ui/gfx/geometry/mojo/geometry.mojom"; +import "ui/gfx/mojo/accelerated_widget.mojom"; +import "ui/ozone/public/interfaces/overlay_surface_candidate.mojom"; + + +// The viz process on CrOS implements the DrmDevice +// service to let the viz host and clients manage DRM displays. +// All functions in DrmDevice are implemented by the lower privilege viz +// process. +interface DrmDevice { + // Starts the DRM service and returns true on success. + [Sync] + StartDrmDevice() => (bool success); + + // Creates scanout capable DRM buffers to back |widget|. + CreateWindow(gfx.mojom.AcceleratedWidget widget); + + // Destroys the DRM buffers backing |widget|. + DestroyWindow(gfx.mojom.AcceleratedWidget widget); + + // Sets the size of the DRM buffer for |widget|. + SetWindowBounds(gfx.mojom.AcceleratedWidget widget, gfx.mojom.Rect bounds); + + // Takes control of the display and invoke a provided callback with a boolean + // status. + TakeDisplayControl() => (bool success); + + // Releases control of the display and invoke a provided callback with a + // boolean status. + RelinquishDisplayControl() => (bool success); + + // Requests a callback providing a list of the available displays. + RefreshNativeDisplays() => + (array<display.mojom.DisplaySnapshot> display_snapshots); + + // Transfers ownership of a DRM device to the GPU process. + AddGraphicsDevice(mojo.common.mojom.FilePath path, + mojo.common.mojom.File file); + + // Instructs the GPU to abandon a DRM device. + RemoveGraphicsDevice(mojo.common.mojom.FilePath path); + + // Instructs the GPU to disable a DRM device. + DisableNativeDisplay(int64 display_id) => (int64 display_id, bool success); + + // Configures a DRM display returning true on success. + ConfigureNativeDisplay(int64 display_id, + display.mojom.DisplayMode display_mode, + gfx.mojom.Point point) => + (int64 display_id, bool success); + + // Gets or sets high-definition content protection (HDCP) (DRM as in + // digital rights management) state. + GetHDCPState(int64 display_id) => + (int64 display_id, bool success, display.mojom.HDCPState state); + SetHDCPState(int64 display_id, display.mojom.HDCPState state) => + (int64 display_id, bool success); + + // Sets a color correction gamma table. + SetColorCorrection(int64 display_id, + array<display.mojom.GammaRampRGBEntry> degamma_lut, + array<display.mojom.GammaRampRGBEntry> gamma_lut, + array<float> correction_matrix); + + // Verifies if the display controller can successfully scanout the given set + // of OverlaySurfaceCandidates and return the status associated with each + // candidate. + CheckOverlayCapabilities(gfx.mojom.AcceleratedWidget widget, + array<ui.ozone.mojom.OverlaySurfaceCandidate> candidates) => + (gfx.mojom.AcceleratedWidget widget, + array<ui.ozone.mojom.OverlaySurfaceCandidate> candidates, + array<ui.ozone.mojom.OverlayStatus> status); +}; + diff --git a/chromium/ui/ozone/public/overlay_candidates_ozone.h b/chromium/ui/ozone/public/overlay_candidates_ozone.h index 760721feea0..8ccc8610215 100644 --- a/chromium/ui/ozone/public/overlay_candidates_ozone.h +++ b/chromium/ui/ozone/public/overlay_candidates_ozone.h @@ -17,7 +17,7 @@ namespace ui { // class from SurfaceFactoryOzone given an AcceleratedWidget. class OZONE_BASE_EXPORT OverlayCandidatesOzone { public: - typedef std::vector<OverlaySurfaceCandidate> OverlaySurfaceCandidateList; + using OverlaySurfaceCandidateList = std::vector<OverlaySurfaceCandidate>; // A list of possible overlay candidates is presented to this function. // The expected result is that those candidates that can be in a separate diff --git a/chromium/ui/ozone/public/overlay_surface_candidate.cc b/chromium/ui/ozone/public/overlay_surface_candidate.cc index 3612d21810f..9065638d37a 100644 --- a/chromium/ui/ozone/public/overlay_surface_candidate.cc +++ b/chromium/ui/ozone/public/overlay_surface_candidate.cc @@ -4,6 +4,8 @@ #include "ui/ozone/public/overlay_surface_candidate.h" +#include "ui/gfx/geometry/rect_conversions.h" + namespace ui { OverlaySurfaceCandidate::OverlaySurfaceCandidate() : is_clipped(false) {} @@ -13,4 +15,18 @@ OverlaySurfaceCandidate::OverlaySurfaceCandidate( OverlaySurfaceCandidate::~OverlaySurfaceCandidate() {} +bool OverlaySurfaceCandidate::operator<( + const OverlaySurfaceCandidate& param) const { + int lwidth = buffer_size.width(); + int lheight = buffer_size.height(); + int rwidth = param.buffer_size.width(); + int rheight = param.buffer_size.height(); + gfx::Rect lrect = gfx::ToNearestRect(display_rect); + gfx::Rect rrect = gfx::ToNearestRect(param.display_rect); + + return std::tie(plane_z_order, format, lrect, lwidth, lheight, transform) < + std::tie(param.plane_z_order, param.format, rrect, rwidth, rheight, + param.transform); +} + } // namespace ui diff --git a/chromium/ui/ozone/public/overlay_surface_candidate.h b/chromium/ui/ozone/public/overlay_surface_candidate.h index 904d69f5df8..aee7095af0c 100644 --- a/chromium/ui/ozone/public/overlay_surface_candidate.h +++ b/chromium/ui/ozone/public/overlay_surface_candidate.h @@ -5,6 +5,8 @@ #ifndef UI_OZONE_PUBLIC_OVERLAY_SURFACE_CANDIDATE_H_ #define UI_OZONE_PUBLIC_OVERLAY_SURFACE_CANDIDATE_H_ +#include <vector> + #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" @@ -27,6 +29,8 @@ class OZONE_BASE_EXPORT OverlaySurfaceCandidate { OverlaySurfaceCandidate(const OverlaySurfaceCandidate& other); ~OverlaySurfaceCandidate(); + bool operator<(const OverlaySurfaceCandidate& plane) const; + // Transformation to apply to layer during composition. gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE; // Format of the buffer to composite. @@ -52,6 +56,9 @@ class OZONE_BASE_EXPORT OverlaySurfaceCandidate { bool overlay_handled = false; }; +using OverlaySurfaceCandidateList = std::vector<OverlaySurfaceCandidate>; +using OverlayStatusList = std::vector<OverlayStatus>; + } // namespace ui #endif // UI_OZONE_PUBLIC_OVERLAY_SURFACE_CANDIDATE_H_ |