sub_surface_unittest.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Copyright 2015 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 "components/exo/sub_surface.h"
  5. #include "components/exo/buffer.h"
  6. #include "components/exo/shell_surface.h"
  7. #include "components/exo/surface.h"
  8. #include "components/exo/test/exo_test_base.h"
  9. #include "components/exo/test/exo_test_helper.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. #include "ui/aura/client/aura_constants.h"
  12. #include "ui/gfx/geometry/point_conversions.h"
  13. namespace exo {
  14. namespace {
  15. using SubSurfaceTest = test::ExoTestBase;
  16. TEST_F(SubSurfaceTest, SetPosition) {
  17. auto parent = std::make_unique<Surface>();
  18. auto shell_surface = std::make_unique<ShellSurface>(parent.get());
  19. auto surface = std::make_unique<Surface>();
  20. auto sub_surface = std::make_unique<SubSurface>(surface.get(), parent.get());
  21. // Initial position is at the origin.
  22. EXPECT_EQ(gfx::Point().ToString(),
  23. surface->window()->bounds().origin().ToString());
  24. // Set position to 10, 10.
  25. gfx::PointF position(10, 10);
  26. sub_surface->SetPosition(position);
  27. // A call to Commit() is required for position to take effect.
  28. EXPECT_EQ(gfx::Point().ToString(),
  29. surface->window()->bounds().origin().ToString());
  30. // Check that position is updated when Commit() is called.
  31. parent->Commit();
  32. EXPECT_EQ(gfx::ToRoundedPoint(position).ToString(),
  33. surface->window()->bounds().origin().ToString());
  34. // Create and commit a new sub-surface using the same surface.
  35. sub_surface.reset();
  36. sub_surface = std::make_unique<SubSurface>(surface.get(), parent.get());
  37. parent->Commit();
  38. // Initial position should be reset to origin.
  39. EXPECT_EQ(gfx::Point().ToString(),
  40. surface->window()->bounds().origin().ToString());
  41. }
  42. TEST_F(SubSurfaceTest, PlaceAbove) {
  43. auto parent = std::make_unique<Surface>();
  44. auto shell_surface = std::make_unique<ShellSurface>(parent.get());
  45. auto surface1 = std::make_unique<Surface>();
  46. auto surface2 = std::make_unique<Surface>();
  47. auto non_sibling_surface = std::make_unique<Surface>();
  48. auto sub_surface1 =
  49. std::make_unique<SubSurface>(surface1.get(), parent.get());
  50. auto sub_surface2 =
  51. std::make_unique<SubSurface>(surface2.get(), parent.get());
  52. ASSERT_EQ(2u, parent->window()->children().size());
  53. EXPECT_EQ(surface1->window(), parent->window()->children()[0]);
  54. EXPECT_EQ(surface2->window(), parent->window()->children()[1]);
  55. sub_surface2->PlaceAbove(parent.get());
  56. sub_surface1->PlaceAbove(non_sibling_surface.get()); // Invalid
  57. sub_surface1->PlaceAbove(surface1.get()); // Invalid
  58. sub_surface1->PlaceAbove(surface2.get());
  59. // Nothing should have changed as Commit() is required for new stacking
  60. // order to take effect.
  61. EXPECT_EQ(surface1->window(), parent->window()->children()[0]);
  62. EXPECT_EQ(surface2->window(), parent->window()->children()[1]);
  63. parent->Commit();
  64. // surface1 should now be stacked above surface2.
  65. EXPECT_EQ(surface2->window(), parent->window()->children()[0]);
  66. EXPECT_EQ(surface1->window(), parent->window()->children()[1]);
  67. }
  68. TEST_F(SubSurfaceTest, PlaceBelow) {
  69. auto parent = std::make_unique<Surface>();
  70. auto shell_surface = std::make_unique<ShellSurface>(parent.get());
  71. auto surface1 = std::make_unique<Surface>();
  72. auto surface2 = std::make_unique<Surface>();
  73. auto non_sibling_surface = std::make_unique<Surface>();
  74. auto sub_surface1 =
  75. std::make_unique<SubSurface>(surface1.get(), parent.get());
  76. auto sub_surface2 =
  77. std::make_unique<SubSurface>(surface2.get(), parent.get());
  78. ASSERT_EQ(2u, parent->window()->children().size());
  79. EXPECT_EQ(surface1->window(), parent->window()->children()[0]);
  80. EXPECT_EQ(surface2->window(), parent->window()->children()[1]);
  81. sub_surface2->PlaceBelow(parent.get()); // Invalid
  82. sub_surface2->PlaceBelow(non_sibling_surface.get()); // Invalid
  83. sub_surface1->PlaceBelow(surface2.get());
  84. sub_surface2->PlaceBelow(surface1.get());
  85. // Nothing should have changed as Commit() is required for new stacking
  86. // order to take effect.
  87. EXPECT_EQ(surface1->window(), parent->window()->children()[0]);
  88. EXPECT_EQ(surface2->window(), parent->window()->children()[1]);
  89. parent->Commit();
  90. // surface1 should now be stacked above surface2.
  91. EXPECT_EQ(surface2->window(), parent->window()->children()[0]);
  92. EXPECT_EQ(surface1->window(), parent->window()->children()[1]);
  93. }
  94. TEST_F(SubSurfaceTest, ParentDamageOnReorder) {
  95. gfx::Size buffer_size(800, 600);
  96. auto buffer = std::make_unique<Buffer>(
  97. exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
  98. auto surface_tree_host = std::make_unique<SurfaceTreeHost>("SubSurfaceTest");
  99. LayerTreeFrameSinkHolder* frame_sink_holder =
  100. surface_tree_host->layer_tree_frame_sink_holder();
  101. auto parent = std::make_unique<Surface>();
  102. parent->Attach(buffer.get());
  103. // Set the overlay priority hint to low to prevent a texture draw quad from
  104. // being used.
  105. parent->SetOverlayPriorityHint(OverlayPriority::LOW);
  106. auto surface1 = std::make_unique<Surface>();
  107. auto surface2 = std::make_unique<Surface>();
  108. auto non_sibling_surface = std::make_unique<Surface>();
  109. auto sub_surface1 =
  110. std::make_unique<SubSurface>(surface1.get(), parent.get());
  111. auto sub_surface2 =
  112. std::make_unique<SubSurface>(surface2.get(), parent.get());
  113. sub_surface2->PlaceBelow(surface1.get());
  114. parent->Commit();
  115. viz::CompositorFrame frame1;
  116. frame1.render_pass_list.push_back(viz::CompositorRenderPass::Create());
  117. parent->AppendSurfaceHierarchyContentsToFrame(
  118. gfx::PointF{}, 1, frame_sink_holder->resource_manager(), &frame1);
  119. // Parent surface damage is extended when sub_surface stacking order changes.
  120. EXPECT_FALSE(frame1.render_pass_list.back()->damage_rect.IsEmpty());
  121. sub_surface1->PlaceAbove(surface2.get()); // no-op
  122. sub_surface2->PlaceBelow(surface1.get()); // no-op
  123. parent->Commit();
  124. viz::CompositorFrame frame2;
  125. frame2.render_pass_list.push_back(viz::CompositorRenderPass::Create());
  126. parent->AppendSurfaceHierarchyContentsToFrame(
  127. gfx::PointF{}, 1, frame_sink_holder->resource_manager(), &frame2);
  128. // Parent surface damage is unaffected.
  129. EXPECT_TRUE(frame2.render_pass_list.back()->damage_rect.IsEmpty());
  130. }
  131. TEST_F(SubSurfaceTest, SetCommitBehavior) {
  132. auto parent = std::make_unique<Surface>();
  133. auto shell_surface = std::make_unique<ShellSurface>(parent.get());
  134. auto child = std::make_unique<Surface>();
  135. auto grandchild = std::make_unique<Surface>();
  136. auto child_sub_surface =
  137. std::make_unique<SubSurface>(child.get(), parent.get());
  138. auto grandchild_sub_surface =
  139. std::make_unique<SubSurface>(grandchild.get(), child.get());
  140. // Initial position is at the origin.
  141. EXPECT_EQ(gfx::Point().ToString(),
  142. grandchild->window()->bounds().origin().ToString());
  143. // Set position to 10, 10.
  144. gfx::PointF position1(10, 10);
  145. grandchild_sub_surface->SetPosition(position1);
  146. child->Commit();
  147. // Initial commit behavior is synchronous and the effect of the child
  148. // Commit() call will not take effect until Commit() is called on the
  149. // parent.
  150. EXPECT_EQ(gfx::Point().ToString(),
  151. grandchild->window()->bounds().origin().ToString());
  152. parent->Commit();
  153. // Position should have been updated when Commit() has been called on both
  154. // child and parent.
  155. EXPECT_EQ(gfx::ToRoundedPoint(position1).ToString(),
  156. grandchild->window()->bounds().origin().ToString());
  157. bool synchronized = false;
  158. child_sub_surface->SetCommitBehavior(synchronized);
  159. // Set position to 20, 20.
  160. gfx::PointF position2(20, 20);
  161. grandchild_sub_surface->SetPosition(position2);
  162. child->Commit();
  163. // A Commit() call on child should be sufficient for the position of
  164. // grandchild to take effect when synchronous is disabled.
  165. EXPECT_EQ(gfx::ToRoundedPoint(position2).ToString(),
  166. grandchild->window()->bounds().origin().ToString());
  167. }
  168. TEST_F(SubSurfaceTest, SetOnParent) {
  169. gfx::Size buffer_size(32, 32);
  170. std::unique_ptr<Buffer> buffer(
  171. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  172. auto parent = std::make_unique<Surface>();
  173. auto shell_surface = std::make_unique<ShellSurface>(parent.get());
  174. parent->Attach(buffer.get());
  175. parent->Commit();
  176. shell_surface->GetWidget()->GetNativeWindow()->SetProperty(
  177. aura::client::kSkipImeProcessing, true);
  178. ASSERT_TRUE(parent->window()->GetProperty(aura::client::kSkipImeProcessing));
  179. // SkipImeProcessing property is propagated to SubSurface.
  180. auto surface = std::make_unique<Surface>();
  181. auto sub_surface = std::make_unique<SubSurface>(surface.get(), parent.get());
  182. surface->SetParent(parent.get(), gfx::Point(10, 10));
  183. EXPECT_TRUE(surface->window()->GetProperty(aura::client::kSkipImeProcessing));
  184. }
  185. } // namespace
  186. } // namespace exo