demo_main.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include "base/at_exit.h"
  6. #include "base/callback.h"
  7. #include "base/command_line.h"
  8. #include "base/i18n/icu_util.h"
  9. #include "base/memory/ptr_util.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/message_loop/message_pump_type.h"
  12. #include "base/power_monitor/power_monitor.h"
  13. #include "base/power_monitor/power_monitor_device_source.h"
  14. #include "base/run_loop.h"
  15. #include "base/task/single_thread_task_executor.h"
  16. #include "base/task/thread_pool/thread_pool_instance.h"
  17. #include "build/build_config.h"
  18. #include "components/viz/host/host_frame_sink_manager.h"
  19. #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
  20. #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
  21. #include "mojo/core/embedder/embedder.h"
  22. #include "third_party/skia/include/core/SkBlendMode.h"
  23. #include "ui/aura/client/default_capture_client.h"
  24. #include "ui/aura/client/window_parenting_client.h"
  25. #include "ui/aura/env.h"
  26. #include "ui/aura/test/test_focus_client.h"
  27. #include "ui/aura/test/test_screen.h"
  28. #include "ui/aura/window.h"
  29. #include "ui/aura/window_delegate.h"
  30. #include "ui/aura/window_tree_host.h"
  31. #include "ui/aura/window_tree_host_observer.h"
  32. #include "ui/base/hit_test.h"
  33. #include "ui/base/ime/init/input_method_initializer.h"
  34. #include "ui/compositor/paint_recorder.h"
  35. #include "ui/compositor/test/in_process_context_factory.h"
  36. #include "ui/events/event.h"
  37. #include "ui/gfx/canvas.h"
  38. #include "ui/gfx/geometry/rect.h"
  39. #include "ui/gfx/geometry/skia_conversions.h"
  40. #include "ui/gl/gl_switches.h"
  41. #include "ui/gl/init/gl_factory.h"
  42. #if BUILDFLAG(IS_WIN)
  43. #include "ui/display/win/dpi.h"
  44. #endif
  45. #if defined(USE_OZONE)
  46. #include "ui/ozone/public/ozone_platform.h"
  47. #endif
  48. namespace {
  49. // Trivial WindowDelegate implementation that draws a colored background.
  50. class DemoWindowDelegate : public aura::WindowDelegate {
  51. public:
  52. explicit DemoWindowDelegate(SkColor color) : color_(color) {}
  53. DemoWindowDelegate(const DemoWindowDelegate&) = delete;
  54. DemoWindowDelegate& operator=(const DemoWindowDelegate&) = delete;
  55. // Overridden from WindowDelegate:
  56. gfx::Size GetMinimumSize() const override { return gfx::Size(); }
  57. gfx::Size GetMaximumSize() const override { return gfx::Size(); }
  58. void OnBoundsChanged(const gfx::Rect& old_bounds,
  59. const gfx::Rect& new_bounds) override {
  60. window_bounds_ = new_bounds;
  61. }
  62. gfx::NativeCursor GetCursor(const gfx::Point& point) override {
  63. return gfx::kNullCursor;
  64. }
  65. int GetNonClientComponent(const gfx::Point& point) const override {
  66. return HTCAPTION;
  67. }
  68. bool ShouldDescendIntoChildForEventHandling(
  69. aura::Window* child,
  70. const gfx::Point& location) override {
  71. return true;
  72. }
  73. bool CanFocus() override { return true; }
  74. void OnCaptureLost() override {}
  75. void OnPaint(const ui::PaintContext& context) override {
  76. ui::PaintRecorder recorder(context, window_bounds_.size());
  77. recorder.canvas()->DrawColor(color_, SkBlendMode::kSrc);
  78. gfx::Rect r;
  79. recorder.canvas()->GetClipBounds(&r);
  80. // Fill with a non-solid color so that the compositor will exercise its
  81. // texture upload path.
  82. while (!r.IsEmpty()) {
  83. r.Inset(2);
  84. recorder.canvas()->FillRect(r, color_, SkBlendMode::kXor);
  85. }
  86. }
  87. void OnDeviceScaleFactorChanged(float old_device_scale_factor,
  88. float new_device_scale_factor) override {}
  89. void OnWindowDestroying(aura::Window* window) override {}
  90. void OnWindowDestroyed(aura::Window* window) override {}
  91. void OnWindowTargetVisibilityChanged(bool visible) override {}
  92. bool HasHitTestMask() const override { return false; }
  93. void GetHitTestMask(SkPath* mask) const override {}
  94. private:
  95. SkColor color_;
  96. gfx::Rect window_bounds_;
  97. };
  98. class DemoWindowParentingClient : public aura::client::WindowParentingClient {
  99. public:
  100. explicit DemoWindowParentingClient(aura::Window* window) : window_(window) {
  101. aura::client::SetWindowParentingClient(window_, this);
  102. }
  103. DemoWindowParentingClient(const DemoWindowParentingClient&) = delete;
  104. DemoWindowParentingClient& operator=(const DemoWindowParentingClient&) =
  105. delete;
  106. ~DemoWindowParentingClient() override {
  107. aura::client::SetWindowParentingClient(window_, nullptr);
  108. }
  109. // Overridden from aura::client::WindowParentingClient:
  110. aura::Window* GetDefaultParent(aura::Window* window,
  111. const gfx::Rect& bounds) override {
  112. if (!capture_client_) {
  113. capture_client_ = std::make_unique<aura::client::DefaultCaptureClient>(
  114. window_->GetRootWindow());
  115. }
  116. return window_;
  117. }
  118. private:
  119. raw_ptr<aura::Window> window_;
  120. std::unique_ptr<aura::client::DefaultCaptureClient> capture_client_;
  121. };
  122. // Runs a base::RunLoop until receiving OnHostCloseRequested from |host|.
  123. void RunRunLoopUntilOnHostCloseRequested(aura::WindowTreeHost* host) {
  124. class Observer : public aura::WindowTreeHostObserver {
  125. public:
  126. explicit Observer(base::OnceClosure quit_closure)
  127. : quit_closure_(std::move(quit_closure)) {}
  128. Observer(const Observer&) = delete;
  129. Observer& operator=(const Observer&) = delete;
  130. void OnHostCloseRequested(aura::WindowTreeHost* host) override {
  131. std::move(quit_closure_).Run();
  132. }
  133. private:
  134. base::OnceClosure quit_closure_;
  135. };
  136. base::RunLoop run_loop;
  137. Observer observer(run_loop.QuitClosure());
  138. host->AddObserver(&observer);
  139. run_loop.Run();
  140. host->RemoveObserver(&observer);
  141. }
  142. int DemoMain() {
  143. #if defined(USE_OZONE)
  144. ui::OzonePlatform::InitParams params;
  145. params.single_process = true;
  146. ui::OzonePlatform::InitializeForUI(params);
  147. ui::OzonePlatform::InitializeForGPU(params);
  148. #endif
  149. gl::init::InitializeGLOneOff(/*system_device_id=*/0);
  150. #if BUILDFLAG(IS_WIN)
  151. display::win::SetDefaultDeviceScaleFactor(1.0f);
  152. #endif
  153. // Create the task executor here before creating the root window.
  154. base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI);
  155. base::ThreadPoolInstance::CreateAndStartWithDefaultParams("demo");
  156. ui::InitializeInputMethodForTesting();
  157. // The ContextFactory must exist before any Compositors are created.
  158. viz::HostFrameSinkManager host_frame_sink_manager;
  159. viz::ServerSharedBitmapManager server_shared_bitmap_manager;
  160. viz::FrameSinkManagerImpl frame_sink_manager{
  161. viz::FrameSinkManagerImpl::InitParams(&server_shared_bitmap_manager)};
  162. host_frame_sink_manager.SetLocalManager(&frame_sink_manager);
  163. frame_sink_manager.SetLocalClient(&host_frame_sink_manager);
  164. auto context_factory = std::make_unique<ui::InProcessContextFactory>(
  165. &host_frame_sink_manager, &frame_sink_manager, /*output_to_window=*/true);
  166. base::PowerMonitor::Initialize(
  167. std::make_unique<base::PowerMonitorDeviceSource>());
  168. std::unique_ptr<aura::Env> env = aura::Env::CreateInstance();
  169. env->set_context_factory(context_factory.get());
  170. std::unique_ptr<aura::TestScreen> test_screen(
  171. aura::TestScreen::Create(gfx::Size()));
  172. display::Screen::SetScreenInstance(test_screen.get());
  173. std::unique_ptr<aura::WindowTreeHost> host(
  174. test_screen->CreateHostForPrimaryDisplay());
  175. DemoWindowParentingClient window_parenting_client(host->window());
  176. aura::test::TestFocusClient focus_client(host->window());
  177. // Create a hierarchy of test windows.
  178. gfx::Rect window1_bounds(100, 100, 400, 400);
  179. DemoWindowDelegate window_delegate1(SK_ColorBLUE);
  180. aura::Window window1(&window_delegate1);
  181. window1.SetId(1);
  182. window1.Init(ui::LAYER_TEXTURED);
  183. window1.SetBounds(window1_bounds);
  184. window1.Show();
  185. aura::client::ParentWindowWithContext(&window1, host->window(), gfx::Rect());
  186. gfx::Rect window2_bounds(200, 200, 350, 350);
  187. DemoWindowDelegate window_delegate2(SK_ColorRED);
  188. aura::Window window2(&window_delegate2);
  189. window2.SetId(2);
  190. window2.Init(ui::LAYER_TEXTURED);
  191. window2.SetBounds(window2_bounds);
  192. window2.Show();
  193. aura::client::ParentWindowWithContext(&window2, host->window(), gfx::Rect());
  194. gfx::Rect window3_bounds(10, 10, 50, 50);
  195. DemoWindowDelegate window_delegate3(SK_ColorGREEN);
  196. aura::Window window3(&window_delegate3);
  197. window3.SetId(3);
  198. window3.Init(ui::LAYER_TEXTURED);
  199. window3.SetBounds(window3_bounds);
  200. window3.Show();
  201. window2.AddChild(&window3);
  202. host->Show();
  203. RunRunLoopUntilOnHostCloseRequested(host.get());
  204. // Input method shutdown needs to happen before thread cleanup while the
  205. // sequence manager is still valid.
  206. ui::ShutdownInputMethodForTesting();
  207. return 0;
  208. }
  209. } // namespace
  210. int main(int argc, char** argv) {
  211. base::CommandLine::Init(argc, argv);
  212. // Disabling Direct Composition works around the limitation that
  213. // InProcessContextFactory doesn't work with Direct Composition, causing the
  214. // window to not render. See http://crbug.com/936249.
  215. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  216. switches::kDisableDirectComposition);
  217. // The exit manager is in charge of calling the dtors of singleton objects.
  218. base::AtExitManager exit_manager;
  219. mojo::core::Init();
  220. base::i18n::InitializeICU();
  221. return DemoMain();
  222. }