ca_layer_tree_unittest_mac.mm 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139
  1. // Copyright 2016 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. #import <AVFoundation/AVFoundation.h>
  5. #include <memory>
  6. #include "gpu/GLES2/gl2extchromium.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. #include "testing/gtest_mac.h"
  9. #include "third_party/skia/include/core/SkColor.h"
  10. #include "ui/accelerated_widget_mac/ca_renderer_layer_tree.h"
  11. #include "ui/gfx/geometry/dip_util.h"
  12. #include "ui/gfx/geometry/point_conversions.h"
  13. #include "ui/gfx/geometry/rect_conversions.h"
  14. #include "ui/gfx/mac/io_surface.h"
  15. #include "ui/gl/ca_renderer_layer_params.h"
  16. #include "ui/gl/gl_image_io_surface.h"
  17. @interface CALayer (Private)
  18. @property BOOL wantsExtendedDynamicRangeContent;
  19. @end
  20. namespace gpu {
  21. namespace {
  22. struct CALayerProperties {
  23. CALayerProperties() {}
  24. ~CALayerProperties() {}
  25. bool is_clipped = true;
  26. gfx::Rect clip_rect;
  27. gfx::RRectF rounded_corner_bounds;
  28. int sorting_context_id = 0;
  29. gfx::Transform transform;
  30. gfx::RectF contents_rect = gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f);
  31. gfx::Rect rect = gfx::Rect(0, 0, 256, 256);
  32. unsigned background_color = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
  33. unsigned edge_aa_mask = 0;
  34. float opacity = 1.0f;
  35. float scale_factor = 1.0f;
  36. unsigned filter = GL_LINEAR;
  37. scoped_refptr<gl::GLImageIOSurface> gl_image;
  38. bool allow_av_layers = true;
  39. bool allow_solid_color_layers = true;
  40. };
  41. scoped_refptr<gl::GLImageIOSurface> CreateGLImage(const gfx::Size& size,
  42. gfx::BufferFormat format,
  43. bool video) {
  44. scoped_refptr<gl::GLImageIOSurface> gl_image(
  45. gl::GLImageIOSurface::Create(size, GL_RGBA));
  46. base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
  47. gfx::CreateIOSurface(size, format));
  48. if (video) {
  49. base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer;
  50. CVPixelBufferCreateWithIOSurface(nullptr, io_surface, nullptr,
  51. cv_pixel_buffer.InitializeInto());
  52. gl_image->InitializeWithCVPixelBuffer(cv_pixel_buffer, 0,
  53. gfx::GenericSharedMemoryId(), format);
  54. } else {
  55. gl_image->Initialize(io_surface, 0, gfx::GenericSharedMemoryId(), format);
  56. }
  57. return gl_image;
  58. }
  59. bool ScheduleCALayer(ui::CARendererLayerTree* tree,
  60. CALayerProperties* properties) {
  61. return tree->ScheduleCALayer(ui::CARendererLayerParams(
  62. properties->is_clipped, properties->clip_rect,
  63. properties->rounded_corner_bounds, properties->sorting_context_id,
  64. properties->transform, properties->gl_image.get(),
  65. properties->contents_rect, properties->rect, properties->background_color,
  66. properties->edge_aa_mask, properties->opacity, properties->filter,
  67. absl::nullopt, gfx::ProtectedVideoType::kClear));
  68. }
  69. void UpdateCALayerTree(std::unique_ptr<ui::CARendererLayerTree>& ca_layer_tree,
  70. CALayerProperties* properties,
  71. CALayer* superlayer) {
  72. std::unique_ptr<ui::CARendererLayerTree> new_ca_layer_tree(
  73. new ui::CARendererLayerTree(properties->allow_av_layers,
  74. properties->allow_solid_color_layers));
  75. bool result = ScheduleCALayer(new_ca_layer_tree.get(), properties);
  76. EXPECT_TRUE(result);
  77. new_ca_layer_tree->CommitScheduledCALayers(
  78. superlayer, std::move(ca_layer_tree), properties->rect.size(),
  79. properties->scale_factor);
  80. std::swap(new_ca_layer_tree, ca_layer_tree);
  81. }
  82. } // namespace
  83. class CALayerTreeTest : public testing::Test {
  84. protected:
  85. void SetUp() override {
  86. superlayer_.reset([[CALayer alloc] init]);
  87. }
  88. // Traverse the tree. Validate that there exists only one content layer, and
  89. // return that layer.
  90. CALayer* GetOnlyContentLayer() {
  91. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  92. CALayer* root_layer = [superlayer_ sublayers][0];
  93. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  94. CALayer* clip_and_sorting_layer = [root_layer sublayers][0];
  95. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  96. CALayer* rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  97. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  98. CALayer* transform_layer = [rounded_rect_layer sublayers][0];
  99. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  100. return [transform_layer sublayers][0];
  101. }
  102. base::scoped_nsobject<CALayer> superlayer_;
  103. };
  104. // Test updating each layer's properties.
  105. class CALayerTreePropertyUpdatesTest : public CALayerTreeTest {
  106. public:
  107. void RunTest(bool allow_solid_color_layers) {
  108. CALayerProperties properties;
  109. properties.allow_solid_color_layers = allow_solid_color_layers;
  110. properties.clip_rect = gfx::Rect(2, 4, 8, 16);
  111. properties.rounded_corner_bounds = gfx::RRectF(2, 4, 8, 16, 13);
  112. properties.transform.Translate(10, 20);
  113. properties.contents_rect = gfx::RectF(0.0f, 0.25f, 0.5f, 0.75f);
  114. properties.rect = gfx::Rect(16, 32, 64, 128);
  115. properties.background_color = SkColorSetARGB(0xFF, 0xFF, 0, 0);
  116. properties.edge_aa_mask = ui::CALayerEdge::kLayerEdgeLeft;
  117. properties.opacity = 0.5f;
  118. properties.gl_image =
  119. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
  120. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree;
  121. CALayer* root_layer = nil;
  122. CALayer* clip_and_sorting_layer = nil;
  123. CALayer* rounded_rect_layer = nil;
  124. CALayer* transform_layer = nil;
  125. CALayer* content_layer = nil;
  126. // Validate the initial values.
  127. {
  128. std::unique_ptr<ui::CARendererLayerTree> new_ca_layer_tree(
  129. new ui::CARendererLayerTree(true, allow_solid_color_layers));
  130. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  131. // Validate the tree structure.
  132. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  133. root_layer = [superlayer_ sublayers][0];
  134. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  135. clip_and_sorting_layer = [root_layer sublayers][0];
  136. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  137. CALayer* superlayer_for_transform = clip_and_sorting_layer;
  138. if (!properties.rounded_corner_bounds.IsEmpty()) {
  139. rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  140. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  141. superlayer_for_transform = rounded_rect_layer;
  142. }
  143. transform_layer = [superlayer_for_transform sublayers][0];
  144. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  145. content_layer = [transform_layer sublayers][0];
  146. // Validate the clip and sorting context layer.
  147. EXPECT_TRUE([clip_and_sorting_layer masksToBounds]);
  148. EXPECT_EQ(gfx::Rect(properties.clip_rect.size()),
  149. gfx::Rect([clip_and_sorting_layer bounds]));
  150. EXPECT_EQ(properties.rounded_corner_bounds.GetSimpleRadius(),
  151. [rounded_rect_layer cornerRadius]);
  152. EXPECT_EQ(properties.clip_rect.origin(),
  153. gfx::Point([clip_and_sorting_layer position]));
  154. EXPECT_EQ(-properties.clip_rect.origin().x(),
  155. [clip_and_sorting_layer sublayerTransform].m41);
  156. EXPECT_EQ(-properties.clip_rect.origin().y(),
  157. [clip_and_sorting_layer sublayerTransform].m42);
  158. // Validate the transform layer.
  159. EXPECT_EQ(properties.transform.matrix().rc(3, 0),
  160. [transform_layer sublayerTransform].m41);
  161. EXPECT_EQ(properties.transform.matrix().rc(3, 1),
  162. [transform_layer sublayerTransform].m42);
  163. // Validate the content layer.
  164. EXPECT_EQ(static_cast<id>(properties.gl_image->io_surface().get()),
  165. [content_layer contents]);
  166. EXPECT_EQ(properties.contents_rect,
  167. gfx::RectF([content_layer contentsRect]));
  168. EXPECT_EQ(properties.rect.origin(), gfx::Point([content_layer position]));
  169. EXPECT_EQ(gfx::Rect(properties.rect.size()),
  170. gfx::Rect([content_layer bounds]));
  171. EXPECT_EQ(kCALayerLeftEdge, [content_layer edgeAntialiasingMask]);
  172. EXPECT_EQ(properties.opacity, [content_layer opacity]);
  173. EXPECT_NSEQ(kCAFilterLinear, [content_layer minificationFilter]);
  174. EXPECT_NSEQ(kCAFilterLinear, [content_layer magnificationFilter]);
  175. EXPECT_EQ(properties.scale_factor, [content_layer contentsScale]);
  176. }
  177. // Update just the clip rect and re-commit.
  178. {
  179. properties.clip_rect = gfx::Rect(4, 8, 16, 32);
  180. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  181. // Validate the tree structure
  182. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  183. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  184. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  185. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  186. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  187. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  188. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  189. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  190. // Validate the clip and sorting context layer.
  191. EXPECT_TRUE([clip_and_sorting_layer masksToBounds]);
  192. EXPECT_EQ(gfx::Rect(properties.clip_rect.size()),
  193. gfx::Rect([clip_and_sorting_layer bounds]));
  194. EXPECT_EQ(properties.clip_rect.origin(),
  195. gfx::Point([clip_and_sorting_layer position]));
  196. EXPECT_EQ(-properties.clip_rect.origin().x(),
  197. [clip_and_sorting_layer sublayerTransform].m41);
  198. EXPECT_EQ(-properties.clip_rect.origin().y(),
  199. [clip_and_sorting_layer sublayerTransform].m42);
  200. }
  201. // Disable clipping and re-commit.
  202. {
  203. properties.is_clipped = false;
  204. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  205. // Validate the tree structure
  206. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  207. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  208. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  209. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  210. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  211. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  212. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  213. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  214. // Validate the clip and sorting context layer.
  215. EXPECT_FALSE([clip_and_sorting_layer masksToBounds]);
  216. EXPECT_EQ(gfx::Rect(), gfx::Rect([clip_and_sorting_layer bounds]));
  217. EXPECT_EQ(gfx::Point(), gfx::Point([clip_and_sorting_layer position]));
  218. EXPECT_EQ(0.0, [clip_and_sorting_layer sublayerTransform].m41);
  219. EXPECT_EQ(0.0, [clip_and_sorting_layer sublayerTransform].m42);
  220. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  221. }
  222. // Change the transform and re-commit.
  223. {
  224. properties.transform.Translate(5, 5);
  225. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  226. // Validate the tree structure.
  227. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  228. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  229. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  230. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  231. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  232. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  233. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  234. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  235. // Validate the transform layer.
  236. EXPECT_EQ(properties.transform.matrix().rc(3, 0),
  237. [transform_layer sublayerTransform].m41);
  238. EXPECT_EQ(properties.transform.matrix().rc(3, 1),
  239. [transform_layer sublayerTransform].m42);
  240. }
  241. // Change the edge antialiasing mask and commit.
  242. {
  243. properties.edge_aa_mask = ui::CALayerEdge::kLayerEdgeTop;
  244. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  245. // Validate the tree structure.
  246. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  247. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  248. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  249. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  250. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  251. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  252. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  253. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  254. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  255. // Validate the content layer. Note that top and bottom edges flip.
  256. EXPECT_EQ(kCALayerBottomEdge, [content_layer edgeAntialiasingMask]);
  257. }
  258. // Change the contents and commit.
  259. {
  260. properties.gl_image = nullptr;
  261. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  262. // Validate the tree structure.
  263. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  264. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  265. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  266. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  267. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  268. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  269. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  270. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  271. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  272. // Validate the content layer. Note that edge anti-aliasing does not flip
  273. // for solid colors.
  274. if (allow_solid_color_layers) {
  275. EXPECT_EQ(nil, [content_layer contents]);
  276. EXPECT_EQ(kCALayerTopEdge, [content_layer edgeAntialiasingMask]);
  277. } else {
  278. EXPECT_EQ(ca_layer_tree->ContentsForSolidColorForTesting(
  279. properties.background_color),
  280. [content_layer contents]);
  281. EXPECT_EQ(kCALayerBottomEdge, [content_layer edgeAntialiasingMask]);
  282. }
  283. }
  284. // Change the rect size.
  285. {
  286. properties.rect = gfx::Rect(properties.rect.origin(), gfx::Size(32, 16));
  287. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  288. // Validate the tree structure.
  289. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  290. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  291. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  292. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  293. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  294. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  295. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  296. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  297. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  298. // Validate the content layer.
  299. EXPECT_EQ(properties.rect.origin(), gfx::Point([content_layer position]));
  300. EXPECT_EQ(gfx::Rect(properties.rect.size()),
  301. gfx::Rect([content_layer bounds]));
  302. }
  303. // Change the rect position.
  304. {
  305. properties.rect = gfx::Rect(gfx::Point(16, 4), properties.rect.size());
  306. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  307. // Validate the tree structure.
  308. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  309. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  310. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  311. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  312. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  313. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  314. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  315. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  316. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  317. // Validate the content layer.
  318. EXPECT_EQ(properties.rect.origin(), gfx::Point([content_layer position]));
  319. EXPECT_EQ(gfx::Rect(properties.rect.size()),
  320. gfx::Rect([content_layer bounds]));
  321. }
  322. // Change the opacity.
  323. {
  324. properties.opacity = 1.0f;
  325. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  326. // Validate the tree structure.
  327. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  328. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  329. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  330. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  331. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  332. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  333. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  334. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  335. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  336. // Validate the content layer.
  337. EXPECT_EQ(properties.opacity, [content_layer opacity]);
  338. }
  339. // Change the filter.
  340. {
  341. properties.filter = GL_NEAREST;
  342. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  343. // Validate the tree structure.
  344. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  345. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  346. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  347. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  348. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  349. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  350. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  351. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  352. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  353. // Validate the content layer.
  354. EXPECT_NSEQ(kCAFilterNearest, [content_layer minificationFilter]);
  355. EXPECT_NSEQ(kCAFilterNearest, [content_layer magnificationFilter]);
  356. }
  357. // Add the clipping and IOSurface contents back.
  358. {
  359. properties.is_clipped = true;
  360. properties.gl_image = CreateGLImage(gfx::Size(256, 256),
  361. gfx::BufferFormat::BGRA_8888, false);
  362. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  363. // Validate the tree structure.
  364. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  365. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  366. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  367. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  368. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  369. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  370. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  371. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  372. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  373. // Validate the content layer.
  374. EXPECT_EQ(static_cast<id>(properties.gl_image->io_surface().get()),
  375. [content_layer contents]);
  376. EXPECT_EQ(kCALayerBottomEdge, [content_layer edgeAntialiasingMask]);
  377. }
  378. // Change the scale factor. This should result in a new tree being created.
  379. {
  380. properties.scale_factor = 2.0f;
  381. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  382. // Validate the tree structure.
  383. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  384. EXPECT_NE(root_layer, [superlayer_ sublayers][0]);
  385. root_layer = [superlayer_ sublayers][0];
  386. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  387. EXPECT_NE(clip_and_sorting_layer, [root_layer sublayers][0]);
  388. clip_and_sorting_layer = [root_layer sublayers][0];
  389. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  390. EXPECT_NE(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  391. rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  392. // Under a 2.0 scale factor, the corner-radius should be halved.
  393. EXPECT_EQ(properties.rounded_corner_bounds.GetSimpleRadius() / 2.0f,
  394. [rounded_rect_layer cornerRadius]);
  395. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  396. EXPECT_NE(transform_layer, [clip_and_sorting_layer sublayers][0]);
  397. transform_layer = [rounded_rect_layer sublayers][0];
  398. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  399. EXPECT_NE(content_layer, [transform_layer sublayers][0]);
  400. content_layer = [transform_layer sublayers][0];
  401. // Validate the clip and sorting context layer.
  402. EXPECT_TRUE([clip_and_sorting_layer masksToBounds]);
  403. EXPECT_EQ(
  404. gfx::ToFlooredRectDeprecated(gfx::ConvertRectToDips(
  405. gfx::Rect(properties.clip_rect.size()), properties.scale_factor)),
  406. gfx::Rect([clip_and_sorting_layer bounds]));
  407. EXPECT_EQ(gfx::ToFlooredPoint(gfx::ConvertPointToDips(
  408. properties.clip_rect.origin(), properties.scale_factor)),
  409. gfx::Point([clip_and_sorting_layer position]));
  410. EXPECT_EQ(-properties.clip_rect.origin().x() / properties.scale_factor,
  411. [clip_and_sorting_layer sublayerTransform].m41);
  412. EXPECT_EQ(-properties.clip_rect.origin().y() / properties.scale_factor,
  413. [clip_and_sorting_layer sublayerTransform].m42);
  414. // Validate the transform layer.
  415. EXPECT_EQ(
  416. properties.transform.matrix().rc(3, 0) / properties.scale_factor,
  417. [transform_layer sublayerTransform].m41);
  418. EXPECT_EQ(
  419. properties.transform.matrix().rc(3, 1) / properties.scale_factor,
  420. [transform_layer sublayerTransform].m42);
  421. // Validate the content layer.
  422. EXPECT_EQ(static_cast<id>(properties.gl_image->io_surface().get()),
  423. [content_layer contents]);
  424. EXPECT_EQ(properties.contents_rect,
  425. gfx::RectF([content_layer contentsRect]));
  426. EXPECT_EQ(gfx::ToFlooredPoint(gfx::ConvertPointToDips(
  427. properties.rect.origin(), properties.scale_factor)),
  428. gfx::Point([content_layer position]));
  429. EXPECT_EQ(
  430. gfx::ToFlooredRectDeprecated(gfx::ConvertRectToDips(
  431. gfx::Rect(properties.rect.size()), properties.scale_factor)),
  432. gfx::Rect([content_layer bounds]));
  433. EXPECT_EQ(kCALayerBottomEdge, [content_layer edgeAntialiasingMask]);
  434. EXPECT_EQ(properties.opacity, [content_layer opacity]);
  435. EXPECT_EQ(properties.scale_factor, [content_layer contentsScale]);
  436. }
  437. // Remove the rounded corners. This should result in the rounded corners
  438. // being removed on that layer.
  439. {
  440. properties.rounded_corner_bounds = gfx::RRectF();
  441. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  442. // Validate the tree structure.
  443. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  444. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  445. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  446. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  447. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  448. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  449. EXPECT_EQ(0, [rounded_rect_layer cornerRadius]);
  450. EXPECT_FALSE([rounded_rect_layer masksToBounds]);
  451. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  452. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  453. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  454. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  455. }
  456. {
  457. // A no-op update should not invalidate any of the layers.
  458. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  459. // Validate the tree structure.
  460. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  461. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  462. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  463. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  464. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  465. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  466. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  467. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  468. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  469. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  470. }
  471. // Re-add rounded corners.
  472. {
  473. properties.rounded_corner_bounds = gfx::RRectF(1, 2, 3, 4, 5);
  474. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  475. // Validate the tree structure.
  476. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  477. EXPECT_EQ(root_layer, [superlayer_ sublayers][0]);
  478. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  479. EXPECT_EQ(clip_and_sorting_layer, [root_layer sublayers][0]);
  480. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  481. EXPECT_EQ(rounded_rect_layer, [clip_and_sorting_layer sublayers][0]);
  482. // Under a 2.0 scale factor, the corer-radius should be halved.
  483. EXPECT_EQ(properties.rounded_corner_bounds.GetSimpleRadius() / 2.0f,
  484. [rounded_rect_layer cornerRadius]);
  485. EXPECT_TRUE([rounded_rect_layer masksToBounds]);
  486. EXPECT_EQ(transform_layer, [rounded_rect_layer sublayers][0]);
  487. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  488. EXPECT_EQ(content_layer, [transform_layer sublayers][0]);
  489. }
  490. }
  491. };
  492. TEST_F(CALayerTreePropertyUpdatesTest, AllowSolidColors) {
  493. RunTest(true);
  494. }
  495. TEST_F(CALayerTreePropertyUpdatesTest, DisallowSolidColors) {
  496. RunTest(false);
  497. }
  498. // Verify that sorting context zero is split at non-flat transforms.
  499. TEST_F(CALayerTreeTest, SplitSortingContextZero) {
  500. CALayerProperties properties;
  501. properties.is_clipped = false;
  502. properties.clip_rect = gfx::Rect();
  503. properties.rect = gfx::Rect(0, 0, 256, 256);
  504. // We'll use the IOSurface contents to identify the content layers.
  505. scoped_refptr<gl::GLImageIOSurface> gl_images[5];
  506. for (size_t i = 0; i < 5; ++i) {
  507. gl_images[i] =
  508. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
  509. }
  510. // Have 5 transforms:
  511. // * 2 flat but different (1 sorting context layer, 2 transform layers)
  512. // * 1 non-flat (new sorting context layer)
  513. // * 2 flat and the same (new sorting context layer, 1 transform layer)
  514. gfx::Transform transforms[5];
  515. transforms[0].Translate(10, 10);
  516. transforms[1].RotateAboutZAxis(45.0f);
  517. transforms[2].RotateAboutYAxis(45.0f);
  518. transforms[3].Translate(10, 10);
  519. transforms[4].Translate(10, 10);
  520. // Schedule and commit the layers.
  521. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree(
  522. new ui::CARendererLayerTree(true, true));
  523. for (size_t i = 0; i < 5; ++i) {
  524. properties.gl_image = gl_images[i];
  525. properties.transform = transforms[i];
  526. bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
  527. EXPECT_TRUE(result);
  528. }
  529. ca_layer_tree->CommitScheduledCALayers(
  530. superlayer_, nullptr, properties.rect.size(), properties.scale_factor);
  531. // Validate the root layer.
  532. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  533. CALayer* root_layer = [superlayer_ sublayers][0];
  534. // Validate that we have 3 sorting context layers.
  535. EXPECT_EQ(3u, [[root_layer sublayers] count]);
  536. CALayer* clip_and_sorting_layer_0 = [root_layer sublayers][0];
  537. CALayer* clip_and_sorting_layer_1 = [root_layer sublayers][1];
  538. CALayer* clip_and_sorting_layer_2 = [root_layer sublayers][2];
  539. CALayer* rounded_rect_layer_0 = [clip_and_sorting_layer_0 sublayers][0];
  540. CALayer* rounded_rect_layer_1 = [clip_and_sorting_layer_1 sublayers][0];
  541. CALayer* rounded_rect_layer_2 = [clip_and_sorting_layer_2 sublayers][0];
  542. // Validate that the first sorting context has 2 transform layers each with
  543. // one content layer.
  544. EXPECT_EQ(2u, [[rounded_rect_layer_0 sublayers] count]);
  545. CALayer* transform_layer_0_0 = [rounded_rect_layer_0 sublayers][0];
  546. CALayer* transform_layer_0_1 = [rounded_rect_layer_0 sublayers][1];
  547. EXPECT_EQ(1u, [[transform_layer_0_0 sublayers] count]);
  548. CALayer* content_layer_0 = [transform_layer_0_0 sublayers][0];
  549. EXPECT_EQ(1u, [[transform_layer_0_1 sublayers] count]);
  550. CALayer* content_layer_1 = [transform_layer_0_1 sublayers][0];
  551. // Validate that the second sorting context has 1 transform layer with one
  552. // content layer.
  553. EXPECT_EQ(1u, [[rounded_rect_layer_1 sublayers] count]);
  554. CALayer* transform_layer_1_0 = [rounded_rect_layer_1 sublayers][0];
  555. EXPECT_EQ(1u, [[transform_layer_1_0 sublayers] count]);
  556. CALayer* content_layer_2 = [transform_layer_1_0 sublayers][0];
  557. // Validate that the third sorting context has 1 transform layer with two
  558. // content layers.
  559. EXPECT_EQ(1u, [[rounded_rect_layer_2 sublayers] count]);
  560. CALayer* transform_layer_2_0 = [rounded_rect_layer_2 sublayers][0];
  561. EXPECT_EQ(2u, [[transform_layer_2_0 sublayers] count]);
  562. CALayer* content_layer_3 = [transform_layer_2_0 sublayers][0];
  563. CALayer* content_layer_4 = [transform_layer_2_0 sublayers][1];
  564. // Validate that the layers come out in order.
  565. EXPECT_EQ(static_cast<id>(gl_images[0]->io_surface().get()),
  566. [content_layer_0 contents]);
  567. EXPECT_EQ(static_cast<id>(gl_images[1]->io_surface().get()),
  568. [content_layer_1 contents]);
  569. EXPECT_EQ(static_cast<id>(gl_images[2]->io_surface().get()),
  570. [content_layer_2 contents]);
  571. EXPECT_EQ(static_cast<id>(gl_images[3]->io_surface().get()),
  572. [content_layer_3 contents]);
  573. EXPECT_EQ(static_cast<id>(gl_images[4]->io_surface().get()),
  574. [content_layer_4 contents]);
  575. }
  576. // Verify that sorting contexts are allocated appropriately.
  577. TEST_F(CALayerTreeTest, SortingContexts) {
  578. CALayerProperties properties;
  579. properties.is_clipped = false;
  580. properties.clip_rect = gfx::Rect();
  581. properties.rect = gfx::Rect(0, 0, 256, 256);
  582. // We'll use the IOSurface contents to identify the content layers.
  583. scoped_refptr<gl::GLImageIOSurface> gl_images[3];
  584. for (size_t i = 0; i < 3; ++i) {
  585. gl_images[i] =
  586. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
  587. }
  588. int sorting_context_ids[3] = {3, -1, 0};
  589. // Schedule and commit the layers.
  590. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree(
  591. new ui::CARendererLayerTree(true, true));
  592. for (size_t i = 0; i < 3; ++i) {
  593. properties.sorting_context_id = sorting_context_ids[i];
  594. properties.gl_image = gl_images[i];
  595. bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
  596. EXPECT_TRUE(result);
  597. }
  598. ca_layer_tree->CommitScheduledCALayers(
  599. superlayer_, nullptr, properties.rect.size(), properties.scale_factor);
  600. // Validate the root layer.
  601. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  602. CALayer* root_layer = [superlayer_ sublayers][0];
  603. // Validate that we have 3 sorting context layers.
  604. EXPECT_EQ(3u, [[root_layer sublayers] count]);
  605. CALayer* clip_and_sorting_layer_0 = [root_layer sublayers][0];
  606. CALayer* clip_and_sorting_layer_1 = [root_layer sublayers][1];
  607. CALayer* clip_and_sorting_layer_2 = [root_layer sublayers][2];
  608. CALayer* rounded_rect_layer_0 = [clip_and_sorting_layer_0 sublayers][0];
  609. CALayer* rounded_rect_layer_1 = [clip_and_sorting_layer_1 sublayers][0];
  610. CALayer* rounded_rect_layer_2 = [clip_and_sorting_layer_2 sublayers][0];
  611. // Validate that each sorting context has 1 transform layer.
  612. EXPECT_EQ(1u, [[rounded_rect_layer_0 sublayers] count]);
  613. CALayer* transform_layer_0 = [rounded_rect_layer_0 sublayers][0];
  614. EXPECT_EQ(1u, [[rounded_rect_layer_1 sublayers] count]);
  615. CALayer* transform_layer_1 = [rounded_rect_layer_1 sublayers][0];
  616. EXPECT_EQ(1u, [[rounded_rect_layer_2 sublayers] count]);
  617. CALayer* transform_layer_2 = [rounded_rect_layer_2 sublayers][0];
  618. // Validate that each transform has 1 content layer.
  619. EXPECT_EQ(1u, [[transform_layer_0 sublayers] count]);
  620. CALayer* content_layer_0 = [transform_layer_0 sublayers][0];
  621. EXPECT_EQ(1u, [[transform_layer_1 sublayers] count]);
  622. CALayer* content_layer_1 = [transform_layer_1 sublayers][0];
  623. EXPECT_EQ(1u, [[transform_layer_2 sublayers] count]);
  624. CALayer* content_layer_2 = [transform_layer_2 sublayers][0];
  625. // Validate that the layers come out in order.
  626. EXPECT_EQ(static_cast<id>(gl_images[0]->io_surface().get()),
  627. [content_layer_0 contents]);
  628. EXPECT_EQ(static_cast<id>(gl_images[1]->io_surface().get()),
  629. [content_layer_1 contents]);
  630. EXPECT_EQ(static_cast<id>(gl_images[2]->io_surface().get()),
  631. [content_layer_2 contents]);
  632. }
  633. // Verify that sorting contexts must all have the same clipping properties.
  634. TEST_F(CALayerTreeTest, SortingContextMustHaveConsistentClip) {
  635. CALayerProperties properties;
  636. // Vary the clipping parameters within sorting contexts.
  637. bool is_clippeds[3] = { true, true, false};
  638. gfx::Rect clip_rects[3] = {
  639. gfx::Rect(0, 0, 16, 16),
  640. gfx::Rect(4, 8, 16, 32),
  641. gfx::Rect(0, 0, 16, 16)
  642. };
  643. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree(
  644. new ui::CARendererLayerTree(true, true));
  645. // First send the various clip parameters to sorting context zero. This is
  646. // legitimate.
  647. for (size_t i = 0; i < 3; ++i) {
  648. properties.is_clipped = is_clippeds[i];
  649. properties.clip_rect = clip_rects[i];
  650. bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
  651. EXPECT_TRUE(result);
  652. }
  653. // Next send the various clip parameters to a non-zero sorting context. This
  654. // will fail when we try to change the clip within the sorting context.
  655. for (size_t i = 0; i < 3; ++i) {
  656. properties.sorting_context_id = 3;
  657. properties.is_clipped = is_clippeds[i];
  658. properties.clip_rect = clip_rects[i];
  659. bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
  660. if (i == 0)
  661. EXPECT_TRUE(result);
  662. else
  663. EXPECT_FALSE(result);
  664. }
  665. // Try once more with the original clip and verify it works.
  666. {
  667. properties.is_clipped = is_clippeds[0];
  668. properties.clip_rect = clip_rects[0];
  669. bool result = ScheduleCALayer(ca_layer_tree.get(), &properties);
  670. EXPECT_TRUE(result);
  671. }
  672. }
  673. // Test updating each layer's properties.
  674. TEST_F(CALayerTreeTest, AVLayer) {
  675. CALayerProperties properties;
  676. properties.gl_image =
  677. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
  678. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree;
  679. CALayer* content_layer_old = nil;
  680. CALayer* content_layer_new = nil;
  681. // Validate the initial values.
  682. {
  683. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  684. content_layer_new = GetOnlyContentLayer();
  685. EXPECT_FALSE([content_layer_new
  686. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  687. }
  688. content_layer_old = content_layer_new;
  689. // Pass a YUV 420 frame. This will become an AVSampleBufferDisplayLayer
  690. // because it is in fullscreen low power mode.
  691. properties.gl_image = CreateGLImage(
  692. gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, false);
  693. {
  694. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  695. content_layer_new = GetOnlyContentLayer();
  696. EXPECT_TRUE([content_layer_new
  697. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  698. EXPECT_NE(content_layer_new, content_layer_old);
  699. }
  700. content_layer_old = content_layer_new;
  701. // Pass a similar frame. Nothing should change.
  702. properties.gl_image = CreateGLImage(
  703. gfx::Size(256, 128), gfx::BufferFormat::YUV_420_BIPLANAR, false);
  704. {
  705. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  706. content_layer_new = GetOnlyContentLayer();
  707. EXPECT_TRUE([content_layer_new
  708. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  709. EXPECT_EQ(content_layer_new, content_layer_old);
  710. }
  711. content_layer_old = content_layer_new;
  712. // Break fullscreen low power mode by changing opacity. This should cause
  713. // us to drop out of using AVSampleBufferDisplayLayer.
  714. properties.opacity = 0.9;
  715. {
  716. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  717. content_layer_new = GetOnlyContentLayer();
  718. EXPECT_FALSE([content_layer_new
  719. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  720. EXPECT_NE(content_layer_new, content_layer_old);
  721. }
  722. content_layer_old = content_layer_new;
  723. // Now try a P010 frame. Because this may be HDR, we should jump back to
  724. // having an AVSampleBufferDisplayLayer.
  725. properties.gl_image =
  726. CreateGLImage(gfx::Size(128, 256), gfx::BufferFormat::P010, false);
  727. {
  728. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  729. content_layer_new = GetOnlyContentLayer();
  730. EXPECT_TRUE([content_layer_new
  731. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  732. EXPECT_NE(content_layer_new, content_layer_old);
  733. }
  734. content_layer_old = content_layer_new;
  735. // Go back to testing AVSampleBufferLayer and fullscreen low power.
  736. properties.opacity = 1.0;
  737. // Pass a frame with a CVPixelBuffer which, when scaled down, will have a
  738. // fractional dimension.
  739. properties.gl_image = CreateGLImage(
  740. gfx::Size(513, 512), gfx::BufferFormat::YUV_420_BIPLANAR, true);
  741. {
  742. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  743. content_layer_new = GetOnlyContentLayer();
  744. // Validate that the layer's size is adjusted to include the fractional
  745. // width, which works around a macOS bug (https://crbug.com/792632).
  746. CGSize layer_size = content_layer_new.bounds.size;
  747. EXPECT_EQ(256.5, layer_size.width);
  748. EXPECT_EQ(256, layer_size.height);
  749. }
  750. content_layer_old = content_layer_new;
  751. // Pass a frame that is clipped.
  752. properties.contents_rect = gfx::RectF(0, 0, 1, 0.9);
  753. properties.gl_image = CreateGLImage(
  754. gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, false);
  755. {
  756. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  757. content_layer_new = GetOnlyContentLayer();
  758. EXPECT_FALSE([content_layer_new
  759. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  760. EXPECT_NE(content_layer_new, content_layer_old);
  761. }
  762. content_layer_old = content_layer_new;
  763. }
  764. // Ensure that blocklisting AVSampleBufferDisplayLayer works.
  765. TEST_F(CALayerTreeTest, AVLayerBlocklist) {
  766. CALayerProperties properties;
  767. properties.gl_image = CreateGLImage(
  768. gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, false);
  769. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree;
  770. CALayer* root_layer = nil;
  771. CALayer* clip_and_sorting_layer = nil;
  772. CALayer* rounded_rect_layer = nil;
  773. CALayer* transform_layer = nil;
  774. CALayer* content_layer1 = nil;
  775. CALayer* content_layer2 = nil;
  776. {
  777. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  778. // Validate the tree structure.
  779. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  780. root_layer = [superlayer_ sublayers][0];
  781. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  782. clip_and_sorting_layer = [root_layer sublayers][0];
  783. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  784. rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  785. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  786. transform_layer = [rounded_rect_layer sublayers][0];
  787. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  788. content_layer1 = [transform_layer sublayers][0];
  789. // Validate the content layer.
  790. EXPECT_TRUE([content_layer1
  791. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  792. }
  793. {
  794. properties.allow_av_layers = false;
  795. UpdateCALayerTree(ca_layer_tree, &properties, superlayer_);
  796. // Validate the tree structure.
  797. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  798. root_layer = [superlayer_ sublayers][0];
  799. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  800. clip_and_sorting_layer = [root_layer sublayers][0];
  801. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  802. rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  803. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  804. transform_layer = [rounded_rect_layer sublayers][0];
  805. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  806. content_layer2 = [transform_layer sublayers][0];
  807. // Validate the content layer.
  808. EXPECT_FALSE([content_layer2
  809. isKindOfClass:NSClassFromString(@"AVSampleBufferDisplayLayer")]);
  810. EXPECT_NE(content_layer1, content_layer2);
  811. }
  812. }
  813. // Test fullscreen low power detection.
  814. TEST_F(CALayerTreeTest, FullscreenLowPower) {
  815. CALayerProperties properties;
  816. properties.gl_image = CreateGLImage(
  817. gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR, true);
  818. properties.is_clipped = false;
  819. CALayerProperties properties_black;
  820. properties_black.is_clipped = false;
  821. properties_black.background_color = SK_ColorBLACK;
  822. CALayerProperties properties_white;
  823. properties_white.is_clipped = false;
  824. properties_white.background_color = SK_ColorWHITE;
  825. std::unique_ptr<ui::CARendererLayerTree> ca_layer_tree;
  826. // Test a configuration with no background.
  827. {
  828. std::unique_ptr<ui::CARendererLayerTree> new_ca_layer_tree(
  829. new ui::CARendererLayerTree(true, true));
  830. bool result = ScheduleCALayer(new_ca_layer_tree.get(), &properties);
  831. EXPECT_TRUE(result);
  832. new_ca_layer_tree->CommitScheduledCALayers(
  833. superlayer_, std::move(ca_layer_tree), properties.rect.size(),
  834. properties.scale_factor);
  835. std::swap(new_ca_layer_tree, ca_layer_tree);
  836. // Validate the tree structure.
  837. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  838. CALayer* root_layer = [superlayer_ sublayers][0];
  839. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  840. CALayer* clip_and_sorting_layer = [root_layer sublayers][0];
  841. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  842. CALayer* rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  843. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  844. CALayer* transform_layer = [rounded_rect_layer sublayers][0];
  845. EXPECT_EQ(1u, [[transform_layer sublayers] count]);
  846. // Validate the content layer and fullscreen low power mode.
  847. EXPECT_FALSE(CGRectEqualToRect([root_layer frame], CGRectZero));
  848. EXPECT_NE([root_layer backgroundColor], nil);
  849. }
  850. // Test a configuration with a black background.
  851. {
  852. std::unique_ptr<ui::CARendererLayerTree> new_ca_layer_tree(
  853. new ui::CARendererLayerTree(true, true));
  854. bool result = ScheduleCALayer(new_ca_layer_tree.get(), &properties_black);
  855. EXPECT_TRUE(result);
  856. result = ScheduleCALayer(new_ca_layer_tree.get(), &properties);
  857. EXPECT_TRUE(result);
  858. new_ca_layer_tree->CommitScheduledCALayers(
  859. superlayer_, std::move(ca_layer_tree), properties.rect.size(),
  860. properties.scale_factor);
  861. std::swap(new_ca_layer_tree, ca_layer_tree);
  862. // Validate the tree structure.
  863. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  864. CALayer* root_layer = [superlayer_ sublayers][0];
  865. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  866. CALayer* clip_and_sorting_layer = [root_layer sublayers][0];
  867. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  868. CALayer* rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  869. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  870. CALayer* transform_layer = [rounded_rect_layer sublayers][0];
  871. EXPECT_EQ(2u, [[transform_layer sublayers] count]);
  872. // Validate the content layer and fullscreen low power mode.
  873. EXPECT_FALSE(CGRectEqualToRect([root_layer frame], CGRectZero));
  874. EXPECT_NE([root_layer backgroundColor], nil);
  875. }
  876. // Test a configuration with a white background. It will fail.
  877. {
  878. std::unique_ptr<ui::CARendererLayerTree> new_ca_layer_tree(
  879. new ui::CARendererLayerTree(true, true));
  880. bool result = ScheduleCALayer(new_ca_layer_tree.get(), &properties_white);
  881. EXPECT_TRUE(result);
  882. result = ScheduleCALayer(new_ca_layer_tree.get(), &properties);
  883. EXPECT_TRUE(result);
  884. new_ca_layer_tree->CommitScheduledCALayers(
  885. superlayer_, std::move(ca_layer_tree), properties.rect.size(),
  886. properties.scale_factor);
  887. std::swap(new_ca_layer_tree, ca_layer_tree);
  888. // Validate the tree structure.
  889. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  890. CALayer* root_layer = [superlayer_ sublayers][0];
  891. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  892. CALayer* clip_and_sorting_layer = [root_layer sublayers][0];
  893. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  894. CALayer* rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  895. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  896. CALayer* transform_layer = [rounded_rect_layer sublayers][0];
  897. EXPECT_EQ(2u, [[transform_layer sublayers] count]);
  898. // Validate the content layer and fullscreen low power mode.
  899. EXPECT_TRUE(CGRectEqualToRect([root_layer frame], CGRectZero));
  900. EXPECT_EQ([root_layer backgroundColor], nil);
  901. }
  902. // Test a configuration with a black foreground. It too will fail.
  903. {
  904. std::unique_ptr<ui::CARendererLayerTree> new_ca_layer_tree(
  905. new ui::CARendererLayerTree(true, true));
  906. bool result = ScheduleCALayer(new_ca_layer_tree.get(), &properties);
  907. EXPECT_TRUE(result);
  908. result = ScheduleCALayer(new_ca_layer_tree.get(), &properties_black);
  909. EXPECT_TRUE(result);
  910. new_ca_layer_tree->CommitScheduledCALayers(
  911. superlayer_, std::move(ca_layer_tree), properties.rect.size(),
  912. properties.scale_factor);
  913. std::swap(new_ca_layer_tree, ca_layer_tree);
  914. // Validate the tree structure.
  915. EXPECT_EQ(1u, [[superlayer_ sublayers] count]);
  916. CALayer* root_layer = [superlayer_ sublayers][0];
  917. EXPECT_EQ(1u, [[root_layer sublayers] count]);
  918. CALayer* clip_and_sorting_layer = [root_layer sublayers][0];
  919. EXPECT_EQ(1u, [[clip_and_sorting_layer sublayers] count]);
  920. CALayer* rounded_rect_layer = [clip_and_sorting_layer sublayers][0];
  921. EXPECT_EQ(1u, [[rounded_rect_layer sublayers] count]);
  922. CALayer* transform_layer = [rounded_rect_layer sublayers][0];
  923. EXPECT_EQ(2u, [[transform_layer sublayers] count]);
  924. // Validate the content layer and fullscreen low power mode.
  925. EXPECT_TRUE(CGRectEqualToRect([root_layer frame], CGRectZero));
  926. EXPECT_EQ([root_layer backgroundColor], nil);
  927. }
  928. }
  929. // Verify that HDR is triggered appropriately.
  930. TEST_F(CALayerTreeTest, HDRTrigger) {
  931. std::unique_ptr<ui::CARendererLayerTree> ca_layer_trees[4]{
  932. std::make_unique<ui::CARendererLayerTree>(true, true),
  933. std::make_unique<ui::CARendererLayerTree>(true, true),
  934. std::make_unique<ui::CARendererLayerTree>(true, true),
  935. std::make_unique<ui::CARendererLayerTree>(true, true),
  936. };
  937. CALayerProperties properties;
  938. properties.is_clipped = false;
  939. properties.clip_rect = gfx::Rect();
  940. properties.rect = gfx::Rect(0, 0, 256, 256);
  941. bool result = false;
  942. // We only copy images that have both high-bit-depth and an HDR color space.
  943. scoped_refptr<gl::GLImageIOSurface> sdr_image =
  944. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
  945. scoped_refptr<gl::GLImageIOSurface> tricky_sdr_image =
  946. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888, false);
  947. scoped_refptr<gl::GLImageIOSurface> hdr_image =
  948. CreateGLImage(gfx::Size(256, 256), gfx::BufferFormat::RGBA_F16, false);
  949. sdr_image->SetColorSpace(gfx::ColorSpace::CreateSRGB());
  950. tricky_sdr_image->SetColorSpace(gfx::ColorSpace::CreateExtendedSRGB());
  951. hdr_image->SetColorSpace(gfx::ColorSpace::CreateExtendedSRGB());
  952. // Schedule and commit the HDR layer.
  953. properties.gl_image = hdr_image;
  954. result = ScheduleCALayer(ca_layer_trees[0].get(), &properties);
  955. EXPECT_TRUE(result);
  956. ca_layer_trees[0]->CommitScheduledCALayers(
  957. superlayer_, nullptr, properties.rect.size(), properties.scale_factor);
  958. // Validate that the root layer has is triggering HDR.
  959. CALayer* content_layer = GetOnlyContentLayer();
  960. if (@available(macos 10.15, *))
  961. EXPECT_TRUE([content_layer wantsExtendedDynamicRangeContent]);
  962. // Commit the SDR layer.
  963. properties.gl_image = sdr_image;
  964. result = ScheduleCALayer(ca_layer_trees[1].get(), &properties);
  965. EXPECT_TRUE(result);
  966. ca_layer_trees[1]->CommitScheduledCALayers(
  967. superlayer_, std::move(ca_layer_trees[0]), properties.rect.size(),
  968. properties.scale_factor);
  969. // Validate that HDR is off. The previous content layer should have been
  970. // un-parented.
  971. EXPECT_EQ([content_layer superlayer], nil);
  972. content_layer = GetOnlyContentLayer();
  973. if (@available(macos 10.15, *))
  974. EXPECT_FALSE([content_layer wantsExtendedDynamicRangeContent]);
  975. // Commit the tricky SDR layer.
  976. properties.gl_image = tricky_sdr_image;
  977. result = ScheduleCALayer(ca_layer_trees[2].get(), &properties);
  978. EXPECT_TRUE(result);
  979. ca_layer_trees[2]->CommitScheduledCALayers(
  980. superlayer_, std::move(ca_layer_trees[1]), properties.rect.size(),
  981. properties.scale_factor);
  982. // Validate that HDR is still off, and that the content layer hasn't changed.
  983. EXPECT_EQ(content_layer, GetOnlyContentLayer());
  984. if (@available(macos 10.15, *))
  985. EXPECT_FALSE([content_layer wantsExtendedDynamicRangeContent]);
  986. // Commit the HDR layer.
  987. properties.gl_image = hdr_image;
  988. result = ScheduleCALayer(ca_layer_trees[3].get(), &properties);
  989. EXPECT_TRUE(result);
  990. ca_layer_trees[3]->CommitScheduledCALayers(
  991. superlayer_, std::move(ca_layer_trees[2]), properties.rect.size(),
  992. properties.scale_factor);
  993. // Validate that HDR is back on. The previous content layer should have
  994. // been un-parented.
  995. EXPECT_EQ([content_layer superlayer], nil);
  996. content_layer = GetOnlyContentLayer();
  997. if (@available(macos 10.15, *))
  998. EXPECT_TRUE([content_layer wantsExtendedDynamicRangeContent]);
  999. }
  1000. } // namespace gpu