diff options
author | Zeno Albisser <zeno.albisser@theqtcompany.com> | 2014-12-05 15:04:29 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@theqtcompany.com> | 2014-12-09 10:49:28 +0100 |
commit | af6588f8d723931a298c995fa97259bb7f7deb55 (patch) | |
tree | 060ca707847ba1735f01af2372e0d5e494dc0366 /chromium/ui/ozone | |
parent | 2fff84d821cc7b1c785f6404e0f8091333283e74 (diff) | |
download | qtwebengine-chromium-af6588f8d723931a298c995fa97259bb7f7deb55.tar.gz |
BASELINE: Update chromium to 40.0.2214.28 and ninja to 1.5.3.
Change-Id: I759465284fd64d59ad120219cbe257f7402c4181
Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/ui/ozone')
174 files changed, 8209 insertions, 3250 deletions
diff --git a/chromium/ui/ozone/BUILD.gn b/chromium/ui/ozone/BUILD.gn index a2d3f4712b7..a01056b46b9 100644 --- a/chromium/ui/ozone/BUILD.gn +++ b/chromium/ui/ozone/BUILD.gn @@ -4,53 +4,169 @@ import("//ui/ozone/ozone.gni") -declare_args() { - # The default platform for Ozone. - ozone_platform = "test" +# The list of platforms that will be built. +ozone_platforms = [] + +# Extra dependencies to pull into ui/ozone for built platforms. +ozone_platform_deps = [] + +# Extra dependencies to pull into ozone_unittests for built platforms. +ozone_platform_test_deps = [] + +if (ozone_platform_egltest) { + ozone_platforms += [ "egltest" ] + ozone_platform_deps += [ "platform/egltest" ] +} + +if (ozone_platform_test) { + ozone_platforms += [ "test" ] + ozone_platform_deps += [ "platform/test" ] +} + +if (ozone_platform_caca) { + ozone_platforms += [ "caca" ] + ozone_platform_deps += [ "platform/caca" ] +} + +if (ozone_platform_dri) { + ozone_platforms += [ "dri" ] + ozone_platform_deps += [ "platform/dri" ] + ozone_platform_test_deps += [ "platform/dri:dri_unittests" ] +} + +if (ozone_platform_gbm) { + ozone_platforms += [ "gbm" ] + ozone_platform_deps += [ "platform/dri:gbm" ] } -platform_list_file = "$target_gen_dir/ozone_platform_list.cc" +platform_list_cc_file = "$target_gen_dir/platform_list.cc" +platform_list_h_file = "$target_gen_dir/platform_list.h" +platform_list_txt_file = "$target_gen_dir/platform_list.txt" +constructor_list_cc_file = "$target_gen_dir/constructor_list.cc" + +# GYP version: ui/ozone/ozone.gyp:ozone_base +component("ozone_base") { + sources = [ + "public/cursor_factory_ozone.cc", + "public/cursor_factory_ozone.h", + "public/gpu_platform_support.cc", + "public/gpu_platform_support.h", + "public/gpu_platform_support_host.cc", + "public/gpu_platform_support_host.h", + "public/overlay_candidates_ozone.cc", + "public/overlay_candidates_ozone.h", + "public/surface_factory_ozone.cc", + "public/surface_factory_ozone.h", + "public/surface_ozone_canvas.h", + "public/surface_ozone_egl.h", + ] + + defines = [ "OZONE_BASE_IMPLEMENTATION" ] + + deps = [ + "//base", + "//skia", + "//ui/gfx/geometry", + ] +} component("ozone") { sources = [ - platform_list_file, - # common/chromeos files are excluded automatically when building with - # chromeos=0, by exclusion rules in filename_rules.gypi due to the - # "chromeos" folder name. - "common/chromeos/native_display_delegate_ozone.cc", - "common/chromeos/native_display_delegate_ozone.h", - "ozone_platform.cc", - "ozone_platform.h", - "ozone_switches.cc", - "ozone_switches.h", + platform_list_cc_file, + platform_list_h_file, + constructor_list_cc_file, + + "common/display_mode_proxy.cc", + "common/display_mode_proxy.h", + "common/display_snapshot_proxy.cc", + "common/display_snapshot_proxy.h", + "common/display_util.cc", + "common/display_util.h", + "common/gpu/ozone_gpu_message_generator.cc", + "common/gpu/ozone_gpu_message_generator.h", + "common/gpu/ozone_gpu_message_params.cc", + "common/gpu/ozone_gpu_message_params.h", + "common/gpu/ozone_gpu_messages.h", + "common/native_display_delegate_ozone.cc", + "common/native_display_delegate_ozone.h", + "public/ozone_platform.cc", + "public/ozone_platform.h", + "public/ozone_switches.cc", + "public/ozone_switches.h", + "public/ui_thread_gpu.cc", + "public/ui_thread_gpu.h", + "platform_selection.cc", + "platform_selection.h", ] defines = [ "OZONE_IMPLEMENTATION" ] deps = [ + ":generate_constructor_list", ":generate_ozone_platform_list", + ":ozone_base", "//base", + "//ipc", "//skia", - "//ui/base", + "//ui/display/types", + "//ui/display/util", "//ui/events", + "//ui/events/ozone:events_ozone", "//ui/gfx", "//ui/gfx/geometry", - "//ui/gfx/ozone", - ] -} + "//ui/gfx/ipc", + # TODO(GYP) the GYP version has a way to add additional dependencies via + # build flags. + ] + ozone_platform_deps -# TODO(GYP) implement the ozone platforms. This should check the various -# ozone_platform_*flags, and add deps and add to the ozone_platforms list for -# the script below. -ozone_platforms = "" +} +# GYP version: ui/ozone/ozone.gyp:generate_ozone_platform_list action("generate_ozone_platform_list") { script = "generate_ozone_platform_list.py" - outputs = [ platform_list_file ] + outputs = [ + platform_list_cc_file, + platform_list_h_file, + platform_list_txt_file + ] args = [ - "--output_file=" + rebase_path(platform_list_file, root_build_dir), + "--output_cc=" + rebase_path(platform_list_cc_file, root_build_dir), + "--output_h=" + rebase_path(platform_list_h_file, root_build_dir), + "--output_txt=" + rebase_path(platform_list_txt_file, root_build_dir), "--default=$ozone_platform", - ozone_platforms, + ] + ozone_platforms +} + +# GYP version: ui/ozone/ozone.gyp:generate_constructor_list +action("generate_constructor_list") { + script = "generate_constructor_list.py" + + source_prereqs = [ + platform_list_txt_file, + ] + outputs = [ + constructor_list_cc_file, ] + + args = [ + "--platform_list=" + rebase_path(platform_list_txt_file, root_build_dir), + "--output_cc=" + rebase_path(constructor_list_cc_file, root_build_dir), + "--namespace=ui", + "--typename=OzonePlatform", + "--include=\"ui/ozone/public/ozone_platform.h\"", + ] + + deps = [ ":generate_ozone_platform_list" ] +} + +test("ozone_unittests") { + sources = [ + "run_all_unittests.cc", + ] + + deps = [ + "//base/test:test_support", + "//testing/gtest", + ] + ozone_platform_test_deps } diff --git a/chromium/ui/ozone/DEPS b/chromium/ui/ozone/DEPS index 734601935b3..a0192580707 100644 --- a/chromium/ui/ozone/DEPS +++ b/chromium/ui/ozone/DEPS @@ -1,6 +1,10 @@ include_rules = [ + "+skia/ext", + "+third_party/khronos", + "+third_party/skia", "+ui/display/types", "+ui/events", "+ui/gfx", "+ui/base/cursor", + "+ui/platform_window", ] diff --git a/chromium/ui/ozone/PRESUBMIT.py b/chromium/ui/ozone/PRESUBMIT.py new file mode 100644 index 00000000000..6b822c90a77 --- /dev/null +++ b/chromium/ui/ozone/PRESUBMIT.py @@ -0,0 +1,14 @@ +# 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. + +"""Presubmit script for ozone. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +def CheckChangeOnUpload(input_api, output_api): + results = [] + results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api) + return results diff --git a/chromium/ui/ozone/common/chromeos/native_display_delegate_ozone.h b/chromium/ui/ozone/common/chromeos/native_display_delegate_ozone.h deleted file mode 100644 index cb61bd7c14f..00000000000 --- a/chromium/ui/ozone/common/chromeos/native_display_delegate_ozone.h +++ /dev/null @@ -1,51 +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_CHROMEOS_NATIVE_DISPLAY_DELEGATE_OZONE_H_ -#define UI_OZONE_COMMON_CHROMEOS_NATIVE_DISPLAY_DELEGATE_OZONE_H_ - -#include "base/macros.h" -#include "ui/display/types/chromeos/native_display_delegate.h" - -namespace ui { - -class NativeDisplayDelegateOzone : public NativeDisplayDelegate { - public: - NativeDisplayDelegateOzone(); - virtual ~NativeDisplayDelegateOzone(); - - // NativeDisplayDelegate overrides: - virtual void Initialize() OVERRIDE; - virtual void GrabServer() OVERRIDE; - virtual void UngrabServer() OVERRIDE; - virtual void SyncWithServer() OVERRIDE; - virtual void SetBackgroundColor(uint32_t color_argb) OVERRIDE; - virtual void ForceDPMSOn() OVERRIDE; - virtual std::vector<ui::DisplaySnapshot*> GetDisplays() OVERRIDE; - virtual void AddMode(const ui::DisplaySnapshot& output, - const ui::DisplayMode* mode) OVERRIDE; - virtual bool Configure(const ui::DisplaySnapshot& output, - const ui::DisplayMode* mode, - const gfx::Point& origin) OVERRIDE; - virtual void CreateFrameBuffer(const gfx::Size& size) OVERRIDE; - virtual bool GetHDCPState(const ui::DisplaySnapshot& output, - ui::HDCPState* state) OVERRIDE; - virtual bool SetHDCPState(const ui::DisplaySnapshot& output, - ui::HDCPState state) OVERRIDE; - virtual std::vector<ui::ColorCalibrationProfile> - GetAvailableColorCalibrationProfiles( - const ui::DisplaySnapshot& output) OVERRIDE; - virtual bool SetColorCalibrationProfile( - const ui::DisplaySnapshot& output, - ui::ColorCalibrationProfile new_profile) OVERRIDE; - virtual void AddObserver(NativeDisplayObserver* observer) OVERRIDE; - virtual void RemoveObserver(NativeDisplayObserver* observer) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateOzone); -}; - -} // namespace ui - -#endif // UI_OZONE_COMMON_CHROMEOS_NATIVE_DISPLAY_DELEGATE_OZONE_H_ diff --git a/chromium/ui/ozone/common/chromeos/touchscreen_device_manager_ozone.cc b/chromium/ui/ozone/common/chromeos/touchscreen_device_manager_ozone.cc deleted file mode 100644 index 92f4ff9fd6d..00000000000 --- a/chromium/ui/ozone/common/chromeos/touchscreen_device_manager_ozone.cc +++ /dev/null @@ -1,20 +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/chromeos/touchscreen_device_manager_ozone.h" - -#include "base/logging.h" - -namespace ui { - -TouchscreenDeviceManagerOzone::TouchscreenDeviceManagerOzone() {} - -TouchscreenDeviceManagerOzone::~TouchscreenDeviceManagerOzone() {} - -std::vector<TouchscreenDevice> TouchscreenDeviceManagerOzone::GetDevices() { - NOTIMPLEMENTED(); - return std::vector<TouchscreenDevice>(); -} - -} // namespace ui diff --git a/chromium/ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h b/chromium/ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h deleted file mode 100644 index db0c00edbf2..00000000000 --- a/chromium/ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h +++ /dev/null @@ -1,27 +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_TOUCHSCREEN_DEVICE_MANAGER_OZONE_H_ -#define UI_OZONE_COMMON_TOUCHSCREEN_DEVICE_MANAGER_OZONE_H_ - -#include "base/macros.h" -#include "ui/display/types/chromeos/touchscreen_device_manager.h" - -namespace ui { - -class TouchscreenDeviceManagerOzone : public TouchscreenDeviceManager { - public: - TouchscreenDeviceManagerOzone(); - virtual ~TouchscreenDeviceManagerOzone(); - - // TouchscreenDeviceManager: - virtual std::vector<TouchscreenDevice> GetDevices() OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(TouchscreenDeviceManagerOzone); -}; - -} // namespace ui - -#endif // UI_OZONE_COMMON_TOUCHSCREEN_DEVICE_MANAGER_OZONE_H_ diff --git a/chromium/ui/ozone/common/display_mode_proxy.cc b/chromium/ui/ozone/common/display_mode_proxy.cc new file mode 100644 index 00000000000..6890b33f37c --- /dev/null +++ b/chromium/ui/ozone/common/display_mode_proxy.cc @@ -0,0 +1,18 @@ +// 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_mode_proxy.h" + +#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" + +namespace ui { + +DisplayModeProxy::DisplayModeProxy(const DisplayMode_Params& params) + : DisplayMode(params.size, params.is_interlaced, params.refresh_rate) { +} + +DisplayModeProxy::~DisplayModeProxy() { +} + +} // namespace ui diff --git a/chromium/ui/ozone/common/display_mode_proxy.h b/chromium/ui/ozone/common/display_mode_proxy.h new file mode 100644 index 00000000000..f9211c13e04 --- /dev/null +++ b/chromium/ui/ozone/common/display_mode_proxy.h @@ -0,0 +1,25 @@ +// 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_MODE_PROXY_H_ +#define UI_OZONE_COMMON_DISPLAY_MODE_PROXY_H_ + +#include "ui/display/types/display_mode.h" + +namespace ui { + +struct DisplayMode_Params; + +class DisplayModeProxy : public DisplayMode { + public: + DisplayModeProxy(const DisplayMode_Params& params); + ~DisplayModeProxy() override; + + private: + DISALLOW_COPY_AND_ASSIGN(DisplayModeProxy); +}; + +} // namespace ui + +#endif // UI_OZONE_COMMON_DISPLAY_MODE_PROXY_H_ diff --git a/chromium/ui/ozone/common/display_snapshot_proxy.cc b/chromium/ui/ozone/common/display_snapshot_proxy.cc new file mode 100644 index 00000000000..4bc9e247ed7 --- /dev/null +++ b/chromium/ui/ozone/common/display_snapshot_proxy.cc @@ -0,0 +1,53 @@ +// 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 "ui/ozone/common/display_mode_proxy.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) + : DisplaySnapshot(params.display_id, + params.origin, + params.physical_size, + params.type, + params.is_aspect_preserving_scaling, + params.has_overscan, + params.display_name, + std::vector<const DisplayMode*>(), + NULL, + NULL), + string_representation_(params.string_representation) { + for (size_t i = 0; i < params.modes.size(); ++i) { + modes_.push_back(new DisplayModeProxy(params.modes[i])); + + if (params.has_current_mode && + SameModes(params.modes[i], params.current_mode)) + current_mode_ = modes_.back(); + + if (params.has_native_mode && + SameModes(params.modes[i], params.native_mode)) + native_mode_ = modes_.back(); + } +} + +DisplaySnapshotProxy::~DisplaySnapshotProxy() { +} + +std::string DisplaySnapshotProxy::ToString() const { + return string_representation_; +} + +} // namespace ui diff --git a/chromium/ui/ozone/common/display_snapshot_proxy.h b/chromium/ui/ozone/common/display_snapshot_proxy.h new file mode 100644 index 00000000000..158f58444f7 --- /dev/null +++ b/chromium/ui/ozone/common/display_snapshot_proxy.h @@ -0,0 +1,30 @@ +// 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 "ui/display/types/display_snapshot.h" + +namespace ui { + +struct DisplaySnapshot_Params; + +class DisplaySnapshotProxy : public DisplaySnapshot { + public: + DisplaySnapshotProxy(const DisplaySnapshot_Params& params); + ~DisplaySnapshotProxy() override; + + // DisplaySnapshot override: + std::string ToString() const override; + + private: + std::string string_representation_; + + DISALLOW_COPY_AND_ASSIGN(DisplaySnapshotProxy); +}; + +} // namespace ui + +#endif // UI_OZONE_COMMON_DISPLAY_SNAPSHOT_PROXY_H_ diff --git a/chromium/ui/ozone/common/display_util.cc b/chromium/ui/ozone/common/display_util.cc new file mode 100644 index 00000000000..8db7c3a6871 --- /dev/null +++ b/chromium/ui/ozone/common/display_util.cc @@ -0,0 +1,47 @@ +// 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_util.h" + +#include "ui/display/types/display_mode.h" +#include "ui/display/types/display_snapshot.h" + +namespace ui { + +DisplayMode_Params GetDisplayModeParams(const DisplayMode& mode) { + DisplayMode_Params params; + params.size = mode.size(); + params.is_interlaced = mode.is_interlaced(); + params.refresh_rate = mode.refresh_rate(); + + return params; +} + +DisplaySnapshot_Params GetDisplaySnapshotParams( + const DisplaySnapshot& display) { + DisplaySnapshot_Params params; + params.display_id = display.display_id(); + params.origin = display.origin(); + params.physical_size = display.physical_size(); + params.type = display.type(); + params.is_aspect_preserving_scaling = display.is_aspect_preserving_scaling(); + params.has_overscan = display.has_overscan(); + params.display_name = display.display_name(); + for (size_t i = 0; i < display.modes().size(); ++i) + params.modes.push_back(GetDisplayModeParams(*display.modes()[i])); + + params.has_current_mode = display.current_mode() != NULL; + if (params.has_current_mode) + params.current_mode = GetDisplayModeParams(*display.current_mode()); + + params.has_native_mode = display.native_mode() != NULL; + if (params.has_native_mode) + params.native_mode = GetDisplayModeParams(*display.native_mode()); + + params.string_representation = display.ToString(); + + return params; +} + +} // namespace ui diff --git a/chromium/ui/ozone/common/display_util.h b/chromium/ui/ozone/common/display_util.h new file mode 100644 index 00000000000..7c4f92aaddf --- /dev/null +++ b/chromium/ui/ozone/common/display_util.h @@ -0,0 +1,20 @@ +// 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_UTIL_H_ +#define UI_OZONE_COMMON_DISPLAY_UTIL_H_ + +#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" + +namespace ui { + +class DisplayMode; +class DisplaySnapshot; + +DisplayMode_Params GetDisplayModeParams(const DisplayMode& mode); +DisplaySnapshot_Params GetDisplaySnapshotParams(const DisplaySnapshot& display); + +} // namespace ui + +#endif // UI_OZONE_COMMON_DISPLAY_UTIL_H_ diff --git a/chromium/ui/ozone/common/gpu/OWNERS b/chromium/ui/ozone/common/gpu/OWNERS new file mode 100644 index 00000000000..8757192bb36 --- /dev/null +++ b/chromium/ui/ozone/common/gpu/OWNERS @@ -0,0 +1,10 @@ +# Changes to IPC messages require a security review to avoid introducing +# new sandbox escapes. +per-file *_message*.h=set noparent +per-file *_message*.h=dcheng@chromium.org +per-file *_message*.h=inferno@chromium.org +per-file *_message*.h=jln@chromium.org +per-file *_message*.h=jschuh@chromium.org +per-file *_message*.h=kenrb@chromium.org +per-file *_message*.h=nasko@chromium.org +per-file *_message*.h=tsepez@chromium.org diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_generator.cc b/chromium/ui/ozone/common/gpu/ozone_gpu_message_generator.cc new file mode 100644 index 00000000000..d3032ed706a --- /dev/null +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_generator.cc @@ -0,0 +1,33 @@ +// 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. + +// Get basic type definitions. +#define IPC_MESSAGE_IMPL +#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" + +// Generate constructors. +#include "ipc/struct_constructor_macros.h" +#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" + +// Generate destructors. +#include "ipc/struct_destructor_macros.h" +#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" + +// Generate param traits write methods. +#include "ipc/param_traits_write_macros.h" +namespace IPC { +#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" +} // namespace IPC + +// Generate param traits read methods. +#include "ipc/param_traits_read_macros.h" +namespace IPC { +#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" +} // namespace IPC + +// Generate param traits log methods. +#include "ipc/param_traits_log_macros.h" +namespace IPC { +#include "ui/ozone/common/gpu/ozone_gpu_message_generator.h" +} // namespace IPC diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_generator.h b/chromium/ui/ozone/common/gpu/ozone_gpu_message_generator.h new file mode 100644 index 00000000000..3b35c0e7bce --- /dev/null +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_generator.h @@ -0,0 +1,7 @@ +// 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. + +// Multiply-included file, hence no include guard. + +#include "ui/ozone/common/gpu/ozone_gpu_messages.h" diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc new file mode 100644 index 00000000000..aae2e147ccd --- /dev/null +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc @@ -0,0 +1,30 @@ +// 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/gpu/ozone_gpu_message_params.h" + +namespace ui { + +DisplayMode_Params::DisplayMode_Params() + : size(), is_interlaced(false), refresh_rate(0.0f) {} + +DisplayMode_Params::~DisplayMode_Params() {} + +DisplaySnapshot_Params::DisplaySnapshot_Params() + : display_id(0), + origin(), + physical_size(), + type(ui::DISPLAY_CONNECTION_TYPE_NONE), + is_aspect_preserving_scaling(false), + has_overscan(false), + display_name(), + modes(), + has_current_mode(false), + current_mode(), + has_native_mode(false), + native_mode() {} + +DisplaySnapshot_Params::~DisplaySnapshot_Params() {} + +} // 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 new file mode 100644 index 00000000000..fe35df9f6b9 --- /dev/null +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h @@ -0,0 +1,48 @@ +// 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_GPU_OZONE_GPU_MESSAGE_PARAMS_H_ +#define UI_OZONE_COMMON_GPU_OZONE_GPU_MESSAGE_PARAMS_H_ + +#include <string> +#include <vector> + +#include "ui/display/types/display_constants.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/size.h" + +namespace ui { + +struct DisplayMode_Params { + DisplayMode_Params(); + ~DisplayMode_Params(); + + gfx::Size size; + bool is_interlaced; + float refresh_rate; +}; + +struct DisplaySnapshot_Params { + DisplaySnapshot_Params(); + ~DisplaySnapshot_Params(); + + int64_t display_id; + gfx::Point origin; + gfx::Size physical_size; + DisplayConnectionType type; + bool is_aspect_preserving_scaling; + bool has_overscan; + std::string display_name; + std::vector<DisplayMode_Params> modes; + bool has_current_mode; + DisplayMode_Params current_mode; + bool has_native_mode; + DisplayMode_Params native_mode; + std::string string_representation; +}; + +} // namespace ui + +#endif // UI_OZONE_COMMON_GPU_OZONE_GPU_MESSAGE_PARAMS_H_ + diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h b/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h new file mode 100644 index 00000000000..c98f153e44a --- /dev/null +++ b/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h @@ -0,0 +1,108 @@ +// 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. + +// Multiply-included message file, hence no include guard here, but see below +// for a much smaller-than-usual include guard section. + +#include <vector> + +#include "ipc/ipc_message_macros.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/ipc/gfx_param_traits.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" +#include "ui/ozone/ozone_export.h" + +#undef IPC_MESSAGE_EXPORT +#define IPC_MESSAGE_EXPORT OZONE_EXPORT + +#define IPC_MESSAGE_START OzoneGpuMsgStart + +IPC_ENUM_TRAITS_MAX_VALUE(ui::DisplayConnectionType, + ui::DISPLAY_CONNECTION_TYPE_LAST) + +IPC_STRUCT_TRAITS_BEGIN(ui::DisplayMode_Params) + IPC_STRUCT_TRAITS_MEMBER(size) + IPC_STRUCT_TRAITS_MEMBER(is_interlaced) + IPC_STRUCT_TRAITS_MEMBER(refresh_rate) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(ui::DisplaySnapshot_Params) + IPC_STRUCT_TRAITS_MEMBER(display_id) + IPC_STRUCT_TRAITS_MEMBER(origin) + IPC_STRUCT_TRAITS_MEMBER(physical_size) + IPC_STRUCT_TRAITS_MEMBER(type) + IPC_STRUCT_TRAITS_MEMBER(is_aspect_preserving_scaling) + IPC_STRUCT_TRAITS_MEMBER(has_overscan) + IPC_STRUCT_TRAITS_MEMBER(display_name) + IPC_STRUCT_TRAITS_MEMBER(modes) + IPC_STRUCT_TRAITS_MEMBER(has_current_mode) + IPC_STRUCT_TRAITS_MEMBER(current_mode) + IPC_STRUCT_TRAITS_MEMBER(has_native_mode) + IPC_STRUCT_TRAITS_MEMBER(native_mode) + IPC_STRUCT_TRAITS_MEMBER(string_representation) +IPC_STRUCT_TRAITS_END() + +//------------------------------------------------------------------------------ +// GPU Messages +// These are messages from the browser to the GPU process. + +// Update the HW cursor bitmap & move to specified location. +IPC_MESSAGE_CONTROL4(OzoneGpuMsg_CursorSet, + gfx::AcceleratedWidget, + std::vector<SkBitmap>, + gfx::Point /* location */, + int /* frame_delay_ms */) + +// Move the HW cursor to the specified location. +IPC_MESSAGE_CONTROL2(OzoneGpuMsg_CursorMove, + gfx::AcceleratedWidget, gfx::Point) + +// Explicit creation of a WindowDelegate. We explicitly create the window +// delegate such that any state change in the window is not lost while the +// surface is created on the GPU side. +IPC_MESSAGE_CONTROL1(OzoneGpuMsg_CreateWindowDelegate, + gfx::AcceleratedWidget /* widget */) + +IPC_MESSAGE_CONTROL1(OzoneGpuMsg_DestroyWindowDelegate, + gfx::AcceleratedWidget /* widget */) + +// Updates the location and size of the widget on the screen. +IPC_MESSAGE_CONTROL2(OzoneGpuMsg_WindowBoundsChanged, + gfx::AcceleratedWidget /* widget */, + gfx::Rect /* bounds */) + +// Force the DPMS state of the display to on. +IPC_MESSAGE_CONTROL0(OzoneGpuMsg_ForceDPMSOn) + +// Trigger a display reconfiguration. OzoneHostMsg_UpdateNativeDisplays will be +// sent as a response. +// The |displays| parameter will hold a list of last known displays. +IPC_MESSAGE_CONTROL1(OzoneGpuMsg_RefreshNativeDisplays, + std::vector<ui::DisplaySnapshot_Params> /* displays */) + +// Configure a display with the specified mode at the specified location. +IPC_MESSAGE_CONTROL3(OzoneGpuMsg_ConfigureNativeDisplay, + int64_t, // display ID + ui::DisplayMode_Params, // display mode + gfx::Point) // origin for the display + +IPC_MESSAGE_CONTROL1(OzoneGpuMsg_DisableNativeDisplay, + int64_t) // display ID + +// Take control of the display +IPC_MESSAGE_CONTROL0(OzoneGpuMsg_TakeDisplayControl) + +// Let other entity control the display +IPC_MESSAGE_CONTROL0(OzoneGpuMsg_RelinquishDisplayControl) + +//------------------------------------------------------------------------------ +// Browser Messages +// These messages are from the GPU to the browser process. + +// Updates the list of active displays. +IPC_MESSAGE_CONTROL1(OzoneHostMsg_UpdateNativeDisplays, + std::vector<ui::DisplaySnapshot_Params>) diff --git a/chromium/ui/ozone/common/chromeos/native_display_delegate_ozone.cc b/chromium/ui/ozone/common/native_display_delegate_ozone.cc index 2efc18d7446..eca120f4a15 100644 --- a/chromium/ui/ozone/common/chromeos/native_display_delegate_ozone.cc +++ b/chromium/ui/ozone/common/native_display_delegate_ozone.cc @@ -2,15 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h" +#include "ui/ozone/common/native_display_delegate_ozone.h" #include "base/logging.h" namespace ui { -NativeDisplayDelegateOzone::NativeDisplayDelegateOzone() {} +NativeDisplayDelegateOzone::NativeDisplayDelegateOzone() { +} -NativeDisplayDelegateOzone::~NativeDisplayDelegateOzone() {} +NativeDisplayDelegateOzone::~NativeDisplayDelegateOzone() { +} void NativeDisplayDelegateOzone::Initialize() { NOTIMPLEMENTED(); @@ -24,6 +26,16 @@ void NativeDisplayDelegateOzone::UngrabServer() { NOTIMPLEMENTED(); } +bool NativeDisplayDelegateOzone::TakeDisplayControl() { + NOTIMPLEMENTED(); + return false; +} + +bool NativeDisplayDelegateOzone::RelinquishDisplayControl() { + NOTIMPLEMENTED(); + return false; +} + void NativeDisplayDelegateOzone::SyncWithServer() { NOTIMPLEMENTED(); } diff --git a/chromium/ui/ozone/common/native_display_delegate_ozone.h b/chromium/ui/ozone/common/native_display_delegate_ozone.h new file mode 100644 index 00000000000..037f231a779 --- /dev/null +++ b/chromium/ui/ozone/common/native_display_delegate_ozone.h @@ -0,0 +1,52 @@ +// 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_NATIVE_DISPLAY_DELEGATE_OZONE_H_ +#define UI_OZONE_COMMON_NATIVE_DISPLAY_DELEGATE_OZONE_H_ + +#include "base/macros.h" +#include "ui/display/types/native_display_delegate.h" + +namespace ui { + +class NativeDisplayDelegateOzone : public NativeDisplayDelegate { + public: + NativeDisplayDelegateOzone(); + ~NativeDisplayDelegateOzone() override; + + // NativeDisplayDelegate overrides: + void Initialize() override; + void GrabServer() override; + void UngrabServer() override; + bool TakeDisplayControl() override; + bool RelinquishDisplayControl() override; + void SyncWithServer() override; + void SetBackgroundColor(uint32_t color_argb) override; + void ForceDPMSOn() override; + std::vector<ui::DisplaySnapshot*> GetDisplays() override; + void AddMode(const ui::DisplaySnapshot& output, + const ui::DisplayMode* mode) override; + bool Configure(const ui::DisplaySnapshot& output, + const ui::DisplayMode* mode, + const gfx::Point& origin) override; + void CreateFrameBuffer(const gfx::Size& size) override; + bool GetHDCPState(const ui::DisplaySnapshot& output, + ui::HDCPState* state) override; + bool SetHDCPState(const ui::DisplaySnapshot& output, + ui::HDCPState state) override; + std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles( + const ui::DisplaySnapshot& output) override; + bool SetColorCalibrationProfile( + const ui::DisplaySnapshot& output, + ui::ColorCalibrationProfile new_profile) override; + void AddObserver(NativeDisplayObserver* observer) override; + void RemoveObserver(NativeDisplayObserver* observer) override; + + private: + DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateOzone); +}; + +} // namespace ui + +#endif // UI_OZONE_COMMON_NATIVE_DISPLAY_DELEGATE_OZONE_H_ diff --git a/chromium/ui/ozone/demo/BUILD.gn b/chromium/ui/ozone/demo/BUILD.gn new file mode 100644 index 00000000000..c58431bf919 --- /dev/null +++ b/chromium/ui/ozone/demo/BUILD.gn @@ -0,0 +1,23 @@ +# 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. + +group("demo") { + deps = [ + ":ozone_demo", + ] +} + +executable("ozone_demo") { + sources = [ + "ozone_demo.cc", + ] + + deps = [ + "//base", + "//skia", + "//ui/gfx/geometry", + "//ui/gl", + "//ui/ozone", + ] +} diff --git a/chromium/ui/ozone/public/DEPS b/chromium/ui/ozone/demo/DEPS index 717f3aeed17..f59fd384c0e 100644 --- a/chromium/ui/ozone/public/DEPS +++ b/chromium/ui/ozone/demo/DEPS @@ -1,3 +1,3 @@ include_rules = [ - "+skia/ext", + "+ui/gl", ] diff --git a/chromium/ui/ozone/demo/ozone_demo.cc b/chromium/ui/ozone/demo/ozone_demo.cc new file mode 100644 index 00000000000..2d4dbf42869 --- /dev/null +++ b/chromium/ui/ozone/demo/ozone_demo.cc @@ -0,0 +1,218 @@ +// 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 "base/at_exit.h" +#include "base/command_line.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/timer/timer.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_surface.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/surface_factory_ozone.h" +#include "ui/ozone/public/surface_ozone_canvas.h" +#include "ui/ozone/public/ui_thread_gpu.h" +#include "ui/platform_window/platform_window.h" +#include "ui/platform_window/platform_window_delegate.h" + +const int kTestWindowWidth = 800; +const int kTestWindowHeight = 600; + +const int kFrameDelayMilliseconds = 16; + +const int kAnimationSteps = 240; + +const char kDisableGpu[] = "disable-gpu"; + +class DemoWindow : public ui::PlatformWindowDelegate { + public: + DemoWindow() : widget_(gfx::kNullAcceleratedWidget), iteration_(0) { + platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( + this, gfx::Rect(kTestWindowWidth, kTestWindowHeight)); + } + ~DemoWindow() override {} + + gfx::AcceleratedWidget GetAcceleratedWidget() { + // TODO(spang): We should start rendering asynchronously. + DCHECK_NE(widget_, gfx::kNullAcceleratedWidget) + << "Widget not available synchronously"; + return widget_; + } + + gfx::Size GetSize() { return platform_window_->GetBounds().size(); } + + void Start() { + if (!CommandLine::ForCurrentProcess()->HasSwitch(kDisableGpu) && + gfx::GLSurface::InitializeOneOff() && StartInProcessGpu() && + InitializeGLSurface()) { + StartAnimationGL(); + } else if (InitializeSoftwareSurface()) { + StartAnimationSoftware(); + } else { + LOG(ERROR) << "Failed to create drawing surface"; + Quit(); + } + } + + void Quit() { + StopAnimation(); + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&base::DeletePointer<DemoWindow>, this)); + } + + // PlatformWindowDelegate: + void OnBoundsChanged(const gfx::Rect& new_bounds) override {} + void OnDamageRect(const gfx::Rect& damaged_region) override {} + void DispatchEvent(ui::Event* event) override {} + void OnCloseRequest() override { Quit(); } + void OnClosed() override {} + void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} + void OnLostCapture() override {} + void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override { + DCHECK_NE(widget, gfx::kNullAcceleratedWidget); + widget_ = widget; + } + void OnActivationChanged(bool active) override {} + + private: + bool InitializeGLSurface() { + surface_ = gfx::GLSurface::CreateViewGLSurface(GetAcceleratedWidget()); + if (!surface_.get()) { + LOG(ERROR) << "Failed to create GL surface"; + return false; + } + + context_ = gfx::GLContext::CreateGLContext( + NULL, surface_.get(), gfx::PreferIntegratedGpu); + if (!context_.get()) { + LOG(ERROR) << "Failed to create GL context"; + surface_ = NULL; + return false; + } + + surface_->Resize(GetSize()); + + if (!context_->MakeCurrent(surface_.get())) { + LOG(ERROR) << "Failed to make GL context current"; + surface_ = NULL; + context_ = NULL; + return false; + } + + return true; + } + + bool InitializeSoftwareSurface() { + software_surface_ = + ui::SurfaceFactoryOzone::GetInstance()->CreateCanvasForWidget( + GetAcceleratedWidget()); + if (!software_surface_) { + LOG(ERROR) << "Failed to create software surface"; + return false; + } + + software_surface_->ResizeCanvas(GetSize()); + return true; + } + + void StartAnimationGL() { + timer_.Start(FROM_HERE, + base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds), + this, + &DemoWindow::RenderFrameGL); + } + + void StartAnimationSoftware() { + timer_.Start(FROM_HERE, + base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds), + this, + &DemoWindow::RenderFrameSoftware); + } + + void StopAnimation() { timer_.Stop(); } + + float NextFraction() { + float fraction = (sinf(iteration_ * 2 * M_PI / kAnimationSteps) + 1) / 2; + + iteration_++; + iteration_ %= kAnimationSteps; + + return fraction; + } + + void RenderFrameGL() { + float fraction = NextFraction(); + gfx::Size window_size = GetSize(); + + glViewport(0, 0, window_size.width(), window_size.height()); + glClearColor(1 - fraction, fraction, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (!surface_->SwapBuffers()) + LOG(FATAL) << "Failed to swap buffers"; + } + + void RenderFrameSoftware() { + float fraction = NextFraction(); + gfx::Size window_size = GetSize(); + + skia::RefPtr<SkCanvas> canvas = software_surface_->GetCanvas(); + + SkColor color = + SkColorSetARGB(0xff, 0, 0xff * fraction, 0xff * (1 - fraction)); + + canvas->clear(color); + + software_surface_->PresentCanvas(gfx::Rect(window_size)); + } + + bool StartInProcessGpu() { return ui_thread_gpu_.Initialize(); } + + // Timer for animation. + base::RepeatingTimer<DemoWindow> timer_; + + // Bits for GL rendering. + scoped_refptr<gfx::GLSurface> surface_; + scoped_refptr<gfx::GLContext> context_; + + // Bits for software rendeirng. + scoped_ptr<ui::SurfaceOzoneCanvas> software_surface_; + + // Window-related state. + scoped_ptr<ui::PlatformWindow> platform_window_; + gfx::AcceleratedWidget widget_; + + // Helper for applications that do GL on main thread. + ui::UiThreadGpu ui_thread_gpu_; + + // Animation state. + int iteration_; + + DISALLOW_COPY_AND_ASSIGN(DemoWindow); +}; + +int main(int argc, char** argv) { + CommandLine::Init(argc, argv); + base::AtExitManager exit_manager; + + // Build UI thread message loop. This is used by platform + // implementations for event polling & running background tasks. + base::MessageLoopForUI message_loop; + + ui::OzonePlatform::InitializeForUI(); + + DemoWindow* window = new DemoWindow; + window->Start(); + + // Run the message loop until there's nothing left to do. + // TODO(spang): Should we use QuitClosure instead? + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + + return 0; +} diff --git a/chromium/ui/ozone/demo/ozone_demos.gyp b/chromium/ui/ozone/demo/ozone_demos.gyp new file mode 100644 index 00000000000..edd3e323def --- /dev/null +++ b/chromium/ui/ozone/demo/ozone_demos.gyp @@ -0,0 +1,26 @@ +# 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'ozone_demo', + 'type': 'executable', + 'dependencies': [ + '../../../base/base.gyp:base', + '../../../skia/skia.gyp:skia', + '../../../ui/gfx/gfx.gyp:gfx_geometry', + '../../../ui/gl/gl.gyp:gl', + '../../../ui/ozone/ozone.gyp:ozone', + '../../../ui/ozone/ozone.gyp:ozone_base', + ], + 'sources': [ + 'ozone_demo.cc', + ], + }, + ], +} diff --git a/chromium/ui/ozone/gpu/BUILD.gn b/chromium/ui/ozone/gpu/BUILD.gn new file mode 100644 index 00000000000..91d38f9c2b0 --- /dev/null +++ b/chromium/ui/ozone/gpu/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +component("gpu") { + sources = [ + "gpu_memory_buffer_factory_ozone_native_buffer.cc", + "gpu_memory_buffer_factory_ozone_native_buffer.h", + ] + + defines = [ "OZONE_GPU_IMPLEMENTATION" ] + + deps = [ + "//base", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + ] +} diff --git a/chromium/ui/ozone/gpu/DEPS b/chromium/ui/ozone/gpu/DEPS new file mode 100644 index 00000000000..f59fd384c0e --- /dev/null +++ b/chromium/ui/ozone/gpu/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+ui/gl", +] diff --git a/chromium/ui/ozone/gpu/README b/chromium/ui/ozone/gpu/README new file mode 100644 index 00000000000..7f96a444856 --- /dev/null +++ b/chromium/ui/ozone/gpu/README @@ -0,0 +1 @@ +This component contains support code for content/common/gpu. diff --git a/chromium/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc b/chromium/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc new file mode 100644 index 00000000000..4dfdba36cdb --- /dev/null +++ b/chromium/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc @@ -0,0 +1,163 @@ +// 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/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h" + +#include "base/logging.h" +#include "ui/gl/gl_image_egl.h" +#include "ui/gl/gl_image_linux_dma_buffer.h" +#include "ui/ozone/public/native_pixmap.h" +#include "ui/ozone/public/surface_factory_ozone.h" +#include "ui/ozone/public/surface_ozone_egl.h" + +namespace ui { +namespace { +class GLImageOzoneNativePixmap : public gfx::GLImageEGL { + public: + explicit GLImageOzoneNativePixmap(const gfx::Size& size) : GLImageEGL(size) {} + + bool Initialize(NativePixmap* pixmap) { + EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; + if (!Initialize(EGL_NATIVE_PIXMAP_KHR, pixmap->GetEGLClientBuffer(), attrs)) + return false; + pixmap_ = pixmap; + return true; + } + + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + gfx::OverlayTransform transform, + const gfx::Rect& bounds_rect, + const gfx::RectF& crop_rect) override { + return SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane( + widget, z_order, transform, pixmap_, bounds_rect, crop_rect); + } + + protected: + ~GLImageOzoneNativePixmap() override {} + + private: + using gfx::GLImageEGL::Initialize; + scoped_refptr<NativePixmap> pixmap_; +}; + +class GLImageOzoneNativePixmapDmaBuf : public gfx::GLImageLinuxDMABuffer { + public: + explicit GLImageOzoneNativePixmapDmaBuf(const gfx::Size& size, + unsigned internalformat) + : GLImageLinuxDMABuffer(size, internalformat) {} + + bool Initialize(NativePixmap* pixmap, gfx::GpuMemoryBuffer::Format format) { + base::FileDescriptor handle(pixmap->GetDmaBufFd(), false); + if (!GLImageLinuxDMABuffer::Initialize(handle, format, + pixmap->GetDmaBufPitch())) + return false; + pixmap_ = pixmap; + return true; + } + + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + gfx::OverlayTransform transform, + const gfx::Rect& bounds_rect, + const gfx::RectF& crop_rect) override { + return SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane( + widget, z_order, transform, pixmap_, bounds_rect, crop_rect); + } + + protected: + ~GLImageOzoneNativePixmapDmaBuf() override {} + + private: + scoped_refptr<NativePixmap> pixmap_; +}; + +SurfaceFactoryOzone::BufferFormat GetOzoneFormatFor( + gfx::GpuMemoryBuffer::Format format) { + switch (format) { + case gfx::GpuMemoryBuffer::RGBA_8888: + return SurfaceFactoryOzone::RGBA_8888; + case gfx::GpuMemoryBuffer::RGBX_8888: + return SurfaceFactoryOzone::RGBX_8888; + case gfx::GpuMemoryBuffer::BGRA_8888: + NOTREACHED(); + return SurfaceFactoryOzone::RGBA_8888; + } + + NOTREACHED(); + return SurfaceFactoryOzone::RGBA_8888; +} + +std::pair<uint32_t, uint32_t> GetIndex(gfx::GpuMemoryBufferId id, + int client_id) { + return std::pair<uint32_t, uint32_t>(id, client_id); +} +} // namespace + +GpuMemoryBufferFactoryOzoneNativeBuffer:: + GpuMemoryBufferFactoryOzoneNativeBuffer() { +} + +GpuMemoryBufferFactoryOzoneNativeBuffer:: + ~GpuMemoryBufferFactoryOzoneNativeBuffer() { +} + +bool GpuMemoryBufferFactoryOzoneNativeBuffer::CreateGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + gfx::GpuMemoryBuffer::Usage usage, + int client_id) { + scoped_refptr<NativePixmap> pixmap = + SurfaceFactoryOzone::GetInstance()->CreateNativePixmap( + size, GetOzoneFormatFor(format)); + if (!pixmap.get()) { + LOG(ERROR) << "Failed to create pixmap " << size.width() << "x" + << size.height() << " format " << format << ", usage " << usage; + return false; + } + native_pixmap_map_[GetIndex(id, client_id)] = pixmap; + return true; +} + +void GpuMemoryBufferFactoryOzoneNativeBuffer::DestroyGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + int client_id) { + native_pixmap_map_.erase(GetIndex(id, client_id)); +} + +scoped_refptr<gfx::GLImage> +GpuMemoryBufferFactoryOzoneNativeBuffer::CreateImageForGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + unsigned internalformat, + int client_id) { + BufferToPixmapMap::iterator it = + native_pixmap_map_.find(GetIndex(id, client_id)); + if (it == native_pixmap_map_.end()) { + return scoped_refptr<gfx::GLImage>(); + } + NativePixmap* pixmap = it->second.get(); + if (pixmap->GetEGLClientBuffer()) { + DCHECK_EQ(-1, pixmap->GetDmaBufFd()); + scoped_refptr<GLImageOzoneNativePixmap> image = + new GLImageOzoneNativePixmap(size); + if (!image->Initialize(pixmap)) { + return scoped_refptr<gfx::GLImage>(); + } + return image; + } + if (pixmap->GetDmaBufFd() > 0) { + scoped_refptr<GLImageOzoneNativePixmapDmaBuf> image = + new GLImageOzoneNativePixmapDmaBuf(size, internalformat); + if (!image->Initialize(pixmap, format)) { + return scoped_refptr<gfx::GLImage>(); + } + return image; + } + return scoped_refptr<gfx::GLImage>(); +} + +} // namespace ui diff --git a/chromium/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h b/chromium/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h new file mode 100644 index 00000000000..f4bc409a3b1 --- /dev/null +++ b/chromium/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h @@ -0,0 +1,54 @@ +// 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_GPU_GPU_MEMORY_BUFFER_FACTORY_OZONE_NATIVE_BUFFER_H_ +#define UI_OZONE_GPU_GPU_MEMORY_BUFFER_FACTORY_OZONE_NATIVE_BUFFER_H_ + +#include <map> + +#include "base/memory/ref_counted.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/gpu_memory_buffer.h" +#include "ui/ozone/gpu/ozone_gpu_export.h" + +namespace gfx { +class GLImage; +} + +namespace ui { +class NativePixmap; + +class OZONE_GPU_EXPORT GpuMemoryBufferFactoryOzoneNativeBuffer { + typedef std::map<std::pair<uint32_t, uint32_t>, scoped_refptr<NativePixmap> > + BufferToPixmapMap; + + public: + GpuMemoryBufferFactoryOzoneNativeBuffer(); + virtual ~GpuMemoryBufferFactoryOzoneNativeBuffer(); + + // Creates a GPU memory buffer identified by |id|. + bool CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + gfx::GpuMemoryBuffer::Usage usage, + int client_id); + + // Destroys GPU memory buffer identified by |id|. + void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id); + + // Creates a GLImage instance for GPU memory buffer identified by |id|. + scoped_refptr<gfx::GLImage> CreateImageForGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + unsigned internalformat, + int client_id); + + private: + BufferToPixmapMap native_pixmap_map_; +}; + +} // namespace ui + +#endif // UI_OZONE_GPU_GPU_MEMORY_BUFFER_FACTORY_OZONE_NATIVE_BUFFER_H_ diff --git a/chromium/ui/ozone/gpu/ozone_gpu.gyp b/chromium/ui/ozone/gpu/ozone_gpu.gyp new file mode 100644 index 00000000000..72bf156abcf --- /dev/null +++ b/chromium/ui/ozone/gpu/ozone_gpu.gyp @@ -0,0 +1,28 @@ +# 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'ozone_gpu', + 'type': '<(component)', + 'dependencies': [ + '../../../base/base.gyp:base', + '../../gfx/gfx.gyp:gfx', + '../../gfx/gfx.gyp:gfx_geometry', + '../../gl/gl.gyp:gl', + ], + 'defines': [ + 'OZONE_GPU_IMPLEMENTATION', + ], + 'sources': [ + 'gpu_memory_buffer_factory_ozone_native_buffer.cc', + 'gpu_memory_buffer_factory_ozone_native_buffer.h', + ], + }, + ], +} diff --git a/chromium/ui/ozone/gpu/ozone_gpu_export.h b/chromium/ui/ozone/gpu/ozone_gpu_export.h new file mode 100644 index 00000000000..cc4a7bc0dd5 --- /dev/null +++ b/chromium/ui/ozone/gpu/ozone_gpu_export.h @@ -0,0 +1,29 @@ +// 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_GPU_OZONE_GPU_EXPORT_H_ +#define UI_OZONE_GPU_OZONE_GPU_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(OZONE_GPU_IMPLEMENTATION) +#define OZONE_GPU_EXPORT __declspec(dllexport) +#else +#define OZONE_GPU_EXPORT __declspec(dllimport) +#endif // defined(OZONE_GPU_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(OZONE_GPU_IMPLEMENTATION) +#define OZONE_GPU_EXPORT __attribute__((visibility("default"))) +#else +#define OZONE_GPU_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define OZONE_GPU_EXPORT +#endif + +#endif // UI_OZONE_GPU_OZONE_GPU_EXPORT_H_ diff --git a/chromium/ui/ozone/ozone.gni b/chromium/ui/ozone/ozone.gni index a777f59a861..867813c50af 100644 --- a/chromium/ui/ozone/ozone.gni +++ b/chromium/ui/ozone/ozone.gni @@ -2,17 +2,30 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/ui.gni") +declare_args() { + # Select platforms automatically. Turn this off for manual control. + ozone_auto_platforms = true +} -if (use_ozone) { - # Enable built-in ozone platforms if ozone is enabled. - ozone_platform_caca = false - ozone_platform_dri = true - ozone_platform_ozonex = false - ozone_platform_test = true -} else { +declare_args() { + # The platform that will be active by default. + ozone_platform = "" + + # Enable individual platforms. ozone_platform_caca = false ozone_platform_dri = false - ozone_platform_ozonex = false + ozone_platform_egltest = false + ozone_platform_gbm = false ozone_platform_test = false + + if (ozone_auto_platforms) { + # Use test as the default platform. + ozone_platform = "test" + + # Build all platforms whose deps are in install-build-deps.sh. + # Only these platforms will be compile tested by buildbots. + ozone_platform_dri = true + ozone_platform_test = true + ozone_platform_egltest = true + } } diff --git a/chromium/ui/ozone/ozone.gyp b/chromium/ui/ozone/ozone.gyp index 74cb523d8a9..f965c61cd04 100644 --- a/chromium/ui/ozone/ozone.gyp +++ b/chromium/ui/ozone/ozone.gyp @@ -5,16 +5,21 @@ { 'variables': { 'chromium_code': 1, - 'external_ozone_platforms': [], - 'external_ozone_platform_files': [], - 'external_ozone_platform_deps': [], - 'external_ozone_platform_unittest_deps': [], + # Normally, the external_ozone_platform* variables below can be + # overridden by supplement.gypi which must exist exactly one level + # below the top-level src directory. They can now also be set in + # $GYP_DEFINES + 'external_ozone_platforms%': [], + 'external_ozone_platform_files%': [], + 'external_ozone_platform_deps%': [], + 'external_ozone_platform_unittest_deps%': [], 'internal_ozone_platforms': [], 'internal_ozone_platform_deps': [], 'internal_ozone_platform_unittest_deps': [], }, 'targets': [ { + # GN version: //ui/ozone:ozone_base 'target_name': 'ozone_base', 'type': '<(component)', 'dependencies': [ @@ -28,12 +33,11 @@ 'sources': [ 'public/cursor_factory_ozone.cc', 'public/cursor_factory_ozone.h', - 'public/event_factory_ozone.cc', - 'public/event_factory_ozone.h', 'public/gpu_platform_support.cc', 'public/gpu_platform_support.h', 'public/gpu_platform_support_host.cc', 'public/gpu_platform_support_host.h', + 'public/native_pixmap.h', 'public/overlay_candidates_ozone.cc', 'public/overlay_candidates_ozone.h', 'public/surface_factory_ozone.cc', @@ -43,15 +47,19 @@ ], }, { + # GN version: //ui/ozone 'target_name': 'ozone', 'type': '<(component)', 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/ipc/ipc.gyp:ipc', + '<(DEPTH)/skia/skia.gyp:skia', + '<(DEPTH)/ui/display/display.gyp:display_types', '<(DEPTH)/ui/events/events.gyp:events', '<(DEPTH)/ui/events/ozone/events_ozone.gyp:events_ozone', '<(DEPTH)/ui/gfx/gfx.gyp:gfx', '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry', - '<(DEPTH)/skia/skia.gyp:skia', + '<(DEPTH)/ui/gfx/ipc/gfx_ipc.gyp:gfx_ipc', '<@(external_ozone_platform_deps)', '<@(internal_ozone_platform_deps)', 'ozone_base', @@ -77,23 +85,32 @@ '<(platform_list_h_file)', '<(constructor_list_cc_file)', - # common/chromeos files are excluded automatically when building with - # chromeos=0, by exclusion rules in filename_rules.gypi due to the - # 'chromeos' folder name. - 'common/chromeos/native_display_delegate_ozone.cc', - 'common/chromeos/native_display_delegate_ozone.h', - 'common/chromeos/touchscreen_device_manager_ozone.cc', - 'common/chromeos/touchscreen_device_manager_ozone.h', - 'ozone_platform.cc', - 'ozone_platform.h', - 'ozone_switches.cc', - 'ozone_switches.h', + 'common/display_mode_proxy.cc', + 'common/display_mode_proxy.h', + 'common/display_snapshot_proxy.cc', + 'common/display_snapshot_proxy.h', + 'common/display_util.cc', + 'common/display_util.h', + 'common/gpu/ozone_gpu_message_generator.cc', + 'common/gpu/ozone_gpu_message_generator.h', + 'common/gpu/ozone_gpu_message_params.cc', + 'common/gpu/ozone_gpu_message_params.h', + 'common/gpu/ozone_gpu_messages.h', + 'common/native_display_delegate_ozone.cc', + 'common/native_display_delegate_ozone.h', + 'public/ozone_platform.cc', + 'public/ozone_platform.h', + 'public/ozone_switches.cc', + 'public/ozone_switches.h', + 'public/ui_thread_gpu.cc', + 'public/ui_thread_gpu.h', 'platform_selection.cc', 'platform_selection.h', '<@(external_ozone_platform_files)', ], 'actions': [ { + # GN version: //ui/ozone:generate_ozone_platform_list 'action_name': 'generate_ozone_platform_list', 'variables': { 'generator_path': 'generate_ozone_platform_list.py', @@ -117,6 +134,7 @@ ], }, { + # GN version: //ui/ozone:generate_constructor_list 'action_name': 'generate_constructor_list', 'variables': { 'generator_path': 'generate_constructor_list.py', @@ -135,7 +153,7 @@ '--output_cc=<(constructor_list_cc_file)', '--namespace=ui', '--typename=OzonePlatform', - '--include="ui/ozone/ozone_platform.h"' + '--include="ui/ozone/public/ozone_platform.h"' ], }, ], @@ -145,11 +163,6 @@ ['exclude', '_udev\\.(h|cc)$'], ], }], - ['chromeos==1', { - 'dependencies': [ - '<(DEPTH)/ui/display/display.gyp:display_types', - ], - }], ], }, { @@ -159,7 +172,6 @@ 'run_all_unittests.cc', ], 'dependencies': [ - 'ozone', 'ozone_base', '../../base/base.gyp:base', '../../base/base.gyp:test_support_base', diff --git a/chromium/ui/ozone/ozone_switches.cc b/chromium/ui/ozone/ozone_switches.cc deleted file mode 100644 index 3c117d0e8fe..00000000000 --- a/chromium/ui/ozone/ozone_switches.cc +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 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/ozone_switches.h" - -namespace switches { - -// Specify ozone platform implementation to use. -const char kOzonePlatform[] = "ozone-platform"; - -// Specify location for image dumps. -const char kOzoneDumpFile[] = "ozone-dump-file"; - -} // namespace switches diff --git a/chromium/ui/ozone/platform/caca/BUILD.gn b/chromium/ui/ozone/platform/caca/BUILD.gn new file mode 100644 index 00000000000..085925d1588 --- /dev/null +++ b/chromium/ui/ozone/platform/caca/BUILD.gn @@ -0,0 +1,34 @@ +# 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. + +import("//build/config/linux/pkg_config.gni") + +source_set("caca") { + sources = [ + "caca_event_source.cc", + "caca_event_source.h", + "caca_window.cc", + "caca_window.h", + "caca_window_manager.cc", + "caca_window_manager.h", + "ozone_platform_caca.cc", + "ozone_platform_caca.h", + "scoped_caca_types.cc", + "scoped_caca_types.h", + ] + + deps = [ + "//base", + "//skia", + "//ui/gfx/geometry", + ] + + configs += [ + ":libcaca", + ] +} + +pkg_config("libcaca") { + packages = [ "caca" ] +} diff --git a/chromium/ui/ozone/platform/caca/DEPS b/chromium/ui/ozone/platform/caca/DEPS deleted file mode 100644 index 46d48b30e10..00000000000 --- a/chromium/ui/ozone/platform/caca/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+third_party/skia", -] diff --git a/chromium/ui/ozone/platform/caca/caca.gypi b/chromium/ui/ozone/platform/caca/caca.gypi index 8c1b55d2a7d..34a5e6943ae 100644 --- a/chromium/ui/ozone/platform/caca/caca.gypi +++ b/chromium/ui/ozone/platform/caca/caca.gypi @@ -31,14 +31,16 @@ ], }, 'sources': [ - 'caca_connection.cc', - 'caca_connection.h', - 'caca_event_factory.cc', - 'caca_event_factory.h', - 'caca_surface_factory.cc', - 'caca_surface_factory.h', + 'caca_event_source.cc', + 'caca_event_source.h', + 'caca_window.cc', + 'caca_window.h', + 'caca_window_manager.cc', + 'caca_window_manager.h', 'ozone_platform_caca.cc', 'ozone_platform_caca.h', + 'scoped_caca_types.cc', + 'scoped_caca_types.h', ], }, ], diff --git a/chromium/ui/ozone/platform/caca/caca_connection.cc b/chromium/ui/ozone/platform/caca/caca_connection.cc deleted file mode 100644 index 49b51a45c86..00000000000 --- a/chromium/ui/ozone/platform/caca/caca_connection.cc +++ /dev/null @@ -1,40 +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/platform/caca/caca_connection.h" - -#include "base/logging.h" - -namespace ui { - -// TODO(dnicoara) As an optimization, |bitmap_size_| should be scaled based on -// |physical_size_| and font size. -CacaConnection::CacaConnection() - : canvas_(NULL), - display_(NULL), - physical_size_(160, 48), - bitmap_size_(800, 600) {} - -CacaConnection::~CacaConnection() { - if (display_) { - caca_free_display(display_); - caca_free_canvas(canvas_); - } -} - -void CacaConnection::Initialize() { - if (display_) - return; - - canvas_ = caca_create_canvas(physical_size_.width(), physical_size_.height()); - display_ = caca_create_display(canvas_); - - physical_size_.SetSize(caca_get_canvas_width(canvas_), - caca_get_canvas_height(canvas_)); - - caca_set_cursor(display_, 1); - caca_set_display_title(display_, "Ozone Content Shell"); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/caca/caca_connection.h b/chromium/ui/ozone/platform/caca/caca_connection.h deleted file mode 100644 index dbe194358ef..00000000000 --- a/chromium/ui/ozone/platform/caca/caca_connection.h +++ /dev/null @@ -1,47 +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_PLATFORM_CACA_CACA_CONNECTION_H_ -#define UI_OZONE_PLATFORM_CACA_CACA_CONNECTION_H_ - -#include <caca.h> - -#include "base/macros.h" -#include "ui/gfx/geometry/size.h" - -namespace ui { - -// Basic initialization of Libcaca. This needs to be shared between SFO and EFO -// since both need the |display_| to draw and process events respectively. -// Note, |canvas_| needs to be here since it is needed for creating a -// |display_|. -class CacaConnection { - public: - CacaConnection(); - ~CacaConnection(); - - void Initialize(); - - // This is the Caca canvas size. - gfx::Size physical_size() const { return physical_size_; } - gfx::Size bitmap_size() const { return bitmap_size_; } - caca_display_t* display() const { return display_; } - - private: - caca_canvas_t* canvas_; - caca_display_t* display_; - - // Size of the console in characters. This can be changed by setting - // CACA_GEOMETRY environment variable. - gfx::Size physical_size_; - - // Size of the backing buffer we draw into. Size in pixels. - gfx::Size bitmap_size_; - - DISALLOW_COPY_AND_ASSIGN(CacaConnection); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_CACA_CACA_CONNECTION_H_ diff --git a/chromium/ui/ozone/platform/caca/caca_event_factory.h b/chromium/ui/ozone/platform/caca/caca_event_factory.h deleted file mode 100644 index f732f00865f..00000000000 --- a/chromium/ui/ozone/platform/caca/caca_event_factory.h +++ /dev/null @@ -1,54 +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_PLATFORM_CACA_CACA_EVENT_FACTORY_H_ -#define UI_OZONE_PLATFORM_CACA_CACA_EVENT_FACTORY_H_ - -#include "base/memory/ref_counted.h" -#include "base/time/time.h" -#include "ui/events/platform/platform_event_source.h" -#include "ui/gfx/geometry/point_f.h" -#include "ui/ozone/public/event_factory_ozone.h" - -namespace ui { - -class CacaConnection; - -class CacaEventFactory : public EventFactoryOzone, - public PlatformEventSource { - public: - CacaEventFactory(CacaConnection* connection); - virtual ~CacaEventFactory(); - - // ui::EventFactoryOzone: - virtual void WarpCursorTo(gfx::AcceleratedWidget widget, - const gfx::PointF& location) OVERRIDE; - - private: - // PlatformEventSource: - virtual void OnDispatcherListChanged() OVERRIDE; - - void ScheduleEventProcessing(); - - void TryProcessingEvent(); - - CacaConnection* connection_; // Not owned. - - base::WeakPtrFactory<CacaEventFactory> weak_ptr_factory_; - - // Delay between event polls. - base::TimeDelta delay_; - - // Keep track of last cursor position to dispatch correct mouse push/release - // events. - gfx::PointF last_cursor_location_; - - int modifier_flags_; - - DISALLOW_COPY_AND_ASSIGN(CacaEventFactory); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_CACA_CACA_EVENT_FACTORY_H_ diff --git a/chromium/ui/ozone/platform/caca/caca_event_factory.cc b/chromium/ui/ozone/platform/caca/caca_event_source.cc index c17e5a4f965..a8da8b40a12 100644 --- a/chromium/ui/ozone/platform/caca/caca_event_factory.cc +++ b/chromium/ui/ozone/platform/caca/caca_event_source.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/caca/caca_event_factory.h" +#include "ui/ozone/platform/caca/caca_event_source.h" #include <caca.h> @@ -10,7 +10,7 @@ #include "base/message_loop/message_loop.h" #include "ui/events/event.h" #include "ui/events/keycodes/keyboard_codes.h" -#include "ui/ozone/platform/caca/caca_connection.h" +#include "ui/ozone/platform/caca/caca_window.h" namespace ui { @@ -108,10 +108,9 @@ int ModifierFromButton(const caca_event_t& event) { } // Translate coordinates to bitmap coordinates. -gfx::PointF TranslateLocation(const gfx::PointF& location, - CacaConnection* connection) { - gfx::Size physical_size = connection->physical_size(); - gfx::Size bitmap_size = connection->bitmap_size(); +gfx::PointF TranslateLocation(const gfx::PointF& location, CacaWindow* window) { + gfx::Size physical_size = window->physical_size(); + gfx::Size bitmap_size = window->bitmap_size(); return gfx::PointF( location.x() * bitmap_size.width() / physical_size.width(), location.y() * bitmap_size.height() / physical_size.height()); @@ -136,97 +135,95 @@ ui::EventType GetEventTypeFromNative(const caca_event_t& event) { } // namespace -CacaEventFactory::CacaEventFactory(CacaConnection* connection) - : connection_(connection), - weak_ptr_factory_(this), - delay_(base::TimeDelta::FromMilliseconds(10)), - modifier_flags_(0) { +CacaEventSource::CacaEventSource() : modifier_flags_(0) { } -CacaEventFactory::~CacaEventFactory() { +CacaEventSource::~CacaEventSource() { } -void CacaEventFactory::WarpCursorTo(gfx::AcceleratedWidget widget, - const gfx::PointF& location) { - NOTIMPLEMENTED(); -} - -void CacaEventFactory::OnDispatcherListChanged() { - ScheduleEventProcessing(); -} +void CacaEventSource::TryProcessingEvent(CacaWindow* window) { + if (!window->display()) + return; -void CacaEventFactory::ScheduleEventProcessing() { - // Caca uses a poll based event retrieval. Since we don't want to block we'd - // either need to spin up a new thread or just poll. For simplicity just poll - // for a message every |delay_| time delta. - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&CacaEventFactory::TryProcessingEvent, - weak_ptr_factory_.GetWeakPtr()), - delay_); -} - -void CacaEventFactory::TryProcessingEvent() { caca_event_t event; int event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE | CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE | - CACA_EVENT_MOUSE_MOTION; - if (connection_->display() && - caca_get_event(connection_->display(), event_mask, &event, 0)) { - - ui::EventType type = GetEventTypeFromNative(event); - bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED; - - switch (type) { - case ui::ET_KEY_PRESSED: - case ui::ET_KEY_RELEASED: { - if (pressed) - modifier_flags_ |= ModifierFromKey(event); - else - modifier_flags_ &= ~ModifierFromKey(event); - - ui::KeyEvent key_event( - type, GetKeyboardCode(event), modifier_flags_, true); - DispatchEvent(&key_event); - break; - } - case ui::ET_MOUSE_MOVED: - last_cursor_location_.SetPoint(caca_get_event_mouse_x(&event), - caca_get_event_mouse_y(&event)); - // Update cursor location. - caca_gotoxy(caca_get_canvas(connection_->display()), - last_cursor_location_.x(), - last_cursor_location_.y()); - // fallthrough - case ui::ET_MOUSE_PRESSED: - case ui::ET_MOUSE_RELEASED: { - int flags = 0; - int changed_flags = 0; - if (type != ui::ET_MOUSE_MOVED) { - if (pressed) { - changed_flags = ModifierFromButton(event); - modifier_flags_ |= changed_flags; - } else { - modifier_flags_ &= ~changed_flags; - } - // On release the button pressed is removed from |modifier_flags_|, - // but sending the event needs it set. - flags = modifier_flags_ | changed_flags; + CACA_EVENT_MOUSE_MOTION | CACA_EVENT_RESIZE | + CACA_EVENT_QUIT; + + if (!caca_get_event(window->display(), event_mask, &event, 0)) + return; + + switch (caca_get_event_type(&event)) { + case CACA_EVENT_KEY_PRESS: + case CACA_EVENT_KEY_RELEASE: + case CACA_EVENT_MOUSE_PRESS: + case CACA_EVENT_MOUSE_RELEASE: + case CACA_EVENT_MOUSE_MOTION: + OnInputEvent(&event, window); + break; + case CACA_EVENT_RESIZE: + window->OnCacaResize(); + break; + case CACA_EVENT_QUIT: + window->OnCacaQuit(); + break; + default: + NOTIMPLEMENTED(); + } +} + +void CacaEventSource::OnInputEvent(caca_event_t* event, CacaWindow* window) { + ui::EventType type = GetEventTypeFromNative(*event); + bool pressed = type == ui::ET_KEY_PRESSED || type == ui::ET_MOUSE_PRESSED; + + switch (type) { + case ui::ET_KEY_PRESSED: + case ui::ET_KEY_RELEASED: { + if (pressed) + modifier_flags_ |= ModifierFromKey(*event); + else + modifier_flags_ &= ~ModifierFromKey(*event); + + ui::KeyEvent key_event( + type, GetKeyboardCode(*event), modifier_flags_); + window->OnCacaEvent(&key_event); + break; + } + case ui::ET_MOUSE_MOVED: + last_cursor_location_.SetPoint(caca_get_event_mouse_x(event), + caca_get_event_mouse_y(event)); + // Update cursor location. + caca_gotoxy(caca_get_canvas(window->display()), + last_cursor_location_.x(), + last_cursor_location_.y()); + + // fallthrough + case ui::ET_MOUSE_PRESSED: + case ui::ET_MOUSE_RELEASED: { + int flags = 0; + int changed_flags = 0; + if (type != ui::ET_MOUSE_MOVED) { + if (pressed) { + changed_flags = ModifierFromButton(*event); + modifier_flags_ |= changed_flags; + } else { + modifier_flags_ &= ~changed_flags; } - gfx::PointF location = TranslateLocation(last_cursor_location_, - connection_); - ui::MouseEvent mouse_event( - type, location, location, flags, changed_flags); - DispatchEvent(&mouse_event); - break; + // On release the button pressed is removed from |modifier_flags_|, + // but sending the event needs it set. + flags = modifier_flags_ | changed_flags; } - default: - NOTIMPLEMENTED(); - break; + gfx::PointF location = TranslateLocation(last_cursor_location_, window); + ui::MouseEvent mouse_event( + type, location, location, flags, changed_flags); + window->OnCacaEvent(&mouse_event); + break; } + default: + NOTIMPLEMENTED(); + break; } - - ScheduleEventProcessing(); } } // namespace ui diff --git a/chromium/ui/ozone/platform/caca/caca_event_source.h b/chromium/ui/ozone/platform/caca/caca_event_source.h new file mode 100644 index 00000000000..180031475aa --- /dev/null +++ b/chromium/ui/ozone/platform/caca/caca_event_source.h @@ -0,0 +1,44 @@ +// 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_PLATFORM_CACA_CACA_EVENT_SOURCE_H_ +#define UI_OZONE_PLATFORM_CACA_CACA_EVENT_SOURCE_H_ + +#include <caca.h> + +#include "base/memory/ref_counted.h" +#include "base/time/time.h" +#include "ui/events/platform/platform_event_source.h" +#include "ui/events/platform/scoped_event_dispatcher.h" +#include "ui/gfx/geometry/point_f.h" + +namespace ui { + +class CacaWindow; + +class CacaEventSource : public PlatformEventSource { + public: + CacaEventSource(); + ~CacaEventSource() override; + + // Poll for an event on a particular window. Input events will be + // dispatched on the given dispatcher. + void TryProcessingEvent(CacaWindow* window); + + // Process an input event on a particular window. + void OnInputEvent(caca_event_t* event, CacaWindow* window); + + private: + // Keep track of last cursor position to dispatch correct mouse push/release + // events. + gfx::PointF last_cursor_location_; + + int modifier_flags_; + + DISALLOW_COPY_AND_ASSIGN(CacaEventSource); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_CACA_CACA_EVENT_SOURCE_H_ diff --git a/chromium/ui/ozone/platform/caca/caca_surface_factory.cc b/chromium/ui/ozone/platform/caca/caca_surface_factory.cc deleted file mode 100644 index 58b5e640c90..00000000000 --- a/chromium/ui/ozone/platform/caca/caca_surface_factory.cc +++ /dev/null @@ -1,147 +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/platform/caca/caca_surface_factory.h" - -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkSurface.h" -#include "ui/gfx/skia_util.h" -#include "ui/gfx/vsync_provider.h" -#include "ui/ozone/platform/caca/caca_connection.h" -#include "ui/ozone/public/surface_ozone_canvas.h" - -namespace ui { - -namespace { - -const gfx::AcceleratedWidget kDefaultWidgetHandle = 1; - -class CacaSurface : public ui::SurfaceOzoneCanvas { - public: - CacaSurface(CacaConnection* connection); - virtual ~CacaSurface(); - - bool Initialize(); - - // ui::SurfaceOzoneCanvas overrides: - virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE; - virtual void ResizeCanvas(const gfx::Size& viewport_size) OVERRIDE; - virtual void PresentCanvas(const gfx::Rect& damage) OVERRIDE; - virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE; - - private: - CacaConnection* connection_; // Not owned. - - caca_dither_t* dither_; - - skia::RefPtr<SkSurface> surface_; - - DISALLOW_COPY_AND_ASSIGN(CacaSurface); -}; - -CacaSurface::CacaSurface(CacaConnection* connection) - : connection_(connection) {} - -CacaSurface::~CacaSurface() { - caca_free_dither(dither_); -} - -bool CacaSurface::Initialize() { - SkImageInfo info = SkImageInfo::Make(connection_->bitmap_size().width(), - connection_->bitmap_size().height(), - kPMColor_SkColorType, - kPremul_SkAlphaType); - - surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); - if (!surface_) { - LOG(ERROR) << "Failed to create SkCanvas"; - return false; - } - - dither_ = caca_create_dither( - info.bytesPerPixel() * 8, - info.width(), - info.height(), - info.minRowBytes(), - 0x00ff0000, - 0x0000ff00, - 0x000000ff, - 0xff000000); - - return true; -} - -skia::RefPtr<SkCanvas> CacaSurface::GetCanvas() { - return skia::SharePtr<SkCanvas>(surface_->getCanvas()); -} - -void CacaSurface::ResizeCanvas(const gfx::Size& viewport_size) { - NOTIMPLEMENTED(); -} - -void CacaSurface::PresentCanvas(const gfx::Rect& damage) { - SkImageInfo info; - size_t row_bytes; - const void* pixels = surface_->peekPixels(&info, &row_bytes); - - caca_canvas_t* canvas = caca_get_canvas(connection_->display()); - caca_dither_bitmap(canvas, 0, 0, - caca_get_canvas_width(canvas), - caca_get_canvas_height(canvas), - dither_, - static_cast<const uint8_t*>(pixels)); - caca_refresh_display(connection_->display()); -} - -scoped_ptr<gfx::VSyncProvider> CacaSurface::CreateVSyncProvider() { - return scoped_ptr<gfx::VSyncProvider>(); -} - -} // namespace - -CacaSurfaceFactory::CacaSurfaceFactory(CacaConnection* connection) - : state_(UNINITIALIZED), - connection_(connection) { -} - -CacaSurfaceFactory::~CacaSurfaceFactory() { - if (state_ == INITIALIZED) - ShutdownHardware(); -} - -ui::SurfaceFactoryOzone::HardwareState -CacaSurfaceFactory::InitializeHardware() { - connection_->Initialize(); - state_ = INITIALIZED; - return state_; -} - -void CacaSurfaceFactory::ShutdownHardware() { - CHECK_EQ(INITIALIZED, state_); - state_ = UNINITIALIZED; -} - -gfx::AcceleratedWidget CacaSurfaceFactory::GetAcceleratedWidget() { - return kDefaultWidgetHandle; -} - -bool CacaSurfaceFactory::LoadEGLGLES2Bindings( - AddGLLibraryCallback add_gl_library, - SetGLGetProcAddressProcCallback set_gl_get_proc_address) { - NOTREACHED(); - return false; -} - -scoped_ptr<ui::SurfaceOzoneCanvas> CacaSurfaceFactory::CreateCanvasForWidget( - gfx::AcceleratedWidget widget) { - CHECK_EQ(INITIALIZED, state_); - CHECK_EQ(kDefaultWidgetHandle, widget); - - scoped_ptr<CacaSurface> canvas(new CacaSurface(connection_)); - CHECK(canvas->Initialize()); - return canvas.PassAs<ui::SurfaceOzoneCanvas>(); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/caca/caca_surface_factory.h b/chromium/ui/ozone/platform/caca/caca_surface_factory.h deleted file mode 100644 index a07033ae54b..00000000000 --- a/chromium/ui/ozone/platform/caca/caca_surface_factory.h +++ /dev/null @@ -1,46 +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_PLATFORM_CACA_CACA_SURFACE_FACTORY_H_ -#define UI_OZONE_PLATFORM_CACA_CACA_SURFACE_FACTORY_H_ - -#include <caca.h> - -#include "base/memory/scoped_ptr.h" -#include "ui/ozone/public/surface_factory_ozone.h" - -namespace gfx { -class SurfaceOzone; -} - -namespace ui { - -class CacaConnection; - -class CacaSurfaceFactory : public ui::SurfaceFactoryOzone { - public: - CacaSurfaceFactory(CacaConnection* connection); - virtual ~CacaSurfaceFactory(); - - // ui::SurfaceFactoryOzone overrides: - virtual HardwareState InitializeHardware() OVERRIDE; - virtual void ShutdownHardware() OVERRIDE; - virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; - virtual bool LoadEGLGLES2Bindings( - AddGLLibraryCallback add_gl_library, - SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE; - virtual scoped_ptr<ui::SurfaceOzoneCanvas> CreateCanvasForWidget( - gfx::AcceleratedWidget widget) OVERRIDE; - - private: - HardwareState state_; - - CacaConnection* connection_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(CacaSurfaceFactory); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_CACA_CACA_SURFACE_FACTORY_H_ diff --git a/chromium/ui/ozone/platform/caca/caca_window.cc b/chromium/ui/ozone/platform/caca/caca_window.cc new file mode 100644 index 00000000000..8f2e0392371 --- /dev/null +++ b/chromium/ui/ozone/platform/caca/caca_window.cc @@ -0,0 +1,145 @@ +// 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/platform/caca/caca_window.h" + +#include "base/bind.h" +#include "base/debug/trace_event.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "ui/events/ozone/events_ozone.h" +#include "ui/events/platform/platform_event_source.h" +#include "ui/ozone/platform/caca/caca_event_source.h" +#include "ui/ozone/platform/caca/caca_window_manager.h" +#include "ui/platform_window/platform_window_delegate.h" + +namespace ui { + +namespace { + +// Size of initial cnavas (in characters). +const int kDefaultCanvasWidth = 160; +const int kDefaultCanvasHeight = 48; + +} // namespace + +// TODO(dnicoara) As an optimization, |bitmap_size_| should be scaled based on +// |physical_size_| and font size. +CacaWindow::CacaWindow(PlatformWindowDelegate* delegate, + CacaWindowManager* manager, + CacaEventSource* event_source, + const gfx::Rect& bounds) + : delegate_(delegate), + manager_(manager), + event_source_(event_source), + weak_ptr_factory_(this) { + widget_ = manager_->AddWindow(this); + ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); + delegate_->OnAcceleratedWidgetAvailable(widget_); +} + +CacaWindow::~CacaWindow() { + ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); + manager_->RemoveWindow(widget_, this); +} + +bool CacaWindow::Initialize() { + if (display_) + return true; + + canvas_.reset(caca_create_canvas(kDefaultCanvasWidth, kDefaultCanvasHeight)); + if (!canvas_) { + PLOG(ERROR) << "failed to create libcaca canvas"; + return false; + } + + display_.reset(caca_create_display(canvas_.get())); + if (!display_) { + PLOG(ERROR) << "failed to initialize libcaca display"; + return false; + } + + caca_set_cursor(display_.get(), 1); + caca_set_display_title(display_.get(), "Ozone Content Shell"); + + UpdateDisplaySize(); + + TryProcessingEvent(); + + return true; +} + +void CacaWindow::TryProcessingEvent() { + event_source_->TryProcessingEvent(this); + + // Caca uses a poll based event retrieval. Since we don't want to block we'd + // either need to spin up a new thread or just poll. For simplicity just poll + // for messages. + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&CacaWindow::TryProcessingEvent, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(10)); +} + +void CacaWindow::UpdateDisplaySize() { + physical_size_.SetSize(caca_get_canvas_width(canvas_.get()), + caca_get_canvas_height(canvas_.get())); + + bitmap_size_.SetSize(caca_get_display_width(display_.get()), + caca_get_display_height(display_.get())); +} + +void CacaWindow::OnCacaResize() { + UpdateDisplaySize(); + + delegate_->OnBoundsChanged(gfx::Rect(bitmap_size_)); +} + +void CacaWindow::OnCacaQuit() { + delegate_->OnCloseRequest(); +} + + +void CacaWindow::OnCacaEvent(ui::Event* event) { + DispatchEventFromNativeUiEvent( + event, base::Bind(&PlatformWindowDelegate::DispatchEvent, + base::Unretained(delegate_))); +} + +gfx::Rect CacaWindow::GetBounds() { return gfx::Rect(bitmap_size_); } + +void CacaWindow::SetBounds(const gfx::Rect& bounds) {} + +void CacaWindow::Show() {} + +void CacaWindow::Hide() {} + +void CacaWindow::Close() {} + +void CacaWindow::SetCapture() {} + +void CacaWindow::ReleaseCapture() {} + +void CacaWindow::ToggleFullscreen() {} + +void CacaWindow::Maximize() {} + +void CacaWindow::Minimize() {} + +void CacaWindow::Restore() {} + +void CacaWindow::SetCursor(PlatformCursor cursor) {} + +void CacaWindow::MoveCursorTo(const gfx::Point& location) {} + +bool CacaWindow::CanDispatchEvent(const PlatformEvent& event) { return true; } + +uint32_t CacaWindow::DispatchEvent(const PlatformEvent& ne) { + // We don't dispatch events via PlatformEventSource. + NOTREACHED(); + return ui::POST_DISPATCH_STOP_PROPAGATION; +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/caca/caca_window.h b/chromium/ui/ozone/platform/caca/caca_window.h new file mode 100644 index 00000000000..70115d09938 --- /dev/null +++ b/chromium/ui/ozone/platform/caca/caca_window.h @@ -0,0 +1,97 @@ +// 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_PLATFORM_CACA_CACA_WINDOW_H_ +#define UI_OZONE_PLATFORM_CACA_CACA_WINDOW_H_ + +#include <caca.h> + +#include "base/debug/stack_trace.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "ui/events/platform/platform_event_dispatcher.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/caca/scoped_caca_types.h" +#include "ui/platform_window/platform_window.h" + +namespace ui { + +class CacaEventSource; +class CacaWindowManager; +class PlatformWindowDelegate; + +// Basic initialization of Libcaca. This needs to be shared between SFO and EFO +// since both need the |display_| to draw and process events respectively. +// Note, |canvas_| needs to be here since it is needed for creating a +// |display_|. +class CacaWindow : public PlatformWindow, public PlatformEventDispatcher { + public: + CacaWindow(PlatformWindowDelegate* delegate, + CacaWindowManager* manager, + CacaEventSource* event_source, + const gfx::Rect& bounds); + ~CacaWindow() override; + + bool Initialize(); + + // Handlers for events received from libcaca. + void OnCacaQuit(); + void OnCacaResize(); + void OnCacaEvent(ui::Event* event); + + // This is the Caca canvas size. + gfx::Size physical_size() const { return physical_size_; } + gfx::Size bitmap_size() const { return bitmap_size_; } + caca_display_t* display() const { return display_.get(); } + + // PlatformWindow: + gfx::Rect GetBounds() override; + void SetBounds(const gfx::Rect& bounds) override; + void Show() override; + void Hide() override; + void Close() override; + void SetCapture() override; + void ReleaseCapture() override; + void ToggleFullscreen() override; + void Maximize() override; + void Minimize() override; + void Restore() override; + void SetCursor(PlatformCursor cursor) override; + void MoveCursorTo(const gfx::Point& location) override; + + // PlatformEventDispatcher: + bool CanDispatchEvent(const PlatformEvent& event) override; + uint32_t DispatchEvent(const PlatformEvent& event) override; + + private: + // Event polling. + void TryProcessingEvent(); + + // Sync sizes with libcaca. + void UpdateDisplaySize(); + + PlatformWindowDelegate* delegate_; + CacaWindowManager* manager_; + CacaEventSource* event_source_; + gfx::AcceleratedWidget widget_; + + ScopedCacaCanvas canvas_; + ScopedCacaDisplay display_; + + // Size of the console in characters. This can be changed by setting + // CACA_GEOMETRY environment variable. + gfx::Size physical_size_; + + // Size of the backing buffer we draw into. Size in pixels. + gfx::Size bitmap_size_; + + base::WeakPtrFactory<CacaWindow> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CacaWindow); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_CACA_CACA_WINDOW_H_ diff --git a/chromium/ui/ozone/platform/caca/caca_window_manager.cc b/chromium/ui/ozone/platform/caca/caca_window_manager.cc new file mode 100644 index 00000000000..05c509e8419 --- /dev/null +++ b/chromium/ui/ozone/platform/caca/caca_window_manager.cc @@ -0,0 +1,141 @@ +// 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/platform/caca/caca_window_manager.h" + +#include "base/debug/trace_event.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkSurface.h" +#include "ui/gfx/skia_util.h" +#include "ui/gfx/vsync_provider.h" +#include "ui/ozone/platform/caca/caca_window.h" +#include "ui/ozone/platform/caca/scoped_caca_types.h" +#include "ui/ozone/public/surface_ozone_canvas.h" + +namespace ui { + +namespace { + +class CacaSurface : public ui::SurfaceOzoneCanvas { + public: + CacaSurface(CacaWindow* window); + ~CacaSurface() override; + + bool Initialize(); + + // ui::SurfaceOzoneCanvas overrides: + skia::RefPtr<SkCanvas> GetCanvas() override; + void ResizeCanvas(const gfx::Size& viewport_size) override; + void PresentCanvas(const gfx::Rect& damage) override; + scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override; + + private: + CacaWindow* window_; // Not owned. + + ScopedCacaDither dither_; + + skia::RefPtr<SkSurface> surface_; + + DISALLOW_COPY_AND_ASSIGN(CacaSurface); +}; + +CacaSurface::CacaSurface(CacaWindow* window) : window_(window) { +} + +CacaSurface::~CacaSurface() { +} + +bool CacaSurface::Initialize() { + ResizeCanvas(window_->bitmap_size()); + return true; +} + +skia::RefPtr<SkCanvas> CacaSurface::GetCanvas() { + return skia::SharePtr<SkCanvas>(surface_->getCanvas()); +} + +void CacaSurface::ResizeCanvas(const gfx::Size& viewport_size) { + TRACE_EVENT0("ozone", "CacaSurface::ResizeCanvas"); + + VLOG(2) << "creating libcaca surface with from window " << (void*)window_; + + SkImageInfo info = SkImageInfo::Make(window_->bitmap_size().width(), + window_->bitmap_size().height(), + kN32_SkColorType, + kPremul_SkAlphaType); + + surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); + if (!surface_) + LOG(ERROR) << "Failed to create SkSurface"; + + dither_.reset(caca_create_dither(info.bytesPerPixel() * 8, + info.width(), + info.height(), + info.minRowBytes(), + 0x00ff0000, + 0x0000ff00, + 0x000000ff, + 0xff000000)); + if (!dither_) + LOG(ERROR) << "failed to create dither"; +} + +void CacaSurface::PresentCanvas(const gfx::Rect& damage) { + TRACE_EVENT0("ozone", "CacaSurface::PresentCanvas"); + + SkImageInfo info; + size_t row_bytes; + const void* pixels = surface_->peekPixels(&info, &row_bytes); + + caca_canvas_t* canvas = caca_get_canvas(window_->display()); + caca_dither_bitmap(canvas, + 0, + 0, + caca_get_canvas_width(canvas), + caca_get_canvas_height(canvas), + dither_.get(), + static_cast<const uint8_t*>(pixels)); + caca_refresh_display(window_->display()); +} + +scoped_ptr<gfx::VSyncProvider> CacaSurface::CreateVSyncProvider() { + return scoped_ptr<gfx::VSyncProvider>(); +} + +} // namespace + +CacaWindowManager::CacaWindowManager() { +} + +int32_t CacaWindowManager::AddWindow(CacaWindow* window) { + return windows_.Add(window); +} + +void CacaWindowManager::RemoveWindow(int window_id, CacaWindow* window) { + DCHECK_EQ(window, windows_.Lookup(window_id)); + windows_.Remove(window_id); +} + +CacaWindowManager::~CacaWindowManager() { +} + +bool CacaWindowManager::LoadEGLGLES2Bindings( + AddGLLibraryCallback add_gl_library, + SetGLGetProcAddressProcCallback set_gl_get_proc_address) { + return false; +} + +scoped_ptr<ui::SurfaceOzoneCanvas> CacaWindowManager::CreateCanvasForWidget( + gfx::AcceleratedWidget widget) { + CacaWindow* window = windows_.Lookup(widget); + DCHECK(window); + + scoped_ptr<CacaSurface> canvas(new CacaSurface(window)); + bool initialized = canvas->Initialize(); + DCHECK(initialized); + return canvas.Pass(); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/caca/caca_window_manager.h b/chromium/ui/ozone/platform/caca/caca_window_manager.h new file mode 100644 index 00000000000..4f51a7f1021 --- /dev/null +++ b/chromium/ui/ozone/platform/caca/caca_window_manager.h @@ -0,0 +1,46 @@ +// 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_PLATFORM_CACA_CACA_WINDOW_MANAGER_H_ +#define UI_OZONE_PLATFORM_CACA_CACA_WINDOW_MANAGER_H_ + +#include "base/id_map.h" +#include "base/memory/scoped_ptr.h" +#include "ui/ozone/public/surface_factory_ozone.h" + +namespace gfx { +class Rect; +} + +namespace ui { + +class CacaWindow; + +class CacaWindowManager : public SurfaceFactoryOzone { + public: + CacaWindowManager(); + ~CacaWindowManager() override; + + // Register a new libcaca window/instance. Returns the window id. + int32_t AddWindow(CacaWindow* window); + + // Remove a libcaca window/instance. + void RemoveWindow(int32_t window_id, CacaWindow* window); + + // ui::SurfaceFactoryOzone overrides: + bool LoadEGLGLES2Bindings( + AddGLLibraryCallback add_gl_library, + SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; + scoped_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget( + gfx::AcceleratedWidget widget) override; + + private: + IDMap<CacaWindow> windows_; + + DISALLOW_COPY_AND_ASSIGN(CacaWindowManager); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_CACA_CACA_WINDOW_MANAGER_H_ diff --git a/chromium/ui/ozone/platform/caca/ozone_platform_caca.cc b/chromium/ui/ozone/platform/caca/ozone_platform_caca.cc index 3a27b4434e3..9cb9fd0706e 100644 --- a/chromium/ui/ozone/platform/caca/ozone_platform_caca.cc +++ b/chromium/ui/ozone/platform/caca/ozone_platform_caca.cc @@ -4,16 +4,12 @@ #include "ui/ozone/platform/caca/ozone_platform_caca.h" -#include "ui/ozone/ozone_platform.h" -#include "ui/ozone/platform/caca/caca_connection.h" -#include "ui/ozone/platform/caca/caca_event_factory.h" -#include "ui/ozone/platform/caca/caca_surface_factory.h" +#include "ui/ozone/common/native_display_delegate_ozone.h" +#include "ui/ozone/platform/caca/caca_event_source.h" +#include "ui/ozone/platform/caca/caca_window.h" +#include "ui/ozone/platform/caca/caca_window_manager.h" #include "ui/ozone/public/cursor_factory_ozone.h" - -#if defined(OS_CHROMEOS) -#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h" -#include "ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h" -#endif +#include "ui/ozone/public/ozone_platform.h" namespace ui { @@ -22,49 +18,45 @@ namespace { class OzonePlatformCaca : public OzonePlatform { public: OzonePlatformCaca() {} - virtual ~OzonePlatformCaca() {} + ~OzonePlatformCaca() override {} // OzonePlatform: - virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE { - return surface_factory_ozone_.get(); - } - virtual EventFactoryOzone* GetEventFactoryOzone() OVERRIDE { - return event_factory_ozone_.get(); + ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { + return window_manager_.get(); } - virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE { + CursorFactoryOzone* GetCursorFactoryOzone() override { return cursor_factory_ozone_.get(); } - virtual GpuPlatformSupport* GetGpuPlatformSupport() OVERRIDE { + GpuPlatformSupport* GetGpuPlatformSupport() override { return NULL; // no GPU support } - virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() OVERRIDE { + GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { return NULL; // no GPU support } - -#if defined(OS_CHROMEOS) - virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() - OVERRIDE { - return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); + scoped_ptr<PlatformWindow> CreatePlatformWindow( + PlatformWindowDelegate* delegate, + const gfx::Rect& bounds) override { + scoped_ptr<CacaWindow> caca_window(new CacaWindow( + delegate, window_manager_.get(), event_source_.get(), bounds)); + if (!caca_window->Initialize()) + return nullptr; + return caca_window.Pass(); } - virtual scoped_ptr<TouchscreenDeviceManager> - CreateTouchscreenDeviceManager() OVERRIDE { - return scoped_ptr<TouchscreenDeviceManager>( - new TouchscreenDeviceManagerOzone()); + scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override { + return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); } -#endif - virtual void InitializeUI() OVERRIDE { - surface_factory_ozone_.reset(new CacaSurfaceFactory(&connection_)); - event_factory_ozone_.reset(new CacaEventFactory(&connection_)); + void InitializeUI() override { + window_manager_.reset(new CacaWindowManager); + event_source_.reset(new CacaEventSource()); cursor_factory_ozone_.reset(new CursorFactoryOzone()); } - virtual void InitializeGPU() OVERRIDE {} + void InitializeGPU() override {} private: - CacaConnection connection_; - scoped_ptr<CacaSurfaceFactory> surface_factory_ozone_; - scoped_ptr<CacaEventFactory> event_factory_ozone_; + scoped_ptr<CacaWindowManager> window_manager_; + scoped_ptr<CacaEventSource> event_source_; scoped_ptr<CursorFactoryOzone> cursor_factory_ozone_; DISALLOW_COPY_AND_ASSIGN(OzonePlatformCaca); diff --git a/chromium/ui/ozone/platform/caca/scoped_caca_types.cc b/chromium/ui/ozone/platform/caca/scoped_caca_types.cc new file mode 100644 index 00000000000..093b7c9370e --- /dev/null +++ b/chromium/ui/ozone/platform/caca/scoped_caca_types.cc @@ -0,0 +1,23 @@ +// 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/platform/caca/scoped_caca_types.h" + +#include <caca.h> + +namespace ui { + +void CacaCanvasDeleter::operator()(caca_canvas_t* canvas) const { + caca_free_canvas(canvas); +} + +void CacaDisplayDeleter::operator()(caca_display_t* display) const { + caca_free_display(display); +} + +void CacaDitherDeleter::operator()(caca_dither_t* dither) const { + caca_free_dither(dither); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/caca/scoped_caca_types.h b/chromium/ui/ozone/platform/caca/scoped_caca_types.h new file mode 100644 index 00000000000..d7894760ad7 --- /dev/null +++ b/chromium/ui/ozone/platform/caca/scoped_caca_types.h @@ -0,0 +1,34 @@ +// 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_PLATFORM_CACA_SCOPED_CACA_TYPES_H_ +#define UI_OZONE_PLATFORM_CACA_SCOPED_CACA_TYPES_H_ + +#include "base/memory/scoped_ptr.h" + +typedef struct caca_canvas caca_canvas_t; +typedef struct caca_dither caca_dither_t; +typedef struct caca_display caca_display_t; + +namespace ui { + +struct CacaCanvasDeleter { + void operator()(caca_canvas_t* canvas) const; +}; + +struct CacaDisplayDeleter { + void operator()(caca_display_t* display) const; +}; + +struct CacaDitherDeleter { + void operator()(caca_dither_t* dither) const; +}; + +typedef scoped_ptr<caca_canvas_t, CacaCanvasDeleter> ScopedCacaCanvas; +typedef scoped_ptr<caca_display_t, CacaDisplayDeleter> ScopedCacaDisplay; +typedef scoped_ptr<caca_dither_t, CacaDitherDeleter> ScopedCacaDither; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_CACA_SCOPED_CACA_TYPES_H_ diff --git a/chromium/ui/ozone/platform/dri/BUILD.gn b/chromium/ui/ozone/platform/dri/BUILD.gn new file mode 100644 index 00000000000..1cb4e0ec9bd --- /dev/null +++ b/chromium/ui/ozone/platform/dri/BUILD.gn @@ -0,0 +1,148 @@ +# 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. + +import("//build/config/linux/pkg_config.gni") +import("//ui/ozone/ozone.gni") + +pkg_config("libdrm") { + packages = [ "libdrm" ] +} + +source_set("dri_common") { + sources = [ + "channel_observer.h", + "crtc_controller.cc", + "crtc_controller.h", + "display_mode_dri.cc", + "display_mode_dri.h", + "display_snapshot_dri.cc", + "display_snapshot_dri.h", + "dri_console_buffer.cc", + "dri_console_buffer.h", + "dri_cursor.cc", + "dri_cursor.h", + "dri_buffer.cc", + "dri_buffer.h", + "dri_gpu_platform_support.cc", + "dri_gpu_platform_support_.h", + "dri_gpu_platform_support_host.cc", + "dri_gpu_platform_support_host.h", + "dri_surface.cc", + "dri_surface.h", + "dri_surface_factory.cc", + "dri_surface_factory.h", + "dri_util.cc", + "dri_util.h", + "dri_vsync_provider.cc", + "dri_vsync_provider.h", + "dri_window.cc", + "dri_window.h", + "dri_window_delegate.h", + "dri_window_delegate_impl.cc", + "dri_window_delegate_impl.h", + "dri_window_delegate_manager.cc", + "dri_window_delegate_manager.h", + "dri_window_manager.cc", + "dri_window_manager.h", + "dri_wrapper.cc", + "dri_wrapper.h", + "hardware_display_controller.cc", + "hardware_display_controller.h", + "native_display_delegate_dri.cc", + "native_display_delegate_dri.h", + "overlay_plane.cc", + "overlay_plane.h", + "scoped_drm_types.cc", + "scoped_drm_types.h", + "screen_manager.cc", + "screen_manager.h", + "scanout_buffer.h", + ] + + deps = [ + "//base", + "//skia", + "//ipc", + "//ui/base", + "//ui/display/types", + "//ui/events", + "//ui/events/ozone:events_ozone_evdev", + "//ui/gfx", + "//ui/gfx/geometry", + ] + + public_configs = [ + ":libdrm", + ] +} + +if (ozone_platform_dri) { + source_set("dri") { + sources = [ + "ozone_platform_dri.cc", + "ozone_platform_dri.h", + ] + + deps = [ + ":dri_common", + "//base", + "//skia", + "//ui/events/ozone:events_ozone_evdev", + ] + } + + source_set("dri_unittests") { + testonly = true + sources = [ + "dri_surface_factory_unittest.cc", + "dri_surface_unittest.cc", + "hardware_display_controller_unittest.cc", + "screen_manager_unittest.cc", + "test/mock_dri_wrapper.cc", + "test/mock_dri_wrapper.h", + ] + + deps = [ + ":dri_common", + "//skia", + "//testing/gtest", + ] + } +} + +if (ozone_platform_gbm) { + pkg_config("libgbm") { + packages = [ "gbm" ] + } + + source_set("gbm") { + sources = [ + "gbm_buffer.cc", + "gbm_buffer.h", + "gbm_buffer_base.cc", + "gbm_buffer_base.h", + "gbm_surface.cc", + "gbm_surface.h", + "gbm_surfaceless.cc", + "gbm_surfaceless.h", + "gbm_surface_factory.cc", + "gbm_surface_factory.h", + "native_display_delegate_proxy.cc", + "native_display_delegate_proxy.h", + "ozone_platform_gbm.cc", + "ozone_platform_gbm.h", + ] + + deps = [ + ":dri_common", + "//base", + "//skia", + "//ui/events/ozone:events_ozone_evdev", + ] + + public_configs = [ + ":libgbm", + ] + } +} diff --git a/chromium/ui/ozone/platform/dri/DEPS b/chromium/ui/ozone/platform/dri/DEPS index ee54c22bef5..0ab14717d97 100644 --- a/chromium/ui/ozone/platform/dri/DEPS +++ b/chromium/ui/ozone/platform/dri/DEPS @@ -1,4 +1,3 @@ include_rules = [ - "+skia/ext", - "+third_party/skia", + "+ui/display/util", ] diff --git a/chromium/ui/ozone/platform/dri/buffer_data.cc b/chromium/ui/ozone/platform/dri/buffer_data.cc deleted file mode 100644 index a2ea1b38cc2..00000000000 --- a/chromium/ui/ozone/platform/dri/buffer_data.cc +++ /dev/null @@ -1,71 +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/platform/dri/buffer_data.h" - -#include <gbm.h> - -#include "base/logging.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" - -namespace ui { - -// Pixel configuration for the current buffer format. -// TODO(dnicoara) These will need to change once we query the hardware for -// supported configurations. -const uint8_t kColorDepth = 24; -const uint8_t kPixelDepth = 32; - -BufferData::BufferData(DriWrapper* dri, gbm_bo* buffer) - : dri_(dri), - handle_(gbm_bo_get_handle(buffer).u32), - framebuffer_(0) { - // Register the buffer with the controller. This will allow us to scan out the - // buffer once we're done drawing into it. If we can't register the buffer - // then there's no point in having BufferData associated with it. - if (!dri_->AddFramebuffer(gbm_bo_get_width(buffer), - gbm_bo_get_height(buffer), - kColorDepth, - kPixelDepth, - gbm_bo_get_stride(buffer), - handle_, - &framebuffer_)) { - LOG(ERROR) << "Failed to register buffer"; - } -} - -BufferData::~BufferData() { - if (framebuffer_) - dri_->RemoveFramebuffer(framebuffer_); -} - -// static -BufferData* BufferData::CreateData(DriWrapper* dri, - gbm_bo* buffer) { - BufferData* data = new BufferData(dri, buffer); - if (!data->framebuffer()) { - delete data; - return NULL; - } - - // GBM can destroy the buffers at any time as long as they aren't locked. This - // sets a callback such that we can clean up all our state when GBM destroys - // the buffer. - gbm_bo_set_user_data(buffer, data, BufferData::Destroy); - - return data; -} - -// static -void BufferData::Destroy(gbm_bo* buffer, void* data) { - BufferData* bd = static_cast<BufferData*>(data); - delete bd; -} - -// static -BufferData* BufferData::GetData(gbm_bo* buffer) { - return static_cast<BufferData*>(gbm_bo_get_user_data(buffer)); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/buffer_data.h b/chromium/ui/ozone/platform/dri/buffer_data.h deleted file mode 100644 index 2f3422d38bc..00000000000 --- a/chromium/ui/ozone/platform/dri/buffer_data.h +++ /dev/null @@ -1,53 +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_PLATFORM_DRI_BUFFER_DATA_H_ -#define UI_OZONE_PLATFORM_DRI_BUFFER_DATA_H_ - -#include "base/memory/scoped_ptr.h" - -struct gbm_bo; - -namespace ui { - -class DriWrapper; - -// This class is used to tag a gbm buffer with custom information needed -// for presentation with the surface factory. -class BufferData { - public: - // When we create the BufferData we need to register the buffer. Once - // successfully registered, the |framebuffer_| field will hold the ID of the - // buffer. The controller will use this ID when scanning out the buffer. On - // creation we will also associate the BufferData with the buffer. - static BufferData* CreateData(DriWrapper* dri, gbm_bo* buffer); - - // Callback used by GBM to destroy the BufferData associated with a buffer. - static void Destroy(gbm_bo* buffer, void* data); - - // Returns the BufferData associated with |buffer|. NULL if no data is - // associated. - static BufferData* GetData(gbm_bo* buffer); - - uint32_t framebuffer() const { return framebuffer_; } - uint32_t handle() const { return handle_; } - - private: - BufferData(DriWrapper* dri, gbm_bo* buffer); - ~BufferData(); - - DriWrapper* dri_; - - uint32_t handle_; - - // ID provided by the controller when the buffer is registered. This ID is - // used when scanning out the buffer. - uint32_t framebuffer_; - - DISALLOW_COPY_AND_ASSIGN(BufferData); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_BUFFER_DATA_H_ diff --git a/chromium/ui/ozone/platform/dri/channel_observer.h b/chromium/ui/ozone/platform/dri/channel_observer.h new file mode 100644 index 00000000000..356a79ea9d4 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/channel_observer.h @@ -0,0 +1,21 @@ +// 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_PLATFORM_DRI_CHANNEL_OBSERVER_H_ +#define UI_OZONE_PLATFORM_DRI_CHANNEL_OBSERVER_H_ + +namespace ui { + +// Observes the channel state. +class ChannelObserver { + public: + virtual ~ChannelObserver() {} + + virtual void OnChannelEstablished() = 0; + virtual void OnChannelDestroyed() = 0; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_CHANNEL_OBSERVER_H_ diff --git a/chromium/ui/ozone/platform/dri/chromeos/DEPS b/chromium/ui/ozone/platform/dri/chromeos/DEPS deleted file mode 100644 index 0ab14717d97..00000000000 --- a/chromium/ui/ozone/platform/dri/chromeos/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+ui/display/util", -] diff --git a/chromium/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc b/chromium/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc deleted file mode 100644 index 66a5cf3136a..00000000000 --- a/chromium/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc +++ /dev/null @@ -1,189 +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/platform/dri/chromeos/native_display_delegate_dri.h" - -#include "base/bind.h" -#include "ui/display/types/chromeos/native_display_observer.h" -#include "ui/events/ozone/device/device_event.h" -#include "ui/events/ozone/device/device_manager.h" -#include "ui/ozone/platform/dri/chromeos/display_mode_dri.h" -#include "ui/ozone/platform/dri/chromeos/display_snapshot_dri.h" -#include "ui/ozone/platform/dri/dri_util.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" -#include "ui/ozone/platform/dri/screen_manager.h" - -namespace ui { - -namespace { -const size_t kMaxDisplayCount = 2; -} // namespace - -NativeDisplayDelegateDri::NativeDisplayDelegateDri( - DriWrapper* dri, - ScreenManager* screen_manager, - DeviceManager* device_manager) - : dri_(dri), - screen_manager_(screen_manager), - device_manager_(device_manager) { -} - -NativeDisplayDelegateDri::~NativeDisplayDelegateDri() { - device_manager_->RemoveObserver(this); -} - -void NativeDisplayDelegateDri::Initialize() { - device_manager_->AddObserver(this); -} - -void NativeDisplayDelegateDri::GrabServer() {} - -void NativeDisplayDelegateDri::UngrabServer() {} - -void NativeDisplayDelegateDri::SyncWithServer() {} - -void NativeDisplayDelegateDri::SetBackgroundColor(uint32_t color_argb) { - NOTIMPLEMENTED(); -} - -void NativeDisplayDelegateDri::ForceDPMSOn() { - for (size_t i = 0; i < cached_displays_.size(); ++i) { - DisplaySnapshotDri* dri_output = cached_displays_[i]; - if (dri_output->dpms_property()) - dri_->SetProperty(dri_output->connector(), - dri_output->dpms_property()->prop_id, - DRM_MODE_DPMS_ON); - } -} - -std::vector<DisplaySnapshot*> NativeDisplayDelegateDri::GetDisplays() { - ScopedVector<DisplaySnapshotDri> old_displays(cached_displays_.Pass()); - cached_modes_.clear(); - - drmModeRes* resources = drmModeGetResources(dri_->get_fd()); - DCHECK(resources) << "Failed to get DRM resources"; - ScopedVector<HardwareDisplayControllerInfo> displays = - GetAvailableDisplayControllerInfos(dri_->get_fd(), resources); - for (size_t i = 0; - i < displays.size() && cached_displays_.size() < kMaxDisplayCount; ++i) { - DisplaySnapshotDri* display = new DisplaySnapshotDri( - dri_, displays[i]->connector(), displays[i]->crtc(), i); - cached_displays_.push_back(display); - // Modes can be shared between different displays, so we need to keep track - // of them independently for cleanup. - cached_modes_.insert(cached_modes_.end(), - display->modes().begin(), - display->modes().end()); - } - - drmModeFreeResources(resources); - - NotifyScreenManager(cached_displays_.get(), old_displays.get()); - - std::vector<DisplaySnapshot*> generic_displays(cached_displays_.begin(), - cached_displays_.end()); - return generic_displays; -} - -void NativeDisplayDelegateDri::AddMode(const DisplaySnapshot& output, - const DisplayMode* mode) {} - -bool NativeDisplayDelegateDri::Configure(const DisplaySnapshot& output, - const DisplayMode* mode, - const gfx::Point& origin) { - const DisplaySnapshotDri& dri_output = - static_cast<const DisplaySnapshotDri&>(output); - - VLOG(1) << "DRM configuring: crtc=" << dri_output.crtc() - << " connector=" << dri_output.connector() - << " origin=" << origin.ToString() - << " size=" << (mode ? mode->size().ToString() : "0x0"); - - if (mode) { - if (!screen_manager_->ConfigureDisplayController( - dri_output.crtc(), - dri_output.connector(), - static_cast<const DisplayModeDri*>(mode)->mode_info())) { - VLOG(1) << "Failed to configure: crtc=" << dri_output.crtc() - << " connector=" << dri_output.connector(); - return false; - } - } else { - if (!screen_manager_->DisableDisplayController(dri_output.crtc(), - dri_output.connector())) { - VLOG(1) << "Failed to disable crtc=" << dri_output.crtc(); - return false; - } - } - - return true; -} - -void NativeDisplayDelegateDri::CreateFrameBuffer(const gfx::Size& size) {} - -bool NativeDisplayDelegateDri::GetHDCPState(const DisplaySnapshot& output, - HDCPState* state) { - NOTIMPLEMENTED(); - return false; -} - -bool NativeDisplayDelegateDri::SetHDCPState(const DisplaySnapshot& output, - HDCPState state) { - NOTIMPLEMENTED(); - return false; -} - -std::vector<ui::ColorCalibrationProfile> -NativeDisplayDelegateDri::GetAvailableColorCalibrationProfiles( - const ui::DisplaySnapshot& output) { - NOTIMPLEMENTED(); - return std::vector<ui::ColorCalibrationProfile>(); -} - -bool NativeDisplayDelegateDri::SetColorCalibrationProfile( - const ui::DisplaySnapshot& output, - ui::ColorCalibrationProfile new_profile) { - NOTIMPLEMENTED(); - return false; -} - -void NativeDisplayDelegateDri::AddObserver(NativeDisplayObserver* observer) { - observers_.AddObserver(observer); -} - -void NativeDisplayDelegateDri::RemoveObserver(NativeDisplayObserver* observer) { - observers_.RemoveObserver(observer); -} - -void NativeDisplayDelegateDri::OnDeviceEvent(const DeviceEvent& event) { - if (event.device_type() != DeviceEvent::DISPLAY) - return; - - if (event.action_type() == DeviceEvent::CHANGE) { - VLOG(1) << "Got display changed event"; - FOR_EACH_OBSERVER( - NativeDisplayObserver, observers_, OnConfigurationChanged()); - } -} - -void NativeDisplayDelegateDri::NotifyScreenManager( - const std::vector<DisplaySnapshotDri*>& new_displays, - const std::vector<DisplaySnapshotDri*>& old_displays) const { - for (size_t i = 0; i < old_displays.size(); ++i) { - bool found = false; - for (size_t j = 0; j < new_displays.size(); ++j) { - if (old_displays[i]->connector() == new_displays[j]->connector() && - old_displays[i]->crtc() == new_displays[j]->crtc()) { - found = true; - break; - } - } - - if (!found) - screen_manager_->RemoveDisplayController(old_displays[i]->crtc(), - old_displays[i]->connector()); - } -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.h b/chromium/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.h deleted file mode 100644 index a48d1a5bc8e..00000000000 --- a/chromium/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.h +++ /dev/null @@ -1,78 +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_PLATFORM_DRI_CHROMEOS_NATIVE_DISPLAY_DELEGATE_DRI_H_ -#define UI_OZONE_PLATFORM_DRI_CHROMEOS_NATIVE_DISPLAY_DELEGATE_DRI_H_ - -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/observer_list.h" -#include "ui/display/types/chromeos/native_display_delegate.h" -#include "ui/events/ozone/device/device_event_observer.h" - -namespace ui { - -class DeviceManager; -class DisplaySnapshotDri; -class DriWrapper; -class ScreenManager; - -class NativeDisplayDelegateDri - : public NativeDisplayDelegate, DeviceEventObserver { - public: - NativeDisplayDelegateDri(DriWrapper* dri, - ScreenManager* screen_manager, - DeviceManager* device_manager); - virtual ~NativeDisplayDelegateDri(); - - // NativeDisplayDelegate overrides: - virtual void Initialize() OVERRIDE; - virtual void GrabServer() OVERRIDE; - virtual void UngrabServer() OVERRIDE; - virtual void SyncWithServer() OVERRIDE; - virtual void SetBackgroundColor(uint32_t color_argb) OVERRIDE; - virtual void ForceDPMSOn() OVERRIDE; - virtual std::vector<DisplaySnapshot*> GetDisplays() OVERRIDE; - virtual void AddMode(const DisplaySnapshot& output, - const DisplayMode* mode) OVERRIDE; - virtual bool Configure(const DisplaySnapshot& output, - const DisplayMode* mode, - const gfx::Point& origin) OVERRIDE; - virtual void CreateFrameBuffer(const gfx::Size& size) OVERRIDE; - virtual bool GetHDCPState(const DisplaySnapshot& output, - HDCPState* state) OVERRIDE; - virtual bool SetHDCPState(const DisplaySnapshot& output, - HDCPState state) OVERRIDE; - virtual std::vector<ui::ColorCalibrationProfile> - GetAvailableColorCalibrationProfiles( - const ui::DisplaySnapshot& output) OVERRIDE; - virtual bool SetColorCalibrationProfile( - const ui::DisplaySnapshot& output, - ui::ColorCalibrationProfile new_profile) OVERRIDE; - virtual void AddObserver(NativeDisplayObserver* observer) OVERRIDE; - virtual void RemoveObserver(NativeDisplayObserver* observer) OVERRIDE; - - // DeviceEventObserver overrides: - virtual void OnDeviceEvent(const DeviceEvent& event) OVERRIDE; - - private: - // Notify ScreenManager of all the displays that were present before the - // update but are gone after the update. - void NotifyScreenManager( - const std::vector<DisplaySnapshotDri*>& new_displays, - const std::vector<DisplaySnapshotDri*>& old_displays) const; - - DriWrapper* dri_; // Not owned. - ScreenManager* screen_manager_; // Not owned. - DeviceManager* device_manager_; // Not owned. - ScopedVector<const DisplayMode> cached_modes_; - ScopedVector<DisplaySnapshotDri> cached_displays_; - ObserverList<NativeDisplayObserver> observers_; - - DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateDri); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_CHROMEOS_NATIVE_DISPLAY_DELEGATE_DRI_H_ diff --git a/chromium/ui/ozone/platform/dri/crtc_controller.cc b/chromium/ui/ozone/platform/dri/crtc_controller.cc new file mode 100644 index 00000000000..8056cc111b1 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/crtc_controller.cc @@ -0,0 +1,138 @@ +// 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/platform/dri/crtc_controller.h" + +#include "base/logging.h" +#include "base/time/time.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/scanout_buffer.h" + +namespace ui { + +CrtcController::CrtcController(DriWrapper* drm, + uint32_t crtc, + uint32_t connector) + : drm_(drm), + crtc_(crtc), + connector_(connector), + saved_crtc_(drm->GetCrtc(crtc)), + is_disabled_(true), + page_flip_pending_(false), + time_of_last_flip_(0) { +} + +CrtcController::~CrtcController() { + if (!is_disabled_) { + drm_->SetCrtc(saved_crtc_.get(), std::vector<uint32_t>(1, connector_)); + UnsetCursor(); + } +} + +bool CrtcController::Modeset(const OverlayPlane& plane, drmModeModeInfo mode) { + if (!drm_->SetCrtc(crtc_, plane.buffer->GetFramebufferId(), + std::vector<uint32_t>(1, connector_), &mode)) { + LOG(ERROR) << "Failed to modeset: error='" << strerror(errno) + << "' crtc=" << crtc_ << " connector=" << connector_ + << " framebuffer_id=" << plane.buffer->GetFramebufferId() + << " mode=" << mode.hdisplay << "x" << mode.vdisplay << "@" + << mode.vrefresh; + return false; + } + + current_planes_ = std::vector<OverlayPlane>(1, plane); + mode_ = mode; + pending_planes_.clear(); + is_disabled_ = false; + page_flip_pending_ = false; + + return true; +} + +bool CrtcController::Disable() { + if (is_disabled_) + return true; + + is_disabled_ = true; + page_flip_pending_ = false; + return drm_->DisableCrtc(crtc_); +} + +bool CrtcController::SchedulePageFlip(const OverlayPlaneList& overlays) { + DCHECK(!page_flip_pending_); + DCHECK(!is_disabled_); + const OverlayPlane& primary = OverlayPlane::GetPrimaryPlane(overlays); + DCHECK(primary.buffer.get()); + + if (primary.buffer->GetSize() != gfx::Size(mode_.hdisplay, mode_.vdisplay)) { + LOG(WARNING) << "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_; + return true; + } + + if (!drm_->PageFlip(crtc_, primary.buffer->GetFramebufferId(), this)) { + // Permission Denied is a legitimate error + if (errno == EACCES) + return true; + LOG(ERROR) << "Cannot page flip: error='" << strerror(errno) << "'" + << " crtc=" << crtc_ + << " framebuffer=" << primary.buffer->GetFramebufferId() + << " size=" << primary.buffer->GetSize().ToString(); + return false; + } + + page_flip_pending_ = true; + pending_planes_ = overlays; + + for (size_t i = 0; i < overlays.size(); i++) { + const OverlayPlane& plane = overlays[i]; + if (!plane.overlay_plane) + continue; + + const gfx::Size& size = plane.buffer->GetSize(); + gfx::RectF crop_rect = plane.crop_rect; + crop_rect.Scale(size.width(), size.height()); + if (!drm_->PageFlipOverlay(crtc_, plane.buffer->GetFramebufferId(), + plane.display_bounds, crop_rect, + plane.overlay_plane)) { + LOG(ERROR) << "Cannot display on overlay: " << strerror(errno); + return false; + } + } + + return true; +} + +void CrtcController::OnPageFlipEvent(unsigned int frame, + unsigned int seconds, + unsigned int useconds) { + page_flip_pending_ = false; + time_of_last_flip_ = + static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + + useconds; + + current_planes_.clear(); + current_planes_.swap(pending_planes_); +} + +bool CrtcController::SetCursor(const scoped_refptr<ScanoutBuffer>& buffer) { + DCHECK(!is_disabled_); + cursor_buffer_ = buffer; + return drm_->SetCursor(crtc_, buffer->GetHandle(), buffer->GetSize()); +} + +bool CrtcController::UnsetCursor() { + bool state = drm_->SetCursor(crtc_, 0, gfx::Size()); + cursor_buffer_ = NULL; + return state; +} + +bool CrtcController::MoveCursor(const gfx::Point& location) { + DCHECK(!is_disabled_); + return drm_->MoveCursor(crtc_, location); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/crtc_controller.h b/chromium/ui/ozone/platform/dri/crtc_controller.h new file mode 100644 index 00000000000..eefe926945b --- /dev/null +++ b/chromium/ui/ozone/platform/dri/crtc_controller.h @@ -0,0 +1,96 @@ +// 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_PLATFORM_DRI_CRTC_CONTROLLER_H_ +#define UI_OZONE_PLATFORM_DRI_CRTC_CONTROLLER_H_ + +#include <stddef.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "ui/ozone/platform/dri/overlay_plane.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" + +namespace ui { + +class DriWrapper; + +// Wrapper around a CRTC. +// +// One CRTC can be paired up with one or more connectors. The simplest +// configuration represents one CRTC driving one monitor, while pairing up a +// CRTC with multiple connectors results in hardware mirroring. +class CrtcController { + public: + CrtcController(DriWrapper* drm, uint32_t crtc, uint32_t connector); + ~CrtcController(); + + uint32_t crtc() const { return crtc_; } + uint32_t connector() const { return connector_; } + DriWrapper* drm() const { return drm_; } + bool is_disabled() const { return is_disabled_; } + bool page_flip_pending() const { return page_flip_pending_; } + uint64_t 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|. + bool Modeset(const OverlayPlane& plane, drmModeModeInfo mode); + + // Disables the controller. + bool Disable(); + + // Schedule a page flip event and present the overlays in |planes|. + bool SchedulePageFlip(const OverlayPlaneList& planes); + + // 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); + + bool SetCursor(const scoped_refptr<ScanoutBuffer>& buffer); + bool UnsetCursor(); + bool MoveCursor(const gfx::Point& location); + + private: + DriWrapper* drm_; // Not owned. + + // Buffers need to be declared first so that they are destroyed last. Needed + // since the controllers may reference the buffers. + OverlayPlaneList current_planes_; + OverlayPlaneList pending_planes_; + scoped_refptr<ScanoutBuffer> cursor_buffer_; + + uint32_t crtc_; + + // TODO(dnicoara) Add support for hardware mirroring (multiple connectors). + uint32_t connector_; + + drmModeModeInfo mode_; + + // Store the state of the CRTC before we took over. Used to restore the CRTC + // once we no longer need it. + ScopedDrmCrtcPtr saved_crtc_; + + // Keeps track of the CRTC state. If a surface has been bound, then the value + // is set to false. Otherwise it is true. + bool is_disabled_; + + // True if a successful SchedulePageFlip occurred. Reset to false by a modeset + // operation or when the OnPageFlipEvent callback is triggered. + bool page_flip_pending_; + + // The time of the last page flip event as reported by the kernel callback. + uint64_t time_of_last_flip_; + + DISALLOW_COPY_AND_ASSIGN(CrtcController); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_CRTC_CONTROLLER_H_ diff --git a/chromium/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc b/chromium/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc deleted file mode 100644 index d03aac1e53c..00000000000 --- a/chromium/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc +++ /dev/null @@ -1,67 +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/platform/dri/cursor_factory_evdev_dri.h" - -#include "ui/gfx/geometry/point_conversions.h" -#include "ui/ozone/platform/dri/dri_surface_factory.h" - -namespace ui { - -CursorFactoryEvdevDri::CursorFactoryEvdevDri(DriSurfaceFactory* dri) - : dri_(dri) { - // TODO(dnicoara) Assume the first widget since at this point there are no - // widgets initialized. - cursor_window_ = DriSurfaceFactory::kDefaultWidgetHandle; - cursor_location_ = gfx::PointF(2560 / 2, 1700 / 2); // TODO(spang): Argh! -} - -CursorFactoryEvdevDri::~CursorFactoryEvdevDri() {} - -void CursorFactoryEvdevDri::SetBitmapCursor( - gfx::AcceleratedWidget widget, - scoped_refptr<BitmapCursorOzone> cursor) { - if (cursor_ == cursor) - return; - - cursor_ = cursor; - if (cursor_) - dri_->SetHardwareCursor( - cursor_window_, cursor_->bitmap(), bitmap_location()); - else - dri_->UnsetHardwareCursor(cursor_window_); -} - -void CursorFactoryEvdevDri::MoveCursorTo(gfx::AcceleratedWidget widget, - const gfx::PointF& location) { - if (widget != cursor_window_) - dri_->UnsetHardwareCursor(cursor_window_); - - cursor_window_ = widget; - cursor_location_ = location; - - gfx::Size size = dri_->GetWidgetSize(cursor_window_); - cursor_location_.SetToMax(gfx::PointF(0, 0)); - cursor_location_.SetToMin(gfx::PointF(size.width(), size.height())); - - if (cursor_) - dri_->MoveHardwareCursor(cursor_window_, bitmap_location()); -} - -void CursorFactoryEvdevDri::MoveCursor(const gfx::Vector2dF& delta) { - MoveCursorTo(cursor_window_, cursor_location_ + delta); -} - -gfx::AcceleratedWidget CursorFactoryEvdevDri::GetCursorWindow() { - return cursor_window_; -} - -gfx::PointF CursorFactoryEvdevDri::location() { return cursor_location_; } - -gfx::Point CursorFactoryEvdevDri::bitmap_location() { - return gfx::ToFlooredPoint(cursor_location_) - - cursor_->hotspot().OffsetFromOrigin(); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/cursor_factory_evdev_dri.h b/chromium/ui/ozone/platform/dri/cursor_factory_evdev_dri.h deleted file mode 100644 index da132199668..00000000000 --- a/chromium/ui/ozone/platform/dri/cursor_factory_evdev_dri.h +++ /dev/null @@ -1,58 +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_PLATFORM_DRI_CURSOR_FACTORY_EVDEV_DRI_H_ -#define UI_OZONE_PLATFORM_DRI_CURSOR_FACTORY_EVDEV_DRI_H_ - -#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" -#include "ui/events/ozone/evdev/cursor_delegate_evdev.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/rect_f.h" -#include "ui/gfx/native_widget_types.h" - -namespace ui { -class DriSurfaceFactory; -} - -namespace ui { - -class CursorFactoryEvdevDri : public BitmapCursorFactoryOzone, - public CursorDelegateEvdev { - public: - CursorFactoryEvdevDri(DriSurfaceFactory* dri); - virtual ~CursorFactoryEvdevDri(); - - // BitmapCursorFactoryOzone: - virtual gfx::AcceleratedWidget GetCursorWindow() OVERRIDE; - virtual void SetBitmapCursor(gfx::AcceleratedWidget widget, - scoped_refptr<BitmapCursorOzone> cursor) - OVERRIDE; - - // CursorDelegateEvdev: - virtual void MoveCursorTo(gfx::AcceleratedWidget widget, - const gfx::PointF& location) OVERRIDE; - virtual void MoveCursor(const gfx::Vector2dF& delta) OVERRIDE; - virtual gfx::PointF location() OVERRIDE; - - private: - // The location of the bitmap (the cursor location is the hotspot location). - gfx::Point bitmap_location(); - - // The DRI implementation for setting the hardware cursor. - DriSurfaceFactory* dri_; - - // The current cursor bitmap. - scoped_refptr<BitmapCursorOzone> cursor_; - - // The window under the cursor. - gfx::AcceleratedWidget cursor_window_; - - // The location of the cursor within the window. - gfx::PointF cursor_location_; -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_CURSOR_FACTORY_EVDEV_DRI_H_ diff --git a/chromium/ui/ozone/platform/dri/chromeos/display_mode_dri.cc b/chromium/ui/ozone/platform/dri/display_mode_dri.cc index 707cb91b7c2..6dd660ca06a 100644 --- a/chromium/ui/ozone/platform/dri/chromeos/display_mode_dri.cc +++ b/chromium/ui/ozone/platform/dri/display_mode_dri.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/dri/chromeos/display_mode_dri.h" +#include "ui/ozone/platform/dri/display_mode_dri.h" namespace ui { @@ -10,8 +10,10 @@ DisplayModeDri::DisplayModeDri(const drmModeModeInfo& mode) : DisplayMode(gfx::Size(mode.hdisplay, mode.vdisplay), mode.flags & DRM_MODE_FLAG_INTERLACE, mode.vrefresh), - mode_info_(mode) {} + mode_info_(mode) { +} -DisplayModeDri::~DisplayModeDri() {} +DisplayModeDri::~DisplayModeDri() { +} } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/chromeos/display_mode_dri.h b/chromium/ui/ozone/platform/dri/display_mode_dri.h index ab50df28d77..d37f8e211c8 100644 --- a/chromium/ui/ozone/platform/dri/chromeos/display_mode_dri.h +++ b/chromium/ui/ozone/platform/dri/display_mode_dri.h @@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_OZONE_PLATFORM_DRI_CHROMEOS_DISPLAY_MODE_DRI_H_ -#define UI_OZONE_PLATFORM_DRI_CHROMEOS_DISPLAY_MODE_DRI_H_ +#ifndef UI_OZONE_PLATFORM_DRI_DISPLAY_MODE_DRI_H_ +#define UI_OZONE_PLATFORM_DRI_DISPLAY_MODE_DRI_H_ #include <stdint.h> #include <stdlib.h> #include <xf86drmMode.h> -#include "ui/display/types/chromeos/display_mode.h" +#include "ui/display/types/display_mode.h" namespace ui { class DisplayModeDri : public DisplayMode { public: DisplayModeDri(const drmModeModeInfo& mode); - virtual ~DisplayModeDri(); + ~DisplayModeDri() override; // Native details about this mode. Only used internally in the DRI // implementation. @@ -30,4 +30,4 @@ class DisplayModeDri : public DisplayMode { } // namespace ui -#endif // UI_OZONE_PLATFORM_DRI_CHROMEOS_DISPLAY_MODE_DRI_H_ +#endif // UI_OZONE_PLATFORM_DRI_DISPLAY_MODE_DRI_H_ diff --git a/chromium/ui/ozone/platform/dri/chromeos/display_snapshot_dri.cc b/chromium/ui/ozone/platform/dri/display_snapshot_dri.cc index b14c590376a..6c6e8f2fa2f 100644 --- a/chromium/ui/ozone/platform/dri/chromeos/display_snapshot_dri.cc +++ b/chromium/ui/ozone/platform/dri/display_snapshot_dri.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/dri/chromeos/display_snapshot_dri.h" +#include "ui/ozone/platform/dri/display_snapshot_dri.h" #include <stdint.h> #include <stdlib.h> @@ -12,7 +12,7 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "ui/display/util/edid_parser.h" -#include "ui/ozone/platform/dri/chromeos/display_mode_dri.h" +#include "ui/ozone/platform/dri/display_mode_dri.h" #include "ui/ozone/platform/dri/dri_util.h" #include "ui/ozone/platform/dri/dri_wrapper.h" @@ -42,18 +42,19 @@ DisplayConnectionType GetDisplayType(drmModeConnector* connector) { } bool IsAspectPreserving(DriWrapper* drm, drmModeConnector* connector) { - drmModePropertyRes* property = drm->GetProperty(connector, "scaling mode"); - if (property) { - for (int j = 0; j < property->count_enums; ++j) { - if (property->enums[j].value == - connector->prop_values[property->prop_id] && - strcmp(property->enums[j].name, "Full aspect") == 0) { - drm->FreeProperty(property); + ScopedDrmPropertyPtr property(drm->GetProperty(connector, "scaling mode")); + if (!property) + return false; + + for (int props_i = 0; props_i < connector->count_props; ++props_i) { + if (connector->props[props_i] != property->prop_id) + continue; + + for (int enums_i = 0; enums_i < property->count_enums; ++enums_i) { + if (property->enums[enums_i].value == connector->prop_values[props_i] && + strcmp(property->enums[enums_i].name, "Full aspect") == 0) return true; - } } - - drm->FreeProperty(property); } return false; @@ -61,13 +62,11 @@ bool IsAspectPreserving(DriWrapper* drm, drmModeConnector* connector) { } // namespace -DisplaySnapshotDri::DisplaySnapshotDri( - DriWrapper* drm, - drmModeConnector* connector, - drmModeCrtc* crtc, - uint32_t index) +DisplaySnapshotDri::DisplaySnapshotDri(DriWrapper* drm, + drmModeConnector* connector, + drmModeCrtc* crtc, + uint32_t index) : DisplaySnapshot(index, - false, gfx::Point(crtc->x, crtc->y), gfx::Size(connector->mmWidth, connector->mmHeight), GetDisplayType(connector), @@ -80,18 +79,22 @@ DisplaySnapshotDri::DisplaySnapshotDri( connector_(connector->connector_id), crtc_(crtc->crtc_id), dpms_property_(drm->GetProperty(connector, "DPMS")) { - drmModePropertyBlobRes* edid_blob = drm->GetPropertyBlob(connector, "EDID"); + if (!dpms_property_) + VLOG(1) << "Failed to find the DPMS property for connector " + << connector->connector_id; + + ScopedDrmPropertyBlobPtr edid_blob(drm->GetPropertyBlob(connector, "EDID")); if (edid_blob) { std::vector<uint8_t> edid( static_cast<uint8_t*>(edid_blob->data), static_cast<uint8_t*>(edid_blob->data) + edid_blob->length); - has_proper_display_id_ = GetDisplayIdFromEDID(edid, index, &display_id_); + if (!GetDisplayIdFromEDID(edid, index, &display_id_)) + display_id_ = index; + ParseOutputDeviceData(edid, NULL, &display_name_); ParseOutputOverscanFlag(edid, &overscan_flag_); - - drm->FreePropertyBlob(edid_blob); } else { VLOG(1) << "Failed to get EDID blob for connector " << connector->connector_id; @@ -107,19 +110,20 @@ DisplaySnapshotDri::DisplaySnapshotDri( if (mode.type & DRM_MODE_TYPE_PREFERRED) native_mode_ = modes_.back(); } + + // If no preferred mode is found then use the first one. Using the first one + // since it should be the best mode. + if (!native_mode_ && !modes_.empty()) + native_mode_ = modes_.front(); } DisplaySnapshotDri::~DisplaySnapshotDri() { - if (dpms_property_) - drmModeFreeProperty(dpms_property_); } std::string DisplaySnapshotDri::ToString() const { return base::StringPrintf( "[type=%d, connector=%" PRIu32 ", crtc=%" PRIu32 ", mode=%s, dim=%s]", - type_, - connector_, - crtc_, + type_, connector_, crtc_, current_mode_ ? current_mode_->ToString().c_str() : "NULL", physical_size_.ToString().c_str()); } diff --git a/chromium/ui/ozone/platform/dri/chromeos/display_snapshot_dri.h b/chromium/ui/ozone/platform/dri/display_snapshot_dri.h index 1f69af47ed9..0ae6b1abaa6 100644 --- a/chromium/ui/ozone/platform/dri/chromeos/display_snapshot_dri.h +++ b/chromium/ui/ozone/platform/dri/display_snapshot_dri.h @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_OZONE_PLATFORM_DRI_CHROMEOS_DISPLAY_SNAPSHOT_DRI_H_ -#define UI_OZONE_PLATFORM_DRI_CHROMEOS_DISPLAY_SNAPSHOT_DRI_H_ +#ifndef UI_OZONE_PLATFORM_DRI_DISPLAY_SNAPSHOT_DRI_H_ +#define UI_OZONE_PLATFORM_DRI_DISPLAY_SNAPSHOT_DRI_H_ -#include "ui/display/types/chromeos/display_snapshot.h" - -typedef struct _drmModeConnector drmModeConnector; -typedef struct _drmModeCrtc drmModeCrtc; -typedef struct _drmModeProperty drmModePropertyRes; +#include "ui/display/types/display_snapshot.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" namespace ui { @@ -21,21 +18,21 @@ class DisplaySnapshotDri : public DisplaySnapshot { drmModeConnector* connector, drmModeCrtc* crtc, uint32_t index); - virtual ~DisplaySnapshotDri(); + ~DisplaySnapshotDri() override; // Native properties of a display used by the DRI implementation in // configuring this display. uint32_t connector() const { return connector_; } uint32_t crtc() const { return crtc_; } - drmModePropertyRes* dpms_property() const { return dpms_property_; } + drmModePropertyRes* dpms_property() const { return dpms_property_.get(); } // DisplaySnapshot overrides: - virtual std::string ToString() const OVERRIDE; + std::string ToString() const override; private: uint32_t connector_; uint32_t crtc_; - drmModePropertyRes* dpms_property_; + ScopedDrmPropertyPtr dpms_property_; std::string name_; bool overscan_flag_; @@ -44,4 +41,4 @@ class DisplaySnapshotDri : public DisplaySnapshot { } // namespace ui -#endif // UI_OZONE_PLATFORM_DRI_CHROMEOS_DISPLAY_SNAPSHOT_DRI_H_ +#endif // UI_OZONE_PLATFORM_DRI_DISPLAY_SNAPSHOT_DRI_H_ diff --git a/chromium/ui/ozone/platform/dri/dri.gypi b/chromium/ui/ozone/platform/dri/dri.gypi index 3e10ca7b8bc..d1f526e020b 100644 --- a/chromium/ui/ozone/platform/dri/dri.gypi +++ b/chromium/ui/ozone/platform/dri/dri.gypi @@ -13,6 +13,7 @@ 'internal_ozone_platforms': [ 'dri', ], + 'use_drm_atomic_flip%': 0, }, 'targets': [ { @@ -20,7 +21,7 @@ 'type': 'static_library', 'dependencies': [ '../../base/base.gyp:base', - '../../build/linux/system.gyp:dridrm', + '../../build/linux/system.gyp:libdrm', '../../skia/skia.gyp:skia', '../base/ui_base.gyp:ui_base', '../display/display.gyp:display_types', @@ -34,16 +35,23 @@ 'OZONE_IMPLEMENTATION', ], 'sources': [ - 'chromeos/display_mode_dri.cc', - 'chromeos/display_mode_dri.h', - 'chromeos/display_snapshot_dri.cc', - 'chromeos/display_snapshot_dri.h', - 'chromeos/native_display_delegate_dri.cc', - 'chromeos/native_display_delegate_dri.h', - 'cursor_factory_evdev_dri.cc', - 'cursor_factory_evdev_dri.h', + 'channel_observer.h', + 'crtc_controller.cc', + 'crtc_controller.h', + 'display_mode_dri.cc', + 'display_mode_dri.h', + 'display_snapshot_dri.cc', + 'display_snapshot_dri.h', + 'dri_console_buffer.cc', + 'dri_console_buffer.h', 'dri_buffer.cc', 'dri_buffer.h', + 'dri_cursor.cc', + 'dri_cursor.h', + 'dri_gpu_platform_support.cc', + 'dri_gpu_platform_support.h', + 'dri_gpu_platform_support_host.cc', + 'dri_gpu_platform_support_host.h', 'dri_surface.cc', 'dri_surface.h', 'dri_surface_factory.cc', @@ -52,29 +60,53 @@ 'dri_util.h', 'dri_vsync_provider.cc', 'dri_vsync_provider.h', + 'dri_window.cc', + 'dri_window.h', + 'dri_window_delegate.h', + 'dri_window_delegate_impl.cc', + 'dri_window_delegate_impl.h', + 'dri_window_delegate_manager.cc', + 'dri_window_delegate_manager.h', + 'dri_window_manager.cc', + 'dri_window_manager.h', 'dri_wrapper.cc', 'dri_wrapper.h', 'hardware_display_controller.cc', 'hardware_display_controller.h', + 'native_display_delegate_dri.cc', + 'native_display_delegate_dri.h', + 'overlay_plane.cc', + 'overlay_plane.h', 'ozone_platform_dri.cc', 'ozone_platform_dri.h', + 'scoped_drm_types.cc', + 'scoped_drm_types.h', 'screen_manager.cc', 'screen_manager.h', - 'scanout_surface.h', - 'virtual_terminal_manager.cc', - 'virtual_terminal_manager.h', + 'scanout_buffer.h', + ], + 'conditions': [ + ['use_drm_atomic_flip==1', { + 'sources': [ + 'hardware_display_plane.cc', + 'hardware_display_plane.h', + 'hardware_display_plane_manager.cc', + 'hardware_display_plane_manager.h', + ], + }], ], }, { 'target_name': 'ozone_platform_dri_unittests', 'type': 'none', 'dependencies': [ - '../../build/linux/system.gyp:dridrm', + '../../build/linux/system.gyp:libdrm', '../../skia/skia.gyp:skia', '../gfx/gfx.gyp:gfx_geometry', + 'ozone_platform_dri', ], 'export_dependent_settings': [ - '../../build/linux/system.gyp:dridrm', + '../../build/linux/system.gyp:libdrm', '../../skia/skia.gyp:skia', '../gfx/gfx.gyp:gfx_geometry', ], @@ -84,12 +116,8 @@ 'dri_surface_unittest.cc', 'hardware_display_controller_unittest.cc', 'screen_manager_unittest.cc', - 'test/mock_dri_surface.cc', - 'test/mock_dri_surface.h', 'test/mock_dri_wrapper.cc', 'test/mock_dri_wrapper.h', - 'test/mock_surface_generator.cc', - 'test/mock_surface_generator.h', ], }, }, diff --git a/chromium/ui/ozone/platform/dri/dri_buffer.cc b/chromium/ui/ozone/platform/dri/dri_buffer.cc index f3dc1b903f3..4a35395c95a 100644 --- a/chromium/ui/ozone/platform/dri/dri_buffer.cc +++ b/chromium/ui/ozone/platform/dri/dri_buffer.cc @@ -4,13 +4,7 @@ #include "ui/ozone/platform/dri/dri_buffer.h" -#include <errno.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <xf86drm.h> - #include "base/logging.h" -#include "third_party/skia/include/core/SkCanvas.h" #include "ui/ozone/platform/dri/dri_wrapper.h" namespace ui { @@ -30,7 +24,7 @@ uint8_t GetColorDepth(SkColorType type) { return 16; case kARGB_4444_SkColorType: return 12; - case kPMColor_SkColorType: + case kN32_SkColorType: return 24; default: NOTREACHED(); @@ -38,57 +32,6 @@ uint8_t GetColorDepth(SkColorType type) { } } -void DestroyDumbBuffer(int fd, uint32_t handle) { - struct drm_mode_destroy_dumb destroy_request; - destroy_request.handle = handle; - drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request); -} - -bool CreateDumbBuffer(DriWrapper* dri, - const SkImageInfo& info, - uint32_t* handle, - uint32_t* stride, - void** pixels) { - struct drm_mode_create_dumb request; - request.width = info.width(); - request.height = info.height(); - request.bpp = info.bytesPerPixel() << 3; - request.flags = 0; - - if (drmIoctl(dri->get_fd(), DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) { - DLOG(ERROR) << "Cannot create dumb buffer (" << errno << ") " - << strerror(errno); - return false; - } - - *handle = request.handle; - *stride = request.pitch; - - struct drm_mode_map_dumb map_request; - map_request.handle = request.handle; - if (drmIoctl(dri->get_fd(), DRM_IOCTL_MODE_MAP_DUMB, &map_request)) { - DLOG(ERROR) << "Cannot prepare dumb buffer for mapping (" << errno << ") " - << strerror(errno); - DestroyDumbBuffer(dri->get_fd(), request.handle); - return false; - } - - *pixels = mmap(0, - request.size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - dri->get_fd(), - map_request.offset); - if (*pixels == MAP_FAILED) { - DLOG(ERROR) << "Cannot mmap dumb buffer (" << errno << ") " - << strerror(errno); - DestroyDumbBuffer(dri->get_fd(), request.handle); - return false; - } - - return true; -} - } // namespace DriBuffer::DriBuffer(DriWrapper* dri) @@ -106,14 +49,13 @@ DriBuffer::~DriBuffer() { if (!pixels) return; - munmap(pixels, info.getSafeSize(stride_)); - DestroyDumbBuffer(dri_->get_fd(), handle_); + dri_->DestroyDumbBuffer(info, handle_, stride_, pixels); } bool DriBuffer::Initialize(const SkImageInfo& info) { void* pixels = NULL; - if (!CreateDumbBuffer(dri_, info, &handle_, &stride_, &pixels)) { - DLOG(ERROR) << "Cannot allocate drm dumb buffer"; + if (!dri_->CreateDumbBuffer(info, &handle_, &stride_, &pixels)) { + VLOG(2) << "Cannot create drm dumb buffer"; return false; } @@ -124,17 +66,46 @@ bool DriBuffer::Initialize(const SkImageInfo& info) { stride_, handle_, &framebuffer_)) { - DLOG(ERROR) << "Failed to register framebuffer: " << strerror(errno); + VLOG(2) << "Failed to register framebuffer: " << strerror(errno); return false; } surface_ = skia::AdoptRef(SkSurface::NewRasterDirect(info, pixels, stride_)); if (!surface_) { - DLOG(ERROR) << "Cannot install Skia pixels for drm buffer"; + VLOG(2) << "Cannot install Skia pixels for drm buffer"; return false; } return true; } +SkCanvas* DriBuffer::GetCanvas() const { + return surface_->getCanvas(); +} + +uint32_t DriBuffer::GetFramebufferId() const { + return framebuffer_; +} + +uint32_t DriBuffer::GetHandle() const { + return handle_; +} + +gfx::Size DriBuffer::GetSize() const { + return gfx::Size(surface_->width(), surface_->height()); +} + +DriBufferGenerator::DriBufferGenerator(DriWrapper* dri) : dri_(dri) {} + +DriBufferGenerator::~DriBufferGenerator() {} + +scoped_refptr<ScanoutBuffer> DriBufferGenerator::Create(const gfx::Size& size) { + scoped_refptr<DriBuffer> buffer(new DriBuffer(dri_)); + SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height()); + if (!buffer->Initialize(info)) + return NULL; + + return buffer; +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_buffer.h b/chromium/ui/ozone/platform/dri/dri_buffer.h index abed28e0039..bdcdb1eb9dd 100644 --- a/chromium/ui/ozone/platform/dri/dri_buffer.h +++ b/chromium/ui/ozone/platform/dri/dri_buffer.h @@ -8,9 +8,7 @@ #include "base/macros.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkSurface.h" -#include "ui/ozone/ozone_export.h" - -class SkCanvas; +#include "ui/ozone/platform/dri/scanout_buffer.h" namespace ui { @@ -19,21 +17,24 @@ class DriWrapper; // Wrapper for a DRM allocated buffer. Keeps track of the native properties of // the buffer and wraps the pixel memory into a SkSurface which can be used to // draw into using Skia. -class OZONE_EXPORT DriBuffer { +class DriBuffer : public ScanoutBuffer { public: DriBuffer(DriWrapper* dri); - virtual ~DriBuffer(); - - uint32_t stride() const { return stride_; } - uint32_t handle() const { return handle_; } - uint32_t framebuffer() const { return framebuffer_; } - SkCanvas* canvas() { return surface_->getCanvas(); } // Allocates the backing pixels and wraps them in |surface_|. |info| is used // to describe the buffer characteristics (size, color format). - virtual bool Initialize(const SkImageInfo& info); + bool Initialize(const SkImageInfo& info); + + SkCanvas* GetCanvas() const; + + // ScanoutBuffer: + uint32_t GetFramebufferId() const override; + uint32_t GetHandle() const override; + gfx::Size GetSize() const override; protected: + ~DriBuffer() override; + DriWrapper* dri_; // Not owned. // Wrapper around the native pixel memory. @@ -52,6 +53,20 @@ class OZONE_EXPORT DriBuffer { DISALLOW_COPY_AND_ASSIGN(DriBuffer); }; +class DriBufferGenerator : public ScanoutBufferGenerator { + public: + DriBufferGenerator(DriWrapper* dri); + ~DriBufferGenerator() override; + + // ScanoutBufferGenerator: + scoped_refptr<ScanoutBuffer> Create(const gfx::Size& size) override; + + private: + DriWrapper* dri_; // Not owned. + + DISALLOW_COPY_AND_ASSIGN(DriBufferGenerator); +}; + } // namespace ui #endif // UI_OZONE_PLATFORM_DRI_DRI_BUFFER_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_console_buffer.cc b/chromium/ui/ozone/platform/dri/dri_console_buffer.cc new file mode 100644 index 00000000000..6c1f7a9ba7a --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_console_buffer.cc @@ -0,0 +1,56 @@ +// 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/platform/dri/dri_console_buffer.h" + +#include <sys/mman.h> +#include <xf86drmMode.h> + +#include "third_party/skia/include/core/SkCanvas.h" +#include "ui/ozone/platform/dri/dri_util.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" + +namespace ui { + +DriConsoleBuffer::DriConsoleBuffer(DriWrapper* dri, uint32_t framebuffer) + : dri_(dri), + handle_(0), + framebuffer_(framebuffer), + mmap_base_(NULL), + mmap_size_(0) { +} + +DriConsoleBuffer::~DriConsoleBuffer() { + if (mmap_base_) + if (munmap(mmap_base_, mmap_size_)) + PLOG(ERROR) << "munmap"; +} + +bool DriConsoleBuffer::Initialize() { + ScopedDrmFramebufferPtr fb(dri_->GetFramebuffer(framebuffer_)); + + if (!fb) + return false; + + handle_ = fb->handle; + stride_ = fb->pitch; + SkImageInfo info = SkImageInfo::MakeN32Premul(fb->width, fb->height); + + mmap_size_ = info.getSafeSize(stride_); + + if (!MapDumbBuffer(dri_->get_fd(), fb->handle, mmap_size_, &mmap_base_)) { + mmap_base_ = NULL; + return false; + } + + surface_ = + skia::AdoptRef(SkSurface::NewRasterDirect(info, mmap_base_, stride_)); + if (!surface_) + return false; + + return true; +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_console_buffer.h b/chromium/ui/ozone/platform/dri/dri_console_buffer.h new file mode 100644 index 00000000000..51cb4adb331 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_console_buffer.h @@ -0,0 +1,58 @@ +// 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_PLATFORM_DRI_DRI_CONSOLE_BUFFER_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_CONSOLE_BUFFER_H_ + +#include "base/macros.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkSurface.h" + +class SkCanvas; + +namespace ui { + +class DriWrapper; + +// Wrapper for the console buffer. This is the buffer that is allocated by +// default by the system and is used when no application is controlling the +// CRTC. Keeps track of the native properties of the buffer and wraps the pixel +// memory into a SkSurface which can be used to draw into using Skia. +class DriConsoleBuffer { + public: + DriConsoleBuffer(DriWrapper* dri, uint32_t framebuffer); + ~DriConsoleBuffer(); + + SkCanvas* canvas() { return surface_->getCanvas(); } + + // Memory map the backing pixels and wrap them in |surface_|. + bool Initialize(); + + protected: + DriWrapper* dri_; // Not owned. + + // Wrapper around the native pixel memory. + skia::RefPtr<SkSurface> surface_; + + // Length of a row of pixels. + uint32_t stride_; + + // Buffer handle used by the DRM allocator. + uint32_t handle_; + + // Buffer ID used by the DRM modesettings API. + uint32_t framebuffer_; + + // Memory map base address. + void* mmap_base_; + + // Memory map size. + size_t mmap_size_; + + DISALLOW_COPY_AND_ASSIGN(DriConsoleBuffer); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_CONSOLE_BUFFER_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_cursor.cc b/chromium/ui/ozone/platform/dri/dri_cursor.cc new file mode 100644 index 00000000000..22d21726136 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_cursor.cc @@ -0,0 +1,96 @@ +// 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/platform/dri/dri_cursor.h" + +#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/point_f.h" +#include "ui/ozone/platform/dri/dri_surface_factory.h" +#include "ui/ozone/platform/dri/dri_window.h" +#include "ui/ozone/platform/dri/dri_window_manager.h" +#include "ui/ozone/platform/dri/hardware_cursor_delegate.h" + +namespace ui { + +DriCursor::DriCursor(HardwareCursorDelegate* hardware, + DriWindowManager* window_manager) + : hardware_(hardware), + window_manager_(window_manager), + cursor_window_(gfx::kNullAcceleratedWidget) { +} + +DriCursor::~DriCursor() { +} + +void DriCursor::SetCursor(gfx::AcceleratedWidget widget, + PlatformCursor platform_cursor) { + DCHECK_NE(widget, gfx::kNullAcceleratedWidget); + scoped_refptr<BitmapCursorOzone> cursor = + BitmapCursorFactoryOzone::GetBitmapCursor(platform_cursor); + if (cursor_ == cursor || cursor_window_ != widget) + return; + + cursor_ = cursor; +} + +void DriCursor::ShowCursor() { + DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget); + if (cursor_.get()) + hardware_->SetHardwareCursor(cursor_window_, cursor_->bitmaps(), + bitmap_location(), cursor_->frame_delay_ms()); + else + HideCursor(); +} + +void DriCursor::HideCursor() { + DCHECK_NE(cursor_window_, gfx::kNullAcceleratedWidget); + hardware_->SetHardwareCursor(cursor_window_, std::vector<SkBitmap>(), + gfx::Point(), 0); +} + +void DriCursor::MoveCursorTo(gfx::AcceleratedWidget widget, + const gfx::PointF& location) { + if (widget != cursor_window_ && cursor_window_ != gfx::kNullAcceleratedWidget) + HideCursor(); + + cursor_window_ = widget; + cursor_location_ = location; + + if (cursor_window_ == gfx::kNullAcceleratedWidget) + return; + + DriWindow* window = window_manager_->GetWindow(cursor_window_); + const gfx::Size& size = window->GetBounds().size(); + cursor_location_.SetToMax(gfx::PointF(0, 0)); + // Right and bottom edges are exclusive. + cursor_location_.SetToMin(gfx::PointF(size.width() - 1, size.height() - 1)); + + if (cursor_.get()) + hardware_->MoveHardwareCursor(cursor_window_, bitmap_location()); +} + +void DriCursor::MoveCursor(const gfx::Vector2dF& delta) { + MoveCursorTo(cursor_window_, cursor_location_ + delta); +} + +gfx::AcceleratedWidget DriCursor::GetCursorWindow() { + return cursor_window_; +} + +bool DriCursor::IsCursorVisible() { + return cursor_.get(); +} + +gfx::PointF DriCursor::location() { + return cursor_location_; +} + +gfx::Point DriCursor::bitmap_location() { + return gfx::ToFlooredPoint(cursor_location_) - + cursor_->hotspot().OffsetFromOrigin(); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_cursor.h b/chromium/ui/ozone/platform/dri/dri_cursor.h new file mode 100644 index 00000000000..4cea2d8822a --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_cursor.h @@ -0,0 +1,67 @@ +// 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_PLATFORM_DRI_DRI_CURSOR_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_CURSOR_H_ + +#include "base/memory/ref_counted.h" +#include "ui/base/cursor/cursor.h" +#include "ui/events/ozone/evdev/cursor_delegate_evdev.h" +#include "ui/gfx/native_widget_types.h" + +namespace gfx { +class PointF; +class Vector2dF; +} + +namespace ui { + +class BitmapCursorOzone; +class BitmapCursorFactoryOzone; +class DriWindowManager; +class HardwareCursorDelegate; + +class DriCursor : public CursorDelegateEvdev { + public: + explicit DriCursor(HardwareCursorDelegate* hardware, + DriWindowManager* window_manager); + ~DriCursor() override; + + // Set's platform_cursor for widget. SetCursor is not responsible for showing + // the cursor. ShowCursor needs to be explicitly called to make the cursor + // visible. + void SetCursor(gfx::AcceleratedWidget widget, PlatformCursor platform_cursor); + void ShowCursor(); + void HideCursor(); + gfx::AcceleratedWidget GetCursorWindow(); + + // CursorDelegateEvdev: + void MoveCursorTo(gfx::AcceleratedWidget widget, + const gfx::PointF& location) override; + void MoveCursor(const gfx::Vector2dF& delta) override; + bool IsCursorVisible() override; + gfx::PointF location() override; + + private: + // The location of the bitmap (the cursor location is the hotspot location). + gfx::Point bitmap_location(); + + // The DRI implementation for setting the hardware cursor. + HardwareCursorDelegate* hardware_; + + DriWindowManager* window_manager_; // Not owned. + + // The current cursor bitmap. + scoped_refptr<BitmapCursorOzone> cursor_; + + // The window under the cursor. + gfx::AcceleratedWidget cursor_window_; + + // The location of the cursor within the window. + gfx::PointF cursor_location_; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_CURSOR_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_gpu_platform_support.cc b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support.cc new file mode 100644 index 00000000000..64cd453bd93 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support.cc @@ -0,0 +1,217 @@ +// 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/platform/dri/dri_gpu_platform_support.h" + +#include "ipc/ipc_message_macros.h" +#include "ui/display/types/display_mode.h" +#include "ui/display/types/display_snapshot.h" +#include "ui/ozone/common/display_util.h" +#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" +#include "ui/ozone/common/gpu/ozone_gpu_messages.h" +#include "ui/ozone/platform/dri/dri_surface_factory.h" +#include "ui/ozone/platform/dri/dri_window_delegate_impl.h" +#include "ui/ozone/platform/dri/dri_window_delegate_manager.h" +#include "ui/ozone/platform/dri/native_display_delegate_dri.h" + +namespace ui { + +namespace { + +class FindDisplayById { + public: + FindDisplayById(int64_t display_id) : display_id_(display_id) {} + + bool operator()(const DisplaySnapshot_Params& display) const { + return display.display_id == display_id_; + } + + private: + int64_t display_id_; +}; + +} // namespace + +DriGpuPlatformSupport::DriGpuPlatformSupport( + DriSurfaceFactory* dri, + DriWindowDelegateManager* window_manager, + ScreenManager* screen_manager, + scoped_ptr<NativeDisplayDelegateDri> ndd) + : sender_(NULL), + dri_(dri), + window_manager_(window_manager), + screen_manager_(screen_manager), + ndd_(ndd.Pass()) { +} + +DriGpuPlatformSupport::~DriGpuPlatformSupport() { +} + +void DriGpuPlatformSupport::AddHandler(scoped_ptr<GpuPlatformSupport> handler) { + handlers_.push_back(handler.release()); +} + +void DriGpuPlatformSupport::OnChannelEstablished(IPC::Sender* sender) { + sender_ = sender; + + for (size_t i = 0; i < handlers_.size(); ++i) + handlers_[i]->OnChannelEstablished(sender); +} + +bool DriGpuPlatformSupport::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + + IPC_BEGIN_MESSAGE_MAP(DriGpuPlatformSupport, message) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_CreateWindowDelegate, OnCreateWindowDelegate) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_DestroyWindowDelegate, + OnDestroyWindowDelegate) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_WindowBoundsChanged, OnWindowBoundsChanged) + + IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorSet, OnCursorSet) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorMove, OnCursorMove) + + IPC_MESSAGE_HANDLER(OzoneGpuMsg_ForceDPMSOn, OnForceDPMSOn) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_RefreshNativeDisplays, + OnRefreshNativeDisplays) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_ConfigureNativeDisplay, + OnConfigureNativeDisplay) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_DisableNativeDisplay, OnDisableNativeDisplay) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_TakeDisplayControl, OnTakeDisplayControl) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_RelinquishDisplayControl, + OnRelinquishDisplayControl) + IPC_MESSAGE_UNHANDLED(handled = false); + IPC_END_MESSAGE_MAP() + + if (!handled) + for (size_t i = 0; i < handlers_.size(); ++i) + if (handlers_[i]->OnMessageReceived(message)) + return true; + + return false; +} + +void DriGpuPlatformSupport::OnCreateWindowDelegate( + gfx::AcceleratedWidget widget) { + // Due to how the GPU process starts up this IPC call may happen after the IPC + // to create a surface. Since a surface wants to know the window associated + // with it, we create it ahead of time. So when this call happens we do not + // create a delegate if it already exists. + if (!window_manager_->HasWindowDelegate(widget)) { + scoped_ptr<DriWindowDelegate> delegate( + new DriWindowDelegateImpl(widget, screen_manager_)); + delegate->Initialize(); + window_manager_->AddWindowDelegate(widget, delegate.Pass()); + } +} + +void DriGpuPlatformSupport::OnDestroyWindowDelegate( + gfx::AcceleratedWidget widget) { + scoped_ptr<DriWindowDelegate> delegate = + window_manager_->RemoveWindowDelegate(widget); + delegate->Shutdown(); +} + +void DriGpuPlatformSupport::OnWindowBoundsChanged(gfx::AcceleratedWidget widget, + const gfx::Rect& bounds) { + window_manager_->GetWindowDelegate(widget)->OnBoundsChanged(bounds); +} + +void DriGpuPlatformSupport::OnCursorSet(gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms) { + dri_->SetHardwareCursor(widget, bitmaps, location, frame_delay_ms); +} + +void DriGpuPlatformSupport::OnCursorMove(gfx::AcceleratedWidget widget, + const gfx::Point& location) { + dri_->MoveHardwareCursor(widget, location); +} + +void DriGpuPlatformSupport::OnForceDPMSOn() { + ndd_->ForceDPMSOn(); +} + +void DriGpuPlatformSupport::OnRefreshNativeDisplays( + const std::vector<DisplaySnapshot_Params>& cached_displays) { + std::vector<DisplaySnapshot_Params> displays; + std::vector<DisplaySnapshot*> native_displays = ndd_->GetDisplays(); + + // If any of the cached displays are in the list of new displays then apply + // their configuration immediately. + for (size_t i = 0; i < native_displays.size(); ++i) { + std::vector<DisplaySnapshot_Params>::const_iterator it = + std::find_if(cached_displays.begin(), cached_displays.end(), + FindDisplayById(native_displays[i]->display_id())); + + if (it == cached_displays.end()) + continue; + + if (it->has_current_mode) + OnConfigureNativeDisplay(it->display_id, it->current_mode, it->origin); + else + OnDisableNativeDisplay(it->display_id); + } + + for (size_t i = 0; i < native_displays.size(); ++i) + displays.push_back(GetDisplaySnapshotParams(*native_displays[i])); + + sender_->Send(new OzoneHostMsg_UpdateNativeDisplays(displays)); +} + +void DriGpuPlatformSupport::OnConfigureNativeDisplay( + int64_t id, + const DisplayMode_Params& mode_param, + const gfx::Point& origin) { + DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id); + if (!display) { + LOG(ERROR) << "There is no display with ID " << id; + return; + } + + const DisplayMode* mode = NULL; + for (size_t i = 0; i < display->modes().size(); ++i) { + if (mode_param.size == display->modes()[i]->size() && + mode_param.is_interlaced == display->modes()[i]->is_interlaced() && + mode_param.refresh_rate == display->modes()[i]->refresh_rate()) { + mode = display->modes()[i]; + break; + } + } + + // If the display doesn't have the mode natively, then lookup the mode from + // other displays and try using it on the current display (some displays + // support panel fitting and they can use different modes even if the mode + // isn't explicitly declared). + if (!mode) + mode = ndd_->FindDisplayMode(mode_param.size, mode_param.is_interlaced, + mode_param.refresh_rate); + + if (!mode) { + LOG(ERROR) << "Failed to find mode: size=" << mode_param.size.ToString() + << " is_interlaced=" << mode_param.is_interlaced + << " refresh_rate=" << mode_param.refresh_rate; + return; + } + + ndd_->Configure(*display, mode, origin); +} + +void DriGpuPlatformSupport::OnDisableNativeDisplay(int64_t id) { + DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id); + if (display) + ndd_->Configure(*display, NULL, gfx::Point()); + else + LOG(ERROR) << "There is no display with ID " << id; +} + +void DriGpuPlatformSupport::OnTakeDisplayControl() { + ndd_->TakeDisplayControl(); +} + +void DriGpuPlatformSupport::OnRelinquishDisplayControl() { + ndd_->RelinquishDisplayControl(); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_gpu_platform_support.h b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support.h new file mode 100644 index 00000000000..05ab7678f66 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support.h @@ -0,0 +1,81 @@ +// 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_PLATFORM_DRI_DRI_GPU_PLATFORM_SUPPORT_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_GPU_PLATFORM_SUPPORT_H_ + +#include "base/containers/scoped_ptr_hash_map.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/public/gpu_platform_support.h" + +class SkBitmap; + +namespace gfx { +class Point; +class Rect; +} + +namespace ui { + +class DriSurfaceFactory; +class DriWindowDelegate; +class DriWindowDelegateManager; +class NativeDisplayDelegateDri; +class ScreenManager; + +struct DisplayMode_Params; +struct DisplaySnapshot_Params; + +class DriGpuPlatformSupport : public GpuPlatformSupport { + public: + DriGpuPlatformSupport(DriSurfaceFactory* dri, + DriWindowDelegateManager* window_manager, + ScreenManager* screen_manager, + scoped_ptr<NativeDisplayDelegateDri> ndd); + ~DriGpuPlatformSupport() override; + + void AddHandler(scoped_ptr<GpuPlatformSupport> handler); + + // GpuPlatformSupport: + void OnChannelEstablished(IPC::Sender* sender) override; + + // IPC::Listener: + bool OnMessageReceived(const IPC::Message& message) override; + + private: + void OnCreateWindowDelegate(gfx::AcceleratedWidget widget); + void OnDestroyWindowDelegate(gfx::AcceleratedWidget widget); + void OnWindowBoundsChanged(gfx::AcceleratedWidget widget, + const gfx::Rect& bounds); + void OnCursorSet(gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms); + void OnCursorMove(gfx::AcceleratedWidget widget, const gfx::Point& location); + + // Display related IPC handlers. + void OnForceDPMSOn(); + void OnRefreshNativeDisplays( + const std::vector<DisplaySnapshot_Params>& cached_displays); + void OnConfigureNativeDisplay(int64_t id, + const DisplayMode_Params& mode, + const gfx::Point& origin); + void OnDisableNativeDisplay(int64_t id); + void OnTakeDisplayControl(); + void OnRelinquishDisplayControl(); + + IPC::Sender* sender_; // Not owned. + DriSurfaceFactory* dri_; // Not owned. + DriWindowDelegateManager* window_manager_; // Not owned. + ScreenManager* screen_manager_; // Not owned. + + scoped_ptr<NativeDisplayDelegateDri> ndd_; + ScopedVector<GpuPlatformSupport> handlers_; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_GPU_PLATFORM_SUPPORT_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_gpu_platform_support_host.cc b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support_host.cc new file mode 100644 index 00000000000..aa8189e45f9 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support_host.cc @@ -0,0 +1,114 @@ +// 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/platform/dri/dri_gpu_platform_support_host.h" + +#include "base/debug/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/dri/channel_observer.h" + +namespace ui { + +DriGpuPlatformSupportHost::DriGpuPlatformSupportHost() + : host_id_(-1), sender_(NULL) { +} + +DriGpuPlatformSupportHost::~DriGpuPlatformSupportHost() { +} + +bool DriGpuPlatformSupportHost::IsConnected() const { + return sender_ != NULL; +} + +void DriGpuPlatformSupportHost::RegisterHandler( + GpuPlatformSupportHost* handler) { + handlers_.push_back(handler); +} + +void DriGpuPlatformSupportHost::UnregisterHandler( + GpuPlatformSupportHost* handler) { + std::vector<GpuPlatformSupportHost*>::iterator it = + std::find(handlers_.begin(), handlers_.end(), handler); + if (it != handlers_.end()) + handlers_.erase(it); +} + +void DriGpuPlatformSupportHost::AddChannelObserver(ChannelObserver* observer) { + channel_observers_.AddObserver(observer); + + if (sender_) + observer->OnChannelEstablished(); +} + +void DriGpuPlatformSupportHost::RemoveChannelObserver( + ChannelObserver* observer) { + channel_observers_.RemoveObserver(observer); +} + +void DriGpuPlatformSupportHost::OnChannelEstablished(int host_id, + IPC::Sender* sender) { + TRACE_EVENT1("dri", "DriGpuPlatformSupportHost::OnChannelEstablished", + "host_id", host_id); + host_id_ = host_id; + sender_ = sender; + + while (!queued_messages_.empty()) { + Send(queued_messages_.front()); + queued_messages_.pop(); + } + + for (size_t i = 0; i < handlers_.size(); ++i) + handlers_[i]->OnChannelEstablished(host_id, sender); + + FOR_EACH_OBSERVER(ChannelObserver, channel_observers_, + OnChannelEstablished()); +} + +void DriGpuPlatformSupportHost::OnChannelDestroyed(int host_id) { + TRACE_EVENT1("dri", "DriGpuPlatformSupportHost::OnChannelDestroyed", + "host_id", host_id); + if (host_id_ == host_id) { + host_id_ = -1; + sender_ = NULL; + + FOR_EACH_OBSERVER(ChannelObserver, channel_observers_, + OnChannelDestroyed()); + } + + for (size_t i = 0; i < handlers_.size(); ++i) + handlers_[i]->OnChannelDestroyed(host_id); +} + +bool DriGpuPlatformSupportHost::OnMessageReceived(const IPC::Message& message) { + for (size_t i = 0; i < handlers_.size(); ++i) + if (handlers_[i]->OnMessageReceived(message)) + return true; + + return false; +} + +bool DriGpuPlatformSupportHost::Send(IPC::Message* message) { + if (sender_) + return sender_->Send(message); + + queued_messages_.push(message); + return true; +} + +void DriGpuPlatformSupportHost::SetHardwareCursor( + gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms) { + Send(new OzoneGpuMsg_CursorSet(widget, bitmaps, location, frame_delay_ms)); +} + +void DriGpuPlatformSupportHost::MoveHardwareCursor( + gfx::AcceleratedWidget widget, + const gfx::Point& location) { + Send(new OzoneGpuMsg_CursorMove(widget, location)); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_gpu_platform_support_host.h b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support_host.h new file mode 100644 index 00000000000..1c5adfeb3a7 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_gpu_platform_support_host.h @@ -0,0 +1,72 @@ +// 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_PLATFORM_DRI_DRI_GPU_PLATFORM_SUPPORT_HOST_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_GPU_PLATFORM_SUPPORT_HOST_H_ + +#include <queue> +#include <vector> + +#include "base/observer_list.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/dri/hardware_cursor_delegate.h" +#include "ui/ozone/public/gpu_platform_support_host.h" + +class SkBitmap; + +namespace gfx { +class Point; +} + +namespace ui { + +class ChannelObserver; + +class DriGpuPlatformSupportHost : public GpuPlatformSupportHost, + public HardwareCursorDelegate, + public IPC::Sender { + public: + DriGpuPlatformSupportHost(); + ~DriGpuPlatformSupportHost() override; + + bool IsConnected() const; + + void RegisterHandler(GpuPlatformSupportHost* handler); + void UnregisterHandler(GpuPlatformSupportHost* handler); + + void AddChannelObserver(ChannelObserver* observer); + void RemoveChannelObserver(ChannelObserver* observer); + + // GpuPlatformSupportHost: + void OnChannelEstablished(int host_id, IPC::Sender* sender) override; + void OnChannelDestroyed(int host_id) override; + + // IPC::Listener: + bool OnMessageReceived(const IPC::Message& message) override; + + // IPC::Sender: + bool Send(IPC::Message* message) override; + + // HardwareCursorDelegate: + void SetHardwareCursor(gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms) override; + void MoveHardwareCursor(gfx::AcceleratedWidget widget, + const gfx::Point& location) override; + + private: + int host_id_; + IPC::Sender* sender_; + std::vector<GpuPlatformSupportHost*> handlers_; + // If messages are sent before the channel is created, store the messages and + // delay sending them until the channel is created. These messages are stored + // in |queued_messaged_|. + std::queue<IPC::Message*> queued_messages_; + ObserverList<ChannelObserver> channel_observers_; +}; + +} // namespace ui + +#endif // UI_OZONE_GPU_DRI_GPU_PLATFORM_SUPPORT_HOST_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_surface.cc b/chromium/ui/ozone/platform/dri/dri_surface.cc index d6b4f5996b2..34f2ce2f6e7 100644 --- a/chromium/ui/ozone/platform/dri/dri_surface.cc +++ b/chromium/ui/ozone/platform/dri/dri_surface.cc @@ -4,77 +4,98 @@ #include "ui/ozone/platform/dri/dri_surface.h" -#include <errno.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <xf86drm.h> - #include "base/logging.h" +#include "base/message_loop/message_loop.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkSurface.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/skia_util.h" #include "ui/ozone/platform/dri/dri_buffer.h" +#include "ui/ozone/platform/dri/dri_vsync_provider.h" +#include "ui/ozone/platform/dri/dri_window_delegate_impl.h" #include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/hardware_display_controller.h" namespace ui { -DriSurface::DriSurface( - DriWrapper* dri, const gfx::Size& size) - : dri_(dri), - bitmaps_(), - front_buffer_(0), - size_(size) { +namespace { + +scoped_refptr<DriBuffer> AllocateBuffer(DriWrapper* dri, + const gfx::Size& size) { + scoped_refptr<DriBuffer> buffer(new DriBuffer(dri)); + SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height()); + + bool initialized = buffer->Initialize(info); + DCHECK(initialized) << "Failed to create drm buffer."; + + return buffer; } -DriSurface::~DriSurface() { +} // namespace + +DriSurface::DriSurface(DriWindowDelegate* window_delegate, DriWrapper* dri) + : window_delegate_(window_delegate), + dri_(dri), + buffers_(), + front_buffer_(0) { } -bool DriSurface::Initialize() { - for (size_t i = 0; i < arraysize(bitmaps_); ++i) { - bitmaps_[i].reset(CreateBuffer()); - // TODO(dnicoara) Should select the configuration based on what the - // underlying system supports. - SkImageInfo info = SkImageInfo::Make(size_.width(), - size_.height(), - kPMColor_SkColorType, - kPremul_SkAlphaType); - if (!bitmaps_[i]->Initialize(info)) { - return false; - } - } - - return true; +DriSurface::~DriSurface() { } -uint32_t DriSurface::GetFramebufferId() const { - CHECK(backbuffer()); - return backbuffer()->framebuffer(); +skia::RefPtr<SkCanvas> DriSurface::GetCanvas() { + return skia::SharePtr(surface_->getCanvas()); } -uint32_t DriSurface::GetHandle() const { - CHECK(backbuffer()); - return backbuffer()->handle(); +void DriSurface::ResizeCanvas(const gfx::Size& viewport_size) { + SkImageInfo info = SkImageInfo::MakeN32( + viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType); + surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); + + HardwareDisplayController* controller = window_delegate_->GetController(); + if (!controller) + return; + + // For the display buffers use the mode size since a |viewport_size| smaller + // than the display size will not scanout. + for (size_t i = 0; i < arraysize(buffers_); ++i) + buffers_[i] = AllocateBuffer(dri_, controller->GetModeSize()); } -// This call is made after the hardware just started displaying our back buffer. -// We need to update our pointer reference and synchronize the two buffers. -void DriSurface::SwapBuffers() { - CHECK(frontbuffer()); - CHECK(backbuffer()); +void DriSurface::PresentCanvas(const gfx::Rect& damage) { + DCHECK(base::MessageLoopForUI::IsCurrent()); + DCHECK(buffers_[front_buffer_ ^ 1].get()); + + HardwareDisplayController* controller = window_delegate_->GetController(); + if (!controller) + return; + + controller->QueueOverlayPlane(OverlayPlane(buffers_[front_buffer_ ^ 1])); + + UpdateNativeSurface(damage); + controller->SchedulePageFlip(); + controller->WaitForPageFlipEvent(); // Update our front buffer pointer. front_buffer_ ^= 1; } -gfx::Size DriSurface::Size() const { - return size_; +scoped_ptr<gfx::VSyncProvider> DriSurface::CreateVSyncProvider() { + return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(window_delegate_)); } -SkCanvas* DriSurface::GetDrawableForWidget() { - CHECK(backbuffer()); - return backbuffer()->canvas(); -} +void DriSurface::UpdateNativeSurface(const gfx::Rect& damage) { + SkCanvas* canvas = buffers_[front_buffer_ ^ 1]->GetCanvas(); + + // The DriSurface is double buffered, so the current back buffer is + // missing the previous update. Expand damage region. + SkRect real_damage = RectToSkRect(UnionRects(damage, last_damage_)); -DriBuffer* DriSurface::CreateBuffer() { return new DriBuffer(dri_); } + // Copy damage region. + skia::RefPtr<SkImage> image = skia::AdoptRef(surface_->newImageSnapshot()); + canvas->drawImageRect(image.get(), &real_damage, real_damage, NULL); + + last_damage_ = damage; +} } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_surface.h b/chromium/ui/ozone/platform/dri/dri_surface.h index 2abae45811e..60450ebd689 100644 --- a/chromium/ui/ozone/platform/dri/dri_surface.h +++ b/chromium/ui/ozone/platform/dri/dri_surface.h @@ -5,56 +5,50 @@ #ifndef UI_OZONE_PLATFORM_DRI_DRI_SURFACE_H_ #define UI_OZONE_PLATFORM_DRI_DRI_SURFACE_H_ -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/skia_util.h" -#include "ui/ozone/ozone_export.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/public/surface_ozone_canvas.h" class SkCanvas; +class SkSurface; namespace ui { class DriBuffer; +class DriWindowDelegate; class DriWrapper; +class HardwareDisplayController; -// An implementation of ScanoutSurface which uses dumb buffers (used for -// software rendering). -class OZONE_EXPORT DriSurface : public ScanoutSurface { +class DriSurface : public SurfaceOzoneCanvas { public: - DriSurface(DriWrapper* dri, const gfx::Size& size); - virtual ~DriSurface(); + DriSurface(DriWindowDelegate* window_delegate, DriWrapper* dri); + ~DriSurface() override; - // Get a Skia canvas for a backbuffer. - SkCanvas* GetDrawableForWidget(); - - // ScanoutSurface: - virtual bool Initialize() OVERRIDE; - virtual uint32_t GetFramebufferId() const OVERRIDE; - virtual uint32_t GetHandle() const OVERRIDE; - virtual void SwapBuffers() OVERRIDE; - virtual gfx::Size Size() const OVERRIDE; + // SurfaceOzoneCanvas: + skia::RefPtr<SkCanvas> GetCanvas() override; + void ResizeCanvas(const gfx::Size& viewport_size) override; + void PresentCanvas(const gfx::Rect& damage) override; + scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override; private: - DriBuffer* frontbuffer() const { return bitmaps_[front_buffer_].get(); } - DriBuffer* backbuffer() const { return bitmaps_[front_buffer_ ^ 1].get(); } + void UpdateNativeSurface(const gfx::Rect& damage); - // Used to create the backing buffers. - virtual DriBuffer* CreateBuffer(); + DriWindowDelegate* window_delegate_; // Stores the connection to the graphics card. Pointer not owned by this // class. DriWrapper* dri_; // The actual buffers used for painting. - scoped_ptr<DriBuffer> bitmaps_[2]; + scoped_refptr<DriBuffer> buffers_[2]; // Keeps track of which bitmap is |buffers_| is the frontbuffer. int front_buffer_; - // Surface size. - gfx::Size size_; + skia::RefPtr<SkSurface> surface_; + gfx::Rect last_damage_; DISALLOW_COPY_AND_ASSIGN(DriSurface); }; diff --git a/chromium/ui/ozone/platform/dri/dri_surface_factory.cc b/chromium/ui/ozone/platform/dri/dri_surface_factory.cc index bbfb6e2e8ff..ad35476a5e4 100644 --- a/chromium/ui/ozone/platform/dri/dri_surface_factory.cc +++ b/chromium/ui/ozone/platform/dri/dri_surface_factory.cc @@ -7,14 +7,15 @@ #include <errno.h> #include "base/debug/trace_event.h" -#include "base/message_loop/message_loop.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_surface.h" #include "ui/ozone/platform/dri/dri_util.h" -#include "ui/ozone/platform/dri/dri_vsync_provider.h" +#include "ui/ozone/platform/dri/dri_window_delegate_impl.h" +#include "ui/ozone/platform/dri/dri_window_delegate_manager.h" #include "ui/ozone/platform/dri/dri_wrapper.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/screen_manager.h" @@ -24,15 +25,20 @@ namespace ui { namespace { -// TODO(dnicoara) Read the cursor plane size from the hardware. -const gfx::Size kCursorSize(64, 64); +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 0x8 +#endif -void UpdateCursorImage(DriSurface* cursor, const SkBitmap& image) { +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + +void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) { SkRect damage; image.getBounds(&damage); // Clear to transparent in case |image| is smaller than the canvas. - SkCanvas* canvas = cursor->GetDrawableForWidget(); + SkCanvas* canvas = cursor->GetCanvas(); canvas->clear(SK_ColorTRANSPARENT); SkRect clip; @@ -42,85 +48,22 @@ void UpdateCursorImage(DriSurface* cursor, const SkBitmap& image) { canvas->drawBitmapRectToRect(image, &damage, damage); } -class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas { - public: - DriSurfaceAdapter(const base::WeakPtr<HardwareDisplayController>& controller); - virtual ~DriSurfaceAdapter(); - - // SurfaceOzoneCanvas: - virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE; - virtual void ResizeCanvas(const gfx::Size& viewport_size) OVERRIDE; - virtual void PresentCanvas(const gfx::Rect& damage) OVERRIDE; - virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE; - - private: - void UpdateNativeSurface(const gfx::Rect& damage); - - skia::RefPtr<SkSurface> surface_; - gfx::Rect last_damage_; - base::WeakPtr<HardwareDisplayController> controller_; - - DISALLOW_COPY_AND_ASSIGN(DriSurfaceAdapter); -}; - -DriSurfaceAdapter::DriSurfaceAdapter( - const base::WeakPtr<HardwareDisplayController>& controller) - : controller_(controller) { -} - -DriSurfaceAdapter::~DriSurfaceAdapter() { -} - -skia::RefPtr<SkCanvas> DriSurfaceAdapter::GetCanvas() { - return skia::SharePtr(surface_->getCanvas()); -} - -void DriSurfaceAdapter::ResizeCanvas(const gfx::Size& viewport_size) { - SkImageInfo info = SkImageInfo::MakeN32( - viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType); - surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); -} - -void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) { - CHECK(base::MessageLoopForUI::IsCurrent()); - if (!controller_) - return; - - UpdateNativeSurface(damage); - controller_->SchedulePageFlip(); - controller_->WaitForPageFlipEvent(); -} - -scoped_ptr<gfx::VSyncProvider> DriSurfaceAdapter::CreateVSyncProvider() { - return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(controller_)); -} - -void DriSurfaceAdapter::UpdateNativeSurface(const gfx::Rect& damage) { - SkCanvas* canvas = static_cast<DriSurface*>(controller_->surface()) - ->GetDrawableForWidget(); - - // The DriSurface is double buffered, so the current back buffer is - // missing the previous update. Expand damage region. - SkRect real_damage = RectToSkRect(UnionRects(damage, last_damage_)); - - // Copy damage region. - skia::RefPtr<SkImage> image = skia::AdoptRef(surface_->newImageSnapshot()); - image->draw(canvas, &real_damage, real_damage, NULL); - - last_damage_ = damage; -} - } // namespace // static const gfx::AcceleratedWidget DriSurfaceFactory::kDefaultWidgetHandle = 1; DriSurfaceFactory::DriSurfaceFactory(DriWrapper* drm, - ScreenManager* screen_manager) + ScreenManager* screen_manager, + DriWindowDelegateManager* window_manager) : drm_(drm), screen_manager_(screen_manager), + window_manager_(window_manager), state_(UNINITIALIZED), - allocated_widgets_(0) { + cursor_frontbuffer_(0), + cursor_widget_(0), + cursor_frame_(0), + cursor_frame_delay_ms_(0) { } DriSurfaceFactory::~DriSurfaceFactory() { @@ -128,7 +71,7 @@ DriSurfaceFactory::~DriSurfaceFactory() { ShutdownHardware(); } -ui::SurfaceFactoryOzone::HardwareState DriSurfaceFactory::InitializeHardware() { +DriSurfaceFactory::HardwareState DriSurfaceFactory::InitializeHardware() { if (state_ != UNINITIALIZED) return state_; @@ -138,11 +81,19 @@ ui::SurfaceFactoryOzone::HardwareState DriSurfaceFactory::InitializeHardware() { return state_; } - cursor_surface_.reset(CreateSurface(kCursorSize)); - if (!cursor_surface_->Initialize()) { - LOG(ERROR) << "Failed to initialize cursor surface"; - state_ = FAILED; - return state_; + uint64_t cursor_width = 64; + uint64_t cursor_height = 64; + drm_->GetCapability(DRM_CAP_CURSOR_WIDTH, &cursor_width); + drm_->GetCapability(DRM_CAP_CURSOR_HEIGHT, &cursor_height); + + SkImageInfo info = SkImageInfo::MakeN32Premul(cursor_width, cursor_height); + for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) { + cursor_buffers_[i] = new DriBuffer(drm_); + if (!cursor_buffers_[i]->Initialize(info)) { + LOG(ERROR) << "Failed to initialize cursor buffer"; + state_ = FAILED; + return state_; + } } state_ = INITIALIZED; @@ -150,26 +101,16 @@ ui::SurfaceFactoryOzone::HardwareState DriSurfaceFactory::InitializeHardware() { } void DriSurfaceFactory::ShutdownHardware() { - CHECK(state_ == INITIALIZED); + DCHECK(state_ == INITIALIZED); state_ = UNINITIALIZED; } -gfx::AcceleratedWidget DriSurfaceFactory::GetAcceleratedWidget() { - CHECK(state_ != FAILED); - - // We're not using 0 since other code assumes that a 0 AcceleratedWidget is an - // invalid widget. - return ++allocated_widgets_; -} - scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget( - gfx::AcceleratedWidget w) { - CHECK(state_ == INITIALIZED); - // Initial cursor set. - ResetCursor(w); + gfx::AcceleratedWidget widget) { + DCHECK(state_ == INITIALIZED); return scoped_ptr<ui::SurfaceOzoneCanvas>( - new DriSurfaceAdapter(screen_manager_->GetDisplayController(w))); + new DriSurface(window_manager_->GetWindowDelegate(widget), drm_)); } bool DriSurfaceFactory::LoadEGLGLES2Bindings( @@ -178,69 +119,60 @@ bool DriSurfaceFactory::LoadEGLGLES2Bindings( return false; } -gfx::Size DriSurfaceFactory::GetWidgetSize(gfx::AcceleratedWidget w) { - base::WeakPtr<HardwareDisplayController> controller = - screen_manager_->GetDisplayController(w); - if (controller) - return gfx::Size(controller->get_mode().hdisplay, - controller->get_mode().vdisplay); - - return gfx::Size(0, 0); -} - -void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget window, - const SkBitmap& image, - const gfx::Point& location) { - cursor_bitmap_ = image; +void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms) { + cursor_widget_ = widget; + cursor_bitmaps_ = bitmaps; cursor_location_ = location; + cursor_frame_ = 0; + cursor_frame_delay_ms_ = frame_delay_ms; + cursor_timer_.Stop(); + + if (cursor_frame_delay_ms_) + cursor_timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(cursor_frame_delay_ms_), + this, &DriSurfaceFactory::OnCursorAnimationTimeout); if (state_ != INITIALIZED) return; - ResetCursor(window); + ResetCursor(); } -void DriSurfaceFactory::MoveHardwareCursor(gfx::AcceleratedWidget window, +void DriSurfaceFactory::MoveHardwareCursor(gfx::AcceleratedWidget widget, const gfx::Point& location) { cursor_location_ = location; if (state_ != INITIALIZED) return; - base::WeakPtr<HardwareDisplayController> controller = - screen_manager_->GetDisplayController(window); + HardwareDisplayController* controller = + window_manager_->GetWindowDelegate(widget)->GetController(); if (controller) controller->MoveCursor(location); } -void DriSurfaceFactory::UnsetHardwareCursor(gfx::AcceleratedWidget window) { - cursor_bitmap_.reset(); - - if (state_ != INITIALIZED) - return; - - ResetCursor(window); -} - //////////////////////////////////////////////////////////////////////////////// // DriSurfaceFactory private -DriSurface* DriSurfaceFactory::CreateSurface(const gfx::Size& size) { - return new DriSurface(drm_, size); -} - -void DriSurfaceFactory::ResetCursor(gfx::AcceleratedWidget w) { - base::WeakPtr<HardwareDisplayController> controller = - screen_manager_->GetDisplayController(w); +void DriSurfaceFactory::ResetCursor() { + if (!cursor_widget_) + return; - if (!cursor_bitmap_.empty()) { + HardwareDisplayController* controller = + window_manager_->GetWindowDelegate(cursor_widget_)->GetController(); + if (cursor_bitmaps_.size()) { // Draw new cursor into backbuffer. - UpdateCursorImage(cursor_surface_.get(), cursor_bitmap_); + UpdateCursorImage(cursor_buffers_[cursor_frontbuffer_ ^ 1].get(), + cursor_bitmaps_[cursor_frame_]); // Reset location & buffer. if (controller) { controller->MoveCursor(cursor_location_); - controller->SetCursor(cursor_surface_.get()); + controller->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]); + cursor_frontbuffer_ ^= 1; } } else { // No cursor set. @@ -249,4 +181,11 @@ void DriSurfaceFactory::ResetCursor(gfx::AcceleratedWidget w) { } } +void DriSurfaceFactory::OnCursorAnimationTimeout() { + cursor_frame_++; + cursor_frame_ %= cursor_bitmaps_.size(); + + ResetCursor(); +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_surface_factory.h b/chromium/ui/ozone/platform/dri/dri_surface_factory.h index 69ec5df243d..2b3eb4fd423 100644 --- a/chromium/ui/ozone/platform/dri/dri_surface_factory.h +++ b/chromium/ui/ozone/platform/dri/dri_surface_factory.h @@ -6,76 +6,84 @@ #define UI_OZONE_PLATFORM_DRI_DRI_SURFACE_FACTORY_H_ #include <map> +#include <vector> #include "base/memory/scoped_ptr.h" +#include "base/timer/timer.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "ui/ozone/ozone_export.h" +#include "ui/ozone/platform/dri/hardware_cursor_delegate.h" #include "ui/ozone/public/surface_factory_ozone.h" -typedef struct _drmModeModeInfo drmModeModeInfo; - -namespace gfx { -class SurfaceOzoneCanvas; -} - namespace ui { -class DriSurface; +class DriBuffer; +class DriWindowDelegateManager; class DriWrapper; -class HardwareDisplayController; class ScreenManager; +class SurfaceOzoneCanvas; // SurfaceFactoryOzone implementation on top of DRM/KMS using dumb buffers. // This implementation is used in conjunction with the software rendering // path. -class OZONE_EXPORT DriSurfaceFactory : public ui::SurfaceFactoryOzone { +class DriSurfaceFactory : public SurfaceFactoryOzone, + public HardwareCursorDelegate { public: static const gfx::AcceleratedWidget kDefaultWidgetHandle; - DriSurfaceFactory(DriWrapper* drm, ScreenManager* screen_manager); - virtual ~DriSurfaceFactory(); + DriSurfaceFactory(DriWrapper* drm, + ScreenManager* screen_manager, + DriWindowDelegateManager* window_manager); + ~DriSurfaceFactory() override; - // SurfaceFactoryOzone overrides: - virtual HardwareState InitializeHardware() OVERRIDE; - virtual void ShutdownHardware() OVERRIDE; + // Describes the state of the hardware after initialization. + enum HardwareState { + UNINITIALIZED, + INITIALIZED, + FAILED, + }; - virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; + // Open the display device. + HardwareState InitializeHardware(); - virtual scoped_ptr<ui::SurfaceOzoneCanvas> CreateCanvasForWidget( - gfx::AcceleratedWidget w) OVERRIDE; + // Close the display device. + void ShutdownHardware(); - virtual bool LoadEGLGLES2Bindings( + // SurfaceFactoryOzone: + scoped_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget( + gfx::AcceleratedWidget widget) override; + bool LoadEGLGLES2Bindings( AddGLLibraryCallback add_gl_library, - SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE; - - gfx::Size GetWidgetSize(gfx::AcceleratedWidget w); - - void SetHardwareCursor(gfx::AcceleratedWidget window, - const SkBitmap& image, - const gfx::Point& location); + SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; + // HardwareCursorDelegate: + void SetHardwareCursor(gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms) override; void MoveHardwareCursor(gfx::AcceleratedWidget window, - const gfx::Point& location); - - void UnsetHardwareCursor(gfx::AcceleratedWidget window); + const gfx::Point& location) override; protected: // Draw the last set cursor & update the cursor plane. - void ResetCursor(gfx::AcceleratedWidget w); + void ResetCursor(); - virtual DriSurface* CreateSurface(const gfx::Size& size); + // Draw next frame in an animated cursor. + void OnCursorAnimationTimeout(); DriWrapper* drm_; // Not owned. ScreenManager* screen_manager_; // Not owned. + DriWindowDelegateManager* window_manager_; // Not owned. HardwareState state_; - // Active outputs. - int allocated_widgets_; - - scoped_ptr<DriSurface> cursor_surface_; + scoped_refptr<DriBuffer> cursor_buffers_[2]; + int cursor_frontbuffer_; - SkBitmap cursor_bitmap_; + gfx::AcceleratedWidget cursor_widget_; + std::vector<SkBitmap> cursor_bitmaps_; gfx::Point cursor_location_; + int cursor_frame_; + int cursor_frame_delay_ms_; + base::RepeatingTimer<DriSurfaceFactory> cursor_timer_; DISALLOW_COPY_AND_ASSIGN(DriSurfaceFactory); }; diff --git a/chromium/ui/ozone/platform/dri/dri_surface_factory_unittest.cc b/chromium/ui/ozone/platform/dri/dri_surface_factory_unittest.cc index 13d81cbc84e..a1e22a17edf 100644 --- a/chromium/ui/ozone/platform/dri/dri_surface_factory_unittest.cc +++ b/chromium/ui/ozone/platform/dri/dri_surface_factory_unittest.cc @@ -13,63 +13,40 @@ #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_surface.h" #include "ui/ozone/platform/dri/dri_surface_factory.h" +#include "ui/ozone/platform/dri/dri_window_delegate_impl.h" +#include "ui/ozone/platform/dri/dri_window_delegate_manager.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/screen_manager.h" -#include "ui/ozone/platform/dri/test/mock_dri_surface.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" -#include "ui/ozone/platform/dri/test/mock_surface_generator.h" #include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_ozone_canvas.h" namespace { +// Mode of size 6x4. const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; -// SSFO would normally allocate DRM resources. We can't rely on having a DRM -// backend to allocate and display our buffers. Thus, we replace these -// resources with stubs. For DRM calls, we simply use stubs that do nothing and -// for buffers we use the default SkBitmap allocator. -class MockDriSurfaceFactory : public ui::DriSurfaceFactory { - public: - MockDriSurfaceFactory(ui::DriWrapper* dri, ui::ScreenManager* screen_manager) - : DriSurfaceFactory(dri, screen_manager), dri_(dri) {} - virtual ~MockDriSurfaceFactory() {}; - - const std::vector<ui::MockDriSurface*>& get_surfaces() const { - return surfaces_; - } - - private: - virtual ui::DriSurface* CreateSurface(const gfx::Size& size) OVERRIDE { - ui::MockDriSurface* surface = new ui::MockDriSurface(dri_, size); - surfaces_.push_back(surface); - return surface; - } - - ui::DriWrapper* dri_; - std::vector<ui::MockDriSurface*> surfaces_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(MockDriSurfaceFactory); -}; +const uint32_t kDefaultCrtc = 1; +const uint32_t kDefaultConnector = 2; class MockScreenManager : public ui::ScreenManager { public: MockScreenManager(ui::DriWrapper* dri, - ui::ScanoutSurfaceGenerator* surface_generator) - : ScreenManager(dri, surface_generator), + ui::ScanoutBufferGenerator* buffer_generator) + : ScreenManager(dri, buffer_generator), dri_(dri) {} - virtual ~MockScreenManager() {} + ~MockScreenManager() override {} // Normally we'd use DRM to figure out the controller configuration. But we // can't use DRM in unit tests, so we just create a fake configuration. - virtual void ForceInitializationOfPrimaryDisplay() OVERRIDE { - ConfigureDisplayController(1, 2, kDefaultMode); + void ForceInitializationOfPrimaryDisplay() override { + ConfigureDisplayController( + kDefaultCrtc, kDefaultConnector, gfx::Point(), kDefaultMode); } private: ui::DriWrapper* dri_; // Not owned. - std::vector<ui::MockDriSurface*> surfaces_; // Not owned. DISALLOW_COPY_AND_ASSIGN(MockScreenManager); }; @@ -80,14 +57,16 @@ class DriSurfaceFactoryTest : public testing::Test { public: DriSurfaceFactoryTest() {} - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; + void SetUp() override; + void TearDown() override; + protected: scoped_ptr<base::MessageLoop> message_loop_; scoped_ptr<ui::MockDriWrapper> dri_; - scoped_ptr<ui::MockSurfaceGenerator> surface_generator_; + scoped_ptr<ui::DriBufferGenerator> buffer_generator_; scoped_ptr<MockScreenManager> screen_manager_; - scoped_ptr<MockDriSurfaceFactory> factory_; + scoped_ptr<ui::DriSurfaceFactory> factory_; + scoped_ptr<ui::DriWindowDelegateManager> window_delegate_manager_; private: DISALLOW_COPY_AND_ASSIGN(DriSurfaceFactoryTest); @@ -96,78 +75,54 @@ class DriSurfaceFactoryTest : public testing::Test { void DriSurfaceFactoryTest::SetUp() { message_loop_.reset(new base::MessageLoopForUI); dri_.reset(new ui::MockDriWrapper(3)); - surface_generator_.reset(new ui::MockSurfaceGenerator(dri_.get())); + buffer_generator_.reset(new ui::DriBufferGenerator(dri_.get())); screen_manager_.reset(new MockScreenManager(dri_.get(), - surface_generator_.get())); - factory_.reset(new MockDriSurfaceFactory(dri_.get(), screen_manager_.get())); + buffer_generator_.get())); + window_delegate_manager_.reset(new ui::DriWindowDelegateManager()); + factory_.reset(new ui::DriSurfaceFactory(dri_.get(), screen_manager_.get(), + window_delegate_manager_.get())); + + scoped_ptr<ui::DriWindowDelegate> window_delegate( + new ui::DriWindowDelegateImpl(ui::DriSurfaceFactory::kDefaultWidgetHandle, + screen_manager_.get())); + window_delegate->Initialize(); + window_delegate_manager_->AddWindowDelegate( + ui::DriSurfaceFactory::kDefaultWidgetHandle, window_delegate.Pass()); } void DriSurfaceFactoryTest::TearDown() { + scoped_ptr<ui::DriWindowDelegate> delegate = + window_delegate_manager_->RemoveWindowDelegate( + ui::DriSurfaceFactory::kDefaultWidgetHandle); + delegate->Shutdown(); factory_.reset(); message_loop_.reset(); } TEST_F(DriSurfaceFactoryTest, FailInitialization) { dri_->fail_init(); - EXPECT_EQ(ui::SurfaceFactoryOzone::FAILED, factory_->InitializeHardware()); + EXPECT_EQ(ui::DriSurfaceFactory::FAILED, factory_->InitializeHardware()); } TEST_F(DriSurfaceFactoryTest, SuccessfulInitialization) { - EXPECT_EQ(ui::SurfaceFactoryOzone::INITIALIZED, + EXPECT_EQ(ui::DriSurfaceFactory::INITIALIZED, factory_->InitializeHardware()); } TEST_F(DriSurfaceFactoryTest, SuccessfulWidgetRealization) { - EXPECT_EQ(ui::SurfaceFactoryOzone::INITIALIZED, + EXPECT_EQ(ui::DriSurfaceFactory::INITIALIZED, factory_->InitializeHardware()); - gfx::AcceleratedWidget w = factory_->GetAcceleratedWidget(); - EXPECT_EQ(ui::DriSurfaceFactory::kDefaultWidgetHandle, w); - - EXPECT_TRUE(factory_->CreateCanvasForWidget(w)); -} - -TEST_F(DriSurfaceFactoryTest, CheckNativeSurfaceContents) { - EXPECT_EQ(ui::SurfaceFactoryOzone::INITIALIZED, - factory_->InitializeHardware()); - - gfx::AcceleratedWidget w = factory_->GetAcceleratedWidget(); - EXPECT_EQ(ui::DriSurfaceFactory::kDefaultWidgetHandle, w); - - scoped_ptr<ui::SurfaceOzoneCanvas> surface = - factory_->CreateCanvasForWidget(w); - - surface->ResizeCanvas( - gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay)); - surface->GetCanvas()->drawColor(SK_ColorWHITE); - surface->PresentCanvas( - gfx::Rect(0, 0, kDefaultMode.hdisplay / 2, kDefaultMode.vdisplay / 2)); - - const std::vector<ui::DriBuffer*>& bitmaps = - surface_generator_->surfaces()[0]->bitmaps(); - - SkBitmap image; - bitmaps[1]->canvas()->readPixels(&image, 0, 0); - - // Make sure the updates are correctly propagated to the native surface. - for (int i = 0; i < image.height(); ++i) { - for (int j = 0; j < image.width(); ++j) { - if (j < kDefaultMode.hdisplay / 2 && i < kDefaultMode.vdisplay / 2) - EXPECT_EQ(SK_ColorWHITE, image.getColor(j, i)); - else - EXPECT_EQ(SK_ColorBLACK, image.getColor(j, i)); - } - } + EXPECT_TRUE(factory_->CreateCanvasForWidget( + ui::DriSurfaceFactory::kDefaultWidgetHandle)); } TEST_F(DriSurfaceFactoryTest, SetCursorImage) { - EXPECT_EQ(ui::SurfaceFactoryOzone::INITIALIZED, + EXPECT_EQ(ui::DriSurfaceFactory::INITIALIZED, factory_->InitializeHardware()); - gfx::AcceleratedWidget w = factory_->GetAcceleratedWidget(); - EXPECT_EQ(ui::DriSurfaceFactory::kDefaultWidgetHandle, w); - - scoped_ptr<ui::SurfaceOzoneCanvas> surf = factory_->CreateCanvasForWidget(w); + scoped_ptr<ui::SurfaceOzoneCanvas> surf = factory_->CreateCanvasForWidget( + ui::DriSurfaceFactory::kDefaultWidgetHandle); EXPECT_TRUE(surf); SkBitmap image; @@ -176,18 +131,15 @@ TEST_F(DriSurfaceFactoryTest, SetCursorImage) { image.allocPixels(info); image.eraseColor(SK_ColorWHITE); - factory_->SetHardwareCursor(w, image, gfx::Point(4, 2)); - const std::vector<ui::MockDriSurface*>& surfaces = factory_->get_surfaces(); - - // The first surface is the cursor surface since it is allocated early in the - // initialization process. - const std::vector<ui::DriBuffer*>& bitmaps = surfaces[0]->bitmaps(); - - // The surface should have been initialized to a double-buffered surface. - EXPECT_EQ(2u, bitmaps.size()); + std::vector<SkBitmap> cursor_bitmaps; + cursor_bitmaps.push_back(image); + factory_->SetHardwareCursor(ui::DriSurfaceFactory::kDefaultWidgetHandle, + cursor_bitmaps, gfx::Point(4, 2), 0); SkBitmap cursor; - bitmaps[1]->canvas()->readPixels(&cursor, 0, 0); + // Buffers 0 and 1 are the cursor buffers. + cursor.setInfo(dri_->buffers()[1]->getCanvas()->imageInfo()); + EXPECT_TRUE(dri_->buffers()[1]->getCanvas()->readPixels(&cursor, 0, 0)); // Check that the frontbuffer is displaying the right image as set above. for (int i = 0; i < cursor.height(); ++i) { diff --git a/chromium/ui/ozone/platform/dri/dri_surface_unittest.cc b/chromium/ui/ozone/platform/dri/dri_surface_unittest.cc index 397e54f0b95..0e5c00ee035 100644 --- a/chromium/ui/ozone/platform/dri/dri_surface_unittest.cc +++ b/chromium/ui/ozone/platform/dri/dri_surface_unittest.cc @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/message_loop/message_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkDevice.h" +#include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_surface.h" +#include "ui/ozone/platform/dri/dri_window_delegate.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" -#include "ui/ozone/platform/dri/test/mock_dri_surface.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" namespace { @@ -18,101 +20,107 @@ namespace { const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; +const uint32_t kDefaultCrtc = 1; +const uint32_t kDefaultConnector = 2; + +class MockDriWindowDelegate : public ui::DriWindowDelegate { + public: + MockDriWindowDelegate(ui::DriWrapper* drm) { + controller_.reset(new ui::HardwareDisplayController(make_scoped_ptr( + new ui::CrtcController(drm, kDefaultCrtc, kDefaultConnector)))); + scoped_refptr<ui::DriBuffer> buffer(new ui::DriBuffer(drm)); + SkImageInfo info = SkImageInfo::MakeN32Premul(kDefaultMode.hdisplay, + kDefaultMode.vdisplay); + EXPECT_TRUE(buffer->Initialize(info)); + EXPECT_TRUE(controller_->Modeset(ui::OverlayPlane(buffer), kDefaultMode)); + } + ~MockDriWindowDelegate() override {} + + // DriWindowDelegate: + void Initialize() override {} + void Shutdown() override {} + gfx::AcceleratedWidget GetAcceleratedWidget() override { return 1; } + ui::HardwareDisplayController* GetController() override { + return controller_.get(); + } + void OnBoundsChanged(const gfx::Rect& bounds) override {} + + private: + scoped_ptr<ui::HardwareDisplayController> controller_; + + DISALLOW_COPY_AND_ASSIGN(MockDriWindowDelegate); +}; + } // namespace class DriSurfaceTest : public testing::Test { public: DriSurfaceTest() {} - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; + void SetUp() override; + void TearDown() override; protected: + scoped_ptr<base::MessageLoop> message_loop_; scoped_ptr<ui::MockDriWrapper> drm_; - scoped_ptr<ui::HardwareDisplayController> controller_; - scoped_ptr<ui::MockDriSurface> surface_; + scoped_ptr<MockDriWindowDelegate> window_delegate_; + scoped_ptr<ui::DriSurface> surface_; private: DISALLOW_COPY_AND_ASSIGN(DriSurfaceTest); }; void DriSurfaceTest::SetUp() { + message_loop_.reset(new base::MessageLoopForUI); drm_.reset(new ui::MockDriWrapper(3)); - controller_.reset(new ui::HardwareDisplayController(drm_.get(), 1, 1)); - - surface_.reset(new ui::MockDriSurface( - drm_.get(), gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay))); + window_delegate_.reset(new MockDriWindowDelegate(drm_.get())); + surface_.reset(new ui::DriSurface(window_delegate_.get(), drm_.get())); + surface_->ResizeCanvas(gfx::Size(kDefaultMode.hdisplay, + kDefaultMode.vdisplay)); } void DriSurfaceTest::TearDown() { surface_.reset(); - controller_.reset(); + window_delegate_.reset(); drm_.reset(); -} - -TEST_F(DriSurfaceTest, FailInitialization) { - surface_->set_initialize_expectation(false); - EXPECT_FALSE(surface_->Initialize()); -} - -TEST_F(DriSurfaceTest, SuccessfulInitialization) { - EXPECT_TRUE(surface_->Initialize()); + message_loop_.reset(); } TEST_F(DriSurfaceTest, CheckFBIDOnSwap) { - EXPECT_TRUE(surface_->Initialize()); - controller_->BindSurfaceToController(surface_.PassAs<ui::ScanoutSurface>(), - kDefaultMode); - - // Check that the framebuffer ID is correct. - EXPECT_EQ(2u, controller_->surface()->GetFramebufferId()); - - controller_->surface()->SwapBuffers(); - - EXPECT_EQ(1u, controller_->surface()->GetFramebufferId()); -} - -TEST_F(DriSurfaceTest, CheckPixelPointerOnSwap) { - EXPECT_TRUE(surface_->Initialize()); - - void* bitmap_pixels1 = surface_->GetDrawableForWidget()->getDevice() - ->accessBitmap(false).getPixels(); - - surface_->SwapBuffers(); - - void* bitmap_pixels2 = surface_->GetDrawableForWidget()->getDevice() - ->accessBitmap(false).getPixels(); - - // Check that once the buffers have been swapped the drawable's underlying - // pixels have been changed. - EXPECT_NE(bitmap_pixels1, bitmap_pixels2); + surface_->PresentCanvas(gfx::Rect()); + // Framebuffer ID 1 is allocated in SetUp for the buffer used to modeset. + EXPECT_EQ(3u, drm_->current_framebuffer()); + surface_->PresentCanvas(gfx::Rect()); + EXPECT_EQ(2u, drm_->current_framebuffer()); } -TEST_F(DriSurfaceTest, CheckCorrectBufferSync) { - EXPECT_TRUE(surface_->Initialize()); - - SkCanvas* canvas = surface_->GetDrawableForWidget(); - SkRect clip; - // Modify part of the canvas. - clip.set(0, 0, - canvas->getDeviceSize().width() / 2, - canvas->getDeviceSize().height() / 2); - canvas->clipRect(clip, SkRegion::kReplace_Op); - - canvas->drawColor(SK_ColorWHITE); - - surface_->SwapBuffers(); - - // Verify that the modified contents have been copied over on swap (make sure - // the 2 buffers have the same content). - for (int i = 0; i < canvas->getDeviceSize().height(); ++i) { - for (int j = 0; j < canvas->getDeviceSize().width(); ++j) { - if (i < clip.height() && j < clip.width()) - EXPECT_EQ(SK_ColorWHITE, - canvas->getDevice()->accessBitmap(false).getColor(j, i)); +TEST_F(DriSurfaceTest, CheckSurfaceContents) { + SkPaint paint; + paint.setColor(SK_ColorWHITE); + SkRect rect = SkRect::MakeWH(kDefaultMode.hdisplay / 2, + kDefaultMode.vdisplay / 2); + surface_->GetCanvas()->drawRect(rect, paint); + surface_->PresentCanvas( + gfx::Rect(0, 0, kDefaultMode.hdisplay / 2, kDefaultMode.vdisplay / 2)); + + SkBitmap image; + // Buffer 0 is the buffer used in SetUp for modesetting and buffer 1 is the + // frontbuffer. + // Buffer 2 is the backbuffer we just painted in, so we want to make sure its + // contents are correct. + image.setInfo(drm_->buffers()[2]->getCanvas()->imageInfo()); + EXPECT_TRUE(drm_->buffers()[2]->getCanvas()->readPixels(&image, 0, 0)); + + EXPECT_EQ(kDefaultMode.hdisplay, image.width()); + EXPECT_EQ(kDefaultMode.vdisplay, image.height()); + + // Make sure the updates are correctly propagated to the native surface. + for (int i = 0; i < image.height(); ++i) { + for (int j = 0; j < image.width(); ++j) { + if (j < kDefaultMode.hdisplay / 2 && i < kDefaultMode.vdisplay / 2) + EXPECT_EQ(SK_ColorWHITE, image.getColor(j, i)); else - EXPECT_EQ(SK_ColorBLACK, - canvas->getDevice()->accessBitmap(false).getColor(j, i)); + EXPECT_EQ(SK_ColorBLACK, image.getColor(j, i)); } } } diff --git a/chromium/ui/ozone/platform/dri/dri_util.cc b/chromium/ui/ozone/platform/dri/dri_util.cc index b3eab02b41a..5305f6d0b48 100644 --- a/chromium/ui/ozone/platform/dri/dri_util.cc +++ b/chromium/ui/ozone/platform/dri/dri_util.cc @@ -4,8 +4,11 @@ #include "ui/ozone/platform/dri/dri_util.h" +#include <errno.h> #include <stdint.h> #include <stdlib.h> +#include <sys/mman.h> +#include <xf86drm.h> #include <xf86drmMode.h> namespace ui { @@ -28,35 +31,25 @@ uint32_t GetCrtc(int fd, const ScopedVector<HardwareDisplayControllerInfo>& displays) { // If the connector already has an encoder try to re-use. if (connector->encoder_id) { - drmModeEncoder* encoder = drmModeGetEncoder(fd, connector->encoder_id); - if (encoder) { - if (encoder->crtc_id && !IsCrtcInUse(encoder->crtc_id, displays)) { - uint32_t crtc = encoder->crtc_id; - drmModeFreeEncoder(encoder); - return crtc; - } - drmModeFreeEncoder(encoder); - } + ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoder_id)); + if (encoder && encoder->crtc_id && !IsCrtcInUse(encoder->crtc_id, displays)) + return encoder->crtc_id; } // Try to find an encoder for the connector. for (int i = 0; i < connector->count_encoders; ++i) { - drmModeEncoder* encoder = drmModeGetEncoder(fd, connector->encoders[i]); + ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoders[i])); if (!encoder) continue; for (int j = 0; j < resources->count_crtcs; ++j) { // Check if the encoder is compatible with this CRTC if (!(encoder->possible_crtcs & (1 << j)) || - IsCrtcInUse(resources->crtcs[j], displays)) { + IsCrtcInUse(resources->crtcs[j], displays)) continue; - } - drmModeFreeEncoder(encoder); return resources->crtcs[j]; } - - drmModeFreeEncoder(encoder); } return 0; @@ -65,41 +58,34 @@ uint32_t GetCrtc(int fd, } // namespace HardwareDisplayControllerInfo::HardwareDisplayControllerInfo( - drmModeConnector* connector, - drmModeCrtc* crtc) - : connector_(connector), - crtc_(crtc) {} - -HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() { - drmModeFreeConnector(connector_); - drmModeFreeCrtc(crtc_); -} + ScopedDrmConnectorPtr connector, + ScopedDrmCrtcPtr crtc) + : connector_(connector.Pass()), + crtc_(crtc.Pass()) {} + +HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() {} ScopedVector<HardwareDisplayControllerInfo> -GetAvailableDisplayControllerInfos(int fd, drmModeRes* resources) { +GetAvailableDisplayControllerInfos(int fd) { + ScopedDrmResourcesPtr resources(drmModeGetResources(fd)); + DCHECK(resources) << "Failed to get DRM resources"; ScopedVector<HardwareDisplayControllerInfo> displays; for (int i = 0; i < resources->count_connectors; ++i) { - drmModeConnector* connector = drmModeGetConnector( - fd, resources->connectors[i]); + ScopedDrmConnectorPtr connector(drmModeGetConnector( + fd, resources->connectors[i])); - if (!connector) + if (!connector || connector->connection != DRM_MODE_CONNECTED || + connector->count_modes == 0) continue; - if (connector->connection != DRM_MODE_CONNECTED || - connector->count_modes == 0) { - drmModeFreeConnector(connector); - continue; - } - - uint32_t crtc_id = GetCrtc(fd, connector, resources, displays); - if (!crtc_id) { - drmModeFreeConnector(connector); + uint32_t crtc_id = GetCrtc(fd, connector.get(), resources.get(), displays); + if (!crtc_id) continue; - } - drmModeCrtc* crtc = drmModeGetCrtc(fd, crtc_id); - displays.push_back(new HardwareDisplayControllerInfo(connector, crtc)); + ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, crtc_id)); + displays.push_back(new HardwareDisplayControllerInfo(connector.Pass(), + crtc.Pass())); } return displays.Pass(); @@ -122,4 +108,31 @@ bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) { strcmp(lhs.name, rhs.name) == 0; } +bool MapDumbBuffer(int fd, + uint32_t handle, + uint32_t size, + void** pixels) { + struct drm_mode_map_dumb map_request; + memset(&map_request, 0, sizeof(map_request)); + map_request.handle = handle; + if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_request)) { + VLOG(2) << "Cannot prepare dumb buffer for mapping (" << errno << ") " + << strerror(errno); + return false; + } + + *pixels = mmap(0, + size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, + map_request.offset); + if (*pixels == MAP_FAILED) { + VLOG(2) << "Cannot mmap dumb buffer (" << errno << ") " << strerror(errno); + return false; + } + + return true; +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_util.h b/chromium/ui/ozone/platform/dri/dri_util.h index 174d2aae657..94f2b452bf6 100644 --- a/chromium/ui/ozone/platform/dri/dri_util.h +++ b/chromium/ui/ozone/platform/dri/dri_util.h @@ -7,11 +7,9 @@ #include "base/macros.h" #include "base/memory/scoped_vector.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" -typedef struct _drmModeConnector drmModeConnector; -typedef struct _drmModeCrtc drmModeCrtc; typedef struct _drmModeModeInfo drmModeModeInfo; -typedef struct _drmModeRes drmModeRes; namespace ui { @@ -19,15 +17,16 @@ namespace ui { // native display. class HardwareDisplayControllerInfo { public: - HardwareDisplayControllerInfo(drmModeConnector* connector, drmModeCrtc* crtc); + HardwareDisplayControllerInfo(ScopedDrmConnectorPtr connector, + ScopedDrmCrtcPtr crtc); ~HardwareDisplayControllerInfo(); - drmModeConnector* connector() const { return connector_; } - drmModeCrtc* crtc() const { return crtc_; } + drmModeConnector* connector() const { return connector_.get(); } + drmModeCrtc* crtc() const { return crtc_.get(); } private: - drmModeConnector* connector_; - drmModeCrtc* crtc_; + ScopedDrmConnectorPtr connector_; + ScopedDrmCrtcPtr crtc_; DISALLOW_COPY_AND_ASSIGN(HardwareDisplayControllerInfo); }; @@ -35,10 +34,16 @@ class HardwareDisplayControllerInfo { // Looks-up and parses the native display configurations returning all available // displays. ScopedVector<HardwareDisplayControllerInfo> -GetAvailableDisplayControllerInfos(int fd, drmModeRes* resources); +GetAvailableDisplayControllerInfos(int fd); bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs); +// Memory maps a DRM buffer. +bool MapDumbBuffer(int fd, + uint32_t handle, + uint32_t size, + void** pixels); + } // namespace ui #endif // UI_OZONE_PLATFORM_DRI_DRI_UTIL_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_vsync_provider.cc b/chromium/ui/ozone/platform/dri/dri_vsync_provider.cc index 6679d38937c..bf88c5d94de 100644 --- a/chromium/ui/ozone/platform/dri/dri_vsync_provider.cc +++ b/chromium/ui/ozone/platform/dri/dri_vsync_provider.cc @@ -5,32 +5,33 @@ #include "ui/ozone/platform/dri/dri_vsync_provider.h" #include "base/time/time.h" +#include "ui/ozone/platform/dri/dri_window_delegate.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" namespace ui { -DriVSyncProvider::DriVSyncProvider( - const base::WeakPtr<HardwareDisplayController>& controller) - : controller_(controller) { +DriVSyncProvider::DriVSyncProvider(DriWindowDelegate* window_delegate) + : window_delegate_(window_delegate) { } DriVSyncProvider::~DriVSyncProvider() {} void DriVSyncProvider::GetVSyncParameters(const UpdateVSyncCallback& callback) { - if (!controller_) + HardwareDisplayController* controller = window_delegate_->GetController(); + if (!controller) return; // The value is invalid, so we can't update the parameters. - if (controller_->get_time_of_last_flip() == 0 || - controller_->get_mode().vrefresh == 0) + if (controller->GetTimeOfLastFlip() == 0 || + controller->get_mode().vrefresh == 0) return; // Stores the time of the last refresh. base::TimeTicks timebase = - base::TimeTicks::FromInternalValue(controller_->get_time_of_last_flip()); + base::TimeTicks::FromInternalValue(controller->GetTimeOfLastFlip()); // Stores the refresh rate. base::TimeDelta interval = - base::TimeDelta::FromSeconds(1) / controller_->get_mode().vrefresh; + base::TimeDelta::FromSeconds(1) / controller->get_mode().vrefresh; callback.Run(timebase, interval); } diff --git a/chromium/ui/ozone/platform/dri/dri_vsync_provider.h b/chromium/ui/ozone/platform/dri/dri_vsync_provider.h index 77ec1782172..7248c52ddd9 100644 --- a/chromium/ui/ozone/platform/dri/dri_vsync_provider.h +++ b/chromium/ui/ozone/platform/dri/dri_vsync_provider.h @@ -5,22 +5,21 @@ #ifndef UI_OZONE_PLATFORM_IMPL_DRI_VSYNC_PROVIDER_H_ #define UI_OZONE_PLATFORM_IMPL_DRI_VSYNC_PROVIDER_H_ -#include "base/memory/weak_ptr.h" #include "ui/gfx/vsync_provider.h" namespace ui { -class HardwareDisplayController; +class DriWindowDelegate; class DriVSyncProvider : public gfx::VSyncProvider { public: - DriVSyncProvider(const base::WeakPtr<HardwareDisplayController>& controller); - virtual ~DriVSyncProvider(); + DriVSyncProvider(DriWindowDelegate* window_delegate); + ~DriVSyncProvider() override; - virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) OVERRIDE; + void GetVSyncParameters(const UpdateVSyncCallback& callback) override; private: - base::WeakPtr<HardwareDisplayController> controller_; + DriWindowDelegate* window_delegate_; // Not owned. DISALLOW_COPY_AND_ASSIGN(DriVSyncProvider); }; diff --git a/chromium/ui/ozone/platform/dri/dri_window.cc b/chromium/ui/ozone/platform/dri/dri_window.cc new file mode 100644 index 00000000000..745a2d007a3 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window.cc @@ -0,0 +1,131 @@ +// 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/platform/dri/dri_window.h" + +#include "base/bind.h" +#include "ui/events/event.h" +#include "ui/events/ozone/evdev/event_factory_evdev.h" +#include "ui/events/ozone/events_ozone.h" +#include "ui/events/platform/platform_event_source.h" +#include "ui/ozone/common/gpu/ozone_gpu_messages.h" +#include "ui/ozone/platform/dri/dri_cursor.h" +#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h" +#include "ui/ozone/platform/dri/dri_window_manager.h" +#include "ui/platform_window/platform_window_delegate.h" + +namespace ui { + +DriWindow::DriWindow(PlatformWindowDelegate* delegate, + const gfx::Rect& bounds, + DriGpuPlatformSupportHost* sender, + EventFactoryEvdev* event_factory, + DriWindowManager* window_manager) + : delegate_(delegate), + sender_(sender), + event_factory_(event_factory), + window_manager_(window_manager), + bounds_(bounds), + widget_(window_manager->NextAcceleratedWidget()) { + window_manager_->AddWindow(widget_, this); +} + +DriWindow::~DriWindow() { + PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); + window_manager_->RemoveWindow(widget_); + + sender_->RemoveChannelObserver(this); + if (!sender_->IsConnected()) + return; + + sender_->Send(new OzoneGpuMsg_DestroyWindowDelegate(widget_)); +} + +void DriWindow::Initialize() { + sender_->AddChannelObserver(this); + delegate_->OnAcceleratedWidgetAvailable(widget_); + PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); +} + +void DriWindow::Show() {} + +void DriWindow::Hide() {} + +void DriWindow::Close() {} + +void DriWindow::SetBounds(const gfx::Rect& bounds) { + bounds_ = bounds; + delegate_->OnBoundsChanged(bounds); + + if (!sender_->IsConnected()) + return; + + if (window_manager_->cursor()->GetCursorWindow() == widget_) + window_manager_->cursor()->HideCursor(); + + sender_->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_, bounds)); + + if (window_manager_->cursor()->GetCursorWindow() == widget_) + window_manager_->cursor()->ShowCursor(); +} + +gfx::Rect DriWindow::GetBounds() { + return bounds_; +} + +void DriWindow::SetCapture() {} + +void DriWindow::ReleaseCapture() {} + +void DriWindow::ToggleFullscreen() {} + +void DriWindow::Maximize() {} + +void DriWindow::Minimize() {} + +void DriWindow::Restore() {} + +void DriWindow::SetCursor(PlatformCursor cursor) { + DriCursor* dri_cursor = window_manager_->cursor(); + dri_cursor->SetCursor(widget_, cursor); + // ShowCursor results in a IPC call to GPU. So, we make sure the channel + // is connected. OnChannelEstablished guarantees that ShowCursor is called + // eventually. + if (sender_->IsConnected() && dri_cursor->GetCursorWindow() == widget_) + dri_cursor->ShowCursor(); +} + +void DriWindow::MoveCursorTo(const gfx::Point& location) { + event_factory_->WarpCursorTo(widget_, location); +} + +bool DriWindow::CanDispatchEvent(const PlatformEvent& ne) { + DCHECK(ne); + Event* event = static_cast<Event*>(ne); + if (event->IsMouseEvent() || event->IsScrollEvent()) + return window_manager_->cursor()->GetCursorWindow() == widget_; + + return true; +} + +uint32_t DriWindow::DispatchEvent(const PlatformEvent& native_event) { + DispatchEventFromNativeUiEvent( + native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent, + base::Unretained(delegate_))); + return POST_DISPATCH_STOP_PROPAGATION; +} + +void DriWindow::OnChannelEstablished() { + sender_->Send(new OzoneGpuMsg_CreateWindowDelegate(widget_)); + sender_->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_, bounds_)); + + DriCursor* dri_cursor = window_manager_->cursor(); + if (dri_cursor->GetCursorWindow() == widget_) + dri_cursor->ShowCursor(); +} + +void DriWindow::OnChannelDestroyed() { +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_window.h b/chromium/ui/ozone/platform/dri/dri_window.h new file mode 100644 index 00000000000..66f4530af85 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window.h @@ -0,0 +1,72 @@ +// 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_PLATFORM_DRI_DRI_WINDOW_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_WINDOW_H_ + +#include "base/memory/scoped_ptr.h" +#include "ui/events/platform/platform_event_dispatcher.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/dri/channel_observer.h" +#include "ui/platform_window/platform_window.h" + +namespace ui { + +class DriWindowDelegate; +class DriWindowManager; +class EventFactoryEvdev; +class DriGpuPlatformSupportHost; + +class DriWindow : public PlatformWindow, + public PlatformEventDispatcher, + public ChannelObserver { + public: + DriWindow(PlatformWindowDelegate* delegate, + const gfx::Rect& bounds, + DriGpuPlatformSupportHost* sender, + EventFactoryEvdev* event_factory, + DriWindowManager* window_manager); + ~DriWindow() override; + + void Initialize(); + + // PlatformWindow: + void Show() override; + void Hide() override; + void Close() override; + void SetBounds(const gfx::Rect& bounds) override; + gfx::Rect GetBounds() override; + void SetCapture() override; + void ReleaseCapture() override; + void ToggleFullscreen() override; + void Maximize() override; + void Minimize() override; + void Restore() override; + void SetCursor(PlatformCursor cursor) override; + void MoveCursorTo(const gfx::Point& location) override; + + // PlatformEventDispatcher: + bool CanDispatchEvent(const PlatformEvent& event) override; + uint32_t DispatchEvent(const PlatformEvent& event) override; + + // ChannelObserver: + void OnChannelEstablished() override; + void OnChannelDestroyed() override; + + private: + PlatformWindowDelegate* delegate_; // Not owned. + DriGpuPlatformSupportHost* sender_; // Not owned. + EventFactoryEvdev* event_factory_; // Not owned. + DriWindowManager* window_manager_; // Not owned. + + gfx::Rect bounds_; + gfx::AcceleratedWidget widget_; + + DISALLOW_COPY_AND_ASSIGN(DriWindow); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_WINDOW_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_window_delegate.h b/chromium/ui/ozone/platform/dri/dri_window_delegate.h new file mode 100644 index 00000000000..2787e2cdf8e --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_delegate.h @@ -0,0 +1,52 @@ +// 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_PLATFORM_DRI_DRI_WINDOW_DELEGATE_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_H_ + +#include "ui/gfx/native_widget_types.h" + +namespace gfx { +class Rect; +} // namespace gfx + +namespace ui { + +class HardwareDisplayController; + +// Interface for the display-server half of a DriWindow. +// +// The main implementation of this lives in the process that owns the display +// connection (usually the GPU process) and associates a platform window +// (DriWindow) with a display. A window is associated with the display whose +// bounds contains the window bounds. If there's no suitable display, the window +// is disconnected and its contents will not be visible. +// +// In software mode, this is owned directly on DriWindow because the display +// controller object is in the same process. +// +// In accelerated mode, there's a proxy implementation and calls are forwarded +// to the real object in the GPU process via IPC. +class DriWindowDelegate { + public: + virtual ~DriWindowDelegate() {} + + virtual void Initialize() = 0; + + virtual void Shutdown() = 0; + + // Returns the accelerated widget associated with the delegate. + virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; + + // Returns the current controller the window is displaying on. Callers should + // not cache the result as the controller may change as the window is moved. + virtual HardwareDisplayController* GetController() = 0; + + // Called when the window is resized/moved. + virtual void OnBoundsChanged(const gfx::Rect& bounds) = 0; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_window_delegate_impl.cc b/chromium/ui/ozone/platform/dri/dri_window_delegate_impl.cc new file mode 100644 index 00000000000..df270ed8ad0 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_delegate_impl.cc @@ -0,0 +1,42 @@ +// 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/platform/dri/dri_window_delegate_impl.h" + +#include "base/debug/trace_event.h" +#include "ui/ozone/platform/dri/screen_manager.h" + +namespace ui { + +DriWindowDelegateImpl::DriWindowDelegateImpl(gfx::AcceleratedWidget widget, + ScreenManager* screen_manager) + : widget_(widget), screen_manager_(screen_manager) { +} + +DriWindowDelegateImpl::~DriWindowDelegateImpl() { +} + +void DriWindowDelegateImpl::Initialize() { + TRACE_EVENT1("dri", "DriWindowDelegateImpl::Initialize", "widget", widget_); +} + +void DriWindowDelegateImpl::Shutdown() { + TRACE_EVENT1("dri", "DriWindowDelegateImpl::Shutdown", "widget", widget_); +} + +gfx::AcceleratedWidget DriWindowDelegateImpl::GetAcceleratedWidget() { + return widget_; +} + +HardwareDisplayController* DriWindowDelegateImpl::GetController() { + return controller_.get(); +} + +void DriWindowDelegateImpl::OnBoundsChanged(const gfx::Rect& bounds) { + TRACE_EVENT2("dri", "DriWindowDelegateImpl::OnBoundsChanged", "widget", + widget_, "bounds", bounds.ToString()); + controller_ = screen_manager_->GetDisplayController(bounds); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_window_delegate_impl.h b/chromium/ui/ozone/platform/dri/dri_window_delegate_impl.h new file mode 100644 index 00000000000..1e910ed9642 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_delegate_impl.h @@ -0,0 +1,46 @@ +// 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_PLATFORM_DRI_DRI_WINDOW_DELEGATE_IMPL_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_IMPL_H_ + +#include "base/memory/weak_ptr.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/dri/dri_window_delegate.h" + +namespace gfx { +class Rect; +} // namespace gfx + +namespace ui { + +class HardwareDisplayController; +class ScreenManager; + +class DriWindowDelegateImpl : public DriWindowDelegate { + public: + DriWindowDelegateImpl(gfx::AcceleratedWidget widget, + ScreenManager* screen_manager); + ~DriWindowDelegateImpl() override; + + // DriWindowDelegate: + void Initialize() override; + void Shutdown() override; + gfx::AcceleratedWidget GetAcceleratedWidget() override; + HardwareDisplayController* GetController() override; + void OnBoundsChanged(const gfx::Rect& bounds) override; + + private: + gfx::AcceleratedWidget widget_; + + ScreenManager* screen_manager_; // Not owned. + + base::WeakPtr<HardwareDisplayController> controller_; + + DISALLOW_COPY_AND_ASSIGN(DriWindowDelegateImpl); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_IMPL_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_window_delegate_manager.cc b/chromium/ui/ozone/platform/dri/dri_window_delegate_manager.cc new file mode 100644 index 00000000000..ffbc4ba6ab2 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_delegate_manager.cc @@ -0,0 +1,49 @@ +// 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/platform/dri/dri_window_delegate_manager.h" + +#include "ui/ozone/platform/dri/dri_window_delegate.h" + +namespace ui { + +DriWindowDelegateManager::DriWindowDelegateManager() { +} + +DriWindowDelegateManager::~DriWindowDelegateManager() { + DCHECK(delegate_map_.empty()); +} + +void DriWindowDelegateManager::AddWindowDelegate( + gfx::AcceleratedWidget widget, + scoped_ptr<DriWindowDelegate> delegate) { + std::pair<WidgetToDelegateMap::iterator, bool> result = + delegate_map_.add(widget, delegate.Pass()); + DCHECK(result.second) << "Delegate already added."; +} + +scoped_ptr<DriWindowDelegate> DriWindowDelegateManager::RemoveWindowDelegate( + gfx::AcceleratedWidget widget) { + scoped_ptr<DriWindowDelegate> delegate = delegate_map_.take_and_erase(widget); + DCHECK(delegate) << "Attempting to remove non-existing delegate for " + << widget; + return delegate.Pass(); +} + +DriWindowDelegate* DriWindowDelegateManager::GetWindowDelegate( + gfx::AcceleratedWidget widget) { + WidgetToDelegateMap::iterator it = delegate_map_.find(widget); + if (it != delegate_map_.end()) + return it->second; + + NOTREACHED() << "Attempting to get non-existing delegate for " << widget; + return NULL; +} + +bool DriWindowDelegateManager::HasWindowDelegate( + gfx::AcceleratedWidget widget) { + return delegate_map_.find(widget) != delegate_map_.end(); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_window_delegate_manager.h b/chromium/ui/ozone/platform/dri/dri_window_delegate_manager.h new file mode 100644 index 00000000000..5f2a572c49e --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_delegate_manager.h @@ -0,0 +1,48 @@ +// 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_PLATFORM_DRI_DRI_WINDOW_DELEGATE_MANAGER_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_MANAGER_H_ + +#include "base/containers/scoped_ptr_hash_map.h" +#include "ui/gfx/native_widget_types.h" + +namespace ui { + +class DriWindowDelegate; + +class DriWindowDelegateManager { + public: + DriWindowDelegateManager(); + ~DriWindowDelegateManager(); + + // Adds a delegate for |widget|. Note: |widget| should not be associated with + // a delegate when calling this function. + void AddWindowDelegate(gfx::AcceleratedWidget widget, + scoped_ptr<DriWindowDelegate> surface); + + // Removes the delegate for |widget|. Note: |widget| must have a delegate + // associated with it when calling this function. + scoped_ptr<DriWindowDelegate> RemoveWindowDelegate( + gfx::AcceleratedWidget widget); + + // Returns the delegate associated with |widget|. Note: This function should + // be called only if a valid delegate has been associated with |widget|. + DriWindowDelegate* GetWindowDelegate(gfx::AcceleratedWidget widget); + + // Check if |widget| has a valid delegate associated with it. + bool HasWindowDelegate(gfx::AcceleratedWidget widget); + + private: + typedef base::ScopedPtrHashMap<gfx::AcceleratedWidget, DriWindowDelegate> + WidgetToDelegateMap; + + WidgetToDelegateMap delegate_map_; + + DISALLOW_COPY_AND_ASSIGN(DriWindowDelegateManager); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_MANAGER_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_window_manager.cc b/chromium/ui/ozone/platform/dri/dri_window_manager.cc new file mode 100644 index 00000000000..289d93061c8 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_manager.cc @@ -0,0 +1,77 @@ +// 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/platform/dri/dri_window_manager.h" + +#include "base/logging.h" +#include "ui/ozone/platform/dri/dri_cursor.h" +#include "ui/ozone/platform/dri/dri_window.h" + +namespace ui { + +namespace { + +gfx::PointF GetDefaultCursorLocation(DriWindow* window) { + return gfx::PointF(window->GetBounds().width() / 2, + window->GetBounds().height() / 2); +} + +} // namespace + +DriWindowManager::DriWindowManager(HardwareCursorDelegate* cursor_delegate) + : last_allocated_widget_(0), cursor_(new DriCursor(cursor_delegate, this)) { +} + +DriWindowManager::~DriWindowManager() { +} + +gfx::AcceleratedWidget DriWindowManager::NextAcceleratedWidget() { + // We're not using 0 since other code assumes that a 0 AcceleratedWidget is an + // invalid widget. + return ++last_allocated_widget_; +} + +void DriWindowManager::AddWindow(gfx::AcceleratedWidget widget, + DriWindow* window) { + std::pair<WidgetToWindowMap::iterator, bool> result = window_map_.insert( + std::pair<gfx::AcceleratedWidget, DriWindow*>(widget, window)); + DCHECK(result.second) << "Window for " << widget << " already added."; + + if (cursor_->GetCursorWindow() == gfx::kNullAcceleratedWidget) + ResetCursorLocation(); +} + +void DriWindowManager::RemoveWindow(gfx::AcceleratedWidget widget) { + WidgetToWindowMap::iterator it = window_map_.find(widget); + if (it != window_map_.end()) + window_map_.erase(it); + else + NOTREACHED() << "Attempting to remove non-existing window " << widget; + + if (cursor_->GetCursorWindow() == widget) + ResetCursorLocation(); +} + +DriWindow* DriWindowManager::GetWindow(gfx::AcceleratedWidget widget) { + WidgetToWindowMap::iterator it = window_map_.find(widget); + if (it != window_map_.end()) + return it->second; + + NOTREACHED() << "Attempting to get non-existing window " << widget; + return NULL; +} + +void DriWindowManager::ResetCursorLocation() { + gfx::AcceleratedWidget cursor_widget = gfx::kNullAcceleratedWidget; + gfx::PointF location; + if (!window_map_.empty()) { + WidgetToWindowMap::iterator it = window_map_.begin(); + cursor_widget = it->first; + location = GetDefaultCursorLocation(it->second); + } + + cursor_->MoveCursorTo(cursor_widget, location); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_window_manager.h b/chromium/ui/ozone/platform/dri/dri_window_manager.h new file mode 100644 index 00000000000..5a03957b8cf --- /dev/null +++ b/chromium/ui/ozone/platform/dri/dri_window_manager.h @@ -0,0 +1,58 @@ +// 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_PLATFORM_DRI_DRI_WINDOW_MANAGER_H_ +#define UI_OZONE_PLATFORM_DRI_DRI_WINDOW_MANAGER_H_ + +#include <map> + +#include "base/memory/scoped_ptr.h" +#include "ui/gfx/native_widget_types.h" + +namespace ui { + +class DriCursor; +class DriWindow; +class HardwareCursorDelegate; + +// Responsible for keeping the mapping between the allocated widgets and +// windows. +class DriWindowManager { + public: + explicit DriWindowManager(HardwareCursorDelegate* cursor_delegate); + ~DriWindowManager(); + + gfx::AcceleratedWidget NextAcceleratedWidget(); + + // Adds a window for |widget|. Note: |widget| should not be associated when + // calling this function. + void AddWindow(gfx::AcceleratedWidget widget, DriWindow* window); + + // Removes the window association for |widget|. Note: |widget| must be + // associated with a window when calling this function. + void RemoveWindow(gfx::AcceleratedWidget widget); + + // Returns the window associated with |widget|. Note: This function should + // only be called if a valid window has been associated. + DriWindow* GetWindow(gfx::AcceleratedWidget widget); + + DriCursor* cursor() const { return cursor_.get(); } + + private: + // Reset the cursor location based on the list of active windows. + void ResetCursorLocation(); + + typedef std::map<gfx::AcceleratedWidget, DriWindow*> WidgetToWindowMap; + + gfx::AcceleratedWidget last_allocated_widget_; + WidgetToWindowMap window_map_; + + scoped_ptr<DriCursor> cursor_; + + DISALLOW_COPY_AND_ASSIGN(DriWindowManager); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_DRI_WINDOW_MANAGER_H_ diff --git a/chromium/ui/ozone/platform/dri/dri_wrapper.cc b/chromium/ui/ozone/platform/dri/dri_wrapper.cc index 5231bd0ea02..3b6ceb0e02e 100644 --- a/chromium/ui/ozone/platform/dri/dri_wrapper.cc +++ b/chromium/ui/ozone/platform/dri/dri_wrapper.cc @@ -5,16 +5,64 @@ #include "ui/ozone/platform/dri/dri_wrapper.h" #include <fcntl.h> +#include <sys/mman.h> #include <unistd.h> #include <xf86drm.h> #include <xf86drmMode.h> +#include "base/debug/trace_event.h" #include "base/logging.h" +#include "base/stl_util.h" +#include "third_party/skia/include/core/SkImageInfo.h" +#include "ui/ozone/platform/dri/dri_util.h" namespace ui { -DriWrapper::DriWrapper(const char* device_path) { - fd_ = open(device_path, O_RDWR | O_CLOEXEC); +namespace { + +uint32_t ToFixedPoint(double v) { + // This returns a number in a 16-bit.16-bit fixed point. + return v * 65536.0; +} + +bool DrmCreateDumbBuffer(int fd, + const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride) { + struct drm_mode_create_dumb request; + memset(&request, 0, sizeof(request)); + request.width = info.width(); + request.height = info.height(); + request.bpp = info.bytesPerPixel() << 3; + request.flags = 0; + + if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) { + VLOG(2) << "Cannot create dumb buffer (" << errno << ") " + << strerror(errno); + return false; + } + + // The driver may choose to align the last row as well. We don't care about + // the last alignment bits since they aren't used for display purposes, so + // just check that the expected size is <= to what the driver allocated. + DCHECK_LE(info.getSafeSize(request.pitch), request.size); + + *handle = request.handle; + *stride = request.pitch; + return true; +} + +void DrmDestroyDumbBuffer(int fd, uint32_t handle) { + struct drm_mode_destroy_dumb destroy_request; + memset(&destroy_request, 0, sizeof(destroy_request)); + destroy_request.handle = handle; + drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request); +} + +} // namespace + +DriWrapper::DriWrapper(const char* device_path) + : fd_(-1), device_path_(device_path) { } DriWrapper::~DriWrapper() { @@ -22,40 +70,69 @@ DriWrapper::~DriWrapper() { close(fd_); } -drmModeCrtc* DriWrapper::GetCrtc(uint32_t crtc_id) { - CHECK(fd_ >= 0); - return drmModeGetCrtc(fd_, crtc_id); +void DriWrapper::Initialize() { + fd_ = open(device_path_, O_RDWR | O_CLOEXEC); + if (fd_ < 0) + PLOG(FATAL) << "open: " << device_path_; } -void DriWrapper::FreeCrtc(drmModeCrtc* crtc) { - drmModeFreeCrtc(crtc); +ScopedDrmCrtcPtr DriWrapper::GetCrtc(uint32_t crtc_id) { + DCHECK(fd_ >= 0); + return ScopedDrmCrtcPtr(drmModeGetCrtc(fd_, crtc_id)); } bool DriWrapper::SetCrtc(uint32_t crtc_id, uint32_t framebuffer, - uint32_t* connectors, + std::vector<uint32_t> connectors, drmModeModeInfo* mode) { - CHECK(fd_ >= 0); - return !drmModeSetCrtc(fd_, crtc_id, framebuffer, 0, 0, connectors, 1, mode); + DCHECK(fd_ >= 0); + DCHECK(!connectors.empty()); + DCHECK(mode); + + TRACE_EVENT2("dri", "DriWrapper::SetCrtc", "crtc", crtc_id, "size", + gfx::Size(mode->hdisplay, mode->vdisplay).ToString()); + return !drmModeSetCrtc(fd_, + crtc_id, + framebuffer, + 0, + 0, + vector_as_array(&connectors), + connectors.size(), mode); } -bool DriWrapper::SetCrtc(drmModeCrtc* crtc, uint32_t* connectors) { - CHECK(fd_ >= 0); +bool DriWrapper::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) { + DCHECK(fd_ >= 0); + // If there's no buffer then the CRTC was disabled. + if (!crtc->buffer_id) + return DisableCrtc(crtc->crtc_id); + + DCHECK(!connectors.empty()); + + TRACE_EVENT1("dri", "DriWrapper::RestoreCrtc", + "crtc", crtc->crtc_id); return !drmModeSetCrtc(fd_, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, - connectors, - 1, + vector_as_array(&connectors), + connectors.size(), &crtc->mode); } bool DriWrapper::DisableCrtc(uint32_t crtc_id) { - CHECK(fd_ >= 0); + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::DisableCrtc", + "crtc", crtc_id); return !drmModeSetCrtc(fd_, crtc_id, 0, 0, 0, NULL, 0, NULL); } +ScopedDrmConnectorPtr DriWrapper::GetConnector(uint32_t connector_id) { + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::GetConnector", "connector", connector_id); + return ScopedDrmConnectorPtr(drmModeGetConnector(fd_, connector_id)); +} + bool DriWrapper::AddFramebuffer(uint32_t width, uint32_t height, uint8_t depth, @@ -63,7 +140,9 @@ bool DriWrapper::AddFramebuffer(uint32_t width, uint32_t stride, uint32_t handle, uint32_t* framebuffer) { - CHECK(fd_ >= 0); + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::AddFramebuffer", + "handle", handle); return !drmModeAddFB(fd_, width, height, @@ -75,14 +154,19 @@ bool DriWrapper::AddFramebuffer(uint32_t width, } bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) { - CHECK(fd_ >= 0); + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer", + "framebuffer", framebuffer); return !drmModeRmFB(fd_, framebuffer); } bool DriWrapper::PageFlip(uint32_t crtc_id, uint32_t framebuffer, void* data) { - CHECK(fd_ >= 0); + DCHECK(fd_ >= 0); + TRACE_EVENT2("dri", "DriWrapper::PageFlip", + "crtc", crtc_id, + "framebuffer", framebuffer); return !drmModePageFlip(fd_, crtc_id, framebuffer, @@ -90,75 +174,141 @@ bool DriWrapper::PageFlip(uint32_t crtc_id, data); } -drmModePropertyRes* DriWrapper::GetProperty(drmModeConnector* connector, - const char* name) { +bool DriWrapper::PageFlipOverlay(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& location, + const gfx::RectF& source, + int overlay_plane) { + DCHECK(fd_ >= 0); + TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay", + "crtc", crtc_id, + "framebuffer", framebuffer); + return !drmModeSetPlane(fd_, + overlay_plane, + crtc_id, + framebuffer, + 0, + location.x(), + location.y(), + location.width(), + location.height(), + ToFixedPoint(source.x()), + ToFixedPoint(source.y()), + ToFixedPoint(source.width()), + ToFixedPoint(source.height())); +} + +ScopedDrmFramebufferPtr DriWrapper::GetFramebuffer(uint32_t framebuffer) { + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::GetFramebuffer", + "framebuffer", framebuffer); + return ScopedDrmFramebufferPtr(drmModeGetFB(fd_, framebuffer)); +} + +ScopedDrmPropertyPtr DriWrapper::GetProperty(drmModeConnector* connector, + const char* name) { + TRACE_EVENT2("dri", "DriWrapper::GetProperty", + "connector", connector->connector_id, + "name", name); for (int i = 0; i < connector->count_props; ++i) { - drmModePropertyRes* property = drmModeGetProperty(fd_, connector->props[i]); + ScopedDrmPropertyPtr property(drmModeGetProperty(fd_, connector->props[i])); if (!property) continue; if (strcmp(property->name, name) == 0) - return property; - - drmModeFreeProperty(property); + return property.Pass(); } - return NULL; + return ScopedDrmPropertyPtr(); } bool DriWrapper::SetProperty(uint32_t connector_id, uint32_t property_id, uint64_t value) { - CHECK(fd_ >= 0); + DCHECK(fd_ >= 0); return !drmModeConnectorSetProperty(fd_, connector_id, property_id, value); } -void DriWrapper::FreeProperty(drmModePropertyRes* prop) { - drmModeFreeProperty(prop); +bool DriWrapper::GetCapability(uint64_t capability, uint64_t* value) { + DCHECK(fd_ >= 0); + return !drmGetCap(fd_, capability, value); } -drmModePropertyBlobRes* DriWrapper::GetPropertyBlob(drmModeConnector* connector, - const char* name) { - CHECK(fd_ >= 0); +ScopedDrmPropertyBlobPtr DriWrapper::GetPropertyBlob( + drmModeConnector* connector, const char* name) { + DCHECK(fd_ >= 0); + TRACE_EVENT2("dri", "DriWrapper::GetPropertyBlob", + "connector", connector->connector_id, + "name", name); for (int i = 0; i < connector->count_props; ++i) { - drmModePropertyRes* property = drmModeGetProperty(fd_, connector->props[i]); + ScopedDrmPropertyPtr property(drmModeGetProperty(fd_, connector->props[i])); if (!property) continue; if (strcmp(property->name, name) == 0 && - property->flags & DRM_MODE_PROP_BLOB) { - drmModePropertyBlobRes* blob = - drmModeGetPropertyBlob(fd_, connector->prop_values[i]); - drmModeFreeProperty(property); - return blob; - } - - drmModeFreeProperty(property); + property->flags & DRM_MODE_PROP_BLOB) + return ScopedDrmPropertyBlobPtr( + drmModeGetPropertyBlob(fd_, connector->prop_values[i])); } - return NULL; -} - -void DriWrapper::FreePropertyBlob(drmModePropertyBlobRes* blob) { - drmModeFreePropertyBlob(blob); + return ScopedDrmPropertyBlobPtr(); } bool DriWrapper::SetCursor(uint32_t crtc_id, uint32_t handle, - uint32_t width, - uint32_t height) { - CHECK(fd_ >= 0); - return !drmModeSetCursor(fd_, crtc_id, handle, width, height); + const gfx::Size& size) { + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::SetCursor", "handle", handle); + return !drmModeSetCursor(fd_, crtc_id, handle, size.width(), size.height()); } -bool DriWrapper::MoveCursor(uint32_t crtc_id, int x, int y) { - CHECK(fd_ >= 0); - return !drmModeMoveCursor(fd_, crtc_id, x, y); +bool DriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { + DCHECK(fd_ >= 0); + return !drmModeMoveCursor(fd_, crtc_id, point.x(), point.y()); } void DriWrapper::HandleEvent(drmEventContext& event) { - CHECK(fd_ >= 0); + DCHECK(fd_ >= 0); + TRACE_EVENT0("dri", "DriWrapper::HandleEvent"); drmHandleEvent(fd_, &event); } +bool DriWrapper::CreateDumbBuffer(const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride, + void** pixels) { + DCHECK(fd_ >= 0); + + TRACE_EVENT0("dri", "DriWrapper::CreateDumbBuffer"); + if (!DrmCreateDumbBuffer(fd_, info, handle, stride)) + return false; + + if (!MapDumbBuffer(fd_, *handle, info.getSafeSize(*stride), pixels)) { + DrmDestroyDumbBuffer(fd_, *handle); + return false; + } + + return true; +} + +void DriWrapper::DestroyDumbBuffer(const SkImageInfo& info, + uint32_t handle, + uint32_t stride, + void* pixels) { + DCHECK(fd_ >= 0); + TRACE_EVENT1("dri", "DriWrapper::DestroyDumbBuffer", "handle", handle); + munmap(pixels, info.getSafeSize(stride)); + DrmDestroyDumbBuffer(fd_, handle); +} + +bool DriWrapper::SetMaster() { + DCHECK(fd_ >= 0); + return (drmSetMaster(fd_) == 0); +} + +bool DriWrapper::DropMaster() { + DCHECK(fd_ >= 0); + return (drmDropMaster(fd_) == 0); +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/dri_wrapper.h b/chromium/ui/ozone/platform/dri/dri_wrapper.h index 014d143ec57..be9809c6c9d 100644 --- a/chromium/ui/ozone/platform/dri/dri_wrapper.h +++ b/chromium/ui/ozone/platform/dri/dri_wrapper.h @@ -7,33 +7,36 @@ #include <stdint.h> +#include <vector> + #include "base/macros.h" -#include "ui/ozone/ozone_export.h" +#include "ui/gfx/overlay_transform.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/rect_f.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" typedef struct _drmEventContext drmEventContext; -typedef struct _drmModeConnector drmModeConnector; -typedef struct _drmModeCrtc drmModeCrtc; typedef struct _drmModeModeInfo drmModeModeInfo; -typedef struct _drmModeProperty drmModePropertyRes; -typedef struct _drmModePropertyBlob drmModePropertyBlobRes; + +struct SkImageInfo; namespace ui { // Wraps DRM calls into a nice interface. Used to provide different // implementations of the DRM calls. For the actual implementation the DRM API // would be called. In unit tests this interface would be stubbed. -class OZONE_EXPORT DriWrapper { +class DriWrapper { public: DriWrapper(const char* device_path); virtual ~DriWrapper(); + // Open device. + virtual void Initialize(); + // Get the CRTC state. This is generally used to save state before using the // CRTC. When the user finishes using the CRTC, the user should restore the // CRTC to it's initial state. Use |SetCrtc| to restore the state. - virtual drmModeCrtc* GetCrtc(uint32_t crtc_id); - - // Frees the CRTC mode object. - virtual void FreeCrtc(drmModeCrtc* crtc); + virtual ScopedDrmCrtcPtr GetCrtc(uint32_t crtc_id); // Used to configure CRTC with ID |crtc_id| to use the connector in // |connectors|. The CRTC will be configured with mode |mode| and will display @@ -41,16 +44,19 @@ class OZONE_EXPORT DriWrapper { // framebuffer, it should be registered with the CRTC using |AddFramebuffer|. virtual bool SetCrtc(uint32_t crtc_id, uint32_t framebuffer, - uint32_t* connectors, + std::vector<uint32_t> connectors, drmModeModeInfo* mode); // Used to set a specific configuration to the CRTC. Normally this function // would be called with a CRTC saved state (from |GetCrtc|) to restore it to // its original configuration. - virtual bool SetCrtc(drmModeCrtc* crtc, uint32_t* connectors); + virtual bool SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors); virtual bool DisableCrtc(uint32_t crtc_id); + // Returns the connector properties for |connector_id|. + virtual ScopedDrmConnectorPtr GetConnector(uint32_t connector_id); + // Register a buffer with the CRTC. On successful registration, the CRTC will // assign a framebuffer ID to |framebuffer|. virtual bool AddFramebuffer(uint32_t width, @@ -64,6 +70,9 @@ class OZONE_EXPORT DriWrapper { // Deregister the given |framebuffer|. virtual bool RemoveFramebuffer(uint32_t framebuffer); + // Get the DRM details associated with |framebuffer|. + virtual ScopedDrmFramebufferPtr GetFramebuffer(uint32_t framebuffer); + // Schedules a pageflip for CRTC |crtc_id|. This function will return // immediately. Upon completion of the pageflip event, the CRTC will be // displaying the buffer with ID |framebuffer| and will have a DRM event @@ -71,11 +80,20 @@ class OZONE_EXPORT DriWrapper { // will receive when processing the pageflip event. virtual bool PageFlip(uint32_t crtc_id, uint32_t framebuffer, void* data); + // Schedule an overlay to be show during the page flip for CRTC |crtc_id|. + // |source| location from |framebuffer| will be shown on overlay + // |overlay_plane|, in the bounds specified by |location| on the screen. + virtual bool PageFlipOverlay(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& location, + const gfx::RectF& source, + int overlay_plane); + // Returns the property with name |name| associated with |connector|. Returns // NULL if property not found. If the returned value is valid, it must be // released using FreeProperty(). - virtual drmModePropertyRes* GetProperty(drmModeConnector* connector, - const char* name); + virtual ScopedDrmPropertyPtr GetProperty(drmModeConnector* connector, + const char* name); // Sets the value of property with ID |property_id| to |value|. The property // is applied to the connector with ID |connector_id|. @@ -83,34 +101,43 @@ class OZONE_EXPORT DriWrapper { uint32_t property_id, uint64_t value); - // Frees |prop| and any resources it allocated when it was created. |prop| - // must be a valid object. - virtual void FreeProperty(drmModePropertyRes* prop); + // Can be used to query device/driver |capability|. Sets the value of + // |capability to |value|. Returns true in case of a succesful query. + virtual bool GetCapability(uint64_t capability, uint64_t* value); // Return a binary blob associated with |connector|. The binary blob is // associated with the property with name |name|. Return NULL if the property // could not be found or if the property does not have a binary blob. If valid // the returned object must be freed using FreePropertyBlob(). - virtual drmModePropertyBlobRes* GetPropertyBlob(drmModeConnector* connector, - const char* name); - - // Frees |blob| and any resources allocated when it was created. |blob| must - // be a valid object. - virtual void FreePropertyBlob(drmModePropertyBlobRes* blob); + virtual ScopedDrmPropertyBlobPtr GetPropertyBlob(drmModeConnector* connector, + const char* name); // Set the cursor to be displayed in CRTC |crtc_id|. (width, height) is the // cursor size pointed by |handle|. virtual bool SetCursor(uint32_t crtc_id, uint32_t handle, - uint32_t width, - uint32_t height); + const gfx::Size& size); // Move the cursor on CRTC |crtc_id| to (x, y); - virtual bool MoveCursor(uint32_t crtc_id, int x, int y); + virtual bool MoveCursor(uint32_t crtc_id, const gfx::Point& point); virtual void HandleEvent(drmEventContext& event); + virtual bool CreateDumbBuffer(const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride, + void** pixels); + + virtual void DestroyDumbBuffer(const SkImageInfo& info, + uint32_t handle, + uint32_t stride, + void* pixels); + + // Drm master related + virtual bool SetMaster(); + virtual bool DropMaster(); + int get_fd() const { return fd_; } protected: @@ -119,6 +146,9 @@ class OZONE_EXPORT DriWrapper { int fd_; private: + // Path to DRM device. + const char* device_path_; + DISALLOW_COPY_AND_ASSIGN(DriWrapper); }; diff --git a/chromium/ui/ozone/platform/dri/gbm.gypi b/chromium/ui/ozone/platform/dri/gbm.gypi index 91c0e872794..088ecce7750 100644 --- a/chromium/ui/ozone/platform/dri/gbm.gypi +++ b/chromium/ui/ozone/platform/dri/gbm.gypi @@ -17,9 +17,10 @@ 'type': 'static_library', 'dependencies': [ '../../base/base.gyp:base', - '../../build/linux/system.gyp:dridrm', + '../../build/linux/system.gyp:libdrm', '../../build/linux/system.gyp:gbm', '../../skia/skia.gyp:skia', + '../../third_party/khronos/khronos.gyp:khronos_headers', '../base/ui_base.gyp:ui_base', '../events/events.gyp:events', '../events/ozone/events_ozone.gyp:events_ozone', @@ -29,12 +30,18 @@ 'OZONE_IMPLEMENTATION', ], 'sources': [ - 'buffer_data.cc', - 'buffer_data.h', + 'gbm_buffer.cc', + 'gbm_buffer.h', + 'gbm_buffer_base.cc', + 'gbm_buffer_base.h', 'gbm_surface.cc', 'gbm_surface.h', + 'gbm_surfaceless.cc', + 'gbm_surfaceless.h', 'gbm_surface_factory.cc', 'gbm_surface_factory.h', + 'native_display_delegate_proxy.cc', + 'native_display_delegate_proxy.h', 'ozone_platform_gbm.cc', 'ozone_platform_gbm.h', ], diff --git a/chromium/ui/ozone/platform/dri/gbm_buffer.cc b/chromium/ui/ozone/platform/dri/gbm_buffer.cc new file mode 100644 index 00000000000..1239696fce2 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/gbm_buffer.cc @@ -0,0 +1,98 @@ +// 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/platform/dri/gbm_buffer.h" + +#include <drm.h> +#include <fcntl.h> +#include <gbm.h> +#include <xf86drm.h> + +#include "base/logging.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" + +namespace ui { + +namespace { + +int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) { + switch (fmt) { + case SurfaceFactoryOzone::RGBA_8888: + return GBM_BO_FORMAT_ARGB8888; + case SurfaceFactoryOzone::RGBX_8888: + return GBM_BO_FORMAT_XRGB8888; + default: + NOTREACHED(); + return 0; + } +} + +} // namespace + +GbmBuffer::GbmBuffer(DriWrapper* dri, gbm_bo* bo, bool scanout) + : GbmBufferBase(dri, bo, scanout) { +} + +GbmBuffer::~GbmBuffer() { + if (bo()) + gbm_bo_destroy(bo()); +} + +// static +scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( + DriWrapper* dri, + gbm_device* device, + SurfaceFactoryOzone::BufferFormat format, + const gfx::Size& size, + bool scanout) { + unsigned flags = GBM_BO_USE_RENDERING; + if (scanout) + flags |= GBM_BO_USE_SCANOUT; + gbm_bo* bo = gbm_bo_create(device, + size.width(), + size.height(), + GetGbmFormatFromBufferFormat(format), + flags); + if (!bo) + return NULL; + + scoped_refptr<GbmBuffer> buffer(new GbmBuffer(dri, bo, scanout)); + if (scanout && !buffer->GetFramebufferId()) + return NULL; + + return buffer; +} + +GbmPixmap::GbmPixmap(scoped_refptr<GbmBuffer> buffer) + : buffer_(buffer), dma_buf_(-1) { +} + +bool GbmPixmap::Initialize(DriWrapper* dri) { + if (drmPrimeHandleToFD(dri->get_fd(), buffer_->GetHandle(), DRM_CLOEXEC, + &dma_buf_)) { + LOG(ERROR) << "Failed to export buffer to dma_buf"; + return false; + } + + return true; +} + +GbmPixmap::~GbmPixmap() { + if (dma_buf_ > 0) + close(dma_buf_); +} + +void* GbmPixmap::GetEGLClientBuffer() { + return NULL; +} + +int GbmPixmap::GetDmaBufFd() { + return dma_buf_; +} + +int GbmPixmap::GetDmaBufPitch() { + return gbm_bo_get_stride(buffer_->bo()); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/gbm_buffer.h b/chromium/ui/ozone/platform/dri/gbm_buffer.h new file mode 100644 index 00000000000..9b8a9cece02 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/gbm_buffer.h @@ -0,0 +1,61 @@ +// 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_PLATFORM_DRI_GBM_BUFFER_H_ +#define UI_OZONE_PLATFORM_DRI_GBM_BUFFER_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "ui/gfx/geometry/size.h" +#include "ui/ozone/platform/dri/gbm_buffer_base.h" +#include "ui/ozone/public/native_pixmap.h" +#include "ui/ozone/public/surface_factory_ozone.h" + +struct gbm_bo; +struct gbm_device; + +namespace ui { + +class DriWrapper; + +class GbmBuffer : public GbmBufferBase { + public: + static scoped_refptr<GbmBuffer> CreateBuffer( + DriWrapper* dri, + gbm_device* device, + SurfaceFactoryOzone::BufferFormat format, + const gfx::Size& size, + bool scanout); + + private: + GbmBuffer(DriWrapper* dri, gbm_bo* bo, bool scanout); + ~GbmBuffer() override; + + DISALLOW_COPY_AND_ASSIGN(GbmBuffer); +}; + +class GbmPixmap : public NativePixmap { + public: + GbmPixmap(scoped_refptr<GbmBuffer> buffer); + bool Initialize(DriWrapper* dri); + + // NativePixmap: + void* GetEGLClientBuffer() override; + int GetDmaBufFd() override; + int GetDmaBufPitch() override; + + scoped_refptr<GbmBuffer> buffer() { return buffer_; } + + private: + ~GbmPixmap() override; + + scoped_refptr<GbmBuffer> buffer_; + int dma_buf_; + + DISALLOW_COPY_AND_ASSIGN(GbmPixmap); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_GBM_BUFFER_H_ diff --git a/chromium/ui/ozone/platform/dri/gbm_buffer_base.cc b/chromium/ui/ozone/platform/dri/gbm_buffer_base.cc new file mode 100644 index 00000000000..f5c057af381 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/gbm_buffer_base.cc @@ -0,0 +1,53 @@ +// 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/platform/dri/gbm_buffer_base.h" + +#include <gbm.h> + +#include "base/logging.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" + +namespace ui { + +namespace { + +// Pixel configuration for the current buffer format. +// TODO(dnicoara) These will need to change once we query the hardware for +// supported configurations. +const uint8_t kColorDepth = 24; +const uint8_t kPixelDepth = 32; + +} // namespace + +GbmBufferBase::GbmBufferBase(DriWrapper* dri, gbm_bo* bo, bool scanout) + : dri_(dri), bo_(bo), framebuffer_(0) { + if (scanout && !dri_->AddFramebuffer(gbm_bo_get_width(bo), + gbm_bo_get_height(bo), + kColorDepth, + kPixelDepth, + gbm_bo_get_stride(bo), + gbm_bo_get_handle(bo).u32, + &framebuffer_)) + LOG(ERROR) << "Failed to register buffer"; +} + +GbmBufferBase::~GbmBufferBase() { + if (framebuffer_) + dri_->RemoveFramebuffer(framebuffer_); +} + +uint32_t GbmBufferBase::GetFramebufferId() const { + return framebuffer_; +} + +uint32_t GbmBufferBase::GetHandle() const { + return gbm_bo_get_handle(bo_).u32; +} + +gfx::Size GbmBufferBase::GetSize() const { + return gfx::Size(gbm_bo_get_width(bo_), gbm_bo_get_height(bo_)); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/gbm_buffer_base.h b/chromium/ui/ozone/platform/dri/gbm_buffer_base.h new file mode 100644 index 00000000000..bb71aaaf89c --- /dev/null +++ b/chromium/ui/ozone/platform/dri/gbm_buffer_base.h @@ -0,0 +1,43 @@ +// 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_PLATFORM_DRI_GBM_BUFFER_BASE_H_ +#define UI_OZONE_PLATFORM_DRI_GBM_BUFFER_BASE_H_ + +#include "ui/ozone/platform/dri/scanout_buffer.h" + +struct gbm_bo; + +namespace ui { + +class DriWrapper; + +// Wrapper for a GBM buffer. The base class provides common functionality +// required to prepare the buffer for scanout. It does not provide any ownership +// of the buffer. Implementations of this base class should deal with buffer +// ownership. +class GbmBufferBase : public ScanoutBuffer { + public: + gbm_bo* bo() const { return bo_; } + + // ScanoutBuffer: + uint32_t GetFramebufferId() const override; + uint32_t GetHandle() const override; + gfx::Size GetSize() const override; + + protected: + GbmBufferBase(DriWrapper* dri, gbm_bo* bo, bool scanout); + ~GbmBufferBase() override; + + private: + DriWrapper* dri_; + gbm_bo* bo_; + uint32_t framebuffer_; + + DISALLOW_COPY_AND_ASSIGN(GbmBufferBase); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_GBM_BUFFER_BASE_H_ diff --git a/chromium/ui/ozone/platform/dri/gbm_surface.cc b/chromium/ui/ozone/platform/dri/gbm_surface.cc index 99f0ae7016f..a4e624f768b 100644 --- a/chromium/ui/ozone/platform/dri/gbm_surface.cc +++ b/chromium/ui/ozone/platform/dri/gbm_surface.cc @@ -7,106 +7,155 @@ #include <gbm.h> #include "base/logging.h" -#include "third_party/skia/include/core/SkImageInfo.h" -#include "ui/ozone/platform/dri/buffer_data.h" #include "ui/ozone/platform/dri/dri_buffer.h" +#include "ui/ozone/platform/dri/dri_window_delegate.h" #include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/gbm_buffer_base.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" +#include "ui/ozone/platform/dri/scanout_buffer.h" namespace ui { -GbmSurface::GbmSurface(gbm_device* device, - DriWrapper* dri, - const gfx::Size& size) - : gbm_device_(device), +namespace { + +class GbmSurfaceBuffer : public GbmBufferBase { + public: + static scoped_refptr<GbmSurfaceBuffer> CreateBuffer(DriWrapper* dri, + gbm_bo* buffer); + static scoped_refptr<GbmSurfaceBuffer> GetBuffer(gbm_bo* buffer); + + private: + GbmSurfaceBuffer(DriWrapper* dri, gbm_bo* bo); + ~GbmSurfaceBuffer() override; + + static void Destroy(gbm_bo* buffer, void* data); + + // This buffer is special and is released by GBM at any point in time (as + // long as it isn't being used). Since GBM should be the only one to + // release this buffer, keep a self-reference in order to keep this alive. + // When GBM calls Destroy(..) the self-reference will dissapear and this will + // be destroyed. + scoped_refptr<GbmSurfaceBuffer> self_; + + DISALLOW_COPY_AND_ASSIGN(GbmSurfaceBuffer); +}; + +GbmSurfaceBuffer::GbmSurfaceBuffer(DriWrapper* dri, gbm_bo* bo) + : GbmBufferBase(dri, bo, true) { + if (GetFramebufferId()) { + self_ = this; + gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy); + } +} + +GbmSurfaceBuffer::~GbmSurfaceBuffer() {} + +// static +scoped_refptr<GbmSurfaceBuffer> GbmSurfaceBuffer::CreateBuffer( + DriWrapper* dri, gbm_bo* buffer) { + scoped_refptr<GbmSurfaceBuffer> scoped_buffer(new GbmSurfaceBuffer(dri, + buffer)); + if (!scoped_buffer->GetFramebufferId()) + return NULL; + + return scoped_buffer; +} + +// static +scoped_refptr<GbmSurfaceBuffer> GbmSurfaceBuffer::GetBuffer(gbm_bo* buffer) { + return scoped_refptr<GbmSurfaceBuffer>( + static_cast<GbmSurfaceBuffer*>(gbm_bo_get_user_data(buffer))); +} + +// static +void GbmSurfaceBuffer::Destroy(gbm_bo* buffer, void* data) { + GbmSurfaceBuffer* scoped_buffer = static_cast<GbmSurfaceBuffer*>(data); + scoped_buffer->self_ = NULL; +} + +} // namespace + +GbmSurface::GbmSurface(DriWindowDelegate* window_delegate, + gbm_device* device, + DriWrapper* dri) + : GbmSurfaceless(window_delegate), + gbm_device_(device), dri_(dri), - size_(size), native_surface_(NULL), - buffers_(), - front_buffer_(0) { - for (size_t i = 0; i < arraysize(buffers_); ++i) - buffers_[i] = NULL; + current_buffer_(NULL) { } GbmSurface::~GbmSurface() { - for (size_t i = 0; i < arraysize(buffers_); ++i) { - if (buffers_[i]) { - gbm_surface_release_buffer(native_surface_, buffers_[i]); - } - } + if (current_buffer_) + gbm_surface_release_buffer(native_surface_, current_buffer_); if (native_surface_) gbm_surface_destroy(native_surface_); } bool GbmSurface::Initialize() { + // If we're initializing the surface without a controller (possible on startup + // where the surface creation can happen before the native window delegate + // IPCs arrive), initialize the size to a valid value such that surface + // creation doesn't fail. + gfx::Size size(1, 1); + if (window_delegate_->GetController()) { + size = window_delegate_->GetController()->GetModeSize(); + } // TODO(dnicoara) Check underlying system support for pixel format. - native_surface_ = gbm_surface_create( - gbm_device_, - size_.width(), - size_.height(), - GBM_BO_FORMAT_XRGB8888, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + native_surface_ = + gbm_surface_create(gbm_device_, + size.width(), + size.height(), + GBM_BO_FORMAT_XRGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!native_surface_) return false; - dumb_buffer_.reset(new DriBuffer(dri_)); - if (!dumb_buffer_->Initialize(SkImageInfo::MakeN32Premul(size_.width(), - size_.height()))) - return false; - + size_ = size; return true; } -uint32_t GbmSurface::GetFramebufferId() const { - if (!buffers_[front_buffer_ ^ 1]) - return dumb_buffer_->framebuffer(); - - BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]); - CHECK(data); - return data->framebuffer(); +intptr_t GbmSurface::GetNativeWindow() { + DCHECK(native_surface_); + return reinterpret_cast<intptr_t>(native_surface_); } -uint32_t GbmSurface::GetHandle() const { - if (!buffers_[front_buffer_ ^ 1]) - return dumb_buffer_->handle(); +bool GbmSurface::ResizeNativeWindow(const gfx::Size& viewport_size) { + if (size_ == viewport_size) + return true; - BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]); - CHECK(data); - return data->handle(); + return false; } -gfx::Size GbmSurface::Size() const { - return size_; -} +bool GbmSurface::OnSwapBuffers() { + DCHECK(native_surface_); + + gbm_bo* pending_buffer = gbm_surface_lock_front_buffer(native_surface_); + scoped_refptr<GbmSurfaceBuffer> primary = + GbmSurfaceBuffer::GetBuffer(pending_buffer); + if (!primary.get()) { + primary = GbmSurfaceBuffer::CreateBuffer(dri_, pending_buffer); + if (!primary.get()) { + LOG(ERROR) << "Failed to associate the buffer with the controller"; + return false; + } + } -void GbmSurface::SwapBuffers() { - // If there was a frontbuffer, is no longer active. Release it back to GBM. - if (buffers_[front_buffer_]) - gbm_surface_release_buffer(native_surface_, buffers_[front_buffer_]); - - // Update the index to the frontbuffer. - front_buffer_ ^= 1; - // We've just released it. Since GBM doesn't guarantee we'll get the same - // buffer back, we set it to NULL so we don't keep track of objects that may - // have been destroyed. - buffers_[front_buffer_ ^ 1] = NULL; -} + // The primary buffer is a special case. + if (window_delegate_->GetController()) + window_delegate_->GetController()->QueueOverlayPlane(OverlayPlane(primary)); -void GbmSurface::LockCurrentDrawable() { - CHECK(native_surface_); - // Lock the buffer we want to display. - buffers_[front_buffer_ ^ 1] = gbm_surface_lock_front_buffer(native_surface_); - - BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]); - // If it is a new buffer, it won't have any data associated with it. So we - // create it. On creation it will associate itself with the buffer and - // register the buffer. - if (!data) { - data = BufferData::CreateData(dri_, buffers_[front_buffer_ ^ 1]); - DCHECK(data) << "Failed to associate the buffer with the controller"; - } + if (!GbmSurfaceless::OnSwapBuffers()) + return false; + + // If there was a frontbuffer, it is no longer active. Release it back to GBM. + if (current_buffer_) + gbm_surface_release_buffer(native_surface_, current_buffer_); + + current_buffer_ = pending_buffer; + return true; } } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/gbm_surface.h b/chromium/ui/ozone/platform/dri/gbm_surface.h index 8a33ab5e997..45e2e710a68 100644 --- a/chromium/ui/ozone/platform/dri/gbm_surface.h +++ b/chromium/ui/ozone/platform/dri/gbm_surface.h @@ -6,9 +6,9 @@ #define UI_OZONE_PLATFORM_DRI_GBM_SURFACE_H_ #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "ui/gfx/geometry/size.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/platform/dri/gbm_surfaceless.h" +#include "ui/ozone/public/surface_ozone_egl.h" struct gbm_bo; struct gbm_device; @@ -18,54 +18,38 @@ namespace ui { class DriBuffer; class DriWrapper; +class DriWindowDelegate; -// Implement the ScanoutSurface interface on top of GBM (Generic Buffer -// Manager). GBM provides generic access to hardware accelerated surfaces which -// can be used in association with EGL to provide accelerated drawing. -class GbmSurface : public ScanoutSurface { +// Extends the GBM surfaceless functionality and adds an implicit surface for +// the primary plane. Arbitrary buffers can still be allocated and displayed as +// overlay planes, however the primary plane is associated with the native +// surface and is updated via an EGLSurface. +class GbmSurface : public GbmSurfaceless { public: - GbmSurface(gbm_device* device, DriWrapper* dri, const gfx::Size& size); - virtual ~GbmSurface(); - - // ScanoutSurface: - virtual bool Initialize() OVERRIDE; - virtual uint32_t GetFramebufferId() const OVERRIDE; - virtual uint32_t GetHandle() const OVERRIDE; - virtual gfx::Size Size() const OVERRIDE; - virtual void SwapBuffers() OVERRIDE; - - // Before scheduling the backbuffer to be scanned out we need to "lock" it. - // When we lock it, GBM will give a pointer to a buffer representing the - // backbuffer. It will also update its information on which buffers can not be - // used for drawing. The buffer will be released when the page flip event - // occurs (see SwapBuffers). This is called from GbmSurfaceFactory before - // scheduling a page flip. - void LockCurrentDrawable(); - - gbm_surface* native_surface() { return native_surface_; }; + GbmSurface(DriWindowDelegate* window_delegate, + gbm_device* device, + DriWrapper* dri); + ~GbmSurface() override; + + bool Initialize(); + + // GbmSurfaceless: + intptr_t GetNativeWindow() override; + bool ResizeNativeWindow(const gfx::Size& viewport_size) override; + bool OnSwapBuffers() override; private: gbm_device* gbm_device_; DriWrapper* dri_; - gfx::Size size_; - // The native GBM surface. In EGL this represents the EGLNativeWindowType. gbm_surface* native_surface_; - // Backing GBM buffers. One is the current front buffer. The other is the - // current backbuffer that is pending scan out. - gbm_bo* buffers_[2]; - - // Index to the front buffer. - int front_buffer_; + // Buffer currently used for scanout. + gbm_bo* current_buffer_; - // We can't lock (and get) an accelerated buffer from the GBM surface until - // after something draws into it. But modesetting needs to happen earlier, - // before an actual window is created and draws. So, we create a dumb buffer - // for this purpose. - scoped_ptr<DriBuffer> dumb_buffer_; + gfx::Size size_; DISALLOW_COPY_AND_ASSIGN(GbmSurface); }; diff --git a/chromium/ui/ozone/platform/dri/gbm_surface_factory.cc b/chromium/ui/ozone/platform/dri/gbm_surface_factory.cc index 5eb93fc427e..8d81c257e72 100644 --- a/chromium/ui/ozone/platform/dri/gbm_surface_factory.cc +++ b/chromium/ui/ozone/platform/dri/gbm_surface_factory.cc @@ -4,87 +4,88 @@ #include "ui/ozone/platform/dri/gbm_surface_factory.h" -#include <EGL/egl.h> #include <gbm.h> +#include "base/command_line.h" #include "base/files/file_path.h" -#include "ui/ozone/platform/dri/buffer_data.h" -#include "ui/ozone/platform/dri/dri_vsync_provider.h" +#include "third_party/khronos/EGL/egl.h" +#include "ui/ozone/platform/dri/dri_window_delegate_impl.h" +#include "ui/ozone/platform/dri/dri_window_delegate_manager.h" +#include "ui/ozone/platform/dri/gbm_buffer.h" #include "ui/ozone/platform/dri/gbm_surface.h" -#include "ui/ozone/platform/dri/hardware_display_controller.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/platform/dri/gbm_surfaceless.h" #include "ui/ozone/platform/dri/screen_manager.h" +#include "ui/ozone/public/native_pixmap.h" +#include "ui/ozone/public/overlay_candidates_ozone.h" +#include "ui/ozone/public/ozone_switches.h" #include "ui/ozone/public/surface_ozone_egl.h" namespace ui { - namespace { -class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL { +class SingleOverlay : public OverlayCandidatesOzone { public: - GbmSurfaceAdapter(const base::WeakPtr<HardwareDisplayController>& controller); - virtual ~GbmSurfaceAdapter(); - - // SurfaceOzoneEGL: - virtual intptr_t GetNativeWindow() OVERRIDE; - virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) OVERRIDE; - virtual bool OnSwapBuffers() OVERRIDE; - virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE; + SingleOverlay() {} + ~SingleOverlay() override {} + + void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) override { + if (candidates->size() == 2) { + OverlayCandidatesOzone::OverlaySurfaceCandidate* first = + &(*candidates)[0]; + OverlayCandidatesOzone::OverlaySurfaceCandidate* second = + &(*candidates)[1]; + OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay; + if (first->plane_z_order == 0) { + overlay = second; + } else if (second->plane_z_order == 0) { + overlay = first; + } else { + NOTREACHED(); + return; + } + if (overlay->plane_z_order > 0 && + IsTransformSupported(overlay->transform)) { + overlay->overlay_handled = true; + } + } + } private: - base::WeakPtr<HardwareDisplayController> controller_; + bool IsTransformSupported(gfx::OverlayTransform transform) { + switch (transform) { + case gfx::OVERLAY_TRANSFORM_NONE: + return true; + default: + return false; + } + } - DISALLOW_COPY_AND_ASSIGN(GbmSurfaceAdapter); + DISALLOW_COPY_AND_ASSIGN(SingleOverlay); }; -GbmSurfaceAdapter::GbmSurfaceAdapter( - const base::WeakPtr<HardwareDisplayController>& controller) - : controller_(controller) {} - -GbmSurfaceAdapter::~GbmSurfaceAdapter() {} - -intptr_t GbmSurfaceAdapter::GetNativeWindow() { - if (!controller_) - return 0; - - return reinterpret_cast<intptr_t>( - static_cast<GbmSurface*>(controller_->surface())->native_surface()); -} +} // namespace -bool GbmSurfaceAdapter::ResizeNativeWindow(const gfx::Size& viewport_size) { - NOTIMPLEMENTED(); - return false; +GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless) + : DriSurfaceFactory(NULL, NULL, NULL), + device_(NULL), + allow_surfaceless_(allow_surfaceless) { } -bool GbmSurfaceAdapter::OnSwapBuffers() { - if (!controller_) - return false; - - static_cast<GbmSurface*>(controller_->surface())->LockCurrentDrawable(); - if (controller_->SchedulePageFlip()) { - controller_->WaitForPageFlipEvent(); - return true; - } - - return false; -} +GbmSurfaceFactory::~GbmSurfaceFactory() {} -scoped_ptr<gfx::VSyncProvider> GbmSurfaceAdapter::CreateVSyncProvider() { - return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(controller_)); +void GbmSurfaceFactory::InitializeGpu( + DriWrapper* dri, + gbm_device* device, + ScreenManager* screen_manager, + DriWindowDelegateManager* window_manager) { + drm_ = dri; + device_ = device; + screen_manager_ = screen_manager; + window_manager_ = window_manager; } -} // namespace - -GbmSurfaceFactory::GbmSurfaceFactory(DriWrapper* dri, - gbm_device* device, - ScreenManager* screen_manager) - : DriSurfaceFactory(dri, screen_manager), - device_(device) {} - -GbmSurfaceFactory::~GbmSurfaceFactory() {} - intptr_t GbmSurfaceFactory::GetNativeDisplay() { - CHECK(state_ == INITIALIZED); + DCHECK(state_ == INITIALIZED); return reinterpret_cast<intptr_t>(device_); } @@ -143,45 +144,91 @@ bool GbmSurfaceFactory::LoadEGLGLES2Bindings( return true; } -scoped_ptr<ui::SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget( - gfx::AcceleratedWidget w) { - CHECK(state_ == INITIALIZED); - ResetCursor(w); +scoped_ptr<SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget( + gfx::AcceleratedWidget widget) { + DCHECK(state_ == INITIALIZED); - return scoped_ptr<ui::SurfaceOzoneEGL>( - new GbmSurfaceAdapter(screen_manager_->GetDisplayController(w))); + DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget); + + scoped_ptr<GbmSurface> surface(new GbmSurface(delegate, device_, drm_)); + if (!surface->Initialize()) + return nullptr; + + return surface.Pass(); +} + +scoped_ptr<SurfaceOzoneEGL> +GbmSurfaceFactory::CreateSurfacelessEGLSurfaceForWidget( + gfx::AcceleratedWidget widget) { + if (!allow_surfaceless_) + return scoped_ptr<SurfaceOzoneEGL>(); + + DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget); + return scoped_ptr<SurfaceOzoneEGL>(new GbmSurfaceless(delegate)); } -gfx::NativeBufferOzone GbmSurfaceFactory::CreateNativeBuffer( +scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap( gfx::Size size, BufferFormat format) { - uint32_t gbm_format = 0; - switch (format) { - case SurfaceFactoryOzone::UNKNOWN: - return 0; - // TODO(alexst): Setting this to XRGB for now to allow presentation - // as a primary plane but disallowing overlay transparency. Address this - // to allow both use cases. - case SurfaceFactoryOzone::RGBA_8888: - gbm_format = GBM_FORMAT_XRGB8888; - break; - case SurfaceFactoryOzone::RGB_888: - gbm_format = GBM_FORMAT_RGB888; - break; + scoped_refptr<GbmBuffer> buffer = GbmBuffer::CreateBuffer( + drm_, device_, format, size, true); + if (!buffer.get()) + return NULL; + + scoped_refptr<GbmPixmap> pixmap(new GbmPixmap(buffer)); + if (!pixmap->Initialize(drm_)) + return NULL; + + return pixmap; +} + +OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates( + gfx::AcceleratedWidget w) { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kOzoneTestSingleOverlaySupport)) + return new SingleOverlay(); + return NULL; +} + +bool GbmSurfaceFactory::ScheduleOverlayPlane( + gfx::AcceleratedWidget widget, + int plane_z_order, + gfx::OverlayTransform plane_transform, + scoped_refptr<NativePixmap> buffer, + const gfx::Rect& display_bounds, + const gfx::RectF& crop_rect) { + scoped_refptr<GbmPixmap> pixmap = static_cast<GbmPixmap*>(buffer.get()); + if (!pixmap.get()) { + LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer."; + return false; } - gbm_bo* buffer_object = - gbm_bo_create(device_, - size.width(), - size.height(), - gbm_format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - if (!buffer_object) - return 0; - - BufferData* data = BufferData::CreateData(drm_, buffer_object); - DCHECK(data) << "Failed to associate the buffer with the controller"; - - return reinterpret_cast<gfx::NativeBufferOzone>(buffer_object); + HardwareDisplayController* hdc = + window_manager_->GetWindowDelegate(widget)->GetController(); + if (!hdc) + return true; + + hdc->QueueOverlayPlane(OverlayPlane(pixmap->buffer(), + plane_z_order, + plane_transform, + display_bounds, + crop_rect)); + return true; +} + +bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() { + return allow_surfaceless_; +} + +DriWindowDelegate* GbmSurfaceFactory::GetOrCreateWindowDelegate( + gfx::AcceleratedWidget widget) { + if (!window_manager_->HasWindowDelegate(widget)) { + scoped_ptr<DriWindowDelegate> delegate( + new DriWindowDelegateImpl(widget, screen_manager_)); + delegate->Initialize(); + window_manager_->AddWindowDelegate(widget, delegate.Pass()); + } + + return window_manager_->GetWindowDelegate(widget); } } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/gbm_surface_factory.h b/chromium/ui/ozone/platform/dri/gbm_surface_factory.h index da624bf0875..a9455db0bca 100644 --- a/chromium/ui/ozone/platform/dri/gbm_surface_factory.h +++ b/chromium/ui/ozone/platform/dri/gbm_surface_factory.h @@ -11,28 +11,47 @@ struct gbm_device; namespace ui { +class DriWindowDelegate; +class DriWindowDelegateManager; + class GbmSurfaceFactory : public DriSurfaceFactory { public: - GbmSurfaceFactory(DriWrapper* dri, - gbm_device* device, - ScreenManager* screen_manager); - virtual ~GbmSurfaceFactory(); + GbmSurfaceFactory(bool allow_surfaceless); + ~GbmSurfaceFactory() override; + + void InitializeGpu(DriWrapper* dri, + gbm_device* device, + ScreenManager* screen_manager, + DriWindowDelegateManager* window_manager); // DriSurfaceFactory: - virtual intptr_t GetNativeDisplay() OVERRIDE; - virtual const int32_t* GetEGLSurfaceProperties( - const int32_t* desired_list) OVERRIDE; - virtual bool LoadEGLGLES2Bindings( + intptr_t GetNativeDisplay() override; + const int32_t* GetEGLSurfaceProperties(const int32_t* desired_list) override; + bool LoadEGLGLES2Bindings( AddGLLibraryCallback add_gl_library, - SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE; - virtual scoped_ptr<ui::SurfaceOzoneEGL> CreateEGLSurfaceForWidget( - gfx::AcceleratedWidget w) OVERRIDE; - virtual gfx::NativeBufferOzone CreateNativeBuffer( + SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; + scoped_ptr<ui::SurfaceOzoneEGL> CreateEGLSurfaceForWidget( + gfx::AcceleratedWidget w) override; + scoped_ptr<SurfaceOzoneEGL> CreateSurfacelessEGLSurfaceForWidget( + gfx::AcceleratedWidget widget) override; + scoped_refptr<ui::NativePixmap> CreateNativePixmap( gfx::Size size, - BufferFormat format) OVERRIDE; + BufferFormat format) override; + OverlayCandidatesOzone* GetOverlayCandidates( + gfx::AcceleratedWidget w) override; + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int plane_z_order, + gfx::OverlayTransform plane_transform, + scoped_refptr<NativePixmap> buffer, + const gfx::Rect& display_bounds, + const gfx::RectF& crop_rect) override; + bool CanShowPrimaryPlaneAsOverlay() override; private: + DriWindowDelegate* GetOrCreateWindowDelegate(gfx::AcceleratedWidget widget); + gbm_device* device_; // Not owned. + bool allow_surfaceless_; DISALLOW_COPY_AND_ASSIGN(GbmSurfaceFactory); }; diff --git a/chromium/ui/ozone/platform/dri/gbm_surfaceless.cc b/chromium/ui/ozone/platform/dri/gbm_surfaceless.cc new file mode 100644 index 00000000000..b3748445a36 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/gbm_surfaceless.cc @@ -0,0 +1,45 @@ +// 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/platform/dri/gbm_surfaceless.h" + +#include "ui/ozone/platform/dri/dri_vsync_provider.h" +#include "ui/ozone/platform/dri/dri_window_delegate.h" +#include "ui/ozone/platform/dri/gbm_buffer.h" +#include "ui/ozone/platform/dri/hardware_display_controller.h" + +namespace ui { + +GbmSurfaceless::GbmSurfaceless(DriWindowDelegate* window_delegate) + : window_delegate_(window_delegate) { +} + +GbmSurfaceless::~GbmSurfaceless() {} + +intptr_t GbmSurfaceless::GetNativeWindow() { + NOTREACHED(); + return 0; +} + +bool GbmSurfaceless::ResizeNativeWindow(const gfx::Size& viewport_size) { + NOTIMPLEMENTED(); + return false; +} + +bool GbmSurfaceless::OnSwapBuffers() { + HardwareDisplayController* controller = window_delegate_->GetController(); + if (!controller) + return true; + + bool success = controller->SchedulePageFlip(); + controller->WaitForPageFlipEvent(); + + return success; +} + +scoped_ptr<gfx::VSyncProvider> GbmSurfaceless::CreateVSyncProvider() { + return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(window_delegate_)); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/gbm_surfaceless.h b/chromium/ui/ozone/platform/dri/gbm_surfaceless.h new file mode 100644 index 00000000000..dd755e41c9a --- /dev/null +++ b/chromium/ui/ozone/platform/dri/gbm_surfaceless.h @@ -0,0 +1,41 @@ +// 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_PLATFORM_DRI_GBM_SURFACELESS_H_ +#define UI_OZONE_PLATFORM_DRI_GBM_SURFACELESS_H_ + +#include "ui/ozone/public/surface_ozone_egl.h" + +namespace gfx { +class Size; +} // namespace gfx + +namespace ui { + +class DriWindowDelegate; + +// In surfaceless mode drawing and displaying happens directly through +// NativePixmap buffers. CC would call into SurfaceFactoryOzone to allocate the +// buffers and then call ScheduleOverlayPlane(..) to schedule the buffer for +// presentation. +class GbmSurfaceless : public SurfaceOzoneEGL { + public: + GbmSurfaceless(DriWindowDelegate* window_delegate); + ~GbmSurfaceless() override; + + // SurfaceOzoneEGL: + intptr_t GetNativeWindow() override; + bool ResizeNativeWindow(const gfx::Size& viewport_size) override; + bool OnSwapBuffers() override; + scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override; + + protected: + DriWindowDelegate* window_delegate_; + + DISALLOW_COPY_AND_ASSIGN(GbmSurfaceless); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_GBM_SURFACELESS_H_ diff --git a/chromium/ui/ozone/platform/dri/hardware_cursor_delegate.h b/chromium/ui/ozone/platform/dri/hardware_cursor_delegate.h new file mode 100644 index 00000000000..ed2a348d31a --- /dev/null +++ b/chromium/ui/ozone/platform/dri/hardware_cursor_delegate.h @@ -0,0 +1,39 @@ +// 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_PLATFORM_DRI_HARDWARE_CURSOR_DELEGATE_H_ +#define UI_OZONE_PLATFORM_DRI_HARDWARE_CURSOR_DELEGATE_H_ + +#include <vector> + +#include "ui/gfx/native_widget_types.h" + +class SkBitmap; + +namespace gfx { +class Point; +} + +namespace ui { + +class HardwareCursorDelegate { + public: + // Update the HW cursor bitmap & move to specified location. If + // the bitmap is empty, the cursor is hidden. + virtual void SetHardwareCursor(gfx::AcceleratedWidget widget, + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& location, + int frame_delay_ms) = 0; + + // Move the HW cursor to the specified location. + virtual void MoveHardwareCursor(gfx::AcceleratedWidget widget, + const gfx::Point& location) = 0; + + protected: + virtual ~HardwareCursorDelegate() {} +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_HARDWARE_CURSOR_DELEGATE_H_ diff --git a/chromium/ui/ozone/platform/dri/hardware_display_controller.cc b/chromium/ui/ozone/platform/dri/hardware_display_controller.cc index 4b00c6efdc0..054e726a447 100644 --- a/chromium/ui/ozone/platform/dri/hardware_display_controller.cc +++ b/chromium/ui/ozone/platform/dri/hardware_display_controller.cc @@ -12,13 +12,13 @@ #include "base/basictypes.h" #include "base/debug/trace_event.h" #include "base/logging.h" -#include "base/time/time.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" +#include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_wrapper.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/public/native_pixmap.h" namespace ui { @@ -39,130 +39,180 @@ void HandlePageFlipEvent(int fd, unsigned int seconds, unsigned int useconds, void* controller) { - TRACE_EVENT0("dri", "HandlePageFlipEvent"); - static_cast<HardwareDisplayController*>(controller) + static_cast<CrtcController*>(controller) ->OnPageFlipEvent(frame, seconds, useconds); } } // namespace HardwareDisplayController::HardwareDisplayController( - DriWrapper* drm, - uint32_t connector_id, - uint32_t crtc_id) - : drm_(drm), - connector_id_(connector_id), - crtc_id_(crtc_id), - surface_(), - time_of_last_flip_(0), - is_disabled_(true) {} + scoped_ptr<CrtcController> controller) + : is_disabled_(true) { + crtc_controllers_.push_back(controller.release()); +} HardwareDisplayController::~HardwareDisplayController() { // Reset the cursor. UnsetCursor(); - UnbindSurfaceFromController(); -} - -bool -HardwareDisplayController::BindSurfaceToController( - scoped_ptr<ScanoutSurface> surface, drmModeModeInfo mode) { - CHECK(surface); - - if (!drm_->SetCrtc(crtc_id_, - surface->GetFramebufferId(), - &connector_id_, - &mode)) { - LOG(ERROR) << "Failed to modeset: error='" << strerror(errno) - << "' crtc=" << crtc_id_ << " connector=" << connector_id_ - << " framebuffer_id=" << surface->GetFramebufferId() - << " mode=" << mode.hdisplay << "x" << mode.vdisplay << "@" - << mode.vrefresh; - return false; - } - - surface_.reset(surface.release()); - mode_ = mode; - is_disabled_ = false; - return true; } -void HardwareDisplayController::UnbindSurfaceFromController() { - drm_->SetCrtc(crtc_id_, 0, 0, NULL); - surface_.reset(); - memset(&mode_, 0, sizeof(mode_)); - is_disabled_ = true; +bool HardwareDisplayController::Modeset(const OverlayPlane& primary, + drmModeModeInfo mode) { + TRACE_EVENT0("dri", "HDC::Modeset"); + DCHECK(primary.buffer.get()); + bool status = true; + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + status &= crtc_controllers_[i]->Modeset(primary, mode); + + current_planes_ = std::vector<OverlayPlane>(1, primary); + pending_planes_.clear(); + is_disabled_ = false; + mode_ = mode; + return status; } bool HardwareDisplayController::Enable() { - CHECK(surface_); - if (is_disabled_) { - scoped_ptr<ScanoutSurface> surface(surface_.release()); - return BindSurfaceToController(surface.Pass(), mode_); - } - - return true; + TRACE_EVENT0("dri", "HDC::Enable"); + DCHECK(!current_planes_.empty()); + OverlayPlane primary = OverlayPlane::GetPrimaryPlane(current_planes_); + DCHECK(primary.buffer.get()); + bool status = true; + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + status &= crtc_controllers_[i]->Modeset(primary, mode_); + + return status; } void HardwareDisplayController::Disable() { - drm_->SetCrtc(crtc_id_, 0, 0, NULL); + TRACE_EVENT0("dri", "HDC::Disable"); + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + crtc_controllers_[i]->Disable(); + is_disabled_ = true; } +void HardwareDisplayController::QueueOverlayPlane(const OverlayPlane& plane) { + pending_planes_.push_back(plane); +} + bool HardwareDisplayController::SchedulePageFlip() { - CHECK(surface_); - if (!is_disabled_ && !drm_->PageFlip(crtc_id_, - surface_->GetFramebufferId(), - this)) { - LOG(ERROR) << "Cannot page flip: " << strerror(errno); - return false; - } + DCHECK(!pending_planes_.empty()); + + if (is_disabled_) + return true; - return true; + bool status = true; + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + status &= crtc_controllers_[i]->SchedulePageFlip(pending_planes_); + + return status; } void HardwareDisplayController::WaitForPageFlipEvent() { - TRACE_EVENT0("dri", "WaitForPageFlipEvent"); - - if (is_disabled_) - return; + TRACE_EVENT0("dri", "HDC::WaitForPageFlipEvent"); drmEventContext drm_event; drm_event.version = DRM_EVENT_CONTEXT_VERSION; drm_event.page_flip_handler = HandlePageFlipEvent; drm_event.vblank_handler = NULL; - // Wait for the page-flip to complete. - drm_->HandleEvent(drm_event); -} + bool has_pending_page_flips = false; + // Wait for the page-flips to complete. + for (size_t i = 0; i < crtc_controllers_.size(); ++i) { + // In mirror mode the page flip callbacks can happen in different order than + // scheduled, so we need to make sure that the event for the current CRTC is + // processed before moving to the next CRTC. + while (crtc_controllers_[i]->page_flip_pending()) { + has_pending_page_flips = true; + crtc_controllers_[i]->drm()->HandleEvent(drm_event); + } + } -void HardwareDisplayController::OnPageFlipEvent(unsigned int frame, - unsigned int seconds, - unsigned int useconds) { - time_of_last_flip_ = - static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + - useconds; + // In case there are no pending pageflips do not replace the current planes + // since they are still being used. + if (has_pending_page_flips) + current_planes_.swap(pending_planes_); - surface_->SwapBuffers(); + pending_planes_.clear(); } -bool HardwareDisplayController::SetCursor(ScanoutSurface* surface) { - bool ret = drm_->SetCursor(crtc_id_, - surface->GetHandle(), - surface->Size().width(), - surface->Size().height()); - surface->SwapBuffers(); - return ret; +bool HardwareDisplayController::SetCursor( + const scoped_refptr<ScanoutBuffer>& buffer) { + bool status = true; + + if (is_disabled_) + return true; + + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + status &= crtc_controllers_[i]->SetCursor(buffer); + + return status; } bool HardwareDisplayController::UnsetCursor() { - return drm_->SetCursor(crtc_id_, 0, 0, 0); + bool status = true; + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + status &= crtc_controllers_[i]->UnsetCursor(); + + return status; } bool HardwareDisplayController::MoveCursor(const gfx::Point& location) { if (is_disabled_) return true; - return drm_->MoveCursor(crtc_id_, location.x(), location.y()); + bool status = true; + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + status &= crtc_controllers_[i]->MoveCursor(location); + + return status; +} + +void HardwareDisplayController::AddCrtc(scoped_ptr<CrtcController> controller) { + crtc_controllers_.push_back(controller.release()); +} + +scoped_ptr<CrtcController> HardwareDisplayController::RemoveCrtc( + uint32_t crtc) { + for (ScopedVector<CrtcController>::iterator it = crtc_controllers_.begin(); + it != crtc_controllers_.end(); ++it) { + if ((*it)->crtc() == crtc) { + scoped_ptr<CrtcController> controller(*it); + crtc_controllers_.weak_erase(it); + return controller.Pass(); + } + } + + return scoped_ptr<CrtcController>(); +} + +bool HardwareDisplayController::HasCrtc(uint32_t crtc) const { + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + if (crtc_controllers_[i]->crtc() == crtc) + return true; + + return false; +} + +bool HardwareDisplayController::IsMirrored() const { + return crtc_controllers_.size() > 1; +} + +bool HardwareDisplayController::IsDisabled() const { + return is_disabled_; +} + +gfx::Size HardwareDisplayController::GetModeSize() const { + return gfx::Size(mode_.hdisplay, mode_.vdisplay); +} + +uint64_t HardwareDisplayController::GetTimeOfLastFlip() const { + uint64_t time = 0; + for (size_t i = 0; i < crtc_controllers_.size(); ++i) + if (time < crtc_controllers_[i]->time_of_last_flip()) + time = crtc_controllers_[i]->time_of_last_flip(); + + return time; } } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/hardware_display_controller.h b/chromium/ui/ozone/platform/dri/hardware_display_controller.h index b6ac900c44d..3a948f63b29 100644 --- a/chromium/ui/ozone/platform/dri/hardware_display_controller.h +++ b/chromium/ui/ozone/platform/dri/hardware_display_controller.h @@ -12,9 +12,9 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" -#include "ui/ozone/ozone_export.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/overlay_plane.h" namespace gfx { class Point; @@ -22,7 +22,8 @@ class Point; namespace ui { -class ScanoutSurface; +class CrtcController; +class ScanoutBuffer; // The HDCOz will handle modesettings and scannout operations for hardware // devices. @@ -78,23 +79,16 @@ class ScanoutSurface; // only a subset of connectors can be active independently, showing different // framebuffers. Though, in this case, it would be possible to have all // connectors active if some use the same CRTC to mirror the display. -// -// TODO(dnicoara) Need to have a way to detect events (such as monitor -// connected or disconnected). -class OZONE_EXPORT HardwareDisplayController +class HardwareDisplayController : public base::SupportsWeakPtr<HardwareDisplayController> { public: - HardwareDisplayController(DriWrapper* drm, - uint32_t connector_id, - uint32_t crtc_id); - + explicit HardwareDisplayController(scoped_ptr<CrtcController> controller); ~HardwareDisplayController(); - // Associate the HDCO with a surface implementation and initialize it. - bool BindSurfaceToController(scoped_ptr<ScanoutSurface> surface, - drmModeModeInfo mode); - - void UnbindSurfaceFromController(); + // Performs the initial CRTC configuration. If successful, it will display the + // framebuffer for |primary| with |mode|. + bool Modeset(const OverlayPlane& primary, + drmModeModeInfo mode); // Reconfigures the CRTC with the current surface and mode. bool Enable(); @@ -102,14 +96,16 @@ class OZONE_EXPORT HardwareDisplayController // Disables the CRTC. void Disable(); - // Schedules the |surface_|'s framebuffer to be displayed on the next vsync + void QueueOverlayPlane(const OverlayPlane& plane); + + // Schedules the |overlays|' framebuffers to be displayed on the next vsync // event. The event will be posted on the graphics card file descriptor |fd_| // and it can be read and processed by |drmHandleEvent|. That function can // define the callback for the page flip event. A generic data argument will // be presented to the callback. We use that argument to pass in the HDCO // object the event belongs to. // - // Between this call and the callback, the framebuffer used in this call + // Between this call and the callback, the framebuffers used in this call // should not be modified in any way as it would cause screen tearing if the // hardware performed the flip. Note that the frontbuffer should also not // be modified as it could still be displayed. @@ -124,54 +120,45 @@ class OZONE_EXPORT HardwareDisplayController // BeginFrame can be triggered explicitly by Ozone. void WaitForPageFlipEvent(); - // 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); - // Set the hardware cursor to show the contents of |surface|. - bool SetCursor(ScanoutSurface* surface); + bool SetCursor(const scoped_refptr<ScanoutBuffer>& buffer); bool UnsetCursor(); // Moves the hardware cursor to |location|. bool MoveCursor(const gfx::Point& location); + void AddCrtc(scoped_ptr<CrtcController> controller); + scoped_ptr<CrtcController> RemoveCrtc(uint32_t crtc); + bool HasCrtc(uint32_t crtc) const; + bool IsMirrored() const; + bool IsDisabled() const; + gfx::Size GetModeSize() const; + + gfx::Point origin() const { return origin_; } + void set_origin(const gfx::Point& origin) { origin_ = origin; } + const drmModeModeInfo& get_mode() const { return mode_; }; - uint32_t connector_id() const { return connector_id_; } - uint32_t crtc_id() const { return crtc_id_; } - ScanoutSurface* surface() const { - return surface_.get(); - }; - uint64_t get_time_of_last_flip() const { - return time_of_last_flip_; - }; + uint64_t GetTimeOfLastFlip() const; private: - // Object containing the connection to the graphics device and wraps the API - // calls to control it. - DriWrapper* drm_; + // Buffers need to be declared first so that they are destroyed last. Needed + // since the controllers may reference the buffers. + OverlayPlaneList current_planes_; + OverlayPlaneList pending_planes_; + scoped_refptr<ScanoutBuffer> cursor_buffer_; - // TODO(dnicoara) Need to allow a CRTC to have multiple connectors. - uint32_t connector_id_; + // Stores the CRTC configuration. This is used to identify monitors and + // configure them. + ScopedVector<CrtcController> crtc_controllers_; - uint32_t crtc_id_; + // Location of the controller on the screen. + gfx::Point origin_; - // TODO(dnicoara) Need to store all the modes. + // The mode used by the last modesetting operation. drmModeModeInfo mode_; - scoped_ptr<ScanoutSurface> surface_; - - uint64_t time_of_last_flip_; - - // Keeps track of the CRTC state. If a surface has been bound, then the value - // is set to false. Otherwise it is true. bool is_disabled_; DISALLOW_COPY_AND_ASSIGN(HardwareDisplayController); diff --git a/chromium/ui/ozone/platform/dri/hardware_display_controller_unittest.cc b/chromium/ui/ozone/platform/dri/hardware_display_controller_unittest.cc index 25169453b2d..5a71d01214a 100644 --- a/chromium/ui/ozone/platform/dri/hardware_display_controller_unittest.cc +++ b/chromium/ui/ozone/platform/dri/hardware_display_controller_unittest.cc @@ -4,12 +4,12 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_buffer.h" -#include "ui/ozone/platform/dri/dri_surface.h" #include "ui/ozone/platform/dri/dri_wrapper.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" -#include "ui/ozone/platform/dri/test/mock_dri_surface.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include "ui/ozone/public/native_pixmap.h" namespace { @@ -17,17 +17,41 @@ namespace { const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; +const uint32_t kPrimaryCrtc = 1; +const uint32_t kPrimaryConnector = 2; +const uint32_t kSecondaryCrtc = 3; +const uint32_t kSecondaryConnector = 4; + const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay); +const gfx::SizeF kDefaultModeSizeF(1.0, 1.0); + +class MockScanoutBuffer : public ui::ScanoutBuffer { + public: + MockScanoutBuffer(const gfx::Size& size) : size_(size) {} + + // ScanoutBuffer: + uint32_t GetFramebufferId() const override { return 0; } + uint32_t GetHandle() const override { return 0; } + gfx::Size GetSize() const override { return size_; } + + private: + ~MockScanoutBuffer() override {} + + gfx::Size size_; + + DISALLOW_COPY_AND_ASSIGN(MockScanoutBuffer); +}; } // namespace class HardwareDisplayControllerTest : public testing::Test { public: HardwareDisplayControllerTest() {} - virtual ~HardwareDisplayControllerTest() {} + ~HardwareDisplayControllerTest() override {} + + void SetUp() override; + void TearDown() override; - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; protected: scoped_ptr<ui::HardwareDisplayController> controller_; scoped_ptr<ui::MockDriWrapper> drm_; @@ -38,7 +62,9 @@ class HardwareDisplayControllerTest : public testing::Test { void HardwareDisplayControllerTest::SetUp() { drm_.reset(new ui::MockDriWrapper(3)); - controller_.reset(new ui::HardwareDisplayController(drm_.get(), 1, 1)); + controller_.reset(new ui::HardwareDisplayController( + scoped_ptr<ui::CrtcController>(new ui::CrtcController( + drm_.get(), kPrimaryCrtc, kPrimaryConnector)))); } void HardwareDisplayControllerTest::TearDown() { @@ -46,67 +72,149 @@ void HardwareDisplayControllerTest::TearDown() { drm_.reset(); } -TEST_F(HardwareDisplayControllerTest, CheckStateAfterSurfaceIsBound) { - scoped_ptr<ui::ScanoutSurface> surface( - new ui::MockDriSurface(drm_.get(), kDefaultModeSize)); +TEST_F(HardwareDisplayControllerTest, CheckModesettingResult) { + ui::OverlayPlane plane(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); - EXPECT_TRUE(surface->Initialize()); - EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), - kDefaultMode)); - EXPECT_TRUE(controller_->surface() != NULL); + EXPECT_TRUE(controller_->Modeset(plane, kDefaultMode)); + EXPECT_FALSE(plane.buffer->HasOneRef()); } TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) { - scoped_ptr<ui::ScanoutSurface> surface( - new ui::MockDriSurface(drm_.get(), kDefaultModeSize)); + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); - EXPECT_TRUE(surface->Initialize()); - EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), - kDefaultMode)); + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + + ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + controller_->QueueOverlayPlane(plane2); EXPECT_TRUE(controller_->SchedulePageFlip()); - EXPECT_TRUE(controller_->surface() != NULL); + controller_->WaitForPageFlipEvent(); + EXPECT_TRUE(plane1.buffer->HasOneRef()); + EXPECT_FALSE(plane2.buffer->HasOneRef()); + + EXPECT_EQ(1, drm_->get_page_flip_call_count()); + EXPECT_EQ(0, drm_->get_overlay_flip_call_count()); } TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) { drm_->set_set_crtc_expectation(false); - scoped_ptr<ui::ScanoutSurface> surface( - new ui::MockDriSurface(drm_.get(), kDefaultModeSize)); + ui::OverlayPlane plane(scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer( + kDefaultModeSize))); - EXPECT_TRUE(surface->Initialize()); - EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass(), - kDefaultMode)); - EXPECT_EQ(NULL, controller_->surface()); + EXPECT_FALSE(controller_->Modeset(plane, kDefaultMode)); } TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) { drm_->set_page_flip_expectation(false); - scoped_ptr<ui::ScanoutSurface> surface( - new ui::MockDriSurface(drm_.get(), kDefaultModeSize)); + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - EXPECT_TRUE(surface->Initialize()); - EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), - kDefaultMode)); + ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + controller_->QueueOverlayPlane(plane2); EXPECT_FALSE(controller_->SchedulePageFlip()); + EXPECT_FALSE(plane1.buffer->HasOneRef()); + EXPECT_FALSE(plane2.buffer->HasOneRef()); + + controller_->WaitForPageFlipEvent(); + EXPECT_FALSE(plane1.buffer->HasOneRef()); + EXPECT_TRUE(plane2.buffer->HasOneRef()); } TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) { - scoped_ptr<ui::ScanoutSurface> surface( - new ui::MockDriSurface(drm_.get(), kDefaultModeSize)); + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); - EXPECT_TRUE(surface->Initialize()); - EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), - kDefaultMode)); + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); controller_->Disable(); + ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + controller_->QueueOverlayPlane(plane2); EXPECT_TRUE(controller_->SchedulePageFlip()); + controller_->WaitForPageFlipEvent(); EXPECT_EQ(0, drm_->get_page_flip_call_count()); - surface.reset(new ui::MockDriSurface(drm_.get(), kDefaultModeSize)); + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + controller_->QueueOverlayPlane(plane2); + EXPECT_TRUE(controller_->SchedulePageFlip()); + controller_->WaitForPageFlipEvent(); + EXPECT_EQ(1, drm_->get_page_flip_call_count()); +} + +TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) { + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + ui::OverlayPlane plane2( + scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer(kDefaultModeSize)), + 1, + gfx::OVERLAY_TRANSFORM_NONE, + gfx::Rect(kDefaultModeSize), + gfx::RectF(kDefaultModeSizeF)); + plane2.overlay_plane = 1; // Force association with a plane. + + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + + controller_->QueueOverlayPlane(plane1); + controller_->QueueOverlayPlane(plane2); - EXPECT_TRUE(surface->Initialize()); - EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(), - kDefaultMode)); EXPECT_TRUE(controller_->SchedulePageFlip()); + controller_->WaitForPageFlipEvent(); EXPECT_EQ(1, drm_->get_page_flip_call_count()); + EXPECT_EQ(1, drm_->get_overlay_flip_call_count()); +} + +TEST_F(HardwareDisplayControllerTest, PageflipMirroredControllers) { + controller_->AddCrtc(scoped_ptr<ui::CrtcController>( + new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector))); + + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + EXPECT_EQ(2, drm_->get_set_crtc_call_count()); + + ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + controller_->QueueOverlayPlane(plane2); + EXPECT_TRUE(controller_->SchedulePageFlip()); + EXPECT_EQ(2, drm_->get_page_flip_call_count()); + + controller_->WaitForPageFlipEvent(); + EXPECT_EQ(2, drm_->get_handle_events_count()); +} + +TEST_F(HardwareDisplayControllerTest, + PageflipMirroredControllersWithInvertedCrtcOrder) { + scoped_ptr<ui::CrtcController> crtc1( + new ui::CrtcController(drm_.get(), kPrimaryCrtc, kPrimaryConnector)); + scoped_ptr<ui::CrtcController> crtc2( + new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector)); + + // Make sure that if the order is reversed everything is still fine. + std::queue<ui::CrtcController*> crtc_queue; + crtc_queue.push(crtc2.get()); + crtc_queue.push(crtc1.get()); + + controller_.reset(new ui::HardwareDisplayController(crtc1.Pass())); + controller_->AddCrtc(crtc2.Pass()); + + ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + EXPECT_EQ(2, drm_->get_set_crtc_call_count()); + + ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( + new MockScanoutBuffer(kDefaultModeSize))); + controller_->QueueOverlayPlane(plane2); + EXPECT_TRUE(controller_->SchedulePageFlip()); + EXPECT_EQ(2, drm_->get_page_flip_call_count()); + + drm_->set_controllers(crtc_queue); + controller_->WaitForPageFlipEvent(); + EXPECT_EQ(2, drm_->get_handle_events_count()); } diff --git a/chromium/ui/ozone/platform/dri/hardware_display_plane.cc b/chromium/ui/ozone/platform/dri/hardware_display_plane.cc new file mode 100644 index 00000000000..61743dc0b24 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/hardware_display_plane.cc @@ -0,0 +1,130 @@ +// 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/platform/dri/hardware_display_plane.h" + +#include <drm.h> +#include <errno.h> +#include <xf86drm.h> + +#include "base/logging.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" + +namespace ui { + +namespace { +const char* kCrtcPropName = "CRTC_ID"; +const char* kFbPropName = "FB_ID"; +const char* kCrtcXPropName = "CRTC_X"; +const char* kCrtcYPropName = "CRTC_Y"; +const char* kCrtcWPropName = "CRTC_W"; +const char* kCrtcHPropName = "CRTC_H"; +const char* kSrcXPropName = "SRC_X"; +const char* kSrcYPropName = "SRC_Y"; +const char* kSrcWPropName = "SRC_W"; +const char* kSrcHPropName = "SRC_H"; +} + +HardwareDisplayPlane::Property::Property() : id_(0) { +} + +bool HardwareDisplayPlane::Property::Initialize( + DriWrapper* drm, + const char* name, + const ScopedDrmObjectPropertyPtr& plane_props) { + for (uint32_t i = 0; i < plane_props->count_props; i++) { + ScopedDrmPropertyPtr property( + drmModeGetProperty(drm->get_fd(), plane_props->props[i])); + if (!strcmp(property->name, name)) { + id_ = property->prop_id; + break; + } + } + if (!id_) { + LOG(ERROR) << "Could not find property " << name; + return false; + } + return true; +} + +HardwareDisplayPlane::HardwareDisplayPlane( + DriWrapper* drm, + drmModePropertySetPtr atomic_property_set, + ScopedDrmPlanePtr plane) + : drm_(drm), + property_set_(atomic_property_set), + plane_(plane.Pass()), + plane_id_(plane_->plane_id) { +} + +HardwareDisplayPlane::~HardwareDisplayPlane() { +} + +bool HardwareDisplayPlane::CanUseForCrtc(uint32_t crtc_id) { + return plane_->possible_crtcs & (1 << crtc_id); +} + +bool HardwareDisplayPlane::SetPlaneData(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& crtc_rect, + const gfx::Rect& src_rect) { + int plane_set_error = + drmModePropertySetAdd( + property_set_, plane_id_, crtc_prop_.id_, crtc_id) || + drmModePropertySetAdd( + property_set_, plane_id_, fb_prop_.id_, framebuffer) || + drmModePropertySetAdd( + property_set_, plane_id_, crtc_x_prop_.id_, crtc_rect.x()) || + drmModePropertySetAdd( + property_set_, plane_id_, crtc_y_prop_.id_, crtc_rect.y()) || + drmModePropertySetAdd( + property_set_, plane_id_, crtc_w_prop_.id_, crtc_rect.width()) || + drmModePropertySetAdd( + property_set_, plane_id_, crtc_h_prop_.id_, crtc_rect.height()) || + drmModePropertySetAdd( + property_set_, plane_id_, src_x_prop_.id_, src_rect.x()) || + drmModePropertySetAdd( + property_set_, plane_id_, src_y_prop_.id_, src_rect.x()) || + drmModePropertySetAdd( + property_set_, plane_id_, src_w_prop_.id_, src_rect.width()) || + drmModePropertySetAdd( + property_set_, plane_id_, src_h_prop_.id_, src_rect.height()); + + if (plane_set_error) { + LOG(ERROR) << "Failed to set plane data"; + return false; + } + return true; +} + +bool HardwareDisplayPlane::Initialize() { + ScopedDrmObjectPropertyPtr plane_props(drmModeObjectGetProperties( + drm_->get_fd(), plane_id_, DRM_MODE_OBJECT_PLANE)); + + if (!plane_props) { + LOG(ERROR) << "Unable to get plane properties."; + return false; + } + + bool props_init = + crtc_prop_.Initialize(drm_, kCrtcPropName, plane_props) && + fb_prop_.Initialize(drm_, kFbPropName, plane_props) && + crtc_x_prop_.Initialize(drm_, kCrtcXPropName, plane_props) && + crtc_y_prop_.Initialize(drm_, kCrtcYPropName, plane_props) && + crtc_w_prop_.Initialize(drm_, kCrtcWPropName, plane_props) && + crtc_h_prop_.Initialize(drm_, kCrtcHPropName, plane_props) && + src_x_prop_.Initialize(drm_, kSrcXPropName, plane_props) && + src_y_prop_.Initialize(drm_, kSrcYPropName, plane_props) && + src_w_prop_.Initialize(drm_, kSrcWPropName, plane_props) && + src_h_prop_.Initialize(drm_, kSrcHPropName, plane_props); + + if (!props_init) { + LOG(ERROR) << "Unable to get plane properties."; + return false; + } + return true; +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/hardware_display_plane.h b/chromium/ui/ozone/platform/dri/hardware_display_plane.h new file mode 100644 index 00000000000..dd79f768023 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/hardware_display_plane.h @@ -0,0 +1,77 @@ +// 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_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_H_ +#define UI_OZONE_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_H_ + +#include <stddef.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "base/basictypes.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" + +namespace gfx { +class Rect; +} + +namespace ui { + +class DriWrapper; + +class HardwareDisplayPlane { + public: + HardwareDisplayPlane(DriWrapper* drm, + drmModePropertySetPtr atomic_property_set, + ScopedDrmPlanePtr plane); + + ~HardwareDisplayPlane(); + + bool Initialize(); + + bool CanUseForCrtc(uint32_t crtc_id); + bool SetPlaneData(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& crtc_rect, + const gfx::Rect& src_rect); + + bool in_use() const { return in_use_; } + void set_in_use(bool in_use) { in_use_ = in_use; } + + private: + struct Property { + Property(); + bool Initialize(DriWrapper* drm, + const char* name, + const ScopedDrmObjectPropertyPtr& plane_properties); + uint32_t id_; + }; + // Object containing the connection to the graphics device and wraps the API + // calls to control it. + DriWrapper* drm_; + + // Not owned. + drmModePropertySetPtr property_set_; + + ScopedDrmPlanePtr plane_; + uint32_t plane_id_; + bool in_use_; + + Property crtc_prop_; + Property fb_prop_; + Property crtc_x_prop_; + Property crtc_y_prop_; + Property crtc_w_prop_; + Property crtc_h_prop_; + Property src_x_prop_; + Property src_y_prop_; + Property src_w_prop_; + Property src_h_prop_; + + DISALLOW_COPY_AND_ASSIGN(HardwareDisplayPlane); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_H_ diff --git a/chromium/ui/ozone/platform/dri/hardware_display_plane_manager.cc b/chromium/ui/ozone/platform/dri/hardware_display_plane_manager.cc new file mode 100644 index 00000000000..0e9bc999b76 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/hardware_display_plane_manager.cc @@ -0,0 +1,57 @@ +// 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/platform/dri/hardware_display_plane_manager.h" + +#include <drm.h> +#include <errno.h> +#include <xf86drm.h> + +#include "base/logging.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" + +namespace ui { + +HardwareDisplayPlaneManager::HardwareDisplayPlaneManager(DriWrapper* drm) + : drm_(drm), property_set_(NULL) { +} + +HardwareDisplayPlaneManager::~HardwareDisplayPlaneManager() { + if (property_set_) + drmModePropertySetFree(property_set_); +} + +bool HardwareDisplayPlaneManager::Initialize() { + ScopedDrmPlaneResPtr plane_resources( + drmModeGetPlaneResources(drm_->get_fd())); + if (!plane_resources) { + LOG(ERROR) << "Failed to get plane resources."; + return false; + } + + property_set_ = drmModePropertySetAlloc(); + if (!property_set_) { + LOG(ERROR) << "Failed to allocate property set."; + return false; + } + + uint32_t num_planes = plane_resources->count_planes; + for (uint32_t i = 0; i < num_planes; ++i) { + ScopedDrmPlanePtr drm_plane( + drmModeGetPlane(drm_->get_fd(), plane_resources->planes[i])); + if (!drm_plane) { + LOG(ERROR) << "Failed to get plane " << i << "."; + return false; + } + scoped_ptr<HardwareDisplayPlane> plane( + new HardwareDisplayPlane(drm_, property_set_, drm_plane.Pass())); + if (plane->Initialize()) + planes_.push_back(plane.release()); + } + + return true; +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/hardware_display_plane_manager.h b/chromium/ui/ozone/platform/dri/hardware_display_plane_manager.h new file mode 100644 index 00000000000..b6862e33d3b --- /dev/null +++ b/chromium/ui/ozone/platform/dri/hardware_display_plane_manager.h @@ -0,0 +1,49 @@ +// 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_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_MANAGER_H_ +#define UI_OZONE_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_MANAGER_H_ + +#include <stddef.h> +#include <stdint.h> +#include <xf86drmMode.h> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/scoped_vector.h" +#include "ui/ozone/platform/dri/hardware_display_plane.h" +#include "ui/ozone/platform/dri/scoped_drm_types.h" + +namespace gfx { +class Rect; +} // namespace gfx + +namespace ui { + +class DriWrapper; + +class HardwareDisplayPlaneManager { + public: + HardwareDisplayPlaneManager(DriWrapper* drm); + + ~HardwareDisplayPlaneManager(); + + bool Initialize(); + + const ScopedVector<HardwareDisplayPlane>& get_planes() { return planes_; } + + private: + // Object containing the connection to the graphics device and wraps the API + // calls to control it. + DriWrapper* drm_; + + drmModePropertySetPtr property_set_; + ScopedVector<HardwareDisplayPlane> planes_; + + DISALLOW_COPY_AND_ASSIGN(HardwareDisplayPlaneManager); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_MANAGER_H_ diff --git a/chromium/ui/ozone/platform/dri/native_display_delegate_dri.cc b/chromium/ui/ozone/platform/dri/native_display_delegate_dri.cc new file mode 100644 index 00000000000..b635ce8c9f9 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/native_display_delegate_dri.cc @@ -0,0 +1,345 @@ +// 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/platform/dri/native_display_delegate_dri.h" + +#include "base/bind.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "ui/display/types/native_display_observer.h" +#include "ui/events/ozone/device/device_event.h" +#include "ui/events/ozone/device/device_manager.h" +#include "ui/ozone/platform/dri/display_mode_dri.h" +#include "ui/ozone/platform/dri/display_snapshot_dri.h" +#include "ui/ozone/platform/dri/dri_console_buffer.h" +#include "ui/ozone/platform/dri/dri_util.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/screen_manager.h" + +namespace ui { + +namespace { + +const size_t kMaxDisplayCount = 2; + +const char kContentProtection[] = "Content Protection"; + +struct ContentProtectionMapping { + const char* name; + HDCPState state; +}; + +const ContentProtectionMapping kContentProtectionStates[] = { + {"Undesired", HDCP_STATE_UNDESIRED}, + {"Desired", HDCP_STATE_DESIRED}, + {"Enabled", HDCP_STATE_ENABLED}}; + +uint32_t GetContentProtectionValue(drmModePropertyRes* property, + HDCPState state) { + std::string name; + for (size_t i = 0; i < arraysize(kContentProtectionStates); ++i) { + if (kContentProtectionStates[i].state == state) { + name = kContentProtectionStates[i].name; + break; + } + } + + for (int i = 0; i < property->count_enums; ++i) + if (name == property->enums[i].name) + return i; + + NOTREACHED(); + return 0; +} + +class DisplaySnapshotComparator { + public: + DisplaySnapshotComparator(const DisplaySnapshotDri* snapshot) + : snapshot_(snapshot) {} + + bool operator()(const DisplaySnapshotDri* other) const { + if (snapshot_->connector() == other->connector() && + snapshot_->crtc() == other->crtc()) + return true; + + return false; + } + + private: + const DisplaySnapshotDri* snapshot_; +}; + +} // namespace + +NativeDisplayDelegateDri::NativeDisplayDelegateDri( + DriWrapper* dri, + ScreenManager* screen_manager, + DeviceManager* device_manager) + : dri_(dri), + screen_manager_(screen_manager), + device_manager_(device_manager) { + // TODO(dnicoara): Remove when async display configuration is supported. + screen_manager_->ForceInitializationOfPrimaryDisplay(); +} + +NativeDisplayDelegateDri::~NativeDisplayDelegateDri() { + if (device_manager_) + device_manager_->RemoveObserver(this); +} + +DisplaySnapshot* NativeDisplayDelegateDri::FindDisplaySnapshot(int64_t id) { + for (size_t i = 0; i < cached_displays_.size(); ++i) + if (cached_displays_[i]->display_id() == id) + return cached_displays_[i]; + + return NULL; +} + +const DisplayMode* NativeDisplayDelegateDri::FindDisplayMode( + const gfx::Size& size, + bool is_interlaced, + float refresh_rate) { + for (size_t i = 0; i < cached_modes_.size(); ++i) + if (cached_modes_[i]->size() == size && + cached_modes_[i]->is_interlaced() == is_interlaced && + cached_modes_[i]->refresh_rate() == refresh_rate) + return cached_modes_[i]; + + return NULL; +} + +void NativeDisplayDelegateDri::Initialize() { + if (device_manager_) + device_manager_->AddObserver(this); + + ScopedVector<HardwareDisplayControllerInfo> displays = + GetAvailableDisplayControllerInfos(dri_->get_fd()); + + // By default all displays show the same console buffer. + console_buffer_.reset( + new DriConsoleBuffer(dri_, displays[0]->crtc()->buffer_id)); + if (!console_buffer_->Initialize()) { + VLOG(1) << "Failed to initialize console buffer"; + console_buffer_.reset(); + } else { + // Clear the console buffer such that restarting Chrome will show a + // predetermined background. + // + // Black was chosen since Chrome's first buffer paints start with a black + // background. + console_buffer_->canvas()->clear(SK_ColorBLACK); + } +} + +void NativeDisplayDelegateDri::GrabServer() { +} + +void NativeDisplayDelegateDri::UngrabServer() { +} + +bool NativeDisplayDelegateDri::TakeDisplayControl() { + if (!dri_->SetMaster()) { + LOG(ERROR) << "Failed to take control of the display"; + return false; + } + return true; +} + +bool NativeDisplayDelegateDri::RelinquishDisplayControl() { + if (!dri_->DropMaster()) { + LOG(ERROR) << "Failed to relinquish control of the display"; + return false; + } + return true; +} + +void NativeDisplayDelegateDri::SyncWithServer() { +} + +void NativeDisplayDelegateDri::SetBackgroundColor(uint32_t color_argb) { + if (console_buffer_) + console_buffer_->canvas()->clear(color_argb); +} + +void NativeDisplayDelegateDri::ForceDPMSOn() { + for (size_t i = 0; i < cached_displays_.size(); ++i) { + DisplaySnapshotDri* dri_output = cached_displays_[i]; + if (dri_output->dpms_property()) + dri_->SetProperty(dri_output->connector(), + dri_output->dpms_property()->prop_id, DRM_MODE_DPMS_ON); + } +} + +std::vector<DisplaySnapshot*> NativeDisplayDelegateDri::GetDisplays() { + ScopedVector<DisplaySnapshotDri> old_displays(cached_displays_.Pass()); + cached_modes_.clear(); + + ScopedVector<HardwareDisplayControllerInfo> displays = + GetAvailableDisplayControllerInfos(dri_->get_fd()); + for (size_t i = 0; + i < displays.size() && cached_displays_.size() < kMaxDisplayCount; ++i) { + DisplaySnapshotDri* display = new DisplaySnapshotDri( + dri_, displays[i]->connector(), displays[i]->crtc(), i); + cached_displays_.push_back(display); + cached_modes_.insert(cached_modes_.end(), display->modes().begin(), + display->modes().end()); + } + + NotifyScreenManager(cached_displays_.get(), old_displays.get()); + + std::vector<DisplaySnapshot*> generic_displays(cached_displays_.begin(), + cached_displays_.end()); + return generic_displays; +} + +void NativeDisplayDelegateDri::AddMode(const DisplaySnapshot& output, + const DisplayMode* mode) { +} + +bool NativeDisplayDelegateDri::Configure(const DisplaySnapshot& output, + const DisplayMode* mode, + const gfx::Point& origin) { + const DisplaySnapshotDri& dri_output = + static_cast<const DisplaySnapshotDri&>(output); + + VLOG(1) << "DRM configuring: crtc=" << dri_output.crtc() + << " connector=" << dri_output.connector() + << " origin=" << origin.ToString() + << " size=" << (mode ? mode->size().ToString() : "0x0"); + + if (mode) { + if (!screen_manager_->ConfigureDisplayController( + dri_output.crtc(), dri_output.connector(), origin, + static_cast<const DisplayModeDri*>(mode)->mode_info())) { + VLOG(1) << "Failed to configure: crtc=" << dri_output.crtc() + << " connector=" << dri_output.connector(); + return false; + } + } else { + if (!screen_manager_->DisableDisplayController(dri_output.crtc())) { + VLOG(1) << "Failed to disable crtc=" << dri_output.crtc(); + return false; + } + } + + return true; +} + +void NativeDisplayDelegateDri::CreateFrameBuffer(const gfx::Size& size) { +} + +bool NativeDisplayDelegateDri::GetHDCPState(const DisplaySnapshot& output, + HDCPState* state) { + const DisplaySnapshotDri& dri_output = + static_cast<const DisplaySnapshotDri&>(output); + + ScopedDrmConnectorPtr connector(dri_->GetConnector(dri_output.connector())); + if (!connector) { + LOG(ERROR) << "Failed to get connector " << dri_output.connector(); + return false; + } + + ScopedDrmPropertyPtr hdcp_property( + dri_->GetProperty(connector.get(), kContentProtection)); + if (!hdcp_property) { + LOG(ERROR) << "'" << kContentProtection << "' property doesn't exist."; + return false; + } + + DCHECK_LT(static_cast<int>(hdcp_property->prop_id), connector->count_props); + int hdcp_state_idx = connector->prop_values[hdcp_property->prop_id]; + DCHECK_LT(hdcp_state_idx, hdcp_property->count_enums); + + std::string name(hdcp_property->enums[hdcp_state_idx].name); + for (size_t i = 0; i < arraysize(kContentProtectionStates); ++i) { + if (name == kContentProtectionStates[i].name) { + *state = kContentProtectionStates[i].state; + VLOG(3) << "HDCP state: " << *state << " (" << name << ")"; + return true; + } + } + + LOG(ERROR) << "Unknown content protection value '" << name << "'"; + return false; +} + +bool NativeDisplayDelegateDri::SetHDCPState(const DisplaySnapshot& output, + HDCPState state) { + const DisplaySnapshotDri& dri_output = + static_cast<const DisplaySnapshotDri&>(output); + + ScopedDrmConnectorPtr connector(dri_->GetConnector(dri_output.connector())); + if (!connector) { + LOG(ERROR) << "Failed to get connector " << dri_output.connector(); + return false; + } + + ScopedDrmPropertyPtr hdcp_property( + dri_->GetProperty(connector.get(), kContentProtection)); + if (!hdcp_property) { + LOG(ERROR) << "'" << kContentProtection << "' property doesn't exist."; + return false; + } + + return dri_->SetProperty( + dri_output.connector(), hdcp_property->prop_id, + GetContentProtectionValue(hdcp_property.get(), state)); +} + +std::vector<ui::ColorCalibrationProfile> +NativeDisplayDelegateDri::GetAvailableColorCalibrationProfiles( + const ui::DisplaySnapshot& output) { + NOTIMPLEMENTED(); + return std::vector<ui::ColorCalibrationProfile>(); +} + +bool NativeDisplayDelegateDri::SetColorCalibrationProfile( + const ui::DisplaySnapshot& output, + ui::ColorCalibrationProfile new_profile) { + NOTIMPLEMENTED(); + return false; +} + +void NativeDisplayDelegateDri::AddObserver(NativeDisplayObserver* observer) { + observers_.AddObserver(observer); +} + +void NativeDisplayDelegateDri::RemoveObserver(NativeDisplayObserver* observer) { + observers_.RemoveObserver(observer); +} + +void NativeDisplayDelegateDri::OnDeviceEvent(const DeviceEvent& event) { + if (event.device_type() != DeviceEvent::DISPLAY) + return; + + if (event.action_type() == DeviceEvent::CHANGE) { + VLOG(1) << "Got display changed event"; + FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, + OnConfigurationChanged()); + } +} + +void NativeDisplayDelegateDri::NotifyScreenManager( + const std::vector<DisplaySnapshotDri*>& new_displays, + const std::vector<DisplaySnapshotDri*>& old_displays) const { + for (size_t i = 0; i < old_displays.size(); ++i) { + const std::vector<DisplaySnapshotDri*>::const_iterator it = + std::find_if(new_displays.begin(), new_displays.end(), + DisplaySnapshotComparator(old_displays[i])); + + if (it == new_displays.end()) + screen_manager_->RemoveDisplayController(old_displays[i]->crtc()); + } + + for (size_t i = 0; i < new_displays.size(); ++i) { + const std::vector<DisplaySnapshotDri*>::const_iterator it = + std::find_if(old_displays.begin(), old_displays.end(), + DisplaySnapshotComparator(new_displays[i])); + + if (it == old_displays.end()) + screen_manager_->AddDisplayController(dri_, new_displays[i]->crtc(), + new_displays[i]->connector()); + } +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/native_display_delegate_dri.h b/chromium/ui/ozone/platform/dri/native_display_delegate_dri.h new file mode 100644 index 00000000000..c192b793d18 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/native_display_delegate_dri.h @@ -0,0 +1,85 @@ +// 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_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_DRI_H_ +#define UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_DRI_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "base/observer_list.h" +#include "ui/display/types/native_display_delegate.h" +#include "ui/events/ozone/device/device_event_observer.h" + +namespace ui { + +class DeviceManager; +class DisplaySnapshotDri; +class DriConsoleBuffer; +class DriWrapper; +class ScreenManager; + +class NativeDisplayDelegateDri : public NativeDisplayDelegate, + DeviceEventObserver { + public: + NativeDisplayDelegateDri(DriWrapper* dri, + ScreenManager* screen_manager, + DeviceManager* device_manager); + ~NativeDisplayDelegateDri() override; + + DisplaySnapshot* FindDisplaySnapshot(int64_t id); + const DisplayMode* FindDisplayMode(const gfx::Size& size, + bool is_interlaced, + float refresh_rate); + + // NativeDisplayDelegate overrides: + void Initialize() override; + void GrabServer() override; + void UngrabServer() override; + bool TakeDisplayControl() override; + bool RelinquishDisplayControl() override; + void SyncWithServer() override; + void SetBackgroundColor(uint32_t color_argb) override; + void ForceDPMSOn() override; + std::vector<DisplaySnapshot*> GetDisplays() override; + void AddMode(const DisplaySnapshot& output, const DisplayMode* mode) override; + bool Configure(const DisplaySnapshot& output, + const DisplayMode* mode, + const gfx::Point& origin) override; + void CreateFrameBuffer(const gfx::Size& size) override; + bool GetHDCPState(const DisplaySnapshot& output, HDCPState* state) override; + bool SetHDCPState(const DisplaySnapshot& output, HDCPState state) override; + std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles( + const ui::DisplaySnapshot& output) override; + bool SetColorCalibrationProfile( + const ui::DisplaySnapshot& output, + ui::ColorCalibrationProfile new_profile) override; + void AddObserver(NativeDisplayObserver* observer) override; + void RemoveObserver(NativeDisplayObserver* observer) override; + + // DeviceEventObserver overrides: + void OnDeviceEvent(const DeviceEvent& event) override; + + private: + // Notify ScreenManager of all the displays that were present before the + // update but are gone after the update. + void NotifyScreenManager( + const std::vector<DisplaySnapshotDri*>& new_displays, + const std::vector<DisplaySnapshotDri*>& old_displays) const; + + DriWrapper* dri_; // Not owned. + ScreenManager* screen_manager_; // Not owned. + DeviceManager* device_manager_; // Not owned. + scoped_ptr<DriConsoleBuffer> console_buffer_; + // Modes can be shared between different displays, so we need to keep track + // of them independently for cleanup. + ScopedVector<const DisplayMode> cached_modes_; + ScopedVector<DisplaySnapshotDri> cached_displays_; + ObserverList<NativeDisplayObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateDri); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_DRI_H_ diff --git a/chromium/ui/ozone/platform/dri/native_display_delegate_proxy.cc b/chromium/ui/ozone/platform/dri/native_display_delegate_proxy.cc new file mode 100644 index 00000000000..ae0da8dea2b --- /dev/null +++ b/chromium/ui/ozone/platform/dri/native_display_delegate_proxy.cc @@ -0,0 +1,172 @@ +// 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/platform/dri/native_display_delegate_proxy.h" + +#include "base/logging.h" +#include "ui/display/types/display_snapshot.h" +#include "ui/display/types/native_display_observer.h" +#include "ui/events/ozone/device/device_event.h" +#include "ui/events/ozone/device/device_manager.h" +#include "ui/ozone/common/display_snapshot_proxy.h" +#include "ui/ozone/common/display_util.h" +#include "ui/ozone/common/gpu/ozone_gpu_messages.h" +#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h" + +namespace ui { + +NativeDisplayDelegateProxy::NativeDisplayDelegateProxy( + DriGpuPlatformSupportHost* proxy, + DeviceManager* device_manager) + : proxy_(proxy), device_manager_(device_manager) { + proxy_->RegisterHandler(this); +} + +NativeDisplayDelegateProxy::~NativeDisplayDelegateProxy() { + if (device_manager_) + device_manager_->RemoveObserver(this); + + proxy_->UnregisterHandler(this); +} + +void NativeDisplayDelegateProxy::Initialize() { + if (device_manager_) + device_manager_->AddObserver(this); +} + +void NativeDisplayDelegateProxy::GrabServer() { +} + +void NativeDisplayDelegateProxy::UngrabServer() { +} + +bool NativeDisplayDelegateProxy::TakeDisplayControl() { + proxy_->Send(new OzoneGpuMsg_TakeDisplayControl()); + return true; +} + +bool NativeDisplayDelegateProxy::RelinquishDisplayControl() { + proxy_->Send(new OzoneGpuMsg_RelinquishDisplayControl()); + return true; +} + +void NativeDisplayDelegateProxy::SyncWithServer() { +} + +void NativeDisplayDelegateProxy::SetBackgroundColor(uint32_t color_argb) { + NOTIMPLEMENTED(); +} + +void NativeDisplayDelegateProxy::ForceDPMSOn() { + proxy_->Send(new OzoneGpuMsg_ForceDPMSOn()); +} + +std::vector<DisplaySnapshot*> NativeDisplayDelegateProxy::GetDisplays() { + return displays_.get(); +} + +void NativeDisplayDelegateProxy::AddMode(const DisplaySnapshot& output, + const DisplayMode* mode) { +} + +bool NativeDisplayDelegateProxy::Configure(const DisplaySnapshot& output, + const DisplayMode* mode, + const gfx::Point& origin) { + // TODO(dnicoara) Should handle an asynchronous response. + if (mode) + proxy_->Send(new OzoneGpuMsg_ConfigureNativeDisplay( + output.display_id(), GetDisplayModeParams(*mode), origin)); + else + proxy_->Send(new OzoneGpuMsg_DisableNativeDisplay(output.display_id())); + + return true; +} + +void NativeDisplayDelegateProxy::CreateFrameBuffer(const gfx::Size& size) { +} + +bool NativeDisplayDelegateProxy::GetHDCPState(const DisplaySnapshot& output, + HDCPState* state) { + NOTIMPLEMENTED(); + return false; +} + +bool NativeDisplayDelegateProxy::SetHDCPState(const DisplaySnapshot& output, + HDCPState state) { + NOTIMPLEMENTED(); + return false; +} + +std::vector<ColorCalibrationProfile> +NativeDisplayDelegateProxy::GetAvailableColorCalibrationProfiles( + const DisplaySnapshot& output) { + NOTIMPLEMENTED(); + return std::vector<ColorCalibrationProfile>(); +} + +bool NativeDisplayDelegateProxy::SetColorCalibrationProfile( + const DisplaySnapshot& output, + ColorCalibrationProfile new_profile) { + NOTIMPLEMENTED(); + return false; +} + +void NativeDisplayDelegateProxy::AddObserver(NativeDisplayObserver* observer) { + observers_.AddObserver(observer); +} + +void NativeDisplayDelegateProxy::RemoveObserver( + NativeDisplayObserver* observer) { + observers_.RemoveObserver(observer); +} + +void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent& event) { + if (event.device_type() != DeviceEvent::DISPLAY) + return; + + if (event.action_type() == DeviceEvent::CHANGE) { + VLOG(1) << "Got display changed event"; + proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays( + std::vector<DisplaySnapshot_Params>())); + } +} + +void NativeDisplayDelegateProxy::OnChannelEstablished(int host_id, + IPC::Sender* sender) { + std::vector<DisplaySnapshot_Params> display_params; + for (size_t i = 0; i < displays_.size(); ++i) + display_params.push_back(GetDisplaySnapshotParams(*displays_[i])); + + // Force an initial configure such that the browser process can get the actual + // state. Pass in the current display state since the GPU process may have + // crashed and we want to re-synchronize the state between processes. + proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays(display_params)); +} + +void NativeDisplayDelegateProxy::OnChannelDestroyed(int host_id) { +} + +bool NativeDisplayDelegateProxy::OnMessageReceived( + const IPC::Message& message) { + bool handled = true; + + IPC_BEGIN_MESSAGE_MAP(NativeDisplayDelegateProxy, message) + IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays, OnUpdateNativeDisplays) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; +} + +void NativeDisplayDelegateProxy::OnUpdateNativeDisplays( + const std::vector<DisplaySnapshot_Params>& displays) { + displays_.clear(); + for (size_t i = 0; i < displays.size(); ++i) + displays_.push_back(new DisplaySnapshotProxy(displays[i])); + + FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, + OnConfigurationChanged()); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/native_display_delegate_proxy.h b/chromium/ui/ozone/platform/dri/native_display_delegate_proxy.h new file mode 100644 index 00000000000..cb4e03dcd84 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/native_display_delegate_proxy.h @@ -0,0 +1,78 @@ +// 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_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_ +#define UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_ + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "base/observer_list.h" +#include "ui/display/types/native_display_delegate.h" +#include "ui/events/ozone/device/device_event_observer.h" +#include "ui/ozone/public/gpu_platform_support_host.h" + +namespace ui { + +class DeviceManager; +class DriGpuPlatformSupportHost; + +struct DisplaySnapshot_Params; + +class NativeDisplayDelegateProxy : public NativeDisplayDelegate, + public DeviceEventObserver, + public GpuPlatformSupportHost { + public: + NativeDisplayDelegateProxy(DriGpuPlatformSupportHost* proxy, + DeviceManager* device_manager); + ~NativeDisplayDelegateProxy() override; + + // NativeDisplayDelegate overrides: + void Initialize() override; + void GrabServer() override; + void UngrabServer() override; + bool TakeDisplayControl() override; + bool RelinquishDisplayControl() override; + void SyncWithServer() override; + void SetBackgroundColor(uint32_t color_argb) override; + void ForceDPMSOn() override; + std::vector<DisplaySnapshot*> GetDisplays() override; + void AddMode(const DisplaySnapshot& output, const DisplayMode* mode) override; + bool Configure(const DisplaySnapshot& output, + const DisplayMode* mode, + const gfx::Point& origin) override; + void CreateFrameBuffer(const gfx::Size& size) override; + bool GetHDCPState(const DisplaySnapshot& output, HDCPState* state) override; + bool SetHDCPState(const DisplaySnapshot& output, HDCPState state) override; + std::vector<ColorCalibrationProfile> GetAvailableColorCalibrationProfiles( + const DisplaySnapshot& output) override; + bool SetColorCalibrationProfile(const DisplaySnapshot& output, + ColorCalibrationProfile new_profile) override; + void AddObserver(NativeDisplayObserver* observer) override; + void RemoveObserver(NativeDisplayObserver* observer) override; + + // DeviceEventObserver overrides: + void OnDeviceEvent(const DeviceEvent& event) override; + + // GpuPlatformSupportHost: + void OnChannelEstablished(int host_id, IPC::Sender* sender) override; + void OnChannelDestroyed(int host_id) override; + + // IPC::Listener overrides: + bool OnMessageReceived(const IPC::Message& message) override; + + private: + void OnUpdateNativeDisplays( + const std::vector<DisplaySnapshot_Params>& displays); + + DriGpuPlatformSupportHost* proxy_; // Not owned. + DeviceManager* device_manager_; // Not owned. + ScopedVector<DisplaySnapshot> displays_; + ObserverList<NativeDisplayObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateProxy); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_ diff --git a/chromium/ui/ozone/platform/dri/overlay_plane.cc b/chromium/ui/ozone/platform/dri/overlay_plane.cc new file mode 100644 index 00000000000..5f48fddb836 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/overlay_plane.cc @@ -0,0 +1,48 @@ +// 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/platform/dri/overlay_plane.h" + +#include "base/logging.h" +#include "ui/ozone/platform/dri/scanout_buffer.h" + +namespace ui { + +OverlayPlane::OverlayPlane(scoped_refptr<ScanoutBuffer> buffer) + : buffer(buffer), + z_order(0), + display_bounds(gfx::Point(), buffer->GetSize()), + crop_rect(0, 0, 1, 1), + overlay_plane(0) { +} + +OverlayPlane::OverlayPlane(scoped_refptr<ScanoutBuffer> buffer, + int z_order, + gfx::OverlayTransform plane_transform, + const gfx::Rect& display_bounds, + const gfx::RectF& crop_rect) + : buffer(buffer), + z_order(z_order), + plane_transform(plane_transform), + display_bounds(display_bounds), + crop_rect(crop_rect), + overlay_plane(0) { +} + +OverlayPlane::~OverlayPlane() { +} + +// static +const OverlayPlane& OverlayPlane::GetPrimaryPlane( + const OverlayPlaneList& overlays) { + for (size_t i = 0; i < overlays.size(); ++i) { + if (overlays[i].z_order == 0) + return overlays[i]; + } + + NOTREACHED(); + return overlays[0]; +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/overlay_plane.h b/chromium/ui/ozone/platform/dri/overlay_plane.h new file mode 100644 index 00000000000..e1aeee08947 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/overlay_plane.h @@ -0,0 +1,46 @@ +// 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_PLATFORM_DRI_OVERLAY_PLANE_H_ +#define UI_OZONE_PLATFORM_DRI_OVERLAY_PLANE_H_ + +#include <vector> + +#include "base/memory/ref_counted.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/overlay_transform.h" + +namespace ui { + +class ScanoutBuffer; + +struct OverlayPlane; +typedef std::vector<OverlayPlane> OverlayPlaneList; + +struct OverlayPlane { + // Simpler constructor for the primary plane. + explicit OverlayPlane(scoped_refptr<ScanoutBuffer> buffer); + + OverlayPlane(scoped_refptr<ScanoutBuffer> buffer, + int z_order, + gfx::OverlayTransform plane_transform, + const gfx::Rect& display_bounds, + const gfx::RectF& crop_rect); + + ~OverlayPlane(); + + // Returns the primary plane in |overlays|. + static const OverlayPlane& GetPrimaryPlane(const OverlayPlaneList& overlays); + + scoped_refptr<ScanoutBuffer> buffer; + int z_order; + gfx::OverlayTransform plane_transform; + gfx::Rect display_bounds; + gfx::RectF crop_rect; + int overlay_plane; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_OVERLAY_PLANE_H_ diff --git a/chromium/ui/ozone/platform/dri/ozone_platform_dri.cc b/chromium/ui/ozone/platform/dri/ozone_platform_dri.cc index 1a703300bbb..f53f1db3d8f 100644 --- a/chromium/ui/ozone/platform/dri/ozone_platform_dri.cc +++ b/chromium/ui/ozone/platform/dri/ozone_platform_dri.cc @@ -5,22 +5,24 @@ #include "ui/ozone/platform/dri/ozone_platform_dri.h" #include "base/at_exit.h" +#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" #include "ui/events/ozone/device/device_manager.h" #include "ui/events/ozone/evdev/cursor_delegate_evdev.h" #include "ui/events/ozone/evdev/event_factory_evdev.h" -#include "ui/ozone/ozone_platform.h" -#include "ui/ozone/platform/dri/cursor_factory_evdev_dri.h" -#include "ui/ozone/platform/dri/dri_surface.h" +#include "ui/ozone/platform/dri/dri_buffer.h" +#include "ui/ozone/platform/dri/dri_cursor.h" +#include "ui/ozone/platform/dri/dri_gpu_platform_support.h" +#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h" #include "ui/ozone/platform/dri/dri_surface_factory.h" +#include "ui/ozone/platform/dri/dri_window.h" +#include "ui/ozone/platform/dri/dri_window_delegate_impl.h" +#include "ui/ozone/platform/dri/dri_window_delegate_manager.h" +#include "ui/ozone/platform/dri/dri_window_manager.h" #include "ui/ozone/platform/dri/dri_wrapper.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/platform/dri/native_display_delegate_dri.h" #include "ui/ozone/platform/dri/screen_manager.h" -#include "ui/ozone/platform/dri/virtual_terminal_manager.h" - -#if defined(OS_CHROMEOS) -#include "ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h" -#include "ui/ozone/platform/dri/chromeos/native_display_delegate_dri.h" -#endif +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/ui_thread_gpu.h" namespace ui { @@ -28,21 +30,6 @@ namespace { const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; -class DriSurfaceGenerator : public ScanoutSurfaceGenerator { - public: - DriSurfaceGenerator(DriWrapper* dri) : dri_(dri) {} - virtual ~DriSurfaceGenerator() {} - - virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE { - return new DriSurface(dri_, size); - } - - private: - DriWrapper* dri_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(DriSurfaceGenerator); -}; - // OzonePlatform for Linux DRI (Direct Rendering Infrastructure) // // This platform is Linux without any display server (no X, wayland, or @@ -50,67 +37,82 @@ class DriSurfaceGenerator : public ScanoutSurfaceGenerator { class OzonePlatformDri : public OzonePlatform { public: OzonePlatformDri() - : vt_manager_(new VirtualTerminalManager()), - dri_(new DriWrapper(kDefaultGraphicsCardPath)), - surface_generator_(new DriSurfaceGenerator(dri_.get())), - screen_manager_(new ScreenManager(dri_.get(), - surface_generator_.get())), + : dri_(new DriWrapper(kDefaultGraphicsCardPath)), + buffer_generator_(new DriBufferGenerator(dri_.get())), + screen_manager_(new ScreenManager(dri_.get(), buffer_generator_.get())), device_manager_(CreateDeviceManager()) { base::AtExitManager::RegisterTask( base::Bind(&base::DeletePointer<OzonePlatformDri>, this)); } - virtual ~OzonePlatformDri() {} + ~OzonePlatformDri() override {} // OzonePlatform: - virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE { + ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { return surface_factory_ozone_.get(); } - virtual EventFactoryOzone* GetEventFactoryOzone() OVERRIDE { - return event_factory_ozone_.get(); - } - virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE { + CursorFactoryOzone* GetCursorFactoryOzone() override { return cursor_factory_ozone_.get(); } - virtual GpuPlatformSupport* GetGpuPlatformSupport() OVERRIDE { - return NULL; // no GPU support + GpuPlatformSupport* GetGpuPlatformSupport() override { + return gpu_platform_support_.get(); } - virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() OVERRIDE { - return NULL; // no GPU support + GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { + return gpu_platform_support_host_.get(); } -#if defined(OS_CHROMEOS) - virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() - OVERRIDE { + scoped_ptr<PlatformWindow> CreatePlatformWindow( + PlatformWindowDelegate* delegate, + const gfx::Rect& bounds) override { + scoped_ptr<DriWindow> platform_window( + new DriWindow(delegate, bounds, gpu_platform_support_host_.get(), + event_factory_ozone_.get(), window_manager_.get())); + platform_window->Initialize(); + return platform_window.Pass(); + } + scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override { return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateDri( dri_.get(), screen_manager_.get(), device_manager_.get())); } - virtual scoped_ptr<TouchscreenDeviceManager> - CreateTouchscreenDeviceManager() OVERRIDE { - return scoped_ptr<TouchscreenDeviceManager>( - new TouchscreenDeviceManagerOzone()); - } -#endif - virtual void InitializeUI() OVERRIDE { - surface_factory_ozone_.reset( - new DriSurfaceFactory(dri_.get(), screen_manager_.get())); - cursor_factory_ozone_.reset( - new CursorFactoryEvdevDri(surface_factory_ozone_.get())); - event_factory_ozone_.reset(new EventFactoryEvdev( - cursor_factory_ozone_.get(), device_manager_.get())); + void InitializeUI() override { + dri_->Initialize(); + surface_factory_ozone_.reset(new DriSurfaceFactory( + dri_.get(), screen_manager_.get(), &window_delegate_manager_)); + gpu_platform_support_.reset(new DriGpuPlatformSupport( + surface_factory_ozone_.get(), &window_delegate_manager_, + screen_manager_.get(), scoped_ptr<NativeDisplayDelegateDri>())); + gpu_platform_support_host_.reset(new DriGpuPlatformSupportHost()); + cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone); + window_manager_.reset(new DriWindowManager(surface_factory_ozone_.get())); + event_factory_ozone_.reset(new EventFactoryEvdev(window_manager_->cursor(), + device_manager_.get())); + if (surface_factory_ozone_->InitializeHardware() != + DriSurfaceFactory::INITIALIZED) + LOG(FATAL) << "Failed to initialize display hardware."; + + if (!ui_thread_gpu_.Initialize()) + LOG(FATAL) << "Failed to initialize dummy channel."; } - virtual void InitializeGPU() OVERRIDE {} + void InitializeGPU() override {} private: - scoped_ptr<VirtualTerminalManager> vt_manager_; scoped_ptr<DriWrapper> dri_; - scoped_ptr<DriSurfaceGenerator> surface_generator_; + scoped_ptr<DriBufferGenerator> buffer_generator_; scoped_ptr<ScreenManager> screen_manager_; scoped_ptr<DeviceManager> device_manager_; scoped_ptr<DriSurfaceFactory> surface_factory_ozone_; - scoped_ptr<CursorFactoryEvdevDri> cursor_factory_ozone_; + scoped_ptr<BitmapCursorFactoryOzone> cursor_factory_ozone_; scoped_ptr<EventFactoryEvdev> event_factory_ozone_; + scoped_ptr<DriWindowManager> window_manager_; + + scoped_ptr<DriGpuPlatformSupport> gpu_platform_support_; + scoped_ptr<DriGpuPlatformSupportHost> gpu_platform_support_host_; + + DriWindowDelegateManager window_delegate_manager_; + + UiThreadGpu ui_thread_gpu_; + DISALLOW_COPY_AND_ASSIGN(OzonePlatformDri); }; diff --git a/chromium/ui/ozone/platform/dri/ozone_platform_gbm.cc b/chromium/ui/ozone/platform/dri/ozone_platform_gbm.cc index 440614bcaf7..3e506fb7854 100644 --- a/chromium/ui/ozone/platform/dri/ozone_platform_gbm.cc +++ b/chromium/ui/ozone/platform/dri/ozone_platform_gbm.cc @@ -9,21 +9,29 @@ #include <stdlib.h> #include "base/at_exit.h" +#include "base/command_line.h" +#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" #include "ui/events/ozone/device/device_manager.h" #include "ui/events/ozone/evdev/event_factory_evdev.h" -#include "ui/ozone/ozone_platform.h" +#include "ui/ozone/platform/dri/dri_cursor.h" +#include "ui/ozone/platform/dri/dri_gpu_platform_support.h" +#include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h" +#include "ui/ozone/platform/dri/dri_window.h" +#include "ui/ozone/platform/dri/dri_window_delegate_manager.h" +#include "ui/ozone/platform/dri/dri_window_manager.h" #include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/gbm_buffer.h" #include "ui/ozone/platform/dri/gbm_surface.h" #include "ui/ozone/platform/dri/gbm_surface_factory.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/platform/dri/native_display_delegate_dri.h" +#include "ui/ozone/platform/dri/native_display_delegate_proxy.h" +#include "ui/ozone/platform/dri/scanout_buffer.h" #include "ui/ozone/platform/dri/screen_manager.h" -#include "ui/ozone/platform/dri/virtual_terminal_manager.h" #include "ui/ozone/public/cursor_factory_ozone.h" - -#if defined(OS_CHROMEOS) -#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h" -#include "ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h" -#endif +#include "ui/ozone/public/gpu_platform_support.h" +#include "ui/ozone/public/gpu_platform_support_host.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/ozone_switches.h" namespace ui { @@ -31,13 +39,16 @@ namespace { const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; -class GbmSurfaceGenerator : public ScanoutSurfaceGenerator { +class GbmBufferGenerator : public ScanoutBufferGenerator { public: - GbmSurfaceGenerator(DriWrapper* dri) + GbmBufferGenerator(DriWrapper* dri) : dri_(dri), glapi_lib_(dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL)), - device_(gbm_create_device(dri_->get_fd())) {} - virtual ~GbmSurfaceGenerator() { + device_(gbm_create_device(dri_->get_fd())) { + if (!device_) + LOG(FATAL) << "Unable to initialize gbm for " << kDefaultGraphicsCardPath; + } + virtual ~GbmBufferGenerator() { gbm_device_destroy(device_); if (glapi_lib_) dlclose(glapi_lib_); @@ -45,11 +56,12 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator { gbm_device* device() const { return device_; } - virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE { - return new GbmSurface(device_, dri_, size); + scoped_refptr<ScanoutBuffer> Create(const gfx::Size& size) override { + return GbmBuffer::CreateBuffer( + dri_, device_, SurfaceFactoryOzone::RGBA_8888, size, true); } - private: + protected: DriWrapper* dri_; // Not owned. // HACK: gbm drivers have broken linkage @@ -57,90 +69,105 @@ class GbmSurfaceGenerator : public ScanoutSurfaceGenerator { gbm_device* device_; - DISALLOW_COPY_AND_ASSIGN(GbmSurfaceGenerator); + DISALLOW_COPY_AND_ASSIGN(GbmBufferGenerator); }; class OzonePlatformGbm : public OzonePlatform { public: - OzonePlatformGbm() { - base::AtExitManager::RegisterTask( + OzonePlatformGbm(bool use_surfaceless) : use_surfaceless_(use_surfaceless) { + base::AtExitManager::RegisterTask( base::Bind(&base::DeletePointer<OzonePlatformGbm>, this)); } - virtual ~OzonePlatformGbm() {} + ~OzonePlatformGbm() override {} // OzonePlatform: - virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE { + ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { return surface_factory_ozone_.get(); } - virtual EventFactoryOzone* GetEventFactoryOzone() OVERRIDE { - return event_factory_ozone_.get(); - } - virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE { + CursorFactoryOzone* GetCursorFactoryOzone() override { return cursor_factory_ozone_.get(); } - virtual GpuPlatformSupport* GetGpuPlatformSupport() OVERRIDE { - return gpu_platform_support_.get() + GpuPlatformSupport* GetGpuPlatformSupport() override { + return gpu_platform_support_.get(); } - virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() OVERRIDE { + GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { return gpu_platform_support_host_.get(); } -#if defined(OS_CHROMEOS) - virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() - OVERRIDE { - return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); + scoped_ptr<PlatformWindow> CreatePlatformWindow( + PlatformWindowDelegate* delegate, + const gfx::Rect& bounds) override { + scoped_ptr<DriWindow> platform_window( + new DriWindow(delegate, bounds, gpu_platform_support_host_.get(), + event_factory_ozone_.get(), window_manager_.get())); + platform_window->Initialize(); + return platform_window.Pass(); } - virtual scoped_ptr<TouchscreenDeviceManager> - CreateTouchscreenDeviceManager() OVERRIDE { - return scoped_ptr<TouchscreenDeviceManager>( - new TouchscreenDeviceManagerOzone()); + scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override { + return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateProxy( + gpu_platform_support_host_.get(), device_manager_.get())); } -#endif - virtual void InitializeUI() OVERRIDE { - vt_manager_.reset(new VirtualTerminalManager()); + void InitializeUI() override { // Needed since the browser process creates the accelerated widgets and that // happens through SFO. - surface_factory_ozone_.reset(new GbmSurfaceFactory(NULL, NULL, NULL)); - + surface_factory_ozone_.reset(new GbmSurfaceFactory(use_surfaceless_)); device_manager_ = CreateDeviceManager(); - cursor_factory_ozone_.reset(new CursorFactoryOzone()); - event_factory_ozone_.reset(new EventFactoryEvdev( - NULL, device_manager_.get())); - - gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); + gpu_platform_support_host_.reset(new DriGpuPlatformSupportHost()); + cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone); + window_manager_.reset( + new DriWindowManager(gpu_platform_support_host_.get())); + event_factory_ozone_.reset(new EventFactoryEvdev(window_manager_->cursor(), + device_manager_.get())); } - virtual void InitializeGPU() OVERRIDE { + void InitializeGPU() override { dri_.reset(new DriWrapper(kDefaultGraphicsCardPath)); - surface_generator_.reset(new GbmSurfaceGenerator(dri_.get())); + dri_->Initialize(); + buffer_generator_.reset(new GbmBufferGenerator(dri_.get())); screen_manager_.reset(new ScreenManager(dri_.get(), - surface_generator_.get())); - surface_factory_ozone_.reset( - new GbmSurfaceFactory(dri_.get(), - surface_generator_->device(), - screen_manager_.get())); - - gpu_platform_support_.reset(CreateStubGpuPlatformSupport()); + buffer_generator_.get())); + window_delegate_manager_.reset(new DriWindowDelegateManager()); + if (!surface_factory_ozone_) + surface_factory_ozone_.reset(new GbmSurfaceFactory(use_surfaceless_)); + + surface_factory_ozone_->InitializeGpu( + dri_.get(), buffer_generator_->device(), screen_manager_.get(), + window_delegate_manager_.get()); + gpu_platform_support_.reset(new DriGpuPlatformSupport( + surface_factory_ozone_.get(), window_delegate_manager_.get(), + screen_manager_.get(), + scoped_ptr<NativeDisplayDelegateDri>(new NativeDisplayDelegateDri( + dri_.get(), screen_manager_.get(), NULL)))); + if (surface_factory_ozone_->InitializeHardware() != + DriSurfaceFactory::INITIALIZED) + LOG(FATAL) << "failed to initialize display hardware"; } private: - scoped_ptr<VirtualTerminalManager> vt_manager_; + bool use_surfaceless_; scoped_ptr<DriWrapper> dri_; - scoped_ptr<GbmSurfaceGenerator> surface_generator_; + scoped_ptr<GbmBufferGenerator> buffer_generator_; scoped_ptr<ScreenManager> screen_manager_; scoped_ptr<DeviceManager> device_manager_; scoped_ptr<GbmSurfaceFactory> surface_factory_ozone_; - scoped_ptr<CursorFactoryOzone> cursor_factory_ozone_; + scoped_ptr<BitmapCursorFactoryOzone> cursor_factory_ozone_; scoped_ptr<EventFactoryEvdev> event_factory_ozone_; - scoped_ptr<GpuPlatformSupport> gpu_platform_support_; - scoped_ptr<GpuPlatformSupportHost> gpu_platform_support_host_; + scoped_ptr<DriGpuPlatformSupport> gpu_platform_support_; + scoped_ptr<DriGpuPlatformSupportHost> gpu_platform_support_host_; + + scoped_ptr<DriWindowDelegateManager> window_delegate_manager_; + // Browser side object only. + scoped_ptr<DriWindowManager> window_manager_; DISALLOW_COPY_AND_ASSIGN(OzonePlatformGbm); }; } // namespace -OzonePlatform* CreateOzonePlatformGbm() { return new OzonePlatformGbm; } +OzonePlatform* CreateOzonePlatformGbm() { + CommandLine* cmd = CommandLine::ForCurrentProcess(); + return new OzonePlatformGbm(cmd->HasSwitch(switches::kOzoneUseSurfaceless)); +} } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/scanout_buffer.h b/chromium/ui/ozone/platform/dri/scanout_buffer.h new file mode 100644 index 00000000000..4475c8db30f --- /dev/null +++ b/chromium/ui/ozone/platform/dri/scanout_buffer.h @@ -0,0 +1,42 @@ +// 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_PLATFORM_DRI_SCANOUT_BUFFER_H_ +#define UI_OZONE_PLATFORM_DRI_SCANOUT_BUFFER_H_ + +#include <stdint.h> + +#include "base/memory/ref_counted.h" +#include "ui/gfx/geometry/size.h" + +namespace ui { + +// Abstraction for a DRM buffer that can be scanned-out of. +class ScanoutBuffer : public base::RefCounted<ScanoutBuffer> { + public: + // ID allocated by the KMS API when the buffer is registered (via the handle). + virtual uint32_t GetFramebufferId() const = 0; + + // Handle for the buffer. This is received when allocating the buffer. + virtual uint32_t GetHandle() const = 0; + + // Size of the buffer. + virtual gfx::Size GetSize() const = 0; + + protected: + virtual ~ScanoutBuffer() {} + + friend class base::RefCounted<ScanoutBuffer>; +}; + +class ScanoutBufferGenerator { + public: + virtual ~ScanoutBufferGenerator() {} + + virtual scoped_refptr<ScanoutBuffer> Create(const gfx::Size& size) = 0; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_SCANOUT_BUFFER_H_ diff --git a/chromium/ui/ozone/platform/dri/scanout_surface.h b/chromium/ui/ozone/platform/dri/scanout_surface.h deleted file mode 100644 index d362ae18e81..00000000000 --- a/chromium/ui/ozone/platform/dri/scanout_surface.h +++ /dev/null @@ -1,84 +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_PLATFORM_DRI_SCANOUT_SURFACE_H_ -#define UI_OZONE_PLATFORM_DRI_SCANOUT_SURFACE_H_ - -#include <stdint.h> - -namespace gfx { -class Size; -} - -namespace ui { - -// ScanoutSurface is an interface for a surface that can be scanned out to a -// monitor using the DRM/KMS API. Implementations will store the internal state -// associated with the drawing surface. Implementations are also required to -// performs all the needed operations to initialize and update the drawing -// surface. -// -// The typical usage pattern is: -// ----------------------------------------------------------------------------- -// HardwareDisplayController controller; -// // Initialize controller -// -// ScanoutSurface* surface = new ScanoutSurfaceImpl(size); -// surface.Initialize(); -// controller.BindSurfaceToController(surface); -// -// while (true) { -// DrawIntoSurface(surface); -// controller.SchedulePageFlip(); -// -// Wait for page flip event. The DRM page flip handler will call -// surface.SwapBuffers(); -// } -// -// delete surface; -// ----------------------------------------------------------------------------- -// In the above example the wait consists of reading a DRM pageflip event from -// the graphics card file descriptor. This is done by calling |drmHandleEvent|, -// which will read and process the event. |drmHandleEvent| will call a callback -// registered by |SchedulePageFlip| which will update the internal state. -// -// |SchedulePageFlip| can also be used to limit drawing to the screen's vsync -// since page flips only happen on vsync. In a threaded environment a message -// loop would listen on the graphics card file descriptor for an event and -// |drmHandleEvent| would be called from the message loop. The event handler -// would also be responsible for updating the renderer's state and signal that -// it is OK to start drawing the next frame. -class ScanoutSurface { - public: - virtual ~ScanoutSurface() {} - - // Used to allocate all necessary buffers for this surface. If the - // initialization succeeds, the device is ready to be used for drawing - // operations. - // Returns true if the initialization is successful, false otherwise. - virtual bool Initialize() = 0; - - // Swaps the back buffer with the front buffer. - virtual void SwapBuffers() = 0; - - // Returns the ID of the current backbuffer. - virtual uint32_t GetFramebufferId() const = 0; - - // Returns the handle of the current backbuffer. - virtual uint32_t GetHandle() const = 0; - - // Returns the surface size. - virtual gfx::Size Size() const = 0; -}; - -class ScanoutSurfaceGenerator { - public: - virtual ~ScanoutSurfaceGenerator() {} - - virtual ScanoutSurface* Create(const gfx::Size& size) = 0; -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_SCANOUT_SURFACE_H_ diff --git a/chromium/ui/ozone/platform/dri/scoped_drm_types.cc b/chromium/ui/ozone/platform/dri/scoped_drm_types.cc new file mode 100644 index 00000000000..0f1c6b32167 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/scoped_drm_types.cc @@ -0,0 +1,53 @@ +// 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/platform/dri/scoped_drm_types.h" + +#include <xf86drmMode.h> + +namespace ui { + +void DrmResourcesDeleter::operator()(drmModeRes* resources) const { + drmModeFreeResources(resources); +} + +void DrmConnectorDeleter::operator()(drmModeConnector* connector) const { + drmModeFreeConnector(connector); +} + +void DrmCrtcDeleter::operator()(drmModeCrtc* crtc) const { + drmModeFreeCrtc(crtc); +} + +void DrmEncoderDeleter::operator()(drmModeEncoder* encoder) const { + drmModeFreeEncoder(encoder); +} + +void DrmObjectPropertiesDeleter::operator()( + drmModeObjectProperties* properties) const { + drmModeFreeObjectProperties(properties); +} + +void DrmPlaneDeleter::operator()(drmModePlane* plane) const { + drmModeFreePlane(plane); +} + +void DrmPlaneResDeleter::operator()(drmModePlaneRes* plane) const { + drmModeFreePlaneResources(plane); +} + +void DrmPropertyDeleter::operator()(drmModePropertyRes* property) const { + drmModeFreeProperty(property); +} + +void DrmPropertyBlobDeleter::operator()( + drmModePropertyBlobRes* property) const { + drmModeFreePropertyBlob(property); +} + +void DrmFramebufferDeleter::operator()(drmModeFB* framebuffer) const { + drmModeFreeFB(framebuffer); +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/scoped_drm_types.h b/chromium/ui/ozone/platform/dri/scoped_drm_types.h new file mode 100644 index 00000000000..e651232b321 --- /dev/null +++ b/chromium/ui/ozone/platform/dri/scoped_drm_types.h @@ -0,0 +1,69 @@ +// 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_PLATFORM_DRI_SCOPED_DRM_TYPES_H_ +#define UI_OZONE_PLATFORM_DRI_SCOPED_DRM_TYPES_H_ + +#include "base/memory/scoped_ptr.h" + +typedef struct _drmModeConnector drmModeConnector; +typedef struct _drmModeCrtc drmModeCrtc; +typedef struct _drmModeEncoder drmModeEncoder; +typedef struct _drmModeFB drmModeFB; +typedef struct _drmModeObjectProperties drmModeObjectProperties; +typedef struct _drmModePlane drmModePlane; +typedef struct _drmModePlaneRes drmModePlaneRes; +typedef struct _drmModeProperty drmModePropertyRes; +typedef struct _drmModePropertyBlob drmModePropertyBlobRes; +typedef struct _drmModeRes drmModeRes; + +namespace ui { + +struct DrmResourcesDeleter { + void operator()(drmModeRes* resources) const; +}; +struct DrmConnectorDeleter { + void operator()(drmModeConnector* connector) const; +}; +struct DrmCrtcDeleter { + void operator()(drmModeCrtc* crtc) const; +}; +struct DrmEncoderDeleter { + void operator()(drmModeEncoder* encoder) const; +}; +struct DrmObjectPropertiesDeleter { + void operator()(drmModeObjectProperties* properties) const; +}; +struct DrmPlaneDeleter { + void operator()(drmModePlane* plane) const; +}; +struct DrmPlaneResDeleter { + void operator()(drmModePlaneRes* plane_res) const; +}; +struct DrmPropertyDeleter { + void operator()(drmModePropertyRes* property) const; +}; +struct DrmPropertyBlobDeleter { + void operator()(drmModePropertyBlobRes* property) const; +}; +struct DrmFramebufferDeleter { + void operator()(drmModeFB* framebuffer) const; +}; + +typedef scoped_ptr<drmModeRes, DrmResourcesDeleter> ScopedDrmResourcesPtr; +typedef scoped_ptr<drmModeConnector, DrmConnectorDeleter> ScopedDrmConnectorPtr; +typedef scoped_ptr<drmModeCrtc, DrmCrtcDeleter> ScopedDrmCrtcPtr; +typedef scoped_ptr<drmModeEncoder, DrmEncoderDeleter> ScopedDrmEncoderPtr; +typedef scoped_ptr<drmModeObjectProperties, DrmObjectPropertiesDeleter> + ScopedDrmObjectPropertyPtr; +typedef scoped_ptr<drmModePlane, DrmPlaneDeleter> ScopedDrmPlanePtr; +typedef scoped_ptr<drmModePlaneRes, DrmPlaneResDeleter> ScopedDrmPlaneResPtr; +typedef scoped_ptr<drmModePropertyRes, DrmPropertyDeleter> ScopedDrmPropertyPtr; +typedef scoped_ptr<drmModePropertyBlobRes, DrmPropertyBlobDeleter> +ScopedDrmPropertyBlobPtr; +typedef scoped_ptr<drmModeFB, DrmFramebufferDeleter> ScopedDrmFramebufferPtr; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_SCOPED_DRM_TYPES_H_ diff --git a/chromium/ui/ozone/platform/dri/screen_manager.cc b/chromium/ui/ozone/platform/dri/screen_manager.cc index 3c1655c77d2..81258c64f7f 100644 --- a/chromium/ui/ozone/platform/dri/screen_manager.cc +++ b/chromium/ui/ozone/platform/dri/screen_manager.cc @@ -9,104 +9,140 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_util.h" +#include "ui/ozone/platform/dri/dri_wrapper.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" -#include "ui/ozone/platform/dri/scanout_surface.h" +#include "ui/ozone/platform/dri/scanout_buffer.h" namespace ui { -ScreenManager::ScreenManager( - DriWrapper* dri, ScanoutSurfaceGenerator* surface_generator) - : dri_(dri), surface_generator_(surface_generator), last_added_widget_(0) { +ScreenManager::ScreenManager(DriWrapper* dri, + ScanoutBufferGenerator* buffer_generator) + : dri_(dri), buffer_generator_(buffer_generator) { } ScreenManager::~ScreenManager() { - STLDeleteContainerPairSecondPointers( - controllers_.begin(), controllers_.end()); } -void ScreenManager::RemoveDisplayController(uint32_t crtc, uint32_t connector) { - HardwareDisplayControllerMap::iterator it = - FindDisplayController(crtc, connector); +void ScreenManager::AddDisplayController(DriWrapper* dri, + uint32_t crtc, + uint32_t connector) { + HardwareDisplayControllers::iterator it = FindDisplayController(crtc); + // TODO(dnicoara): Turn this into a DCHECK when async display configuration is + // properly supported. (When there can't be a race between forcing initial + // display configuration in ScreenManager and NativeDisplayDelegate creating + // the display controllers.) if (it != controllers_.end()) { - delete it->second; - controllers_.erase(it); + LOG(WARNING) << "Display controller (crtc=" << crtc << ") already present."; + return; } + + controllers_.push_back(new HardwareDisplayController( + scoped_ptr<CrtcController>(new CrtcController(dri, crtc, connector)))); } -bool ScreenManager::ConfigureDisplayController(uint32_t crtc, - uint32_t connector, - const drmModeModeInfo& mode) { - HardwareDisplayControllerMap::iterator it = - FindDisplayController(crtc, connector); - HardwareDisplayController* controller = NULL; +void ScreenManager::RemoveDisplayController(uint32_t crtc) { + HardwareDisplayControllers::iterator it = FindDisplayController(crtc); if (it != controllers_.end()) { - if (SameMode(mode, it->second->get_mode())) - return it->second->Enable(); - - controller = it->second; - controller->UnbindSurfaceFromController(); + bool is_mirrored = (*it)->IsMirrored(); + (*it)->RemoveCrtc(crtc); + if (!is_mirrored) + controllers_.erase(it); } +} - if (it == controllers_.end()) { - controller = new HardwareDisplayController(dri_, connector, crtc); - controllers_.insert(std::make_pair(++last_added_widget_, controller)); - } - - // Create a surface suitable for the current controller. - scoped_ptr<ScanoutSurface> surface( - surface_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay))); - - if (!surface->Initialize()) { - LOG(ERROR) << "Failed to initialize surface"; - return false; +bool ScreenManager::ConfigureDisplayController(uint32_t crtc, + uint32_t connector, + const gfx::Point& origin, + const drmModeModeInfo& mode) { + gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay, + mode.vdisplay); + HardwareDisplayControllers::iterator it = FindDisplayController(crtc); + DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc + << ") doesn't exist."; + + HardwareDisplayController* controller = *it; + controller = *it; + // If nothing changed just enable the controller. Note, we perform an exact + // comparison on the mode since the refresh rate may have changed. + if (SameMode(mode, controller->get_mode()) && + origin == controller->origin() && !controller->IsDisabled()) + return controller->Enable(); + + // Either the mode or the location of the display changed, so exit mirror + // mode and configure the display independently. If the caller still wants + // mirror mode, subsequent calls configuring the other controllers will + // restore mirror mode. + if (controller->IsMirrored()) { + controller = new HardwareDisplayController(controller->RemoveCrtc(crtc)); + controllers_.push_back(controller); + it = controllers_.end() - 1; } - // Bind the surface to the controller. This will register the backing buffers - // with the hardware CRTC such that we can show the buffers and performs the - // initial modeset. The controller takes ownership of the surface. - if (!controller->BindSurfaceToController(surface.Pass(), mode)) { - LOG(ERROR) << "Failed to bind surface to controller"; - return false; - } + HardwareDisplayControllers::iterator mirror = + FindActiveDisplayControllerByLocation(modeset_bounds); + // Handle mirror mode. + if (mirror != controllers_.end() && it != mirror) + return HandleMirrorMode(it, mirror, crtc, connector); - return true; + return ModesetDisplayController(controller, origin, mode); } -bool ScreenManager::DisableDisplayController(uint32_t crtc, - uint32_t connector) { - HardwareDisplayControllerMap::iterator it = - FindDisplayController(crtc, connector); +bool ScreenManager::DisableDisplayController(uint32_t crtc) { + HardwareDisplayControllers::iterator it = FindDisplayController(crtc); if (it != controllers_.end()) { - it->second->Disable(); + if ((*it)->IsMirrored()) { + HardwareDisplayController* controller = + new HardwareDisplayController((*it)->RemoveCrtc(crtc)); + controllers_.push_back(controller); + } + + (*it)->Disable(); return true; } + LOG(ERROR) << "Failed to find display controller crtc=" << crtc; return false; } base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController( - gfx::AcceleratedWidget widget) { + const gfx::Rect& bounds) { // TODO(dnicoara): Remove hack once TestScreen uses a simple Ozone display // configuration reader and ScreenManager is called from there to create the // one display needed by the content_shell target. - if (controllers_.empty() && last_added_widget_ == 0) + if (controllers_.empty()) ForceInitializationOfPrimaryDisplay(); - HardwareDisplayControllerMap::iterator it = controllers_.find(widget); + HardwareDisplayControllers::iterator it = + FindActiveDisplayControllerByLocation(bounds); if (it != controllers_.end()) - return it->second->AsWeakPtr(); + return (*it)->AsWeakPtr(); return base::WeakPtr<HardwareDisplayController>(); } -ScreenManager::HardwareDisplayControllerMap::iterator -ScreenManager::FindDisplayController(uint32_t crtc, uint32_t connector) { - for (HardwareDisplayControllerMap::iterator it = controllers_.begin(); +ScreenManager::HardwareDisplayControllers::iterator +ScreenManager::FindDisplayController(uint32_t crtc) { + for (HardwareDisplayControllers::iterator it = controllers_.begin(); + it != controllers_.end(); + ++it) { + if ((*it)->HasCrtc(crtc)) + return it; + } + + return controllers_.end(); +} + +ScreenManager::HardwareDisplayControllers::iterator +ScreenManager::FindActiveDisplayControllerByLocation(const gfx::Rect& bounds) { + for (HardwareDisplayControllers::iterator it = controllers_.begin(); it != controllers_.end(); ++it) { - if (it->second->connector_id() == connector && - it->second->crtc_id() == crtc) + gfx::Rect controller_bounds((*it)->origin(), (*it)->GetModeSize()); + // We don't perform a strict check since content_shell will have windows + // smaller than the display size. + if (controller_bounds.Contains(bounds) && !(*it)->IsDisabled()) return it; } @@ -114,24 +150,69 @@ ScreenManager::FindDisplayController(uint32_t crtc, uint32_t connector) { } void ScreenManager::ForceInitializationOfPrimaryDisplay() { - drmModeRes* resources = drmModeGetResources(dri_->get_fd()); - DCHECK(resources) << "Failed to get DRM resources"; + LOG(WARNING) << "Forcing initialization of primary display."; ScopedVector<HardwareDisplayControllerInfo> displays = - GetAvailableDisplayControllerInfos(dri_->get_fd(), resources); - drmModeFreeResources(resources); + GetAvailableDisplayControllerInfos(dri_->get_fd()); - CHECK_NE(0u, displays.size()); + if (displays.empty()) + return; - drmModePropertyRes* dpms = - dri_->GetProperty(displays[0]->connector(), "DPMS"); + ScopedDrmPropertyPtr dpms( + dri_->GetProperty(displays[0]->connector(), "DPMS")); if (dpms) dri_->SetProperty(displays[0]->connector()->connector_id, dpms->prop_id, DRM_MODE_DPMS_ON); + AddDisplayController(dri_, displays[0]->crtc()->crtc_id, + displays[0]->connector()->connector_id); ConfigureDisplayController(displays[0]->crtc()->crtc_id, displays[0]->connector()->connector_id, + gfx::Point(), displays[0]->connector()->modes[0]); } +bool ScreenManager::ModesetDisplayController( + HardwareDisplayController* controller, + const gfx::Point& origin, + const drmModeModeInfo& mode) { + controller->set_origin(origin); + // Create a surface suitable for the current controller. + scoped_refptr<ScanoutBuffer> buffer = + buffer_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay)); + + if (!buffer.get()) { + LOG(ERROR) << "Failed to create scanout buffer"; + return false; + } + + if (!controller->Modeset(OverlayPlane(buffer), mode)) { + LOG(ERROR) << "Failed to modeset controller"; + return false; + } + + return true; +} + +bool ScreenManager::HandleMirrorMode( + HardwareDisplayControllers::iterator original, + HardwareDisplayControllers::iterator mirror, + uint32_t crtc, + uint32_t connector) { + (*mirror)->AddCrtc((*original)->RemoveCrtc(crtc)); + if ((*mirror)->Enable()) { + controllers_.erase(original); + return true; + } + + LOG(ERROR) << "Failed to switch to mirror mode"; + + // When things go wrong revert back to the previous configuration since + // it is expected that the configuration would not have changed if + // things fail. + (*original)->AddCrtc((*mirror)->RemoveCrtc(crtc)); + (*original)->Enable(); + return false; +} + } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/screen_manager.h b/chromium/ui/ozone/platform/dri/screen_manager.h index fbe7bbb75df..6b955165713 100644 --- a/chromium/ui/ozone/platform/dri/screen_manager.h +++ b/chromium/ui/ozone/platform/dri/screen_manager.h @@ -5,11 +5,9 @@ #ifndef UI_OZONE_PLATFORM_DRI_SCREEN_MANAGER_H_ #define UI_OZONE_PLATFORM_DRI_SCREEN_MANAGER_H_ -#include <map> - #include "base/macros.h" +#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" -#include "ui/gfx/native_widget_types.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" typedef struct _drmModeModeInfo drmModeModeInfo; @@ -23,57 +21,76 @@ class Size; namespace ui { class DriWrapper; -class ScanoutSurfaceGenerator; +class ScanoutBufferGenerator; // Responsible for keeping track of active displays and configuring them. -class OZONE_EXPORT ScreenManager { +class ScreenManager { public: - ScreenManager(DriWrapper* dri, ScanoutSurfaceGenerator* surface_generator); + ScreenManager(DriWrapper* dri, ScanoutBufferGenerator* surface_generator); virtual ~ScreenManager(); + // Register a display controller. This must be called before trying to + // configure it. + void AddDisplayController(DriWrapper* dri, uint32_t crtc, uint32_t connector); + // Remove a display controller from the list of active controllers. The // controller is removed since it was disconnected. - void RemoveDisplayController(uint32_t crtc, uint32_t connector); + void RemoveDisplayController(uint32_t crtc); - // Configure (and add if not present) a display controller. The display - // controller is identified by (|crtc|, |connector|) and the controller is - // modeset using |mode|. + // Configure a display controller. The display controller is identified by + // (|crtc|, |connector|) and the controller is modeset using |mode|. bool ConfigureDisplayController(uint32_t crtc, uint32_t connector, + const gfx::Point& origin, const drmModeModeInfo& mode); - // Disable the display controller identified by (|crtc|, |connector|). Note, - // the controller may still be connected, so this does not remove the - // controller. - bool DisableDisplayController(uint32_t crtc, uint32_t connector); + // Disable the display controller identified by |crtc|. Note, the controller + // may still be connected, so this does not remove the controller. + bool DisableDisplayController(uint32_t crtc); - // Returns a reference to the display controller associated with |widget|. + // Returns a reference to the display controller configured to display within + // |bounds|. // This returns a weak reference since the display controller may be destroyed // at any point in time, but the changes are propagated to the compositor much // later (Compositor owns SurfaceOzone*, which is responsible for updating the // display surface). base::WeakPtr<HardwareDisplayController> GetDisplayController( - gfx::AcceleratedWidget widget); - - private: - typedef std::map<gfx::AcceleratedWidget, HardwareDisplayController*> - HardwareDisplayControllerMap; - - // Returns an iterator into |controllers_| for the controller identified by - // (|crtc|, |connector|). - HardwareDisplayControllerMap::iterator FindDisplayController( - uint32_t crtc, uint32_t connector); + const gfx::Rect& bounds); // On non CrOS builds there is no display configurator to look-up available // displays and initialize the HDCs. In such cases this is called internally // to initialize a display. virtual void ForceInitializationOfPrimaryDisplay(); + private: + typedef ScopedVector<HardwareDisplayController> HardwareDisplayControllers; + + // Returns an iterator into |controllers_| for the controller identified by + // (|crtc|, |connector|). + HardwareDisplayControllers::iterator FindDisplayController(uint32_t crtc); + + // Returns an iterator into |controllers_| for the controller located at + // |origin|. + HardwareDisplayControllers::iterator FindActiveDisplayControllerByLocation( + const gfx::Rect& bounds); + + // Perform modesetting in |controller| using |origin| and |mode|. + bool ModesetDisplayController(HardwareDisplayController* controller, + const gfx::Point& origin, + const drmModeModeInfo& mode); + + // Tries to set the controller identified by (|crtc|, |connector|) to mirror + // those in |mirror|. |original| is an iterator to the HDC where the + // controller is currently present. + bool HandleMirrorMode(HardwareDisplayControllers::iterator original, + HardwareDisplayControllers::iterator mirror, + uint32_t crtc, + uint32_t connector); + DriWrapper* dri_; // Not owned. - ScanoutSurfaceGenerator* surface_generator_; // Not owned. - // Mapping between an accelerated widget and an active display. - HardwareDisplayControllerMap controllers_; - gfx::AcceleratedWidget last_added_widget_; + ScanoutBufferGenerator* buffer_generator_; // Not owned. + // List of display controllers (active and disabled). + HardwareDisplayControllers controllers_; DISALLOW_COPY_AND_ASSIGN(ScreenManager); }; diff --git a/chromium/ui/ozone/platform/dri/screen_manager_unittest.cc b/chromium/ui/ozone/platform/dri/screen_manager_unittest.cc index 0851000a385..1312cdba52f 100644 --- a/chromium/ui/ozone/platform/dri/screen_manager_unittest.cc +++ b/chromium/ui/ozone/platform/dri/screen_manager_unittest.cc @@ -3,10 +3,10 @@ // found in the LICENSE file. #include "testing/gtest/include/gtest/gtest.h" +#include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/screen_manager.h" #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" -#include "ui/ozone/platform/dri/test/mock_surface_generator.h" namespace { @@ -14,13 +14,18 @@ namespace { const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; +const uint32_t kPrimaryCrtc = 1; +const uint32_t kPrimaryConnector = 2; +const uint32_t kSecondaryCrtc = 3; +const uint32_t kSecondaryConnector = 4; + class MockScreenManager : public ui::ScreenManager { public: MockScreenManager(ui::DriWrapper* dri, - ui::ScanoutSurfaceGenerator* surface_generator) - : ScreenManager(dri, surface_generator), dri_(dri) {} + ui::ScanoutBufferGenerator* buffer_generator) + : ScreenManager(dri, buffer_generator), dri_(dri) {} - virtual void ForceInitializationOfPrimaryDisplay() OVERRIDE {} + void ForceInitializationOfPrimaryDisplay() override {} private: ui::DriWrapper* dri_; @@ -33,22 +38,32 @@ class MockScreenManager : public ui::ScreenManager { class ScreenManagerTest : public testing::Test { public: ScreenManagerTest() {} - virtual ~ScreenManagerTest() {} + ~ScreenManagerTest() override {} + + gfx::Rect GetPrimaryBounds() const { + return gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay); + } - virtual void SetUp() OVERRIDE { + // Secondary is in extended mode, right-of primary. + gfx::Rect GetSecondaryBounds() const { + return gfx::Rect( + kDefaultMode.hdisplay, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay); + } + + void SetUp() override { dri_.reset(new ui::MockDriWrapper(3)); - surface_generator_.reset(new ui::MockSurfaceGenerator(dri_.get())); + buffer_generator_.reset(new ui::DriBufferGenerator(dri_.get())); screen_manager_.reset(new MockScreenManager( - dri_.get(), surface_generator_.get())); + dri_.get(), buffer_generator_.get())); } - virtual void TearDown() OVERRIDE { + void TearDown() override { screen_manager_.reset(); dri_.reset(); } protected: scoped_ptr<ui::MockDriWrapper> dri_; - scoped_ptr<ui::MockSurfaceGenerator> surface_generator_; + scoped_ptr<ui::DriBufferGenerator> buffer_generator_; scoped_ptr<MockScreenManager> screen_manager_; private: @@ -56,61 +71,182 @@ class ScreenManagerTest : public testing::Test { }; TEST_F(ScreenManagerTest, CheckWithNoControllers) { - EXPECT_FALSE(screen_manager_->GetDisplayController(1)); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds())); } TEST_F(ScreenManagerTest, CheckWithValidController) { - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); base::WeakPtr<ui::HardwareDisplayController> controller = - screen_manager_->GetDisplayController(1); + screen_manager_->GetDisplayController(GetPrimaryBounds()); EXPECT_TRUE(controller); - EXPECT_EQ(1u, controller->crtc_id()); - EXPECT_EQ(2u, controller->connector_id()); + EXPECT_TRUE(controller->HasCrtc(kPrimaryCrtc)); } -TEST_F(ScreenManagerTest, CheckWithInvalidId) { - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); +TEST_F(ScreenManagerTest, CheckWithInvalidBounds) { + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); - EXPECT_TRUE(screen_manager_->GetDisplayController(1)); - EXPECT_FALSE(screen_manager_->GetDisplayController(2)); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); } TEST_F(ScreenManagerTest, CheckForSecondValidController) { - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); - screen_manager_->ConfigureDisplayController(3, 4, kDefaultMode); - - EXPECT_TRUE(screen_manager_->GetDisplayController(1)); - EXPECT_TRUE(screen_manager_->GetDisplayController(2)); + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kSecondaryCrtc, + kSecondaryConnector); + screen_manager_->ConfigureDisplayController( + kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + kDefaultMode); + + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); } TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) { - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); base::WeakPtr<ui::HardwareDisplayController> controller = - screen_manager_->GetDisplayController(1); + screen_manager_->GetDisplayController(GetPrimaryBounds()); EXPECT_TRUE(controller); - screen_manager_->RemoveDisplayController(1, 2); + screen_manager_->RemoveDisplayController(kPrimaryCrtc); EXPECT_FALSE(controller); } TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) { - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); - - EXPECT_TRUE(screen_manager_->GetDisplayController(1)); - EXPECT_FALSE(screen_manager_->GetDisplayController(2)); + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); } TEST_F(ScreenManagerTest, CheckChangingMode) { - screen_manager_->ConfigureDisplayController(1, 2, kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); drmModeModeInfo new_mode = kDefaultMode; new_mode.vdisplay = 10; - screen_manager_->ConfigureDisplayController(1, 2, new_mode); - - EXPECT_TRUE(screen_manager_->GetDisplayController(1)); - EXPECT_FALSE(screen_manager_->GetDisplayController(2)); - drmModeModeInfo mode = screen_manager_->GetDisplayController(1)->get_mode(); + screen_manager_->ConfigureDisplayController( + kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), new_mode); + + gfx::Rect new_bounds(0, 0, new_mode.hdisplay, new_mode.vdisplay); + EXPECT_TRUE(screen_manager_->GetDisplayController(new_bounds)); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); + drmModeModeInfo mode = + screen_manager_->GetDisplayController(new_bounds)->get_mode(); EXPECT_EQ(new_mode.vdisplay, mode.vdisplay); EXPECT_EQ(new_mode.hdisplay, mode.hdisplay); } + +TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) { + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kSecondaryCrtc, + kSecondaryConnector); + screen_manager_->ConfigureDisplayController(kSecondaryCrtc, + kSecondaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); +} + +TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) { + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kSecondaryCrtc, + kSecondaryConnector); + screen_manager_->ConfigureDisplayController(kSecondaryCrtc, + kSecondaryConnector, + GetSecondaryBounds().origin(), + kDefaultMode); + + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); + + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController(kSecondaryCrtc, + kSecondaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); + + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetSecondaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController(kSecondaryCrtc, + kSecondaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); +} + +TEST_F(ScreenManagerTest, MonitorGoneInMirrorMode) { + screen_manager_->AddDisplayController(dri_.get(), kPrimaryCrtc, + kPrimaryConnector); + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->AddDisplayController(dri_.get(), kSecondaryCrtc, + kSecondaryConnector); + screen_manager_->ConfigureDisplayController(kSecondaryCrtc, + kSecondaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode); + + screen_manager_->RemoveDisplayController(kSecondaryCrtc); + EXPECT_TRUE( + screen_manager_->ConfigureDisplayController(kPrimaryCrtc, + kPrimaryConnector, + GetPrimaryBounds().origin(), + kDefaultMode)); + EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); + EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); +} diff --git a/chromium/ui/ozone/platform/dri/test/mock_dri_surface.cc b/chromium/ui/ozone/platform/dri/test/mock_dri_surface.cc deleted file mode 100644 index 4e0131110f5..00000000000 --- a/chromium/ui/ozone/platform/dri/test/mock_dri_surface.cc +++ /dev/null @@ -1,53 +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/platform/dri/test/mock_dri_surface.h" - -#include "third_party/skia/include/core/SkCanvas.h" -#include "ui/ozone/platform/dri/dri_buffer.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" - -namespace ui { - -namespace { - -class MockDriBuffer : public DriBuffer { - public: - MockDriBuffer(DriWrapper* dri, bool initialize_expectation) - : DriBuffer(dri), initialize_expectation_(initialize_expectation) {} - virtual ~MockDriBuffer() { surface_.clear(); } - - virtual bool Initialize(const SkImageInfo& info) OVERRIDE { - if (!initialize_expectation_) - return false; - - dri_->AddFramebuffer( - info.width(), info.height(), 24, 32, stride_, handle_, &framebuffer_); - surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); - surface_->getCanvas()->clear(SK_ColorBLACK); - - return true; - } - - private: - bool initialize_expectation_; - - DISALLOW_COPY_AND_ASSIGN(MockDriBuffer); -}; - -} // namespace - -MockDriSurface::MockDriSurface(DriWrapper* dri, const gfx::Size& size) - : DriSurface(dri, size), dri_(dri), initialize_expectation_(true) {} - -MockDriSurface::~MockDriSurface() {} - -DriBuffer* MockDriSurface::CreateBuffer() { - MockDriBuffer* bitmap = new MockDriBuffer(dri_, initialize_expectation_); - bitmaps_.push_back(bitmap); - - return bitmap; -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/test/mock_dri_surface.h b/chromium/ui/ozone/platform/dri/test/mock_dri_surface.h deleted file mode 100644 index 61b9a9f7757..00000000000 --- a/chromium/ui/ozone/platform/dri/test/mock_dri_surface.h +++ /dev/null @@ -1,45 +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_PLATFORM_DRI_TEST_MOCK_DRI_SURFACE_H_ -#define UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_SURFACE_H_ - -#include <vector> - -#include "ui/ozone/platform/dri/dri_surface.h" - -namespace gfx { -class Size; -} // namespace gfx - -namespace ui { - -class DriBuffer; -class DriWrapper; - -class MockDriSurface : public DriSurface { - public: - MockDriSurface(DriWrapper* dri, const gfx::Size& size); - virtual ~MockDriSurface(); - - const std::vector<ui::DriBuffer*>& bitmaps() const { return bitmaps_; } - void set_initialize_expectation(bool state) { - initialize_expectation_ = state; - } - - private: - // DriSurface: - virtual ui::DriBuffer* CreateBuffer() OVERRIDE; - - DriWrapper* dri_; // Not owned. - std::vector<DriBuffer*> bitmaps_; // Not owned. - - bool initialize_expectation_; - - DISALLOW_COPY_AND_ASSIGN(MockDriSurface); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_SURFACE_H_ diff --git a/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.cc b/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.cc index f950db2152f..76c3ee188a5 100644 --- a/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.cc +++ b/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.cc @@ -4,24 +4,38 @@ #include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include <xf86drm.h> #include <xf86drmMode.h> -#include "ui/ozone/platform/dri/dri_surface.h" -#include "ui/ozone/platform/dri/hardware_display_controller.h" +#include "base/logging.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "ui/ozone/platform/dri/crtc_controller.h" namespace ui { +namespace { + +template<class Object> Object* DrmAllocator() { + return static_cast<Object*>(drmMalloc(sizeof(Object))); +} + +} // namespace + MockDriWrapper::MockDriWrapper(int fd) : DriWrapper(""), get_crtc_call_count_(0), - free_crtc_call_count_(0), + set_crtc_call_count_(0), restore_crtc_call_count_(0), add_framebuffer_call_count_(0), remove_framebuffer_call_count_(0), page_flip_call_count_(0), + overlay_flip_call_count_(0), + handle_events_count_(0), set_crtc_expectation_(true), add_framebuffer_expectation_(true), - page_flip_expectation_(true) { + page_flip_expectation_(true), + create_dumb_buffer_expectation_(true), + current_framebuffer_(0) { fd_ = fd; } @@ -29,28 +43,30 @@ MockDriWrapper::~MockDriWrapper() { fd_ = -1; } -drmModeCrtc* MockDriWrapper::GetCrtc(uint32_t crtc_id) { +ScopedDrmCrtcPtr MockDriWrapper::GetCrtc(uint32_t crtc_id) { get_crtc_call_count_++; - return new drmModeCrtc; -} - -void MockDriWrapper::FreeCrtc(drmModeCrtc* crtc) { - free_crtc_call_count_++; - delete crtc; + return ScopedDrmCrtcPtr(DrmAllocator<drmModeCrtc>()); } bool MockDriWrapper::SetCrtc(uint32_t crtc_id, uint32_t framebuffer, - uint32_t* connectors, + std::vector<uint32_t> connectors, drmModeModeInfo* mode) { + current_framebuffer_ = framebuffer; + set_crtc_call_count_++; return set_crtc_expectation_; } -bool MockDriWrapper::SetCrtc(drmModeCrtc* crtc, uint32_t* connectors) { +bool MockDriWrapper::SetCrtc(drmModeCrtc* crtc, + std::vector<uint32_t> connectors) { restore_crtc_call_count_++; return true; } +ScopedDrmConnectorPtr MockDriWrapper::GetConnector(uint32_t connector_id) { + return ScopedDrmConnectorPtr(DrmAllocator<drmModeConnector>()); +} + bool MockDriWrapper::AddFramebuffer(uint32_t width, uint32_t height, uint8_t depth, @@ -72,42 +88,80 @@ bool MockDriWrapper::PageFlip(uint32_t crtc_id, uint32_t framebuffer, void* data) { page_flip_call_count_++; - static_cast<ui::HardwareDisplayController*>(data)->surface()->SwapBuffers(); + current_framebuffer_ = framebuffer; + controllers_.push(static_cast<ui::CrtcController*>(data)); return page_flip_expectation_; } +bool MockDriWrapper::PageFlipOverlay(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& location, + const gfx::RectF& source, + int overlay_plane) { + overlay_flip_call_count_++; + return true; +} + +ScopedDrmPropertyPtr MockDriWrapper::GetProperty(drmModeConnector* connector, + const char* name) { + return ScopedDrmPropertyPtr(DrmAllocator<drmModePropertyRes>()); +} + bool MockDriWrapper::SetProperty(uint32_t connector_id, uint32_t property_id, uint64_t value) { return true; } -void MockDriWrapper::FreeProperty(drmModePropertyRes* prop) { - delete prop; +bool MockDriWrapper::GetCapability(uint64_t capability, uint64_t* value) { + return true; } -drmModePropertyBlobRes* MockDriWrapper::GetPropertyBlob( +ScopedDrmPropertyBlobPtr MockDriWrapper::GetPropertyBlob( drmModeConnector* connector, const char* name) { - return new drmModePropertyBlobRes; -} - -void MockDriWrapper::FreePropertyBlob(drmModePropertyBlobRes* blob) { - delete blob; + return ScopedDrmPropertyBlobPtr(DrmAllocator<drmModePropertyBlobRes>()); } bool MockDriWrapper::SetCursor(uint32_t crtc_id, uint32_t handle, - uint32_t width, - uint32_t height) { + const gfx::Size& size) { return true; } -bool MockDriWrapper::MoveCursor(uint32_t crtc_id, int x, int y) { +bool MockDriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { return true; } void MockDriWrapper::HandleEvent(drmEventContext& event) { + CHECK(!controllers_.empty()); + controllers_.front()->OnPageFlipEvent(0, 0, 0); + controllers_.pop(); + handle_events_count_++; +} + +bool MockDriWrapper::CreateDumbBuffer(const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride, + void** pixels) { + if (!create_dumb_buffer_expectation_) + return false; + + *handle = 0; + *stride = info.minRowBytes(); + *pixels = new char[info.getSafeSize(*stride)]; + buffers_.push_back( + skia::AdoptRef(SkSurface::NewRasterDirect(info, *pixels, *stride))); + buffers_.back()->getCanvas()->clear(SK_ColorBLACK); + + return true; +} + +void MockDriWrapper::DestroyDumbBuffer(const SkImageInfo& info, + uint32_t handle, + uint32_t stride, + void* pixels) { + delete[] static_cast<char*>(pixels); } } // namespace ui diff --git a/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.h b/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.h index 791d55c2ecd..947c15a2217 100644 --- a/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.h +++ b/chromium/ui/ozone/platform/dri/test/mock_dri_wrapper.h @@ -5,18 +5,25 @@ #ifndef UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_WRAPPER_H_ #define UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_WRAPPER_H_ +#include <queue> +#include <vector> + +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkSurface.h" #include "ui/ozone/platform/dri/dri_wrapper.h" namespace ui { +class CrtcController; + // The real DriWrapper makes actual DRM calls which we can't use in unit tests. class MockDriWrapper : public ui::DriWrapper { public: MockDriWrapper(int fd); - virtual ~MockDriWrapper(); + ~MockDriWrapper() override; int get_get_crtc_call_count() const { return get_crtc_call_count_; } - int get_free_crtc_call_count() const { return free_crtc_call_count_; } + int get_set_crtc_call_count() const { return set_crtc_call_count_; } int get_restore_crtc_call_count() const { return restore_crtc_call_count_; } int get_add_framebuffer_call_count() const { return add_framebuffer_call_count_; @@ -25,57 +32,93 @@ class MockDriWrapper : public ui::DriWrapper { return remove_framebuffer_call_count_; } int get_page_flip_call_count() const { return page_flip_call_count_; } + int get_overlay_flip_call_count() const { return overlay_flip_call_count_; } + int get_handle_events_count() const { return handle_events_count_; } void fail_init() { fd_ = -1; } void set_set_crtc_expectation(bool state) { set_crtc_expectation_ = state; } void set_page_flip_expectation(bool state) { page_flip_expectation_ = state; } void set_add_framebuffer_expectation(bool state) { add_framebuffer_expectation_ = state; } + void set_create_dumb_buffer_expectation(bool state) { + create_dumb_buffer_expectation_ = state; + } + + uint32_t current_framebuffer() const { return current_framebuffer_; } + + const std::vector<skia::RefPtr<SkSurface> > buffers() const { + return buffers_; + } + + // Overwrite the list of controllers used when serving the PageFlip requests. + void set_controllers(const std::queue<CrtcController*>& controllers) { + controllers_ = controllers; + } // DriWrapper: - virtual drmModeCrtc* GetCrtc(uint32_t crtc_id) OVERRIDE; - virtual void FreeCrtc(drmModeCrtc* crtc) OVERRIDE; - virtual bool SetCrtc(uint32_t crtc_id, + ScopedDrmCrtcPtr GetCrtc(uint32_t crtc_id) override; + bool SetCrtc(uint32_t crtc_id, + uint32_t framebuffer, + std::vector<uint32_t> connectors, + drmModeModeInfo* mode) override; + bool SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) override; + ScopedDrmConnectorPtr GetConnector(uint32_t connector_id) override; + bool AddFramebuffer(uint32_t width, + uint32_t height, + uint8_t depth, + uint8_t bpp, + uint32_t stride, + uint32_t handle, + uint32_t* framebuffer) override; + bool RemoveFramebuffer(uint32_t framebuffer) override; + bool PageFlip(uint32_t crtc_id, uint32_t framebuffer, void* data) override; + bool PageFlipOverlay(uint32_t crtc_id, uint32_t framebuffer, - uint32_t* connectors, - drmModeModeInfo* mode) OVERRIDE; - virtual bool SetCrtc(drmModeCrtc* crtc, uint32_t* connectors) OVERRIDE; - virtual bool AddFramebuffer(uint32_t width, - uint32_t height, - uint8_t depth, - uint8_t bpp, - uint32_t stride, - uint32_t handle, - uint32_t* framebuffer) OVERRIDE; - virtual bool RemoveFramebuffer(uint32_t framebuffer) OVERRIDE; - virtual bool PageFlip(uint32_t crtc_id, - uint32_t framebuffer, - void* data) OVERRIDE; - virtual bool SetProperty(uint32_t connector_id, - uint32_t property_id, - uint64_t value) OVERRIDE; - virtual void FreeProperty(drmModePropertyRes* prop) OVERRIDE; - virtual drmModePropertyBlobRes* GetPropertyBlob(drmModeConnector* connector, - const char* name) OVERRIDE; - virtual void FreePropertyBlob(drmModePropertyBlobRes* blob) OVERRIDE; - virtual bool SetCursor(uint32_t crtc_id, + const gfx::Rect& location, + const gfx::RectF& source, + int overlay_plane) override; + ScopedDrmPropertyPtr GetProperty(drmModeConnector* connector, + const char* name) override; + bool SetProperty(uint32_t connector_id, + uint32_t property_id, + uint64_t value) override; + bool GetCapability(uint64_t capability, uint64_t* value) override; + ScopedDrmPropertyBlobPtr GetPropertyBlob(drmModeConnector* connector, + const char* name) override; + bool SetCursor(uint32_t crtc_id, + uint32_t handle, + const gfx::Size& size) override; + bool MoveCursor(uint32_t crtc_id, const gfx::Point& point) override; + void HandleEvent(drmEventContext& event) override; + bool CreateDumbBuffer(const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride, + void** pixels) override; + void DestroyDumbBuffer(const SkImageInfo& info, uint32_t handle, - uint32_t width, - uint32_t height) OVERRIDE; - virtual bool MoveCursor(uint32_t crtc_id, int x, int y) OVERRIDE; - virtual void HandleEvent(drmEventContext& event) OVERRIDE; + uint32_t stride, + void* pixels) override; private: int get_crtc_call_count_; - int free_crtc_call_count_; + int set_crtc_call_count_; int restore_crtc_call_count_; int add_framebuffer_call_count_; int remove_framebuffer_call_count_; int page_flip_call_count_; + int overlay_flip_call_count_; + int handle_events_count_; bool set_crtc_expectation_; bool add_framebuffer_expectation_; bool page_flip_expectation_; + bool create_dumb_buffer_expectation_; + + uint32_t current_framebuffer_; + + std::vector<skia::RefPtr<SkSurface> > buffers_; + + std::queue<CrtcController*> controllers_; DISALLOW_COPY_AND_ASSIGN(MockDriWrapper); }; diff --git a/chromium/ui/ozone/platform/dri/test/mock_surface_generator.cc b/chromium/ui/ozone/platform/dri/test/mock_surface_generator.cc deleted file mode 100644 index 97df5bdbd2c..00000000000 --- a/chromium/ui/ozone/platform/dri/test/mock_surface_generator.cc +++ /dev/null @@ -1,18 +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/platform/dri/test/mock_surface_generator.h" - -namespace ui { - -MockSurfaceGenerator::MockSurfaceGenerator(DriWrapper* dri) : dri_(dri) {} - -MockSurfaceGenerator::~MockSurfaceGenerator() {} - -ScanoutSurface* MockSurfaceGenerator::Create(const gfx::Size& size) { - surfaces_.push_back(new MockDriSurface(dri_, size)); - return surfaces_.back(); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/test/mock_surface_generator.h b/chromium/ui/ozone/platform/dri/test/mock_surface_generator.h deleted file mode 100644 index d9b77f8620d..00000000000 --- a/chromium/ui/ozone/platform/dri/test/mock_surface_generator.h +++ /dev/null @@ -1,40 +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_PLATFORM_DRI_TEST_MOCK_SURFACE_GENERATOR_H_ -#define UI_OZONE_PLATFORM_DRI_TEST_MOCK_SURFACE_GENERATOR_H_ - -#include <vector> - -#include "ui/ozone/platform/dri/test/mock_dri_surface.h" - -namespace gfx { -class Size; -} - -namespace ui { - -class DriWrapper; - -class MockSurfaceGenerator : public ScanoutSurfaceGenerator { - public: - MockSurfaceGenerator(DriWrapper* dri); - virtual ~MockSurfaceGenerator(); - - std::vector<MockDriSurface*> surfaces() const { return surfaces_; } - - // ScanoutSurfaceGenerator: - virtual ScanoutSurface* Create(const gfx::Size& size) OVERRIDE; - - private: - DriWrapper* dri_; // Not owned. - - std::vector<MockDriSurface*> surfaces_; - - DISALLOW_COPY_AND_ASSIGN(MockSurfaceGenerator); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_TEST_MOCK_SURFACE_GENERATOR_H_ diff --git a/chromium/ui/ozone/platform/dri/virtual_terminal_manager.cc b/chromium/ui/ozone/platform/dri/virtual_terminal_manager.cc deleted file mode 100644 index efd83504577..00000000000 --- a/chromium/ui/ozone/platform/dri/virtual_terminal_manager.cc +++ /dev/null @@ -1,75 +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/platform/dri/virtual_terminal_manager.h" - -#include <errno.h> -#include <fcntl.h> -#include <linux/kd.h> -#include <linux/vt.h> -#include <sys/ioctl.h> -#include <unistd.h> - -#include "base/logging.h" - -namespace ui { - -namespace { - -const char kTTYDevice[] = "/dev/tty1"; - -const int kVT = 1; - -} // namespace - -VirtualTerminalManager::VirtualTerminalManager() { - // Use the current console. - fd_ = open(kTTYDevice, O_RDWR | O_CLOEXEC, 0); - if (fd_ < 0) - LOG(ERROR) << "Failed to open '" << kTTYDevice << "' " << strerror(errno); - - if (ioctl(fd_, VT_ACTIVATE, kVT) || ioctl(fd_, VT_WAITACTIVE, kVT)) - LOG(ERROR) << "Failed to switch to VT: " << kVT - << " error: " << strerror(errno);; - - if (ioctl(fd_, KDGETMODE, &vt_mode_)) - LOG(ERROR) << "Failed to get VT mode: " << strerror(errno); - - if (ioctl(fd_, KDSETMODE, KD_GRAPHICS)) - LOG(ERROR) << "Failed to set graphics mode: " << strerror(errno); - - if (tcgetattr(fd_, &terminal_attributes_)) - LOG(ERROR) << "Failed to get terminal attributes"; - - // Stop the TTY from processing keys and echo-ing them to the terminal. - struct termios raw_attributes = terminal_attributes_; - cfmakeraw(&raw_attributes); - raw_attributes.c_oflag |= OPOST; - if (tcsetattr(fd_, TCSANOW, &raw_attributes)) - LOG(ERROR) << "Failed to set raw attributes"; - - if (ioctl(fd_, KDGKBMODE, &previous_keyboard_mode_)) - LOG(ERROR) << "Failed to get keyboard mode"; - - if (ioctl(fd_, KDSKBMODE, K_OFF) && ioctl(fd_, KDSKBMODE, K_RAW)) - LOG(ERROR) << "Failed to set keyboard mode"; -} - -VirtualTerminalManager::~VirtualTerminalManager() { - if (fd_ < 0) - return; - - if (ioctl(fd_, KDSETMODE, &vt_mode_)) - LOG(ERROR) << "Failed to restore VT mode"; - - if (ioctl(fd_, KDSKBMODE, previous_keyboard_mode_)) - LOG(ERROR) << "Failed to restore keyboard mode"; - - if (tcsetattr(fd_, TCSANOW, &terminal_attributes_)) - LOG(ERROR) << "Failed to restore terminal attributes"; - - close(fd_); -} - -} // namespace ui diff --git a/chromium/ui/ozone/platform/dri/virtual_terminal_manager.h b/chromium/ui/ozone/platform/dri/virtual_terminal_manager.h deleted file mode 100644 index 11af0b0c2a2..00000000000 --- a/chromium/ui/ozone/platform/dri/virtual_terminal_manager.h +++ /dev/null @@ -1,31 +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_PLATFORM_DRI_VIRTUAL_TERMINAL_MANAGER_H_ -#define UI_OZONE_PLATFORM_DRI_VIRTUAL_TERMINAL_MANAGER_H_ - -#include <termios.h> - -#include "base/basictypes.h" - -namespace ui { - -class VirtualTerminalManager { - public: - VirtualTerminalManager(); - ~VirtualTerminalManager(); - - private: - - int fd_; - int vt_mode_; - int previous_keyboard_mode_; - struct termios terminal_attributes_; - - DISALLOW_COPY_AND_ASSIGN(VirtualTerminalManager); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_VIRTUAL_TERMINAL_MANAGER_H_ diff --git a/chromium/ui/ozone/platform/egltest/BUILD.gn b/chromium/ui/ozone/platform/egltest/BUILD.gn new file mode 100644 index 00000000000..04cae36a95b --- /dev/null +++ b/chromium/ui/ozone/platform/egltest/BUILD.gn @@ -0,0 +1,40 @@ +# 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. + +import("//tools/generate_library_loader/generate_library_loader.gni") + +source_set("egltest") { + sources = [ + "ozone_platform_egltest.cc", + "ozone_platform_egltest.h", + ] + + deps = [ + ":eglplatform_shim", + "//base", + "//ui/events/ozone:events_ozone_evdev", + "//ui/gfx", + ] +} + +generate_library_loader("eglplatform_shim") { + name = "LibeglplatformShimLoader" + output_h = "libeglplatform_shim.h" + output_cc = "libeglplatform_shim_loader.cc" + header = "\"ui/ozone/platform/egltest/eglplatform_shim.h\"" + + functions = [ + "ShimQueryString", + "ShimInitialize", + "ShimTerminate", + "ShimCreateWindow", + "ShimQueryWindow", + "ShimDestroyWindow", + "ShimGetNativeDisplay", + "ShimGetNativeWindow", + "ShimReleaseNativeWindow", + ] +} + +# TODO(spang): eglplatform_shim_x11 once support lands: http://crbug.com/380327 diff --git a/chromium/ui/ozone/platform/egltest/eglplatform_shim_xeleven.cc b/chromium/ui/ozone/platform/egltest/eglplatform_shim_xeleven.cc index af1228d0fc0..c7e00808619 100644 --- a/chromium/ui/ozone/platform/egltest/eglplatform_shim_xeleven.cc +++ b/chromium/ui/ozone/platform/egltest/eglplatform_shim_xeleven.cc @@ -17,8 +17,8 @@ Display* g_display; const int kDefaultX = 0; const int kDefaultY = 0; -const int kDefaultWidth = 800; -const int kDefaultHeight = 600; +const int kDefaultWidth = 1280; +const int kDefaultHeight = 720; const int kDefaultBorderWidth = 0; const char* ShimQueryString(int name) { diff --git a/chromium/ui/ozone/platform/egltest/egltest.gypi b/chromium/ui/ozone/platform/egltest/egltest.gypi index 220099efa6e..8191af555de 100644 --- a/chromium/ui/ozone/platform/egltest/egltest.gypi +++ b/chromium/ui/ozone/platform/egltest/egltest.gypi @@ -20,6 +20,7 @@ ], 'dependencies': [ '../../base/base.gyp:base', + '../../third_party/khronos/khronos.gyp:khronos_headers', '../events/events.gyp:events', '../events/ozone/events_ozone.gyp:events_ozone_evdev', '../gfx/gfx.gyp:gfx', diff --git a/chromium/ui/ozone/platform/egltest/ozone_platform_egltest.cc b/chromium/ui/ozone/platform/egltest/ozone_platform_egltest.cc index 8179aa49135..08aa8ab75b7 100644 --- a/chromium/ui/ozone/platform/egltest/ozone_platform_egltest.cc +++ b/chromium/ui/ozone/platform/egltest/ozone_platform_egltest.cc @@ -4,28 +4,28 @@ #include "ui/ozone/platform/egltest/ozone_platform_egltest.h" +#include "base/bind.h" #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "library_loaders/libeglplatform_shim.h" +#include "third_party/khronos/EGL/egl.h" #include "ui/events/ozone/device/device_manager.h" #include "ui/events/ozone/evdev/event_factory_evdev.h" +#include "ui/events/ozone/events_ozone.h" +#include "ui/events/platform/platform_event_dispatcher.h" #include "ui/gfx/vsync_provider.h" -#include "ui/ozone/ozone_platform.h" -#include "ui/ozone/ozone_switches.h" -#include "ui/ozone/platform/test/file_surface_factory.h" +#include "ui/ozone/common/native_display_delegate_ozone.h" #include "ui/ozone/public/cursor_factory_ozone.h" #include "ui/ozone/public/gpu_platform_support.h" #include "ui/ozone/public/gpu_platform_support_host.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/ozone_switches.h" +#include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_ozone_egl.h" - -#if defined(OS_CHROMEOS) -#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h" -#include "ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h" -#endif - -#include <EGL/egl.h> +#include "ui/platform_window/platform_window.h" +#include "ui/platform_window/platform_window_delegate.h" namespace ui { @@ -45,6 +45,118 @@ std::string GetShimLibraryName() { return kEglplatformShimDefault; } +class EgltestWindow : public PlatformWindow, public PlatformEventDispatcher { + public: + EgltestWindow(PlatformWindowDelegate* delegate, + LibeglplatformShimLoader* eglplatform_shim, + EventFactoryEvdev* event_factory, + const gfx::Rect& bounds); + ~EgltestWindow() override; + + // PlatformWindow: + gfx::Rect GetBounds() override; + void SetBounds(const gfx::Rect& bounds) override; + void Show() override; + void Hide() override; + void Close() override; + void SetCapture() override; + void ReleaseCapture() override; + void ToggleFullscreen() override; + void Maximize() override; + void Minimize() override; + void Restore() override; + void SetCursor(PlatformCursor cursor) override; + void MoveCursorTo(const gfx::Point& location) override; + + // PlatformEventDispatcher: + bool CanDispatchEvent(const PlatformEvent& event) override; + uint32_t DispatchEvent(const PlatformEvent& event) override; + + private: + PlatformWindowDelegate* delegate_; + LibeglplatformShimLoader* eglplatform_shim_; + EventFactoryEvdev* event_factory_; + gfx::Rect bounds_; + ShimNativeWindowId window_id_; + + DISALLOW_COPY_AND_ASSIGN(EgltestWindow); +}; + +EgltestWindow::EgltestWindow(PlatformWindowDelegate* delegate, + LibeglplatformShimLoader* eglplatform_shim, + EventFactoryEvdev* event_factory, + const gfx::Rect& bounds) + : delegate_(delegate), + eglplatform_shim_(eglplatform_shim), + event_factory_(event_factory), + bounds_(bounds), + window_id_(SHIM_NO_WINDOW_ID) { + window_id_ = eglplatform_shim_->ShimCreateWindow(); + delegate_->OnAcceleratedWidgetAvailable(window_id_); + ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); +} + +EgltestWindow::~EgltestWindow() { + ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); + if (window_id_ != SHIM_NO_WINDOW_ID) + eglplatform_shim_->ShimDestroyWindow(window_id_); +} + +gfx::Rect EgltestWindow::GetBounds() { + return bounds_; +} + +void EgltestWindow::SetBounds(const gfx::Rect& bounds) { + bounds_ = bounds; + delegate_->OnBoundsChanged(bounds); +} + +void EgltestWindow::Show() { +} + +void EgltestWindow::Hide() { +} + +void EgltestWindow::Close() { +} + +void EgltestWindow::SetCapture() { +} + +void EgltestWindow::ReleaseCapture() { +} + +void EgltestWindow::ToggleFullscreen() { +} + +void EgltestWindow::Maximize() { +} + +void EgltestWindow::Minimize() { +} + +void EgltestWindow::Restore() { +} + +void EgltestWindow::SetCursor(PlatformCursor cursor) { +} + +void EgltestWindow::MoveCursorTo(const gfx::Point& location) { + event_factory_->WarpCursorTo(window_id_, location); +} + +bool EgltestWindow::CanDispatchEvent(const ui::PlatformEvent& ne) { + return true; +} + +uint32_t EgltestWindow::DispatchEvent(const ui::PlatformEvent& native_event) { + DispatchEventFromNativeUiEvent( + native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent, + base::Unretained(delegate_))); + + return ui::POST_DISPATCH_STOP_PROPAGATION; +} + // EGL surface wrapper for libeglplatform_shim. // // This just manages the native window lifetime using @@ -56,19 +168,20 @@ class SurfaceOzoneEgltest : public SurfaceOzoneEGL { : eglplatform_shim_(eglplatform_shim) { native_window_ = eglplatform_shim_->ShimGetNativeWindow(window_id); } - virtual ~SurfaceOzoneEgltest() { - CHECK(eglplatform_shim_->ShimReleaseNativeWindow(native_window_)); + ~SurfaceOzoneEgltest() { + bool ret = eglplatform_shim_->ShimReleaseNativeWindow(native_window_); + DCHECK(ret); } - virtual intptr_t GetNativeWindow() OVERRIDE { return native_window_; } + intptr_t GetNativeWindow() override { return native_window_; } - virtual bool OnSwapBuffers() OVERRIDE { return true; } + bool OnSwapBuffers() override { return true; } - virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) OVERRIDE { + bool ResizeNativeWindow(const gfx::Size& viewport_size) override { return true; } - virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE { + scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override { return scoped_ptr<gfx::VSyncProvider>(); } @@ -85,61 +198,26 @@ class SurfaceOzoneEgltest : public SurfaceOzoneEGL { class SurfaceFactoryEgltest : public ui::SurfaceFactoryOzone { public: SurfaceFactoryEgltest(LibeglplatformShimLoader* eglplatform_shim) - : eglplatform_shim_(eglplatform_shim), window_id_(SHIM_NO_WINDOW_ID) {} - virtual ~SurfaceFactoryEgltest() { DestroySingleWindow(); } - - // Create the window. - bool CreateSingleWindow(); - void DestroySingleWindow(); + : eglplatform_shim_(eglplatform_shim) {} + ~SurfaceFactoryEgltest() override {} // SurfaceFactoryOzone: - virtual HardwareState InitializeHardware() OVERRIDE; - virtual void ShutdownHardware() OVERRIDE; - virtual intptr_t GetNativeDisplay() OVERRIDE; - virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; - virtual scoped_ptr<SurfaceOzoneEGL> CreateEGLSurfaceForWidget( - gfx::AcceleratedWidget widget) OVERRIDE; - virtual const int32* GetEGLSurfaceProperties( - const int32* desired_list) OVERRIDE; - virtual bool LoadEGLGLES2Bindings( + intptr_t GetNativeDisplay() override; + scoped_ptr<SurfaceOzoneEGL> CreateEGLSurfaceForWidget( + gfx::AcceleratedWidget widget) override; + const int32* GetEGLSurfaceProperties(const int32* desired_list) override; + bool LoadEGLGLES2Bindings( AddGLLibraryCallback add_gl_library, - SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE; + SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; private: LibeglplatformShimLoader* eglplatform_shim_; - - // TODO(spang): Remove once we have a windowing API. This limits to 1 window. - ShimNativeWindowId window_id_; }; -bool SurfaceFactoryEgltest::CreateSingleWindow() { - window_id_ = eglplatform_shim_->ShimCreateWindow(); - return (window_id_ != SHIM_NO_WINDOW_ID); -} - -void SurfaceFactoryEgltest::DestroySingleWindow() { - if (window_id_ != SHIM_NO_WINDOW_ID) - CHECK(eglplatform_shim_->ShimDestroyWindow(window_id_)); -} - -SurfaceFactoryEgltest::HardwareState -SurfaceFactoryEgltest::InitializeHardware() { - return INITIALIZED; -} - -void SurfaceFactoryEgltest::ShutdownHardware() { -} - intptr_t SurfaceFactoryEgltest::GetNativeDisplay() { return eglplatform_shim_->ShimGetNativeDisplay(); } -gfx::AcceleratedWidget SurfaceFactoryEgltest::GetAcceleratedWidget() { - if (window_id_ == SHIM_NO_WINDOW_ID && !CreateSingleWindow()) - LOG(FATAL) << "failed to create window"; - return window_id_; -} - scoped_ptr<SurfaceOzoneEGL> SurfaceFactoryEgltest::CreateEGLSurfaceForWidget( gfx::AcceleratedWidget widget) { return make_scoped_ptr<SurfaceOzoneEGL>( @@ -237,45 +315,46 @@ class OzonePlatformEgltest : public OzonePlatform { } // OzonePlatform: - virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE { + ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { return surface_factory_ozone_.get(); } - virtual EventFactoryOzone* GetEventFactoryOzone() OVERRIDE { - return event_factory_ozone_.get(); - } - virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE { + CursorFactoryOzone* GetCursorFactoryOzone() override { return cursor_factory_ozone_.get(); } - virtual GpuPlatformSupport* GetGpuPlatformSupport() OVERRIDE { + GpuPlatformSupport* GetGpuPlatformSupport() override { return gpu_platform_support_.get(); } - virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() OVERRIDE { + GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { return gpu_platform_support_host_.get(); } - -#if defined(OS_CHROMEOS) - virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() - OVERRIDE { - return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); + scoped_ptr<PlatformWindow> CreatePlatformWindow( + PlatformWindowDelegate* delegate, + const gfx::Rect& bounds) override { + return make_scoped_ptr<PlatformWindow>( + new EgltestWindow(delegate, + &eglplatform_shim_, + event_factory_ozone_.get(), + bounds)); } - virtual scoped_ptr<TouchscreenDeviceManager> - CreateTouchscreenDeviceManager() OVERRIDE { - return scoped_ptr<TouchscreenDeviceManager>( - new TouchscreenDeviceManagerOzone()); + scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override { + return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); } -#endif - virtual void InitializeUI() OVERRIDE { + void InitializeUI() override { device_manager_ = CreateDeviceManager(); - surface_factory_ozone_.reset(new SurfaceFactoryEgltest(&eglplatform_shim_)); + if (!surface_factory_ozone_) + surface_factory_ozone_.reset( + new SurfaceFactoryEgltest(&eglplatform_shim_)); event_factory_ozone_.reset( new EventFactoryEvdev(NULL, device_manager_.get())); cursor_factory_ozone_.reset(new CursorFactoryOzone()); gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); } - virtual void InitializeGPU() OVERRIDE { - surface_factory_ozone_.reset(new SurfaceFactoryEgltest(&eglplatform_shim_)); + void InitializeGPU() override { + if (!surface_factory_ozone_) + surface_factory_ozone_.reset( + new SurfaceFactoryEgltest(&eglplatform_shim_)); gpu_platform_support_.reset(CreateStubGpuPlatformSupport()); } diff --git a/chromium/ui/ozone/platform/test/BUILD.gn b/chromium/ui/ozone/platform/test/BUILD.gn new file mode 100644 index 00000000000..d1ff71707c7 --- /dev/null +++ b/chromium/ui/ozone/platform/test/BUILD.gn @@ -0,0 +1,21 @@ +# 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. + +source_set("test") { + sources = [ + "ozone_platform_test.cc", + "ozone_platform_test.h", + "test_window.cc", + "test_window.h", + "test_window_manager.cc", + "test_window_manager.h", + ] + + deps = [ + "//base", + "//skia", + "//ui/base", + "//ui/gfx/geometry", + ] +} diff --git a/chromium/ui/ozone/platform/test/file_surface_factory.h b/chromium/ui/ozone/platform/test/file_surface_factory.h deleted file mode 100644 index 54ab1046e26..00000000000 --- a/chromium/ui/ozone/platform/test/file_surface_factory.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_OZONE_PLATFORM_TEST_FILE_SURFACE_FACTORY_H_ -#define UI_OZONE_PLATFORM_TEST_FILE_SURFACE_FACTORY_H_ - -#include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/ozone/public/surface_factory_ozone.h" - -namespace ui { - -class OZONE_BASE_EXPORT FileSurfaceFactory : public SurfaceFactoryOzone { - public: - explicit FileSurfaceFactory(const base::FilePath& dump_location); - virtual ~FileSurfaceFactory(); - - private: - // SurfaceFactoryOzone: - virtual HardwareState InitializeHardware() OVERRIDE; - virtual void ShutdownHardware() OVERRIDE; - virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; - virtual scoped_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget( - gfx::AcceleratedWidget w) OVERRIDE; - virtual bool LoadEGLGLES2Bindings( - AddGLLibraryCallback add_gl_library, - SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE; - - base::FilePath location_; - - DISALLOW_COPY_AND_ASSIGN(FileSurfaceFactory); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_TEST_FILE_SURFACE_FACTORY_H_ diff --git a/chromium/ui/ozone/platform/test/ozone_platform_test.cc b/chromium/ui/ozone/platform/test/ozone_platform_test.cc index fa0cedb24f9..3a4e689f0cf 100644 --- a/chromium/ui/ozone/platform/test/ozone_platform_test.cc +++ b/chromium/ui/ozone/platform/test/ozone_platform_test.cc @@ -6,17 +6,16 @@ #include "base/command_line.h" #include "base/files/file_path.h" -#include "ui/events/ozone/device/device_manager.h" -#include "ui/events/ozone/evdev/event_factory_evdev.h" -#include "ui/ozone/ozone_platform.h" -#include "ui/ozone/ozone_switches.h" -#include "ui/ozone/platform/test/file_surface_factory.h" +#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" +#include "ui/events/platform/platform_event_source.h" +#include "ui/ozone/common/native_display_delegate_ozone.h" +#include "ui/ozone/platform/test/test_window.h" +#include "ui/ozone/platform/test/test_window_manager.h" #include "ui/ozone/public/cursor_factory_ozone.h" - -#if defined(OS_CHROMEOS) -#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h" -#include "ui/ozone/common/chromeos/touchscreen_device_manager_ozone.h" -#endif +#include "ui/ozone/public/gpu_platform_support.h" +#include "ui/ozone/public/gpu_platform_support_host.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/ozone_switches.h" namespace ui { @@ -28,52 +27,52 @@ namespace { class OzonePlatformTest : public OzonePlatform { public: OzonePlatformTest(const base::FilePath& dump_file) : file_path_(dump_file) {} - virtual ~OzonePlatformTest() {} + ~OzonePlatformTest() override {} // OzonePlatform: - virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE { - return surface_factory_ozone_.get(); - } - virtual EventFactoryOzone* GetEventFactoryOzone() OVERRIDE { - return event_factory_ozone_.get(); + ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { + return window_manager_.get(); } - virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE { + CursorFactoryOzone* GetCursorFactoryOzone() override { return cursor_factory_ozone_.get(); } - virtual GpuPlatformSupport* GetGpuPlatformSupport() OVERRIDE { - return NULL; // no GPU support + GpuPlatformSupport* GetGpuPlatformSupport() override { + return gpu_platform_support_.get(); } - virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() OVERRIDE { - return NULL; // no GPU support + GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { + return gpu_platform_support_host_.get(); } - -#if defined(OS_CHROMEOS) - virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() - OVERRIDE { - return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); + scoped_ptr<PlatformWindow> CreatePlatformWindow( + PlatformWindowDelegate* delegate, + const gfx::Rect& bounds) override { + return make_scoped_ptr<PlatformWindow>( + new TestWindow(delegate, window_manager_.get(), bounds)); } - virtual scoped_ptr<TouchscreenDeviceManager> - CreateTouchscreenDeviceManager() OVERRIDE { - return scoped_ptr<TouchscreenDeviceManager>( - new TouchscreenDeviceManagerOzone()); + scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override { + return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone()); } -#endif - virtual void InitializeUI() OVERRIDE { - device_manager_ = CreateDeviceManager(); - surface_factory_ozone_.reset(new FileSurfaceFactory(file_path_)); - event_factory_ozone_.reset( - new EventFactoryEvdev(NULL, device_manager_.get())); - cursor_factory_ozone_.reset(new CursorFactoryOzone()); + void InitializeUI() override { + window_manager_.reset(new TestWindowManager(file_path_)); + window_manager_->Initialize(); + // This unbreaks tests that create their own. + if (!PlatformEventSource::GetInstance()) + platform_event_source_ = PlatformEventSource::CreateDefault(); + + cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone); + gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); } - virtual void InitializeGPU() OVERRIDE {} + void InitializeGPU() override { + gpu_platform_support_.reset(CreateStubGpuPlatformSupport()); + } private: - scoped_ptr<DeviceManager> device_manager_; - scoped_ptr<FileSurfaceFactory> surface_factory_ozone_; - scoped_ptr<EventFactoryEvdev> event_factory_ozone_; + scoped_ptr<TestWindowManager> window_manager_; + scoped_ptr<PlatformEventSource> platform_event_source_; scoped_ptr<CursorFactoryOzone> cursor_factory_ozone_; + scoped_ptr<GpuPlatformSupport> gpu_platform_support_; + scoped_ptr<GpuPlatformSupportHost> gpu_platform_support_host_; base::FilePath file_path_; DISALLOW_COPY_AND_ASSIGN(OzonePlatformTest); @@ -83,7 +82,7 @@ class OzonePlatformTest : public OzonePlatform { OzonePlatform* CreateOzonePlatformTest() { CommandLine* cmd = CommandLine::ForCurrentProcess(); - base::FilePath location = base::FilePath("/dev/null"); + base::FilePath location; if (cmd->HasSwitch(switches::kOzoneDumpFile)) location = cmd->GetSwitchValuePath(switches::kOzoneDumpFile); return new OzonePlatformTest(location); diff --git a/chromium/ui/ozone/platform/test/test.gypi b/chromium/ui/ozone/platform/test/test.gypi index c75c840f1e6..d1a35c8388e 100644 --- a/chromium/ui/ozone/platform/test/test.gypi +++ b/chromium/ui/ozone/platform/test/test.gypi @@ -21,14 +21,15 @@ 'dependencies': [ '../../base/base.gyp:base', '../events/events.gyp:events', - '../events/ozone/events_ozone.gyp:events_ozone_evdev', '../gfx/gfx.gyp:gfx', ], 'sources': [ - 'file_surface_factory.cc', - 'file_surface_factory.h', 'ozone_platform_test.cc', 'ozone_platform_test.h', + 'test_window.cc', + 'test_window.h', + 'test_window_manager.cc', + 'test_window_manager.h', ], }, ], diff --git a/chromium/ui/ozone/platform/test/test_window.cc b/chromium/ui/ozone/platform/test/test_window.cc new file mode 100644 index 00000000000..2cfa26ce644 --- /dev/null +++ b/chromium/ui/ozone/platform/test/test_window.cc @@ -0,0 +1,80 @@ +// 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/platform/test/test_window.h" + +#include <string> + +#include "base/files/file_path.h" +#include "base/strings/string_number_conversions.h" +#include "ui/events/platform/platform_event_source.h" +#include "ui/ozone/platform/test/test_window_manager.h" +#include "ui/platform_window/platform_window_delegate.h" + +namespace ui { + +TestWindow::TestWindow(PlatformWindowDelegate* delegate, + TestWindowManager* manager, + const gfx::Rect& bounds) + : delegate_(delegate), manager_(manager), bounds_(bounds) { + widget_ = manager_->AddWindow(this); + delegate_->OnAcceleratedWidgetAvailable(widget_); +} + +TestWindow::~TestWindow() { + manager_->RemoveWindow(widget_, this); +} + +base::FilePath TestWindow::path() { + base::FilePath base_path = manager_->base_path(); + if (base_path.empty() || base_path == base::FilePath("/dev/null")) + return base_path; + + // Disambiguate multiple window output files with the window id. + return base_path.Append(base::IntToString(widget_)); +} + +gfx::Rect TestWindow::GetBounds() { + return bounds_; +} + +void TestWindow::SetBounds(const gfx::Rect& bounds) { + bounds_ = bounds; + delegate_->OnBoundsChanged(bounds); +} + +void TestWindow::Show() { +} + +void TestWindow::Hide() { +} + +void TestWindow::Close() { +} + +void TestWindow::SetCapture() { +} + +void TestWindow::ReleaseCapture() { +} + +void TestWindow::ToggleFullscreen() { +} + +void TestWindow::Maximize() { +} + +void TestWindow::Minimize() { +} + +void TestWindow::Restore() { +} + +void TestWindow::SetCursor(PlatformCursor cursor) { +} + +void TestWindow::MoveCursorTo(const gfx::Point& location) { +} + +} // namespace ui diff --git a/chromium/ui/ozone/platform/test/test_window.h b/chromium/ui/ozone/platform/test/test_window.h new file mode 100644 index 00000000000..64397e70b50 --- /dev/null +++ b/chromium/ui/ozone/platform/test/test_window.h @@ -0,0 +1,54 @@ +// 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_PLATFORM_TEST_TEST_WINDOW_H_ +#define UI_OZONE_PLATFORM_TEST_TEST_WINDOW_H_ + +#include "base/files/file_path.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/platform_window/platform_window.h" + +namespace ui { + +class PlatformWindowDelegate; +class TestWindowManager; + +class TestWindow : public PlatformWindow { + public: + TestWindow(PlatformWindowDelegate* delegate, + TestWindowManager* manager, + const gfx::Rect& bounds); + ~TestWindow() override; + + // Path for image file for this window. + base::FilePath path(); + + // PlatformWindow: + gfx::Rect GetBounds() override; + void SetBounds(const gfx::Rect& bounds) override; + void Show() override; + void Hide() override; + void Close() override; + void SetCapture() override; + void ReleaseCapture() override; + void ToggleFullscreen() override; + void Maximize() override; + void Minimize() override; + void Restore() override; + void SetCursor(PlatformCursor cursor) override; + void MoveCursorTo(const gfx::Point& location) override; + + private: + PlatformWindowDelegate* delegate_; + TestWindowManager* manager_; + gfx::Rect bounds_; + gfx::AcceleratedWidget widget_; + + DISALLOW_COPY_AND_ASSIGN(TestWindow); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_TEST_TEST_WINDOW_H_ diff --git a/chromium/ui/ozone/platform/test/file_surface_factory.cc b/chromium/ui/ozone/platform/test/test_window_manager.cc index ab1e67cbaad..92b7fe07857 100644 --- a/chromium/ui/ozone/platform/test/file_surface_factory.cc +++ b/chromium/ui/ozone/platform/test/test_window_manager.cc @@ -1,11 +1,11 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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/platform/test/file_surface_factory.h" +#include "ui/ozone/platform/test/test_window_manager.h" #include "base/bind.h" -#include "base/file_util.h" +#include "base/files/file_util.h" #include "base/location.h" #include "base/stl_util.h" #include "base/threading/worker_pool.h" @@ -21,6 +21,7 @@ namespace ui { namespace { void WriteDataToFile(const base::FilePath& location, const SkBitmap& bitmap) { + DCHECK(!location.empty()); std::vector<unsigned char> png_data; gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, true, &png_data); base::WriteFile(location, @@ -31,17 +32,19 @@ void WriteDataToFile(const base::FilePath& location, const SkBitmap& bitmap) { class FileSurface : public SurfaceOzoneCanvas { public: FileSurface(const base::FilePath& location) : location_(location) {} - virtual ~FileSurface() {} + ~FileSurface() override {} // SurfaceOzoneCanvas overrides: - virtual void ResizeCanvas(const gfx::Size& viewport_size) OVERRIDE { + void ResizeCanvas(const gfx::Size& viewport_size) override { surface_ = skia::AdoptRef(SkSurface::NewRaster(SkImageInfo::MakeN32Premul( viewport_size.width(), viewport_size.height()))); } - virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE { + skia::RefPtr<SkCanvas> GetCanvas() override { return skia::SharePtr(surface_->getCanvas()); } - virtual void PresentCanvas(const gfx::Rect& damage) OVERRIDE { + void PresentCanvas(const gfx::Rect& damage) override { + if (location_.empty()) + return; SkBitmap bitmap; bitmap.setInfo(surface_->getCanvas()->imageInfo()); @@ -52,7 +55,7 @@ class FileSurface : public SurfaceOzoneCanvas { FROM_HERE, base::Bind(&WriteDataToFile, location_, bitmap), true); } } - virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE { + scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override { return scoped_ptr<gfx::VSyncProvider>(); } @@ -63,33 +66,44 @@ class FileSurface : public SurfaceOzoneCanvas { } // namespace -FileSurfaceFactory::FileSurfaceFactory(const base::FilePath& dump_location) +TestWindowManager::TestWindowManager(const base::FilePath& dump_location) : location_(dump_location) { - CHECK(!base::DirectoryExists(location_)) << "Location cannot be a directory (" - << location_.value() << ")"; - CHECK(!base::PathExists(location_) || base::PathIsWritable(location_)); } -FileSurfaceFactory::~FileSurfaceFactory() { +TestWindowManager::~TestWindowManager() { } -SurfaceFactoryOzone::HardwareState FileSurfaceFactory::InitializeHardware() { - return INITIALIZED; +void TestWindowManager::Initialize() { + if (location_.empty()) + return; + if (!DirectoryExists(location_) && !base::CreateDirectory(location_) && + location_ != base::FilePath("/dev/null")) + PLOG(FATAL) << "unable to create output directory"; + if (!base::PathIsWritable(location_)) + PLOG(FATAL) << "unable to write to output location"; } -void FileSurfaceFactory::ShutdownHardware() { +int32_t TestWindowManager::AddWindow(TestWindow* window) { + return windows_.Add(window); } -gfx::AcceleratedWidget FileSurfaceFactory::GetAcceleratedWidget() { - return 1; +void TestWindowManager::RemoveWindow(int32_t window_id, TestWindow* window) { + DCHECK_EQ(window, windows_.Lookup(window_id)); + windows_.Remove(window_id); } -scoped_ptr<SurfaceOzoneCanvas> FileSurfaceFactory::CreateCanvasForWidget( - gfx::AcceleratedWidget w) { - return make_scoped_ptr<SurfaceOzoneCanvas>(new FileSurface(location_)); +base::FilePath TestWindowManager::base_path() const { + return location_; } -bool FileSurfaceFactory::LoadEGLGLES2Bindings( +scoped_ptr<SurfaceOzoneCanvas> TestWindowManager::CreateCanvasForWidget( + gfx::AcceleratedWidget widget) { + TestWindow* window = windows_.Lookup(widget); + DCHECK(window); + return make_scoped_ptr<SurfaceOzoneCanvas>(new FileSurface(window->path())); +} + +bool TestWindowManager::LoadEGLGLES2Bindings( AddGLLibraryCallback add_gl_library, SetGLGetProcAddressProcCallback set_gl_get_proc_address) { return false; diff --git a/chromium/ui/ozone/platform/test/test_window_manager.h b/chromium/ui/ozone/platform/test/test_window_manager.h new file mode 100644 index 00000000000..69be81d91e3 --- /dev/null +++ b/chromium/ui/ozone/platform/test/test_window_manager.h @@ -0,0 +1,51 @@ +// 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_PLATFORM_TEST_FILE_SURFACE_FACTORY_H_ +#define UI_OZONE_PLATFORM_TEST_FILE_SURFACE_FACTORY_H_ + +#include "base/files/file_path.h" +#include "base/id_map.h" +#include "base/memory/scoped_ptr.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/ozone/platform/test/test_window.h" +#include "ui/ozone/public/surface_factory_ozone.h" + +namespace ui { + +class TestWindowManager : public SurfaceFactoryOzone { + public: + explicit TestWindowManager(const base::FilePath& dump_location); + ~TestWindowManager() override; + + // Initialize (mainly check that we have a place to write output to). + void Initialize(); + + // Register a new window. Returns the window id. + int32_t AddWindow(TestWindow* window); + + // Remove a window. + void RemoveWindow(int32_t window_id, TestWindow* window); + + // User-supplied path for images. + base::FilePath base_path() const; + + // SurfaceFactoryOzone: + scoped_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget( + gfx::AcceleratedWidget w) override; + bool LoadEGLGLES2Bindings( + AddGLLibraryCallback add_gl_library, + SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; + + private: + base::FilePath location_; + + IDMap<TestWindow> windows_; + + DISALLOW_COPY_AND_ASSIGN(TestWindowManager); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_TEST_FILE_SURFACE_FACTORY_H_ diff --git a/chromium/ui/ozone/platform_object.h b/chromium/ui/ozone/platform_object.h index 3d3a65ae524..2518c7cd764 100644 --- a/chromium/ui/ozone/platform_object.h +++ b/chromium/ui/ozone/platform_object.h @@ -16,7 +16,7 @@ namespace ui { // For the platform called "foo", PlatformObject<PlatformWidget> will ultimately // call the function with signature // -// Bar* CreatePlatformWidgetFoo(); +// PlatformWidget* CreatePlatformWidgetFoo(); // // A definition of this function for each compiled platform must be provided, or // link errors will result. diff --git a/chromium/ui/ozone/platform_selection.cc b/chromium/ui/ozone/platform_selection.cc index 7e462099396..823e2bd97ed 100644 --- a/chromium/ui/ozone/platform_selection.cc +++ b/chromium/ui/ozone/platform_selection.cc @@ -6,8 +6,8 @@ #include "base/command_line.h" #include "base/logging.h" -#include "ui/ozone/ozone_switches.h" #include "ui/ozone/platform_list.h" +#include "ui/ozone/public/ozone_switches.h" namespace ui { diff --git a/chromium/ui/ozone/public/cursor_factory_ozone.cc b/chromium/ui/ozone/public/cursor_factory_ozone.cc index c50f55eac21..c7f388dc060 100644 --- a/chromium/ui/ozone/public/cursor_factory_ozone.cc +++ b/chromium/ui/ozone/public/cursor_factory_ozone.cc @@ -12,17 +12,17 @@ namespace ui { CursorFactoryOzone* CursorFactoryOzone::impl_ = NULL; CursorFactoryOzone::CursorFactoryOzone() { - CHECK(!impl_) << "There should only be a single CursorFactoryOzone."; + DCHECK(!impl_) << "There should only be a single CursorFactoryOzone."; impl_ = this; } CursorFactoryOzone::~CursorFactoryOzone() { - CHECK_EQ(impl_, this); + DCHECK_EQ(impl_, this); impl_ = NULL; } CursorFactoryOzone* CursorFactoryOzone::GetInstance() { - CHECK(impl_) << "No CursorFactoryOzone implementation set."; + DCHECK(impl_) << "No CursorFactoryOzone implementation set."; return impl_; } @@ -38,22 +38,20 @@ PlatformCursor CursorFactoryOzone::CreateImageCursor( return NULL; } -void CursorFactoryOzone::RefImageCursor(PlatformCursor cursor) { - NOTIMPLEMENTED(); -} - -void CursorFactoryOzone::UnrefImageCursor(PlatformCursor cursor) { +PlatformCursor CursorFactoryOzone::CreateAnimatedCursor( + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& hotspot, + int frame_delay_ms) { NOTIMPLEMENTED(); + return NULL; } -void CursorFactoryOzone::SetCursor(gfx::AcceleratedWidget widget, - PlatformCursor cursor) { +void CursorFactoryOzone::RefImageCursor(PlatformCursor cursor) { NOTIMPLEMENTED(); } -gfx::AcceleratedWidget CursorFactoryOzone::GetCursorWindow() { +void CursorFactoryOzone::UnrefImageCursor(PlatformCursor cursor) { NOTIMPLEMENTED(); - return 0; } } // namespace ui diff --git a/chromium/ui/ozone/public/cursor_factory_ozone.h b/chromium/ui/ozone/public/cursor_factory_ozone.h index 5c044849117..4950a3186ee 100644 --- a/chromium/ui/ozone/public/cursor_factory_ozone.h +++ b/chromium/ui/ozone/public/cursor_factory_ozone.h @@ -5,6 +5,8 @@ #ifndef UI_OZONE_PUBLIC_CURSOR_FACTORY_OZONE_H_ #define UI_OZONE_PUBLIC_CURSOR_FACTORY_OZONE_H_ +#include <vector> + #include "ui/gfx/native_widget_types.h" #include "ui/ozone/ozone_base_export.h" @@ -35,21 +37,21 @@ class OZONE_BASE_EXPORT CursorFactoryOzone { virtual PlatformCursor CreateImageCursor(const SkBitmap& bitmap, const gfx::Point& hotspot); + // Return a animated cursor from the specified image & hotspot. Animated + // cursors are referenced counted and have an initial refcount of 1. + // Therefore, each CreateAnimatedCursor call must be matched with a call to + // UnrefImageCursor. + virtual PlatformCursor CreateAnimatedCursor( + const std::vector<SkBitmap>& bitmaps, + const gfx::Point& hotspot, + int frame_delay_ms); + // Increment platform image cursor refcount. virtual void RefImageCursor(PlatformCursor cursor); // Decrement platform image cursor refcount. virtual void UnrefImageCursor(PlatformCursor cursor); - // Change the active cursor for an AcceleratedWidget. - // TODO(spang): Move this. - virtual void SetCursor(gfx::AcceleratedWidget widget, PlatformCursor cursor); - - // Returns the window on which the cursor is active. - // TODO(dnicoara) Move this once the WindowTreeHost refactoring finishes and - // WindowTreeHost::CanDispatchEvent() is no longer present. - virtual gfx::AcceleratedWidget GetCursorWindow(); - private: static CursorFactoryOzone* impl_; // not owned }; diff --git a/chromium/ui/ozone/public/event_factory_ozone.cc b/chromium/ui/ozone/public/event_factory_ozone.cc deleted file mode 100644 index 85ecf3ceddc..00000000000 --- a/chromium/ui/ozone/public/event_factory_ozone.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2013 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/public/event_factory_ozone.h" - -#include "base/logging.h" - -namespace ui { - -// static -EventFactoryOzone* EventFactoryOzone::impl_ = NULL; - -EventFactoryOzone::EventFactoryOzone() { - CHECK(!impl_) << "There should only be a single EventFactoryOzone"; - impl_ = this; -} - -EventFactoryOzone::~EventFactoryOzone() { - CHECK_EQ(impl_, this); - impl_ = NULL; -} - -EventFactoryOzone* EventFactoryOzone::GetInstance() { - CHECK(impl_) << "No EventFactoryOzone implementation set."; - return impl_; -} - -void EventFactoryOzone::WarpCursorTo(gfx::AcceleratedWidget widget, - const gfx::PointF& location) { - NOTIMPLEMENTED(); -} - -} // namespace ui diff --git a/chromium/ui/ozone/public/event_factory_ozone.h b/chromium/ui/ozone/public/event_factory_ozone.h deleted file mode 100644 index bbca9fdf107..00000000000 --- a/chromium/ui/ozone/public/event_factory_ozone.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2013 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_PUBLIC_EVENT_FACTORY_OZONE_H_ -#define UI_OZONE_PUBLIC_EVENT_FACTORY_OZONE_H_ - -#include <map> - -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_pump_libevent.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/ozone/ozone_base_export.h" - -namespace gfx { -class PointF; -} - -namespace ui { - -class Event; - -// Creates and dispatches |ui.Event|'s. Ozone assumes that events arrive on file -// descriptors with one |EventConverterOzone| instance for each descriptor. -// Ozone presumes that the set of file descriptors can vary at runtime so this -// class supports dynamically adding and removing |EventConverterOzone| -// instances as necessary. -class OZONE_BASE_EXPORT EventFactoryOzone { - public: - EventFactoryOzone(); - virtual ~EventFactoryOzone(); - - // Warp the cursor to a location within an AccelerateWidget. - // If the cursor actually moves, the implementation must dispatch a mouse - // move event with the new location. - virtual void WarpCursorTo(gfx::AcceleratedWidget widget, - const gfx::PointF& location); - - // Returns the singleton instance. - static EventFactoryOzone* GetInstance(); - - private: - static EventFactoryOzone* impl_; // not owned - - DISALLOW_COPY_AND_ASSIGN(EventFactoryOzone); -}; - -} // namespace ui - -#endif // UI_OZONE_PUBLIC_EVENT_FACTORY_OZONE_H_ diff --git a/chromium/ui/ozone/public/gpu_platform_support.cc b/chromium/ui/ozone/public/gpu_platform_support.cc index db4148f58a8..4b7f5275849 100644 --- a/chromium/ui/ozone/public/gpu_platform_support.cc +++ b/chromium/ui/ozone/public/gpu_platform_support.cc @@ -15,8 +15,8 @@ namespace { class StubGpuPlatformSupport : public GpuPlatformSupport { public: // GpuPlatformSupport: - virtual void OnChannelEstablished(IPC::Sender* sender) {} - bool OnMessageReceived(const IPC::Message&) OVERRIDE { return false; } + void OnChannelEstablished(IPC::Sender* sender) override {} + bool OnMessageReceived(const IPC::Message&) override { return false; } }; } // namespace diff --git a/chromium/ui/ozone/public/gpu_platform_support.h b/chromium/ui/ozone/public/gpu_platform_support.h index 6aba7faf825..c912fa0af78 100644 --- a/chromium/ui/ozone/public/gpu_platform_support.h +++ b/chromium/ui/ozone/public/gpu_platform_support.h @@ -17,7 +17,7 @@ namespace ui { class OZONE_BASE_EXPORT GpuPlatformSupport : public IPC::Listener { public: GpuPlatformSupport(); - virtual ~GpuPlatformSupport(); + ~GpuPlatformSupport() override; // Called when the GPU process is spun up & channel established. virtual void OnChannelEstablished(IPC::Sender* sender) = 0; diff --git a/chromium/ui/ozone/public/gpu_platform_support_host.cc b/chromium/ui/ozone/public/gpu_platform_support_host.cc index 1a75efd5af5..7178737a341 100644 --- a/chromium/ui/ozone/public/gpu_platform_support_host.cc +++ b/chromium/ui/ozone/public/gpu_platform_support_host.cc @@ -16,10 +16,9 @@ namespace { class StubGpuPlatformSupportHost : public GpuPlatformSupportHost { public: // GpuPlatformSupportHost: - virtual void OnChannelEstablished(int host_id, IPC::Sender* sender) OVERRIDE { - } - virtual void OnChannelDestroyed(int host_id) OVERRIDE {} - virtual bool OnMessageReceived(const IPC::Message&) OVERRIDE { return false; } + void OnChannelEstablished(int host_id, IPC::Sender* sender) override {} + void OnChannelDestroyed(int host_id) override {} + bool OnMessageReceived(const IPC::Message&) override { return false; } }; } // namespace diff --git a/chromium/ui/ozone/public/gpu_platform_support_host.h b/chromium/ui/ozone/public/gpu_platform_support_host.h index 700b75b6052..252ebe0a331 100644 --- a/chromium/ui/ozone/public/gpu_platform_support_host.h +++ b/chromium/ui/ozone/public/gpu_platform_support_host.h @@ -23,7 +23,7 @@ namespace ui { class OZONE_BASE_EXPORT GpuPlatformSupportHost : public IPC::Listener { public: GpuPlatformSupportHost(); - virtual ~GpuPlatformSupportHost(); + ~GpuPlatformSupportHost() override; // Called when the GPU process is spun up & channel established. virtual void OnChannelEstablished(int host_id, IPC::Sender* sender) = 0; diff --git a/chromium/ui/ozone/public/native_pixmap.h b/chromium/ui/ozone/public/native_pixmap.h new file mode 100644 index 00000000000..8342ca2d867 --- /dev/null +++ b/chromium/ui/ozone/public/native_pixmap.h @@ -0,0 +1,32 @@ +// 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_PUBLIC_NATIVE_PIXMAP_H_ +#define UI_OZONE_PUBLIC_NATIVE_PIXMAP_H_ + +#include "base/memory/ref_counted.h" + +namespace ui { + +// This represents a buffer that can be directly imported via GL for +// rendering, or exported via dma-buf fds. +class NativePixmap : public base::RefCounted<NativePixmap> { + public: + NativePixmap() {} + + virtual void* /* EGLClientBuffer */ GetEGLClientBuffer() = 0; + virtual int GetDmaBufFd() = 0; + virtual int GetDmaBufPitch() = 0; + + protected: + virtual ~NativePixmap() {} + + friend class base::RefCounted<NativePixmap>; + + DISALLOW_COPY_AND_ASSIGN(NativePixmap); +}; + +} // namespace ui + +#endif // UI_OZONE_PUBLIC_NATIVE_PIXMAP_H_ diff --git a/chromium/ui/ozone/ozone_platform.cc b/chromium/ui/ozone/public/ozone_platform.cc index 35855649793..654026f2d49 100644 --- a/chromium/ui/ozone/ozone_platform.cc +++ b/chromium/ui/ozone/public/ozone_platform.cc @@ -1,14 +1,15 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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 "base/command_line.h" #include "base/debug/trace_event.h" #include "base/logging.h" -#include "ui/ozone/ozone_platform.h" -#include "ui/ozone/ozone_switches.h" +#include "ui/events/devices/device_data_manager.h" #include "ui/ozone/platform_object.h" #include "ui/ozone/platform_selection.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/ozone_switches.h" namespace ui { @@ -20,14 +21,14 @@ bool g_platform_initialized_gpu = false; } OzonePlatform::OzonePlatform() { - CHECK(!instance_) << "There should only be a single OzonePlatform."; + DCHECK(!instance_) << "There should only be a single OzonePlatform."; instance_ = this; g_platform_initialized_ui = false; g_platform_initialized_gpu = false; } OzonePlatform::~OzonePlatform() { - CHECK_EQ(instance_, this); + DCHECK_EQ(instance_, this); instance_ = NULL; } @@ -38,6 +39,9 @@ void OzonePlatform::InitializeForUI() { return; g_platform_initialized_ui = true; instance_->InitializeUI(); + // This is deliberately created after initializing so that the platform can + // create its own version of DDM. + DeviceDataManager::CreateInstance(); } // static @@ -51,7 +55,7 @@ void OzonePlatform::InitializeForGPU() { // static OzonePlatform* OzonePlatform::GetInstance() { - CHECK(instance_) << "OzonePlatform is not initialized"; + DCHECK(instance_) << "OzonePlatform is not initialized"; return instance_; } @@ -66,7 +70,8 @@ void OzonePlatform::CreateInstance() { PlatformObject<OzonePlatform>::Create(); // TODO(spang): Currently need to leak this object. - CHECK_EQ(instance_, platform.release()); + OzonePlatform* pl = platform.release(); + DCHECK_EQ(instance_, pl); } } diff --git a/chromium/ui/ozone/ozone_platform.h b/chromium/ui/ozone/public/ozone_platform.h index 710eb9daf49..c01800c021a 100644 --- a/chromium/ui/ozone/ozone_platform.h +++ b/chromium/ui/ozone/public/ozone_platform.h @@ -1,22 +1,26 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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_OZONE_PLATFORM_H_ -#define UI_OZONE_OZONE_PLATFORM_H_ +#ifndef UI_OZONE_PUBLIC_OZONE_PLATFORM_H_ +#define UI_OZONE_PUBLIC_OZONE_PLATFORM_H_ #include "base/memory/scoped_ptr.h" #include "ui/ozone/ozone_export.h" +namespace gfx { +class Rect; +} + namespace ui { class CursorFactoryOzone; -class EventFactoryOzone; class NativeDisplayDelegate; class SurfaceFactoryOzone; -class TouchscreenDeviceManager; class GpuPlatformSupport; class GpuPlatformSupportHost; +class PlatformWindow; +class PlatformWindowDelegate; // Base class for Ozone platform implementations. // @@ -50,16 +54,14 @@ class OZONE_EXPORT OzonePlatform { // injected into the appropriate layer at startup. Subclasses should not // inject these objects themselves. Ownership is retained by OzonePlatform. virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() = 0; - virtual ui::EventFactoryOzone* GetEventFactoryOzone() = 0; virtual ui::CursorFactoryOzone* GetCursorFactoryOzone() = 0; virtual ui::GpuPlatformSupport* GetGpuPlatformSupport() = 0; virtual ui::GpuPlatformSupportHost* GetGpuPlatformSupportHost() = 0; -#if defined(OS_CHROMEOS) + virtual scoped_ptr<PlatformWindow> CreatePlatformWindow( + PlatformWindowDelegate* delegate, + const gfx::Rect& bounds) = 0; virtual scoped_ptr<ui::NativeDisplayDelegate> CreateNativeDisplayDelegate() = 0; - virtual scoped_ptr<ui::TouchscreenDeviceManager> - CreateTouchscreenDeviceManager() = 0; -#endif private: virtual void InitializeUI() = 0; @@ -74,4 +76,4 @@ class OZONE_EXPORT OzonePlatform { } // namespace ui -#endif // UI_OZONE_OZONE_PLATFORM_H_ +#endif // UI_OZONE_PUBLIC_OZONE_PLATFORM_H_ diff --git a/chromium/ui/ozone/public/ozone_switches.cc b/chromium/ui/ozone/public/ozone_switches.cc new file mode 100644 index 00000000000..32d532793bd --- /dev/null +++ b/chromium/ui/ozone/public/ozone_switches.cc @@ -0,0 +1,23 @@ +// 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/public/ozone_switches.h" + +namespace switches { + +// Specify ozone platform implementation to use. +const char kOzonePlatform[] = "ozone-platform"; + +// Specify location for image dumps. +const char kOzoneDumpFile[] = "ozone-dump-file"; + +// Specify if the accelerated path should use surfaceless rendering. In this +// mode there is no EGL surface. +const char kOzoneUseSurfaceless[] = "ozone-use-surfaceless"; + +// Enable support for a single overlay plane. +const char kOzoneTestSingleOverlaySupport[] = + "ozone-test-single-overlay-support"; + +} // namespace switches diff --git a/chromium/ui/ozone/ozone_switches.h b/chromium/ui/ozone/public/ozone_switches.h index 3204fa7f99f..e25c674d737 100644 --- a/chromium/ui/ozone/ozone_switches.h +++ b/chromium/ui/ozone/public/ozone_switches.h @@ -1,9 +1,9 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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_OZONE_SWITCHES_H_ -#define UI_OZONE_OZONE_SWITCHES_H_ +#ifndef UI_OZONE_PUBLIC_OZONE_SWITCHES_H_ +#define UI_OZONE_PUBLIC_OZONE_SWITCHES_H_ #include "base/compiler_specific.h" #include "ui/ozone/ozone_export.h" @@ -14,6 +14,10 @@ OZONE_EXPORT extern const char kOzonePlatform[]; OZONE_EXPORT extern const char kOzoneDumpFile[]; +OZONE_EXPORT extern const char kOzoneUseSurfaceless[]; + +OZONE_EXPORT extern const char kOzoneTestSingleOverlaySupport[]; + } // namespace switches -#endif // UI_OZONE_OZONE_SWITCHES_H_ +#endif // UI_OZONE_PUBLIC_OZONE_SWITCHES_H_ diff --git a/chromium/ui/ozone/public/surface_factory_ozone.cc b/chromium/ui/ozone/public/surface_factory_ozone.cc index 9d33be43524..46cee88d6b3 100644 --- a/chromium/ui/ozone/public/surface_factory_ozone.cc +++ b/chromium/ui/ozone/public/surface_factory_ozone.cc @@ -7,6 +7,7 @@ #include <stdlib.h> #include "base/command_line.h" +#include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/ozone/public/surface_ozone_egl.h" @@ -16,17 +17,17 @@ namespace ui { SurfaceFactoryOzone* SurfaceFactoryOzone::impl_ = NULL; SurfaceFactoryOzone::SurfaceFactoryOzone() { - CHECK(!impl_) << "There should only be a single SurfaceFactoryOzone."; + DCHECK(!impl_) << "There should only be a single SurfaceFactoryOzone."; impl_ = this; } SurfaceFactoryOzone::~SurfaceFactoryOzone() { - CHECK_EQ(impl_, this); + DCHECK_EQ(impl_, this); impl_ = NULL; } SurfaceFactoryOzone* SurfaceFactoryOzone::GetInstance() { - CHECK(impl_) << "No SurfaceFactoryOzone implementation set."; + DCHECK(impl_) << "No SurfaceFactoryOzone implementation set."; return impl_; } @@ -40,6 +41,13 @@ scoped_ptr<SurfaceOzoneEGL> SurfaceFactoryOzone::CreateEGLSurfaceForWidget( return scoped_ptr<SurfaceOzoneEGL>(); } +scoped_ptr<SurfaceOzoneEGL> +SurfaceFactoryOzone::CreateSurfacelessEGLSurfaceForWidget( + gfx::AcceleratedWidget widget) { + NOTIMPLEMENTED(); + return scoped_ptr<SurfaceOzoneEGL>(); +} + scoped_ptr<SurfaceOzoneCanvas> SurfaceFactoryOzone::CreateCanvasForWidget( gfx::AcceleratedWidget widget) { NOTIMPLEMENTED(); @@ -56,20 +64,23 @@ ui::OverlayCandidatesOzone* SurfaceFactoryOzone::GetOverlayCandidates( return NULL; } -void SurfaceFactoryOzone::ScheduleOverlayPlane( - gfx::AcceleratedWidget w, +scoped_refptr<ui::NativePixmap> SurfaceFactoryOzone::CreateNativePixmap( + gfx::Size size, + BufferFormat format) { + return NULL; +} + +bool SurfaceFactoryOzone::ScheduleOverlayPlane( + gfx::AcceleratedWidget widget, int plane_z_order, gfx::OverlayTransform plane_transform, - ui::NativeBufferOzone buffer, + scoped_refptr<NativePixmap> buffer, const gfx::Rect& display_bounds, - gfx::RectF crop_rect) { - NOTREACHED(); + const gfx::RectF& crop_rect) { + return false; } -ui::NativeBufferOzone SurfaceFactoryOzone::CreateNativeBuffer( - gfx::Size size, - BufferFormat format) { - return 0; +bool SurfaceFactoryOzone::CanShowPrimaryPlaneAsOverlay() { + return false; } - } // namespace ui diff --git a/chromium/ui/ozone/public/surface_factory_ozone.h b/chromium/ui/ozone/public/surface_factory_ozone.h index 4702d69a59d..62df13e5074 100644 --- a/chromium/ui/ozone/public/surface_factory_ozone.h +++ b/chromium/ui/ozone/public/surface_factory_ozone.h @@ -20,7 +20,7 @@ class SkCanvas; namespace ui { -typedef intptr_t NativeBufferOzone; +class NativePixmap; class OverlayCandidatesOzone; class SurfaceOzoneCanvas; class SurfaceOzoneEGL; @@ -58,19 +58,13 @@ class SurfaceOzoneEGL; // modes (See comments bellow for descriptions). class OZONE_BASE_EXPORT SurfaceFactoryOzone { public: - // Describes the state of the hardware after initialization. - enum HardwareState { - UNINITIALIZED, - INITIALIZED, - FAILED, - }; - // Describes overlay buffer format. // TODO: this is a placeholder for now and will be populated with more // formats once we know what sorts of content, video, etc. we can support. enum BufferFormat { UNKNOWN, RGBA_8888, + RGBX_8888, RGB_888, }; @@ -85,23 +79,10 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone { // Returns the singleton instance. static SurfaceFactoryOzone* GetInstance(); - // Configures the display hardware. Must be called from within the GPU - // process before the sandbox has been activated. - virtual HardwareState InitializeHardware() = 0; - - // Cleans up display hardware state. Call this from within the GPU process. - // This method must be safe to run inside of the sandbox. - virtual void ShutdownHardware() = 0; - // Returns native platform display handle. This is used to obtain the EGL // display connection for the native display. virtual intptr_t GetNativeDisplay(); - // Obtains an AcceleratedWidget backed by a native Linux framebuffer. - // The returned AcceleratedWidget is an opaque token that must realized - // before it can be used to create a GL surface. - virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; - // Create SurfaceOzoneEGL for the specified gfx::AcceleratedWidget. // // Note: When used from content, this is called in the GPU process. The @@ -110,6 +91,12 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone { virtual scoped_ptr<SurfaceOzoneEGL> CreateEGLSurfaceForWidget( gfx::AcceleratedWidget widget); + // Create an EGL surface that isn't backed by any buffers, and is used + // for overlay-only displays. This will return NULL if this mode is + // not supported. + virtual scoped_ptr<SurfaceOzoneEGL> CreateSurfacelessEGLSurfaceForWidget( + gfx::AcceleratedWidget widget); + // Create SurfaceOzoneCanvas for the specified gfx::AcceleratedWidget. // // Note: The platform must support creation of SurfaceOzoneCanvas from the @@ -134,25 +121,33 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone { virtual OverlayCandidatesOzone* GetOverlayCandidates( gfx::AcceleratedWidget w); + // Cleate a single native buffer to be used for overlay planes. + virtual scoped_refptr<NativePixmap> CreateNativePixmap( + gfx::Size size, + BufferFormat format); + // Sets the overlay plane to switch to at the next page flip. + // |w| specifies the screen to display this overlay plane on. // |plane_z_order| specifies the stacking order of the plane relative to the // main framebuffer located at index 0. // |plane_transform| specifies how the buffer is to be transformed during. // composition. // |buffer| to be presented by the overlay. // |display_bounds| specify where it is supposed to be on the screen. - // |crop_rect| specifies the region within the buffer to be placed inside - // |display_bounds|. - virtual void ScheduleOverlayPlane(gfx::AcceleratedWidget w, + // |crop_rect| specifies the region within the buffer to be placed + // inside |display_bounds|. This is specified in texture coordinates, in the + // range of [0,1]. + virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, int plane_z_order, gfx::OverlayTransform plane_transform, - ui::NativeBufferOzone buffer, + scoped_refptr<NativePixmap> buffer, const gfx::Rect& display_bounds, - gfx::RectF crop_rect); + const gfx::RectF& crop_rect); - // Cleate a single native buffer to be used for overlay planes. - virtual ui::NativeBufferOzone CreateNativeBuffer(gfx::Size size, - BufferFormat format); + // Returns true if overlays can be shown at z-index 0, replacing the main + // surface. Combined with surfaceless extensions, it allows for an + // overlay-only mode. + virtual bool CanShowPrimaryPlaneAsOverlay(); private: static SurfaceFactoryOzone* impl_; // not owned diff --git a/chromium/ui/ozone/public/surface_ozone_egl.h b/chromium/ui/ozone/public/surface_ozone_egl.h index fa7e43a3ef1..4f38f06b211 100644 --- a/chromium/ui/ozone/public/surface_ozone_egl.h +++ b/chromium/ui/ozone/public/surface_ozone_egl.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "ui/gfx/overlay_transform.h" #include "ui/ozone/ozone_base_export.h" namespace gfx { @@ -15,6 +16,7 @@ class VSyncProvider; } namespace ui { +class NativePixmap; // The platform-specific part of an EGL surface. // diff --git a/chromium/ui/ozone/public/ui_thread_gpu.cc b/chromium/ui/ozone/public/ui_thread_gpu.cc new file mode 100644 index 00000000000..b788bd5c1c5 --- /dev/null +++ b/chromium/ui/ozone/public/ui_thread_gpu.cc @@ -0,0 +1,55 @@ +// 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/public/ui_thread_gpu.h" + +#include "ipc/ipc_listener.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_sender.h" +#include "ui/ozone/public/gpu_platform_support.h" +#include "ui/ozone/public/gpu_platform_support_host.h" +#include "ui/ozone/public/ozone_platform.h" + +namespace ui { + +class UiThreadGpuForwardingSender : public IPC::Sender { + public: + explicit UiThreadGpuForwardingSender(IPC::Listener* listener) + : listener_(listener) {} + ~UiThreadGpuForwardingSender() override {} + + // IPC::Sender: + bool Send(IPC::Message* msg) override { + listener_->OnMessageReceived(*msg); + delete msg; + return true; + } + + private: + IPC::Listener* listener_; +}; + +UiThreadGpu::UiThreadGpu() { +} + +UiThreadGpu::~UiThreadGpu() { +} + +bool UiThreadGpu::Initialize() { + OzonePlatform* platform = ui::OzonePlatform::GetInstance(); + + ui_sender_.reset( + new UiThreadGpuForwardingSender(platform->GetGpuPlatformSupportHost())); + gpu_sender_.reset( + new UiThreadGpuForwardingSender(platform->GetGpuPlatformSupport())); + + const int kHostId = 1; + platform->GetGpuPlatformSupportHost()->OnChannelEstablished( + kHostId, gpu_sender_.get()); + platform->GetGpuPlatformSupport()->OnChannelEstablished(ui_sender_.get()); + + return true; +} + +} // namespace ui diff --git a/chromium/ui/ozone/public/ui_thread_gpu.h b/chromium/ui/ozone/public/ui_thread_gpu.h new file mode 100644 index 00000000000..8e2358a6b96 --- /dev/null +++ b/chromium/ui/ozone/public/ui_thread_gpu.h @@ -0,0 +1,40 @@ +// 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_PUBLIC_UI_THREAD_GPU_H_ +#define UI_OZONE_PUBLIC_UI_THREAD_GPU_H_ + +#include "base/memory/scoped_ptr.h" +#include "ui/ozone/ozone_export.h" + +namespace IPC { +class Sender; +} + +namespace ui { + +class UiThreadGpuForwardingSender; + +// Helper class for applications that do GL on the UI thead. +// +// This sets up message forwarding between the "gpu" and "ui" threads, +// for applications in which they are both the same thread. +class OZONE_EXPORT UiThreadGpu { + public: + UiThreadGpu(); + virtual ~UiThreadGpu(); + + // Start processing gpu messages. + bool Initialize(); + + private: + scoped_ptr<UiThreadGpuForwardingSender> ui_sender_; + scoped_ptr<UiThreadGpuForwardingSender> gpu_sender_; + + DISALLOW_COPY_AND_ASSIGN(UiThreadGpu); +}; + +} // namespace ui + +#endif // UI_OZONE_PUBLIC_UI_THREAD_GPU_H_ diff --git a/chromium/ui/ozone/run_all_unittests.cc b/chromium/ui/ozone/run_all_unittests.cc index 32270992bb7..5f038b30dea 100644 --- a/chromium/ui/ozone/run_all_unittests.cc +++ b/chromium/ui/ozone/run_all_unittests.cc @@ -15,8 +15,8 @@ class OzoneTestSuite : public base::TestSuite { protected: // base::TestSuite: - virtual void Initialize() OVERRIDE; - virtual void Shutdown() OVERRIDE; + void Initialize() override; + void Shutdown() override; private: DISALLOW_COPY_AND_ASSIGN(OzoneTestSuite); |