texture_layer_unittest.cc 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985
  1. // Copyright 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 "cc/layers/texture_layer.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <algorithm>
  8. #include <memory>
  9. #include <string>
  10. #include <utility>
  11. #include "base/bind.h"
  12. #include "base/callback.h"
  13. #include "base/location.h"
  14. #include "base/memory/ptr_util.h"
  15. #include "base/memory/raw_ptr.h"
  16. #include "base/run_loop.h"
  17. #include "base/synchronization/lock.h"
  18. #include "base/synchronization/waitable_event.h"
  19. #include "base/task/sequenced_task_runner.h"
  20. #include "base/task/single_thread_task_runner.h"
  21. #include "base/threading/thread.h"
  22. #include "base/threading/thread_task_runner_handle.h"
  23. #include "base/time/time.h"
  24. #include "build/build_config.h"
  25. #include "cc/animation/animation_host.h"
  26. #include "cc/layers/solid_color_layer.h"
  27. #include "cc/layers/texture_layer_client.h"
  28. #include "cc/layers/texture_layer_impl.h"
  29. #include "cc/test/fake_impl_task_runner_provider.h"
  30. #include "cc/test/fake_layer_tree_frame_sink.h"
  31. #include "cc/test/fake_layer_tree_host_client.h"
  32. #include "cc/test/fake_layer_tree_host_impl.h"
  33. #include "cc/test/layer_test_common.h"
  34. #include "cc/test/layer_tree_test.h"
  35. #include "cc/test/stub_layer_tree_host_single_thread_client.h"
  36. #include "cc/test/test_layer_tree_frame_sink.h"
  37. #include "cc/test/test_task_graph_runner.h"
  38. #include "cc/trees/layer_tree_host.h"
  39. #include "cc/trees/layer_tree_impl.h"
  40. #include "cc/trees/single_thread_proxy.h"
  41. #include "components/viz/common/gpu/context_provider.h"
  42. #include "components/viz/common/gpu/raster_context_provider.h"
  43. #include "components/viz/common/quads/texture_draw_quad.h"
  44. #include "components/viz/common/resources/bitmap_allocation.h"
  45. #include "components/viz/common/resources/returned_resource.h"
  46. #include "components/viz/common/resources/shared_bitmap.h"
  47. #include "components/viz/common/resources/transferable_resource.h"
  48. #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
  49. #include "components/viz/service/display/software_output_device.h"
  50. #include "components/viz/test/fake_output_surface.h"
  51. #include "gpu/GLES2/gl2extchromium.h"
  52. #include "testing/gmock/include/gmock/gmock.h"
  53. #include "testing/gtest/include/gtest/gtest.h"
  54. using ::testing::Mock;
  55. using ::testing::_;
  56. using ::testing::AtLeast;
  57. using ::testing::AnyNumber;
  58. using ::testing::InvokeWithoutArgs;
  59. namespace cc {
  60. namespace {
  61. gpu::Mailbox MailboxFromChar(char value) {
  62. gpu::Mailbox mailbox;
  63. memset(mailbox.name, value, sizeof(mailbox.name));
  64. return mailbox;
  65. }
  66. gpu::SyncToken SyncTokenFromUInt(uint32_t value) {
  67. return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
  68. gpu::CommandBufferId::FromUnsafeValue(0x123), value);
  69. }
  70. class MockLayerTreeHost : public LayerTreeHost {
  71. public:
  72. static std::unique_ptr<MockLayerTreeHost> Create(
  73. FakeLayerTreeHostClient* client,
  74. TaskGraphRunner* task_graph_runner,
  75. MutatorHost* mutator_host) {
  76. LayerTreeHost::InitParams params;
  77. params.client = client;
  78. params.task_graph_runner = task_graph_runner;
  79. params.mutator_host = mutator_host;
  80. LayerTreeSettings settings;
  81. params.settings = &settings;
  82. return base::WrapUnique(new MockLayerTreeHost(std::move(params)));
  83. }
  84. MOCK_METHOD0(SetNeedsCommit, void());
  85. MOCK_METHOD0(StartRateLimiter, void());
  86. MOCK_METHOD0(StopRateLimiter, void());
  87. private:
  88. explicit MockLayerTreeHost(LayerTreeHost::InitParams params)
  89. : LayerTreeHost(std::move(params), CompositorMode::SINGLE_THREADED) {
  90. InitializeSingleThreaded(&single_thread_client_,
  91. base::ThreadTaskRunnerHandle::Get());
  92. }
  93. StubLayerTreeHostSingleThreadClient single_thread_client_;
  94. };
  95. class MockReleaseCallback {
  96. public:
  97. MOCK_METHOD3(Release,
  98. void(const gpu::Mailbox& mailbox,
  99. const gpu::SyncToken& sync_token,
  100. bool lost_resource));
  101. MOCK_METHOD3(Release2,
  102. void(const viz::SharedBitmapId& shared_bitmap_id,
  103. const gpu::SyncToken& sync_token,
  104. bool lost_resource));
  105. };
  106. struct CommonResourceObjects {
  107. explicit CommonResourceObjects(viz::SharedBitmapManager* manager)
  108. : mailbox_name1_(MailboxFromChar('1')),
  109. mailbox_name2_(MailboxFromChar('2')),
  110. sync_token1_(gpu::CommandBufferNamespace::GPU_IO,
  111. gpu::CommandBufferId::FromUnsafeValue(0x234),
  112. 1),
  113. sync_token2_(gpu::CommandBufferNamespace::GPU_IO,
  114. gpu::CommandBufferId::FromUnsafeValue(0x234),
  115. 2) {
  116. release_callback1_ =
  117. base::BindRepeating(&MockReleaseCallback::Release,
  118. base::Unretained(&mock_callback_), mailbox_name1_);
  119. release_callback2_ =
  120. base::BindRepeating(&MockReleaseCallback::Release,
  121. base::Unretained(&mock_callback_), mailbox_name2_);
  122. const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
  123. const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
  124. gfx::Size size(128, 128);
  125. resource1_ = viz::TransferableResource::MakeGL(
  126. mailbox_name1_, GL_LINEAR, arbitrary_target1, sync_token1_, size,
  127. false /* is_overlay_candidate */);
  128. resource2_ = viz::TransferableResource::MakeGL(
  129. mailbox_name2_, GL_LINEAR, arbitrary_target2, sync_token2_, size,
  130. false /* is_overlay_candidate */);
  131. shared_bitmap_id_ = viz::SharedBitmap::GenerateId();
  132. sw_release_callback_ = base::BindRepeating(
  133. &MockReleaseCallback::Release2, base::Unretained(&mock_callback_),
  134. shared_bitmap_id_);
  135. sw_resource_ = viz::TransferableResource::MakeSoftware(
  136. shared_bitmap_id_, size, viz::RGBA_8888);
  137. }
  138. using RepeatingReleaseCallback =
  139. base::RepeatingCallback<void(const gpu::SyncToken& sync_token,
  140. bool is_lost)>;
  141. gpu::Mailbox mailbox_name1_;
  142. gpu::Mailbox mailbox_name2_;
  143. MockReleaseCallback mock_callback_;
  144. RepeatingReleaseCallback release_callback1_;
  145. RepeatingReleaseCallback release_callback2_;
  146. RepeatingReleaseCallback sw_release_callback_;
  147. gpu::SyncToken sync_token1_;
  148. gpu::SyncToken sync_token2_;
  149. viz::SharedBitmapId shared_bitmap_id_;
  150. viz::TransferableResource resource1_;
  151. viz::TransferableResource resource2_;
  152. viz::TransferableResource sw_resource_;
  153. };
  154. class TextureLayerTest : public testing::Test {
  155. public:
  156. TextureLayerTest()
  157. : layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()),
  158. host_impl_(&task_runner_provider_, &task_graph_runner_),
  159. test_data_(&shared_bitmap_manager_) {}
  160. protected:
  161. void SetUp() override {
  162. animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  163. layer_tree_host_ = MockLayerTreeHost::Create(
  164. &fake_client_, &task_graph_runner_, animation_host_.get());
  165. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
  166. layer_tree_host_->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
  167. viz::LocalSurfaceId());
  168. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  169. }
  170. void TearDown() override {
  171. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  172. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
  173. animation_host_->SetMutatorHostClient(nullptr);
  174. layer_tree_host_->SetRootLayer(nullptr);
  175. layer_tree_host_ = nullptr;
  176. animation_host_ = nullptr;
  177. }
  178. std::unique_ptr<MockLayerTreeHost> layer_tree_host_;
  179. std::unique_ptr<AnimationHost> animation_host_;
  180. FakeImplTaskRunnerProvider task_runner_provider_;
  181. FakeLayerTreeHostClient fake_client_;
  182. viz::TestSharedBitmapManager shared_bitmap_manager_;
  183. TestTaskGraphRunner task_graph_runner_;
  184. std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_;
  185. FakeLayerTreeHostImpl host_impl_;
  186. CommonResourceObjects test_data_;
  187. };
  188. TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
  189. scoped_refptr<TextureLayer> test_layer =
  190. TextureLayer::CreateForMailbox(nullptr);
  191. EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
  192. // Test properties that should call SetNeedsCommit. All properties need to
  193. // be set to new values in order for SetNeedsCommit to be called.
  194. EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
  195. EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
  196. EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
  197. gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
  198. EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
  199. EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
  200. }
  201. class RunOnCommitLayerTreeHostClient : public FakeLayerTreeHostClient {
  202. public:
  203. void set_run_on_commit_and_draw(base::OnceClosure c) {
  204. run_on_commit_and_draw_ = std::move(c);
  205. }
  206. void DidCommitAndDrawFrame() override {
  207. if (run_on_commit_and_draw_)
  208. std::move(run_on_commit_and_draw_).Run();
  209. }
  210. private:
  211. base::OnceClosure run_on_commit_and_draw_;
  212. };
  213. // If the compositor is destroyed while TextureLayer has a resource in it, the
  214. // resource should be returned to the client. https://crbug.com/857262
  215. TEST_F(TextureLayerTest, ShutdownWithResource) {
  216. for (int i = 0; i < 2; ++i) {
  217. bool gpu = i == 0;
  218. SCOPED_TRACE(gpu);
  219. // Make our own LayerTreeHost for this test so we can control the lifetime.
  220. StubLayerTreeHostSingleThreadClient single_thread_client;
  221. RunOnCommitLayerTreeHostClient client;
  222. LayerTreeHost::InitParams params;
  223. params.client = &client;
  224. params.task_graph_runner = &task_graph_runner_;
  225. params.mutator_host = animation_host_.get();
  226. LayerTreeSettings settings;
  227. params.settings = &settings;
  228. params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
  229. auto host = LayerTreeHost::CreateSingleThreaded(&single_thread_client,
  230. std::move(params));
  231. client.SetLayerTreeHost(host.get());
  232. client.SetUseSoftwareCompositing(!gpu);
  233. scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(nullptr);
  234. layer->SetIsDrawable(true);
  235. layer->SetBounds(gfx::Size(10, 10));
  236. if (gpu) {
  237. layer->SetTransferableResource(test_data_.resource1_,
  238. test_data_.release_callback1_);
  239. } else {
  240. layer->SetTransferableResource(test_data_.sw_resource_,
  241. test_data_.sw_release_callback_);
  242. }
  243. viz::ParentLocalSurfaceIdAllocator allocator;
  244. allocator.GenerateId();
  245. host->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
  246. allocator.GetCurrentLocalSurfaceId());
  247. host->SetVisible(true);
  248. host->SetRootLayer(layer);
  249. // Commit and activate the TransferableResource in the TextureLayer.
  250. {
  251. base::RunLoop loop;
  252. client.set_run_on_commit_and_draw(loop.QuitClosure());
  253. loop.Run();
  254. }
  255. // Destroy the LayerTreeHost and the compositor-thread LayerImpl trees
  256. // while the resource is still in the layer. The resource should be released
  257. // back to the TextureLayer's client, but is post-tasked back so...
  258. host = nullptr;
  259. // We have to wait for the posted ReleaseCallback to run.
  260. // Our LayerTreeHostClient makes a FakeLayerTreeFrameSink which returns all
  261. // resources when its detached, so the resources will not be in use in the
  262. // display compositor, and will be returned as not lost.
  263. if (gpu) {
  264. EXPECT_CALL(test_data_.mock_callback_,
  265. Release(test_data_.mailbox_name1_, _, false))
  266. .Times(1);
  267. } else {
  268. EXPECT_CALL(test_data_.mock_callback_,
  269. Release2(test_data_.shared_bitmap_id_, _, false))
  270. .Times(1);
  271. }
  272. {
  273. base::RunLoop loop;
  274. loop.RunUntilIdle();
  275. }
  276. }
  277. }
  278. class TestMailboxHolder : public TextureLayer::TransferableResourceHolder {
  279. public:
  280. using TextureLayer::TransferableResourceHolder::Create;
  281. protected:
  282. ~TestMailboxHolder() override = default;
  283. };
  284. class TextureLayerWithResourceTest : public TextureLayerTest {
  285. protected:
  286. void TearDown() override {
  287. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  288. EXPECT_CALL(
  289. test_data_.mock_callback_,
  290. Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
  291. .Times(1);
  292. TextureLayerTest::TearDown();
  293. }
  294. };
  295. TEST_F(TextureLayerWithResourceTest, ReplaceMailboxOnMainThreadBeforeCommit) {
  296. scoped_refptr<TextureLayer> test_layer =
  297. TextureLayer::CreateForMailbox(nullptr);
  298. ASSERT_TRUE(test_layer.get());
  299. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
  300. layer_tree_host_->SetRootLayer(test_layer);
  301. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  302. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  303. test_layer->SetTransferableResource(test_data_.resource1_,
  304. test_data_.release_callback1_);
  305. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  306. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  307. EXPECT_CALL(
  308. test_data_.mock_callback_,
  309. Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
  310. .Times(1);
  311. test_layer->SetTransferableResource(test_data_.resource2_,
  312. test_data_.release_callback2_);
  313. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  314. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  315. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  316. EXPECT_CALL(
  317. test_data_.mock_callback_,
  318. Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
  319. .Times(1);
  320. test_layer->ClearTexture();
  321. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  322. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  323. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  324. test_layer->SetTransferableResource(test_data_.sw_resource_,
  325. test_data_.sw_release_callback_);
  326. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  327. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  328. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  329. EXPECT_CALL(test_data_.mock_callback_,
  330. Release2(test_data_.shared_bitmap_id_, _, false))
  331. .Times(1);
  332. test_layer->ClearTexture();
  333. Mock::VerifyAndClearExpectations(layer_tree_host_.get());
  334. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  335. // Test destructor.
  336. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  337. test_layer->SetTransferableResource(test_data_.resource1_,
  338. test_data_.release_callback1_);
  339. }
  340. class TextureLayerMailboxHolderTest : public TextureLayerTest {
  341. public:
  342. TextureLayerMailboxHolderTest()
  343. : main_thread_("MAIN") {
  344. main_thread_.Start();
  345. }
  346. void Wait(const base::Thread& thread) {
  347. base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  348. base::WaitableEvent::InitialState::NOT_SIGNALED);
  349. thread.task_runner()->PostTask(
  350. FROM_HERE,
  351. base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
  352. event.Wait();
  353. }
  354. void CreateMainRef() {
  355. resource_holder_ = TestMailboxHolder::Create(test_data_.resource1_,
  356. test_data_.release_callback1_);
  357. }
  358. void ReleaseMainRef() { resource_holder_ = nullptr; }
  359. void CreateImplRef(
  360. viz::ReleaseCallback* impl_ref,
  361. scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner) {
  362. *impl_ref =
  363. base::BindOnce(&TextureLayer::TransferableResourceHolder::Return,
  364. resource_holder_, main_thread_task_runner);
  365. }
  366. protected:
  367. scoped_refptr<TextureLayer::TransferableResourceHolder> resource_holder_;
  368. base::Thread main_thread_;
  369. };
  370. TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
  371. scoped_refptr<TextureLayer> test_layer =
  372. TextureLayer::CreateForMailbox(nullptr);
  373. ASSERT_TRUE(test_layer.get());
  374. main_thread_.task_runner()->PostTask(
  375. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
  376. base::Unretained(this)));
  377. Wait(main_thread_);
  378. // The texture layer is attached to compositor1, and passes a reference to its
  379. // impl tree.
  380. viz::ReleaseCallback compositor1;
  381. main_thread_.task_runner()->PostTask(
  382. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
  383. base::Unretained(this), &compositor1,
  384. main_thread_.task_runner()));
  385. // Then the texture layer is removed and attached to compositor2, and passes a
  386. // reference to its impl tree.
  387. viz::ReleaseCallback compositor2;
  388. main_thread_.task_runner()->PostTask(
  389. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
  390. base::Unretained(this), &compositor2,
  391. main_thread_.task_runner()));
  392. Wait(main_thread_);
  393. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  394. // The compositors both destroy their impl trees before the main thread layer
  395. // is destroyed.
  396. std::move(compositor1).Run(SyncTokenFromUInt(100), false);
  397. std::move(compositor2).Run(SyncTokenFromUInt(200), false);
  398. Wait(main_thread_);
  399. EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
  400. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  401. // The main thread ref is the last one, so the resource is released back to
  402. // the embedder, with the last sync point provided by the impl trees.
  403. EXPECT_CALL(test_data_.mock_callback_,
  404. Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), false))
  405. .Times(1);
  406. main_thread_.task_runner()->PostTask(
  407. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
  408. base::Unretained(this)));
  409. Wait(main_thread_);
  410. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  411. }
  412. TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
  413. scoped_refptr<TextureLayer> test_layer =
  414. TextureLayer::CreateForMailbox(nullptr);
  415. ASSERT_TRUE(test_layer.get());
  416. main_thread_.task_runner()->PostTask(
  417. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
  418. base::Unretained(this)));
  419. Wait(main_thread_);
  420. // The texture layer is attached to compositor1, and passes a reference to its
  421. // impl tree.
  422. viz::ReleaseCallback compositor1;
  423. main_thread_.task_runner()->PostTask(
  424. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
  425. base::Unretained(this), &compositor1,
  426. main_thread_.task_runner()));
  427. // Then the texture layer is removed and attached to compositor2, and passes a
  428. // reference to its impl tree.
  429. viz::ReleaseCallback compositor2;
  430. main_thread_.task_runner()->PostTask(
  431. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
  432. base::Unretained(this), &compositor2,
  433. main_thread_.task_runner()));
  434. Wait(main_thread_);
  435. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  436. // One compositor destroys their impl tree.
  437. std::move(compositor1).Run(SyncTokenFromUInt(100), false);
  438. // Then the main thread reference is destroyed.
  439. main_thread_.task_runner()->PostTask(
  440. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
  441. base::Unretained(this)));
  442. Wait(main_thread_);
  443. EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
  444. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  445. // The second impl reference is destroyed last, causing the resource to be
  446. // released back to the embedder with the last sync point from the impl tree.
  447. EXPECT_CALL(test_data_.mock_callback_,
  448. Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
  449. .Times(1);
  450. std::move(compositor2).Run(SyncTokenFromUInt(200), true);
  451. Wait(main_thread_);
  452. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  453. }
  454. TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
  455. scoped_refptr<TextureLayer> test_layer =
  456. TextureLayer::CreateForMailbox(nullptr);
  457. ASSERT_TRUE(test_layer.get());
  458. main_thread_.task_runner()->PostTask(
  459. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateMainRef,
  460. base::Unretained(this)));
  461. Wait(main_thread_);
  462. // The texture layer is attached to compositor1, and passes a reference to its
  463. // impl tree.
  464. viz::ReleaseCallback compositor1;
  465. main_thread_.task_runner()->PostTask(
  466. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
  467. base::Unretained(this), &compositor1,
  468. main_thread_.task_runner()));
  469. // Then the texture layer is removed and attached to compositor2, and passes a
  470. // reference to its impl tree.
  471. viz::ReleaseCallback compositor2;
  472. main_thread_.task_runner()->PostTask(
  473. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::CreateImplRef,
  474. base::Unretained(this), &compositor2,
  475. main_thread_.task_runner()));
  476. Wait(main_thread_);
  477. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  478. // The main thread reference is destroyed first.
  479. main_thread_.task_runner()->PostTask(
  480. FROM_HERE, base::BindOnce(&TextureLayerMailboxHolderTest::ReleaseMainRef,
  481. base::Unretained(this)));
  482. // One compositor destroys their impl tree.
  483. std::move(compositor2).Run(SyncTokenFromUInt(200), false);
  484. Wait(main_thread_);
  485. EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
  486. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  487. // The second impl reference is destroyed last, causing the resource to be
  488. // released back to the embedder with the last sync point from the impl tree.
  489. EXPECT_CALL(test_data_.mock_callback_,
  490. Release(test_data_.mailbox_name1_, SyncTokenFromUInt(100), true))
  491. .Times(1);
  492. std::move(compositor1).Run(SyncTokenFromUInt(100), true);
  493. Wait(main_thread_);
  494. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  495. }
  496. class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
  497. public:
  498. std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
  499. const viz::RendererSettings& renderer_settings,
  500. double refresh_rate,
  501. scoped_refptr<viz::ContextProvider> compositor_context_provider,
  502. scoped_refptr<viz::RasterContextProvider> worker_context_provider)
  503. override {
  504. constexpr bool disable_display_vsync = false;
  505. bool synchronous_composite =
  506. !HasImplThread() &&
  507. !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
  508. return std::make_unique<TestLayerTreeFrameSink>(
  509. compositor_context_provider, std::move(worker_context_provider),
  510. gpu_memory_buffer_manager(), renderer_settings, &debug_settings_,
  511. task_runner_provider(), synchronous_composite, disable_display_vsync,
  512. refresh_rate);
  513. }
  514. void AdvanceTestCase() {
  515. ++test_case_;
  516. switch (test_case_) {
  517. case 1:
  518. // Case #1: change resource before the commit. The old resource should
  519. // be released immediately.
  520. SetMailbox('2');
  521. EXPECT_EQ(1, callback_count_);
  522. PostSetNeedsCommitToMainThread();
  523. // Case 2 does not rely on callbacks to advance.
  524. pending_callback_ = false;
  525. break;
  526. case 2:
  527. // Case #2: change resource after the commit (and draw), where the
  528. // layer draws. The old resource should be released during the next
  529. // commit.
  530. SetMailbox('3');
  531. EXPECT_EQ(1, callback_count_);
  532. // Cases 3-5 rely on a callback to advance.
  533. pending_callback_ = true;
  534. break;
  535. case 3:
  536. EXPECT_EQ(2, callback_count_);
  537. // Case #3: change resource when the layer doesn't draw. The old
  538. // resource should be released during the next commit.
  539. layer_->SetBounds(gfx::Size());
  540. SetMailbox('4');
  541. break;
  542. case 4:
  543. EXPECT_EQ(3, callback_count_);
  544. // Case #4: release resource that was committed but never drawn. The
  545. // old resource should be released during the next commit.
  546. layer_->ClearTexture();
  547. break;
  548. case 5:
  549. EXPECT_EQ(4, callback_count_);
  550. // Restore a resource for the next step.
  551. SetMailbox('5');
  552. // Cases 6 and 7 do not rely on callbacks to advance.
  553. pending_callback_ = false;
  554. break;
  555. case 6:
  556. // Case #5: remove layer from tree. Callback should *not* be called, the
  557. // resource is returned to the main thread.
  558. EXPECT_EQ(4, callback_count_);
  559. layer_->RemoveFromParent();
  560. break;
  561. case 7:
  562. EXPECT_EQ(4, callback_count_);
  563. // Resetting the resource will call the callback now, before another
  564. // commit is needed, as the ReleaseCallback is already in flight from
  565. // RemoveFromParent().
  566. pending_callback_ = true;
  567. layer_->ClearTexture();
  568. frame_number_ = layer_tree_host()->SourceFrameNumber();
  569. break;
  570. case 8:
  571. // A commit wasn't needed, the ReleaseCallback was already in flight.
  572. EXPECT_EQ(frame_number_, layer_tree_host()->SourceFrameNumber());
  573. EXPECT_EQ(5, callback_count_);
  574. EndTest();
  575. break;
  576. default:
  577. NOTREACHED();
  578. break;
  579. }
  580. }
  581. // Make sure callback is received on main and doesn't block the impl thread.
  582. void ReleaseCallback(char mailbox_char,
  583. const gpu::SyncToken& sync_token,
  584. bool lost_resource) {
  585. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  586. EXPECT_FALSE(lost_resource);
  587. ++callback_count_;
  588. // If we are waiting on a callback, advance now.
  589. if (pending_callback_) {
  590. layer_tree_host()
  591. ->GetTaskRunnerProvider()
  592. ->MainThreadTaskRunner()
  593. ->PostTask(
  594. FROM_HERE,
  595. base::BindOnce(
  596. &TextureLayerImplWithMailboxThreadedCallback::AdvanceTestCase,
  597. base::Unretained(this)));
  598. }
  599. }
  600. void SetMailbox(char mailbox_char) {
  601. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  602. viz::ReleaseCallback callback = base::BindOnce(
  603. &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
  604. base::Unretained(this), mailbox_char);
  605. const gfx::Size size(64, 64);
  606. auto resource = viz::TransferableResource::MakeGL(
  607. MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
  608. SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
  609. false /* is_overlay_candidate */);
  610. layer_->SetTransferableResource(resource, std::move(callback));
  611. // Damage the layer so we send a new frame with the new resource to the
  612. // Display compositor.
  613. layer_->SetNeedsDisplay();
  614. }
  615. void BeginTest() override {
  616. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  617. gfx::Size bounds(100, 100);
  618. root_ = Layer::Create();
  619. root_->SetBounds(bounds);
  620. layer_ = TextureLayer::CreateForMailbox(nullptr);
  621. layer_->SetIsDrawable(true);
  622. layer_->SetBounds(bounds);
  623. root_->AddChild(layer_);
  624. layer_tree_host()->SetRootLayer(root_);
  625. layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f,
  626. viz::LocalSurfaceId());
  627. SetMailbox('1');
  628. EXPECT_EQ(0, callback_count_);
  629. // Setup is complete - advance to test case 1.
  630. AdvanceTestCase();
  631. }
  632. void DidCommit() override {
  633. // If we are not waiting on a callback, advance now.
  634. if (!pending_callback_)
  635. AdvanceTestCase();
  636. }
  637. private:
  638. base::ThreadChecker main_thread_;
  639. int callback_count_ = 0;
  640. int test_case_ = 0;
  641. int frame_number_ = 0;
  642. // Whether we are waiting on a callback to advance the test case.
  643. bool pending_callback_ = false;
  644. scoped_refptr<Layer> root_;
  645. scoped_refptr<TextureLayer> layer_;
  646. };
  647. SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerImplWithMailboxThreadedCallback);
  648. class TextureLayerImplWithResourceTest : public TextureLayerTest {
  649. protected:
  650. void SetUp() override {
  651. TextureLayerTest::SetUp();
  652. layer_tree_host_ = MockLayerTreeHost::Create(
  653. &fake_client_, &task_graph_runner_, animation_host_.get());
  654. host_impl_.SetVisible(true);
  655. EXPECT_TRUE(host_impl_.InitializeFrameSink(layer_tree_frame_sink_.get()));
  656. }
  657. std::unique_ptr<TextureLayerImpl> CreateTextureLayer() {
  658. auto layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
  659. layer->set_visible_layer_rect(gfx::Rect(100, 100));
  660. return layer;
  661. }
  662. bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
  663. bool will_draw = layer->WillDraw(
  664. mode, host_impl_.active_tree()->resource_provider());
  665. if (will_draw)
  666. layer->DidDraw(host_impl_.active_tree()->resource_provider());
  667. return will_draw;
  668. }
  669. FakeLayerTreeHostClient fake_client_;
  670. };
  671. // Test conditions for results of TextureLayerImpl::WillDraw under
  672. // different configurations of different mailbox, texture_id, and draw_mode.
  673. TEST_F(TextureLayerImplWithResourceTest, TestWillDraw) {
  674. EXPECT_CALL(
  675. test_data_.mock_callback_,
  676. Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
  677. .Times(AnyNumber());
  678. EXPECT_CALL(test_data_.mock_callback_,
  679. Release2(test_data_.shared_bitmap_id_, gpu::SyncToken(), false))
  680. .Times(AnyNumber());
  681. // Hardware mode.
  682. {
  683. std::unique_ptr<TextureLayerImpl> impl_layer = CreateTextureLayer();
  684. impl_layer->SetTransferableResource(test_data_.resource1_,
  685. test_data_.release_callback1_);
  686. EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
  687. }
  688. {
  689. std::unique_ptr<TextureLayerImpl> impl_layer =
  690. TextureLayerImpl::Create(host_impl_.active_tree(), 1);
  691. impl_layer->SetTransferableResource(viz::TransferableResource(),
  692. viz::ReleaseCallback());
  693. EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
  694. }
  695. // Software mode.
  696. {
  697. std::unique_ptr<TextureLayerImpl> impl_layer = CreateTextureLayer();
  698. impl_layer->SetTransferableResource(test_data_.resource1_,
  699. test_data_.release_callback1_);
  700. EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
  701. }
  702. {
  703. std::unique_ptr<TextureLayerImpl> impl_layer = CreateTextureLayer();
  704. impl_layer->SetTransferableResource(viz::TransferableResource(),
  705. viz::ReleaseCallback());
  706. EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
  707. }
  708. {
  709. // Software resource.
  710. std::unique_ptr<TextureLayerImpl> impl_layer = CreateTextureLayer();
  711. impl_layer->SetTransferableResource(test_data_.sw_resource_,
  712. test_data_.sw_release_callback_);
  713. EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
  714. }
  715. // Resourceless software mode.
  716. {
  717. std::unique_ptr<TextureLayerImpl> impl_layer = CreateTextureLayer();
  718. impl_layer->SetTransferableResource(test_data_.resource1_,
  719. test_data_.release_callback1_);
  720. EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
  721. }
  722. }
  723. TEST_F(TextureLayerImplWithResourceTest, TestImplLayerCallbacks) {
  724. host_impl_.CreatePendingTree();
  725. std::unique_ptr<TextureLayerImpl> pending_layer;
  726. pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
  727. ASSERT_TRUE(pending_layer);
  728. std::unique_ptr<LayerImpl> active_layer(
  729. pending_layer->CreateLayerImpl(host_impl_.active_tree()));
  730. ASSERT_TRUE(active_layer);
  731. pending_layer->SetTransferableResource(test_data_.resource1_,
  732. test_data_.release_callback1_);
  733. // Test multiple commits without an activation. The resource wasn't used so
  734. // the original sync token is returned.
  735. EXPECT_CALL(
  736. test_data_.mock_callback_,
  737. Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
  738. .Times(1);
  739. pending_layer->SetTransferableResource(test_data_.resource2_,
  740. test_data_.release_callback2_);
  741. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  742. // Test callback after activation.
  743. pending_layer->PushPropertiesTo(active_layer.get());
  744. active_layer->DidBecomeActive();
  745. EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
  746. pending_layer->SetTransferableResource(test_data_.resource1_,
  747. test_data_.release_callback1_);
  748. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  749. EXPECT_CALL(test_data_.mock_callback_,
  750. Release(test_data_.mailbox_name2_, _, false))
  751. .Times(1);
  752. pending_layer->PushPropertiesTo(active_layer.get());
  753. active_layer->DidBecomeActive();
  754. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  755. // Test resetting the mailbox.
  756. EXPECT_CALL(test_data_.mock_callback_,
  757. Release(test_data_.mailbox_name1_, _, false))
  758. .Times(1);
  759. pending_layer->SetTransferableResource(viz::TransferableResource(),
  760. viz::ReleaseCallback());
  761. pending_layer->PushPropertiesTo(active_layer.get());
  762. active_layer->DidBecomeActive();
  763. Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
  764. // Test destructor. The resource wasn't used so the original sync token is
  765. // returned.
  766. EXPECT_CALL(
  767. test_data_.mock_callback_,
  768. Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
  769. .Times(1);
  770. pending_layer->SetTransferableResource(test_data_.resource1_,
  771. test_data_.release_callback1_);
  772. }
  773. TEST_F(TextureLayerImplWithResourceTest,
  774. TestDestructorCallbackOnCreatedResource) {
  775. std::unique_ptr<TextureLayerImpl> impl_layer = CreateTextureLayer();
  776. ASSERT_TRUE(impl_layer);
  777. EXPECT_CALL(test_data_.mock_callback_,
  778. Release(test_data_.mailbox_name1_, _, false))
  779. .Times(1);
  780. impl_layer->SetTransferableResource(test_data_.resource1_,
  781. test_data_.release_callback1_);
  782. impl_layer->DidBecomeActive();
  783. EXPECT_TRUE(impl_layer->WillDraw(
  784. DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
  785. impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
  786. impl_layer->SetTransferableResource(viz::TransferableResource(),
  787. viz::ReleaseCallback());
  788. }
  789. // Checks that TextureLayer::Update does not cause an extra commit when setting
  790. // the texture mailbox.
  791. class TextureLayerNoExtraCommitForMailboxTest
  792. : public LayerTreeTest,
  793. public TextureLayerClient {
  794. public:
  795. // TextureLayerClient implementation.
  796. bool PrepareTransferableResource(
  797. SharedBitmapIdRegistrar* bitmap_registrar,
  798. viz::TransferableResource* resource,
  799. viz::ReleaseCallback* release_callback) override {
  800. if (layer_tree_host()->SourceFrameNumber() == 1) {
  801. // Once this has been committed, the resource will be released.
  802. *resource = viz::TransferableResource();
  803. return true;
  804. }
  805. constexpr gfx::Size size(64, 64);
  806. *resource = viz::TransferableResource::MakeGL(
  807. MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D,
  808. SyncTokenFromUInt(0x123), size, false /* is_overlay_candidate */);
  809. *release_callback = base::BindOnce(
  810. &TextureLayerNoExtraCommitForMailboxTest::ResourceReleased,
  811. base::Unretained(this));
  812. return true;
  813. }
  814. void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
  815. EXPECT_TRUE(sync_token.HasData());
  816. EndTest();
  817. }
  818. void SetupTree() override {
  819. scoped_refptr<Layer> root = Layer::Create();
  820. root->SetBounds(gfx::Size(10, 10));
  821. root->SetIsDrawable(true);
  822. texture_layer_ = TextureLayer::CreateForMailbox(this);
  823. texture_layer_->SetBounds(gfx::Size(10, 10));
  824. texture_layer_->SetIsDrawable(true);
  825. root->AddChild(texture_layer_);
  826. layer_tree_host()->SetRootLayer(root);
  827. LayerTreeTest::SetupTree();
  828. }
  829. void BeginTest() override { PostSetNeedsCommitToMainThread(); }
  830. void DidCommitAndDrawFrame() override {
  831. switch (layer_tree_host()->SourceFrameNumber()) {
  832. case 1:
  833. EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
  834. // Invalidate the texture layer to clear the mailbox before
  835. // ending the test.
  836. texture_layer_->SetNeedsDisplay();
  837. break;
  838. case 2:
  839. break;
  840. default:
  841. NOTREACHED();
  842. break;
  843. }
  844. }
  845. private:
  846. scoped_refptr<TextureLayer> texture_layer_;
  847. };
  848. SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
  849. // Checks that changing a mailbox in the client for a TextureLayer that's
  850. // invisible correctly works and uses the new mailbox as soon as the layer
  851. // becomes visible (and returns the old one).
  852. class TextureLayerChangeInvisibleMailboxTest
  853. : public LayerTreeTest,
  854. public TextureLayerClient {
  855. public:
  856. TextureLayerChangeInvisibleMailboxTest()
  857. : resource_changed_(true),
  858. resource_(MakeResource('1')),
  859. resource_returned_(0),
  860. prepare_called_(0),
  861. commit_count_(0) {}
  862. // TextureLayerClient implementation.
  863. bool PrepareTransferableResource(
  864. SharedBitmapIdRegistrar* bitmap_registrar,
  865. viz::TransferableResource* resource,
  866. viz::ReleaseCallback* release_callback) override {
  867. ++prepare_called_;
  868. if (!resource_changed_)
  869. return false;
  870. resource_changed_ = false;
  871. *resource = resource_;
  872. *release_callback = base::BindOnce(
  873. &TextureLayerChangeInvisibleMailboxTest::ResourceReleased,
  874. base::Unretained(this));
  875. return true;
  876. }
  877. viz::TransferableResource MakeResource(char name) {
  878. constexpr gfx::Size size(64, 64);
  879. return viz::TransferableResource::MakeGL(
  880. MailboxFromChar(name), GL_LINEAR, GL_TEXTURE_2D,
  881. SyncTokenFromUInt(static_cast<uint32_t>(name)), size,
  882. false /* is_overlay_candidate */);
  883. }
  884. void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
  885. EXPECT_TRUE(sync_token.HasData());
  886. ++resource_returned_;
  887. }
  888. void SetupTree() override {
  889. scoped_refptr<Layer> root = Layer::Create();
  890. root->SetBounds(gfx::Size(10, 10));
  891. root->SetIsDrawable(true);
  892. solid_layer_ = SolidColorLayer::Create();
  893. solid_layer_->SetBounds(gfx::Size(10, 10));
  894. solid_layer_->SetIsDrawable(true);
  895. solid_layer_->SetBackgroundColor(SkColors::kWhite);
  896. root->AddChild(solid_layer_);
  897. parent_layer_ = Layer::Create();
  898. parent_layer_->SetBounds(gfx::Size(10, 10));
  899. parent_layer_->SetIsDrawable(true);
  900. root->AddChild(parent_layer_);
  901. texture_layer_ = TextureLayer::CreateForMailbox(this);
  902. texture_layer_->SetBounds(gfx::Size(10, 10));
  903. texture_layer_->SetIsDrawable(true);
  904. parent_layer_->AddChild(texture_layer_);
  905. layer_tree_host()->SetRootLayer(root);
  906. LayerTreeTest::SetupTree();
  907. }
  908. void BeginTest() override { PostSetNeedsCommitToMainThread(); }
  909. void DidReceiveCompositorFrameAck() override {
  910. ++commit_count_;
  911. switch (commit_count_) {
  912. case 1:
  913. // We should have updated the layer, committing the texture.
  914. EXPECT_EQ(1, prepare_called_);
  915. // Make layer invisible.
  916. parent_layer_->SetOpacity(0.f);
  917. break;
  918. case 2:
  919. // Layer shouldn't have been updated.
  920. EXPECT_EQ(1, prepare_called_);
  921. // Change the texture.
  922. resource_ = MakeResource('2');
  923. resource_changed_ = true;
  924. texture_layer_->SetNeedsDisplay();
  925. // Force a change to make sure we draw a frame.
  926. solid_layer_->SetBackgroundColor(SkColors::kGray);
  927. break;
  928. case 3:
  929. // Layer shouldn't have been updated.
  930. EXPECT_EQ(1, prepare_called_);
  931. // So the old resource isn't returned yet.
  932. EXPECT_EQ(0, resource_returned_);
  933. // Make layer visible again.
  934. parent_layer_->SetOpacity(0.9f);
  935. break;
  936. case 4:
  937. // Layer should have been updated.
  938. // It's not sufficient to check if |prepare_called_| is 2. It's possible
  939. // for BeginMainFrame and hence PrepareTransferableResource to run twice
  940. // before DidReceiveCompositorFrameAck due to pipelining.
  941. EXPECT_GE(prepare_called_, 2);
  942. // So the old resource should have been returned already.
  943. EXPECT_EQ(1, resource_returned_);
  944. texture_layer_->ClearClient();
  945. break;
  946. case 5:
  947. EXPECT_EQ(2, resource_returned_);
  948. EndTest();
  949. break;
  950. default:
  951. NOTREACHED();
  952. break;
  953. }
  954. }
  955. private:
  956. scoped_refptr<SolidColorLayer> solid_layer_;
  957. scoped_refptr<Layer> parent_layer_;
  958. scoped_refptr<TextureLayer> texture_layer_;
  959. // Used on the main thread.
  960. bool resource_changed_;
  961. viz::TransferableResource resource_;
  962. int resource_returned_;
  963. int prepare_called_;
  964. int commit_count_;
  965. };
  966. // TODO(crbug.com/1197350): Test fails on chromeos-amd64-generic-rel.
  967. #if BUILDFLAG(IS_CHROMEOS)
  968. #define MAYBE_SINGLE_AND_MULTI_THREAD_TEST_F MULTI_THREAD_TEST_F
  969. #else
  970. #define MAYBE_SINGLE_AND_MULTI_THREAD_TEST_F SINGLE_AND_MULTI_THREAD_TEST_F
  971. #endif
  972. MAYBE_SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
  973. // Test that TextureLayerImpl::ReleaseResources can be called which releases
  974. // the resource back to TextureLayerClient.
  975. class TextureLayerReleaseResourcesBase
  976. : public LayerTreeTest,
  977. public TextureLayerClient {
  978. public:
  979. // TextureLayerClient implementation.
  980. bool PrepareTransferableResource(
  981. SharedBitmapIdRegistrar* bitmap_registrar,
  982. viz::TransferableResource* resource,
  983. viz::ReleaseCallback* release_callback) override {
  984. constexpr gfx::Size size(64, 64);
  985. *resource = viz::TransferableResource::MakeGL(
  986. MailboxFromChar('1'), GL_LINEAR, GL_TEXTURE_2D, SyncTokenFromUInt(1),
  987. size, false /* is_overlay_candidate */);
  988. *release_callback =
  989. base::BindOnce(&TextureLayerReleaseResourcesBase::ResourceReleased,
  990. base::Unretained(this));
  991. return true;
  992. }
  993. void ResourceReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
  994. resource_released_ = true;
  995. }
  996. void SetupTree() override {
  997. LayerTreeTest::SetupTree();
  998. scoped_refptr<TextureLayer> texture_layer =
  999. TextureLayer::CreateForMailbox(this);
  1000. texture_layer->SetBounds(gfx::Size(10, 10));
  1001. texture_layer->SetIsDrawable(true);
  1002. layer_tree_host()->root_layer()->AddChild(texture_layer);
  1003. texture_layer_id_ = texture_layer->id();
  1004. }
  1005. void BeginTest() override {
  1006. resource_released_ = false;
  1007. PostSetNeedsCommitToMainThread();
  1008. }
  1009. void DidCommitAndDrawFrame() override { EndTest(); }
  1010. void AfterTest() override { EXPECT_TRUE(resource_released_); }
  1011. protected:
  1012. int texture_layer_id_;
  1013. private:
  1014. bool resource_released_;
  1015. };
  1016. class TextureLayerReleaseResourcesAfterCommit
  1017. : public TextureLayerReleaseResourcesBase {
  1018. public:
  1019. void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
  1020. LayerTreeImpl* tree = nullptr;
  1021. tree = host_impl->sync_tree();
  1022. tree->LayerById(texture_layer_id_)->ReleaseResources();
  1023. }
  1024. };
  1025. SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
  1026. class TextureLayerReleaseResourcesAfterActivate
  1027. : public TextureLayerReleaseResourcesBase {
  1028. public:
  1029. void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
  1030. host_impl->active_tree()->LayerById(texture_layer_id_)->ReleaseResources();
  1031. }
  1032. };
  1033. SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
  1034. class TextureLayerWithResourceMainThreadDeleted : public LayerTreeTest {
  1035. public:
  1036. void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
  1037. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  1038. EXPECT_FALSE(lost_resource);
  1039. ++callback_count_;
  1040. EndTest();
  1041. }
  1042. void SetMailbox(char mailbox_char) {
  1043. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  1044. viz::ReleaseCallback callback = base::BindOnce(
  1045. &TextureLayerWithResourceMainThreadDeleted::ReleaseCallback,
  1046. base::Unretained(this));
  1047. constexpr gfx::Size size(64, 64);
  1048. auto resource = viz::TransferableResource::MakeGL(
  1049. MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
  1050. SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
  1051. false /* is_overlay_candidate */);
  1052. layer_->SetTransferableResource(resource, std::move(callback));
  1053. }
  1054. void SetupTree() override {
  1055. gfx::Size bounds(100, 100);
  1056. root_ = Layer::Create();
  1057. root_->SetBounds(bounds);
  1058. layer_ = TextureLayer::CreateForMailbox(nullptr);
  1059. layer_->SetIsDrawable(true);
  1060. layer_->SetBounds(bounds);
  1061. root_->AddChild(layer_);
  1062. layer_tree_host()->SetRootLayer(root_);
  1063. layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f,
  1064. viz::LocalSurfaceId());
  1065. }
  1066. void BeginTest() override {
  1067. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  1068. callback_count_ = 0;
  1069. // Set the resource on the main thread.
  1070. SetMailbox('1');
  1071. EXPECT_EQ(0, callback_count_);
  1072. PostSetNeedsCommitToMainThread();
  1073. }
  1074. void DidCommitAndDrawFrame() override {
  1075. switch (layer_tree_host()->SourceFrameNumber()) {
  1076. case 1:
  1077. // Delete the TextureLayer on the main thread while the resource is in
  1078. // the impl tree.
  1079. layer_->RemoveFromParent();
  1080. layer_ = nullptr;
  1081. break;
  1082. }
  1083. }
  1084. void AfterTest() override { EXPECT_EQ(1, callback_count_); }
  1085. private:
  1086. base::ThreadChecker main_thread_;
  1087. int callback_count_;
  1088. scoped_refptr<Layer> root_;
  1089. scoped_refptr<TextureLayer> layer_;
  1090. };
  1091. SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerWithResourceMainThreadDeleted);
  1092. class TextureLayerWithResourceImplThreadDeleted : public LayerTreeTest {
  1093. public:
  1094. void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
  1095. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  1096. EXPECT_FALSE(lost_resource);
  1097. ++callback_count_;
  1098. EndTest();
  1099. }
  1100. void SetMailbox(char mailbox_char) {
  1101. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  1102. viz::ReleaseCallback callback = base::BindOnce(
  1103. &TextureLayerWithResourceImplThreadDeleted::ReleaseCallback,
  1104. base::Unretained(this));
  1105. constexpr gfx::Size size(64, 64);
  1106. auto resource = viz::TransferableResource::MakeGL(
  1107. MailboxFromChar(mailbox_char), GL_LINEAR, GL_TEXTURE_2D,
  1108. SyncTokenFromUInt(static_cast<uint32_t>(mailbox_char)), size,
  1109. false /* is_overlay_candidate */);
  1110. layer_->SetTransferableResource(resource, std::move(callback));
  1111. }
  1112. void SetupTree() override {
  1113. gfx::Size bounds(100, 100);
  1114. root_ = Layer::Create();
  1115. root_->SetBounds(bounds);
  1116. layer_ = TextureLayer::CreateForMailbox(nullptr);
  1117. layer_->SetIsDrawable(true);
  1118. layer_->SetBounds(bounds);
  1119. root_->AddChild(layer_);
  1120. layer_tree_host()->SetRootLayer(root_);
  1121. layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f,
  1122. viz::LocalSurfaceId());
  1123. }
  1124. void BeginTest() override {
  1125. EXPECT_EQ(true, main_thread_.CalledOnValidThread());
  1126. callback_count_ = 0;
  1127. // Set the resource on the main thread.
  1128. SetMailbox('1');
  1129. EXPECT_EQ(0, callback_count_);
  1130. PostSetNeedsCommitToMainThread();
  1131. }
  1132. void DidCommitAndDrawFrame() override {
  1133. switch (layer_tree_host()->SourceFrameNumber()) {
  1134. case 1:
  1135. // Remove the TextureLayer on the main thread while the resource is in
  1136. // the impl tree, but don't delete the TextureLayer until after the impl
  1137. // tree side is deleted.
  1138. layer_->RemoveFromParent();
  1139. break;
  1140. case 2:
  1141. layer_ = nullptr;
  1142. break;
  1143. }
  1144. }
  1145. void AfterTest() override { EXPECT_EQ(1, callback_count_); }
  1146. private:
  1147. base::ThreadChecker main_thread_;
  1148. int callback_count_;
  1149. scoped_refptr<Layer> root_;
  1150. scoped_refptr<TextureLayer> layer_;
  1151. };
  1152. SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerWithResourceImplThreadDeleted);
  1153. class StubTextureLayerClient : public TextureLayerClient {
  1154. public:
  1155. // TextureLayerClient implementation.
  1156. bool PrepareTransferableResource(
  1157. SharedBitmapIdRegistrar* bitmap_registrar,
  1158. viz::TransferableResource* resource,
  1159. viz::ReleaseCallback* release_callback) override {
  1160. return false;
  1161. }
  1162. };
  1163. class SoftwareLayerTreeHostClient : public StubLayerTreeHostClient {
  1164. public:
  1165. SoftwareLayerTreeHostClient() = default;
  1166. ~SoftwareLayerTreeHostClient() override = default;
  1167. // Caller responsible for unsetting this and maintaining the host's lifetime.
  1168. void SetLayerTreeHost(LayerTreeHost* host) { host_ = host; }
  1169. // StubLayerTreeHostClient overrides.
  1170. void RequestNewLayerTreeFrameSink() override {
  1171. auto sink = FakeLayerTreeFrameSink::CreateSoftware();
  1172. frame_sink_ = sink.get();
  1173. host_->SetLayerTreeFrameSink(std::move(sink));
  1174. }
  1175. FakeLayerTreeFrameSink* frame_sink() const { return frame_sink_; }
  1176. private:
  1177. raw_ptr<FakeLayerTreeFrameSink> frame_sink_ = nullptr;
  1178. raw_ptr<LayerTreeHost> host_ = nullptr;
  1179. };
  1180. class SoftwareTextureLayerTest : public LayerTreeTest {
  1181. protected:
  1182. SoftwareTextureLayerTest() : LayerTreeTest(viz::RendererType::kSoftware) {}
  1183. void SetupTree() override {
  1184. root_ = Layer::Create();
  1185. root_->SetBounds(gfx::Size(10, 10));
  1186. // A drawable layer so that frames always get drawn.
  1187. solid_color_layer_ = SolidColorLayer::Create();
  1188. solid_color_layer_->SetIsDrawable(true);
  1189. solid_color_layer_->SetBackgroundColor(SkColors::kRed);
  1190. solid_color_layer_->SetBounds(gfx::Size(10, 10));
  1191. root_->AddChild(solid_color_layer_);
  1192. texture_layer_ = TextureLayer::CreateForMailbox(&client_);
  1193. texture_layer_->SetIsDrawable(true);
  1194. texture_layer_->SetBounds(gfx::Size(10, 10));
  1195. layer_tree_host()->SetRootLayer(root_);
  1196. LayerTreeTest::SetupTree();
  1197. }
  1198. std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
  1199. const viz::RendererSettings& renderer_settings,
  1200. double refresh_rate,
  1201. scoped_refptr<viz::ContextProvider> compositor_context_provider,
  1202. scoped_refptr<viz::RasterContextProvider> worker_context_provider)
  1203. override {
  1204. constexpr bool disable_display_vsync = false;
  1205. bool synchronous_composite =
  1206. !HasImplThread() &&
  1207. !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
  1208. auto sink = std::make_unique<TestLayerTreeFrameSink>(
  1209. nullptr, nullptr, gpu_memory_buffer_manager(), renderer_settings,
  1210. &debug_settings_, task_runner_provider(), synchronous_composite,
  1211. disable_display_vsync, refresh_rate);
  1212. frame_sink_ = sink.get();
  1213. num_frame_sinks_created_++;
  1214. return sink;
  1215. }
  1216. StubTextureLayerClient client_;
  1217. scoped_refptr<Layer> root_;
  1218. scoped_refptr<SolidColorLayer> solid_color_layer_;
  1219. scoped_refptr<TextureLayer> texture_layer_;
  1220. raw_ptr<TestLayerTreeFrameSink> frame_sink_ = nullptr;
  1221. int num_frame_sinks_created_ = 0;
  1222. };
  1223. class SoftwareTextureLayerSwitchTreesTest : public SoftwareTextureLayerTest {
  1224. protected:
  1225. void BeginTest() override {
  1226. PostSetNeedsCommitToMainThread();
  1227. gfx::Size size(1, 1);
  1228. viz::ResourceFormat format = viz::RGBA_8888;
  1229. id_ = viz::SharedBitmap::GenerateId();
  1230. bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1231. id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1232. format);
  1233. }
  1234. void DidCommitAndDrawFrame() override {
  1235. step_ = layer_tree_host()->SourceFrameNumber();
  1236. switch (step_) {
  1237. case 1:
  1238. // The test starts by inserting the TextureLayer to the tree.
  1239. root_->AddChild(texture_layer_);
  1240. // And registers a SharedBitmapId, which should be given to the
  1241. // LayerTreeFrameSink.
  1242. registration_ = texture_layer_->RegisterSharedBitmapId(id_, bitmap_);
  1243. // Give the TextureLayer a resource so it contributes to the frame. It
  1244. // doesn't need to register the SharedBitmapId otherwise.
  1245. texture_layer_->SetTransferableResource(
  1246. viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
  1247. viz::RGBA_8888),
  1248. base::BindOnce([](const gpu::SyncToken&, bool) {}));
  1249. break;
  1250. case 2:
  1251. // When the layer is removed from the tree, the bitmap should be
  1252. // unregistered.
  1253. texture_layer_->RemoveFromParent();
  1254. break;
  1255. case 3:
  1256. // When the layer is added to a new tree, the SharedBitmapId is
  1257. // registered again.
  1258. root_->AddChild(texture_layer_);
  1259. break;
  1260. case 4:
  1261. // If the layer is removed and added back to the same tree in one
  1262. // commit, there should be no side effects, the bitmap stays
  1263. // registered.
  1264. texture_layer_->RemoveFromParent();
  1265. root_->AddChild(texture_layer_);
  1266. break;
  1267. case 5:
  1268. // Release the TransferableResource before shutdown.
  1269. texture_layer_->ClearClient();
  1270. break;
  1271. case 6:
  1272. EndTest();
  1273. }
  1274. }
  1275. void DisplayReceivedCompositorFrameOnThread(
  1276. const viz::CompositorFrame& frame) override {
  1277. switch (step_) {
  1278. case 0:
  1279. // Before commit 1, the |texture_layer_| has no SharedBitmapId yet.
  1280. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1281. verified_frames_++;
  1282. break;
  1283. case 1:
  1284. // For commit 1, we added a SharedBitmapId to |texture_layer_|.
  1285. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1286. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id_);
  1287. verified_frames_++;
  1288. break;
  1289. case 2:
  1290. // For commit 2, we removed |texture_layer_| from the tree.
  1291. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1292. verified_frames_++;
  1293. break;
  1294. case 3:
  1295. // For commit 3, we added |texture_layer_| back to the tree.
  1296. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1297. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id_);
  1298. verified_frames_++;
  1299. break;
  1300. case 4:
  1301. // For commit 3, we removed+added |texture_layer_| back to the tree.
  1302. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1303. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id_);
  1304. verified_frames_++;
  1305. break;
  1306. }
  1307. }
  1308. void AfterTest() override { EXPECT_EQ(5, verified_frames_); }
  1309. int step_ = 0;
  1310. int verified_frames_ = 0;
  1311. viz::SharedBitmapId id_;
  1312. SharedBitmapIdRegistration registration_;
  1313. scoped_refptr<CrossThreadSharedBitmap> bitmap_;
  1314. };
  1315. SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerSwitchTreesTest);
  1316. // Verify that duplicate SharedBitmapIds aren't registered if resources are
  1317. // purged due to memory pressure.
  1318. class SoftwareTextureLayerPurgeMemoryTest : public SoftwareTextureLayerTest {
  1319. protected:
  1320. void BeginTest() override {
  1321. PostSetNeedsCommitToMainThread();
  1322. const gfx::Size size(1, 1);
  1323. const viz::ResourceFormat format = viz::RGBA_8888;
  1324. id_ = viz::SharedBitmap::GenerateId();
  1325. bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1326. id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1327. format);
  1328. }
  1329. void DidCommitAndDrawFrame() override {
  1330. step_ = layer_tree_host()->SourceFrameNumber();
  1331. switch (step_) {
  1332. case 1:
  1333. // The test starts by inserting the TextureLayer to the tree.
  1334. root_->AddChild(texture_layer_);
  1335. // And registers a SharedBitmapId, which should be given to the
  1336. // LayerTreeFrameSink.
  1337. registration_ = texture_layer_->RegisterSharedBitmapId(id_, bitmap_);
  1338. // Give the TextureLayer a resource so it contributes to the frame. It
  1339. // doesn't need to register the SharedBitmapId otherwise.
  1340. texture_layer_->SetTransferableResource(
  1341. viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
  1342. viz::RGBA_8888),
  1343. base::BindOnce([](const gpu::SyncToken&, bool) {}));
  1344. break;
  1345. case 2:
  1346. // Draw again after OnPurgeMemory() was called on the impl thread so we
  1347. // can verify that duplicate SharedBitmapIds aren't registered by
  1348. // TextureLayerImpl.
  1349. texture_layer_->SetNeedsDisplay();
  1350. break;
  1351. case 3:
  1352. // Release the TransferableResource before shutdown.
  1353. texture_layer_->ClearClient();
  1354. break;
  1355. case 4:
  1356. EndTest();
  1357. }
  1358. }
  1359. void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
  1360. // TextureLayerImpl will have registered the SharedBitmapId at this point.
  1361. // Call OnPurgeMemory() to ensure that the same SharedBitmapId doesn't get
  1362. // registered again on the next draw.
  1363. if (step_ == 1)
  1364. base::MemoryPressureListener::SimulatePressureNotification(
  1365. base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
  1366. }
  1367. void DisplayReceivedCompositorFrameOnThread(
  1368. const viz::CompositorFrame& frame) override {
  1369. if (step_ == 0) {
  1370. // Before commit 1, the |texture_layer_| has no SharedBitmapId yet.
  1371. EXPECT_THAT(frame_sink_->owned_bitmaps(), testing::IsEmpty());
  1372. verified_frames_++;
  1373. } else {
  1374. // After commit 1, we added a SharedBitmapId to |texture_layer_|.
  1375. EXPECT_THAT(frame_sink_->owned_bitmaps(), testing::ElementsAre(id_));
  1376. verified_frames_++;
  1377. }
  1378. }
  1379. void AfterTest() override { EXPECT_EQ(4, verified_frames_); }
  1380. int step_ = 0;
  1381. int verified_frames_ = 0;
  1382. viz::SharedBitmapId id_;
  1383. SharedBitmapIdRegistration registration_;
  1384. scoped_refptr<CrossThreadSharedBitmap> bitmap_;
  1385. };
  1386. SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerPurgeMemoryTest);
  1387. class SoftwareTextureLayerMultipleRegisterTest
  1388. : public SoftwareTextureLayerTest {
  1389. protected:
  1390. void BeginTest() override {
  1391. PostSetNeedsCommitToMainThread();
  1392. gfx::Size size(1, 1);
  1393. viz::ResourceFormat format = viz::RGBA_8888;
  1394. id1_ = viz::SharedBitmap::GenerateId();
  1395. bitmap1_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1396. id1_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1397. format);
  1398. id2_ = viz::SharedBitmap::GenerateId();
  1399. bitmap2_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1400. id2_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1401. format);
  1402. }
  1403. void DidCommitAndDrawFrame() override {
  1404. step_ = layer_tree_host()->SourceFrameNumber();
  1405. switch (step_) {
  1406. case 1:
  1407. // The test starts by inserting the TextureLayer to the tree.
  1408. root_->AddChild(texture_layer_);
  1409. // And registers 2 SharedBitmapIds, which should be given to the
  1410. // LayerTreeFrameSink.
  1411. registration1_ = texture_layer_->RegisterSharedBitmapId(id1_, bitmap1_);
  1412. registration2_ = texture_layer_->RegisterSharedBitmapId(id2_, bitmap2_);
  1413. // Give the TextureLayer a resource so it contributes to the frame. It
  1414. // doesn't need to register the SharedBitmapId otherwise.
  1415. texture_layer_->SetTransferableResource(
  1416. viz::TransferableResource::MakeSoftware(id1_, gfx::Size(1, 1),
  1417. viz::RGBA_8888),
  1418. base::BindOnce([](const gpu::SyncToken&, bool) {}));
  1419. break;
  1420. case 2:
  1421. // Drop one registration, and force a commit and SubmitCompositorFrame
  1422. // so that we can see it.
  1423. registration2_ = SharedBitmapIdRegistration();
  1424. texture_layer_->SetNeedsDisplay();
  1425. break;
  1426. case 3:
  1427. // Drop the other registration.
  1428. texture_layer_->ClearClient();
  1429. registration1_ = SharedBitmapIdRegistration();
  1430. break;
  1431. case 4:
  1432. EndTest();
  1433. }
  1434. }
  1435. void DisplayReceivedCompositorFrameOnThread(
  1436. const viz::CompositorFrame& frame) override {
  1437. switch (step_) {
  1438. case 0:
  1439. // Before commit 1, the |texture_layer_| has no SharedBitmapId yet.
  1440. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1441. verified_frames_++;
  1442. break;
  1443. case 1:
  1444. // For commit 1, we added 2 SharedBitmapIds to |texture_layer_|.
  1445. EXPECT_EQ(2u, frame_sink_->owned_bitmaps().size());
  1446. verified_frames_++;
  1447. break;
  1448. case 2:
  1449. // For commit 2, we removed one SharedBitmapId.
  1450. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1451. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id1_);
  1452. verified_frames_++;
  1453. break;
  1454. case 3:
  1455. // For commit 3, we removed the other SharedBitmapId.
  1456. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1457. verified_frames_++;
  1458. break;
  1459. }
  1460. }
  1461. void AfterTest() override { EXPECT_EQ(4, verified_frames_); }
  1462. int step_ = 0;
  1463. int verified_frames_ = 0;
  1464. viz::SharedBitmapId id1_;
  1465. viz::SharedBitmapId id2_;
  1466. SharedBitmapIdRegistration registration1_;
  1467. SharedBitmapIdRegistration registration2_;
  1468. scoped_refptr<CrossThreadSharedBitmap> bitmap1_;
  1469. scoped_refptr<CrossThreadSharedBitmap> bitmap2_;
  1470. };
  1471. SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerMultipleRegisterTest);
  1472. class SoftwareTextureLayerRegisterUnregisterTest
  1473. : public SoftwareTextureLayerTest {
  1474. protected:
  1475. void BeginTest() override {
  1476. PostSetNeedsCommitToMainThread();
  1477. gfx::Size size(1, 1);
  1478. viz::ResourceFormat format = viz::RGBA_8888;
  1479. id1_ = viz::SharedBitmap::GenerateId();
  1480. bitmap1_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1481. id1_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1482. format);
  1483. id2_ = viz::SharedBitmap::GenerateId();
  1484. bitmap2_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1485. id2_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1486. format);
  1487. }
  1488. void DidCommitAndDrawFrame() override {
  1489. step_ = layer_tree_host()->SourceFrameNumber();
  1490. switch (step_) {
  1491. case 1:
  1492. // The test starts by inserting the TextureLayer to the tree.
  1493. root_->AddChild(texture_layer_);
  1494. // And registers 2 SharedBitmapIds, which would be given to the
  1495. // LayerTreeFrameSink. But we unregister one.
  1496. {
  1497. registration1_ =
  1498. texture_layer_->RegisterSharedBitmapId(id1_, bitmap1_);
  1499. // We explicitly drop this registration by letting it go out of scope
  1500. // and being destroyed. Versus the registration1_ which we drop by
  1501. // assigning an empty registration to it. Both should do the same
  1502. // thing.
  1503. SharedBitmapIdRegistration temp_reg =
  1504. texture_layer_->RegisterSharedBitmapId(id2_, bitmap2_);
  1505. }
  1506. // Give the TextureLayer a resource so it contributes to the frame. It
  1507. // doesn't need to register the SharedBitmapId otherwise.
  1508. texture_layer_->SetTransferableResource(
  1509. viz::TransferableResource::MakeSoftware(id1_, gfx::Size(1, 1),
  1510. viz::RGBA_8888),
  1511. base::BindOnce([](const gpu::SyncToken&, bool) {}));
  1512. break;
  1513. case 2:
  1514. // Drop the other registration.
  1515. texture_layer_->ClearClient();
  1516. registration1_ = SharedBitmapIdRegistration();
  1517. break;
  1518. case 3:
  1519. EndTest();
  1520. }
  1521. }
  1522. void DisplayReceivedCompositorFrameOnThread(
  1523. const viz::CompositorFrame& frame) override {
  1524. switch (step_) {
  1525. case 0:
  1526. // Before commit 1, the |texture_layer_| has no SharedBitmapId yet.
  1527. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1528. verified_frames_++;
  1529. break;
  1530. case 1:
  1531. // For commit 1, we added 1 SharedBitmapId to |texture_layer_|.
  1532. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1533. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id1_);
  1534. verified_frames_++;
  1535. break;
  1536. case 2:
  1537. // For commit 2, we removed the other SharedBitmapId.
  1538. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1539. verified_frames_++;
  1540. break;
  1541. }
  1542. }
  1543. void AfterTest() override { EXPECT_EQ(3, verified_frames_); }
  1544. int step_ = 0;
  1545. int verified_frames_ = 0;
  1546. viz::SharedBitmapId id1_;
  1547. viz::SharedBitmapId id2_;
  1548. SharedBitmapIdRegistration registration1_;
  1549. scoped_refptr<CrossThreadSharedBitmap> bitmap1_;
  1550. scoped_refptr<CrossThreadSharedBitmap> bitmap2_;
  1551. };
  1552. SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerRegisterUnregisterTest);
  1553. class SoftwareTextureLayerLoseFrameSinkTest : public SoftwareTextureLayerTest {
  1554. protected:
  1555. void BeginTest() override {
  1556. PostSetNeedsCommitToMainThread();
  1557. gfx::Size size(1, 1);
  1558. viz::ResourceFormat format = viz::RGBA_8888;
  1559. id_ = viz::SharedBitmap::GenerateId();
  1560. bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1561. id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1562. format);
  1563. }
  1564. void DidCommitAndDrawFrame() override {
  1565. // We run the next step in a clean stack, so that we don't cause side
  1566. // effects that will interfere with this current stack unwinding.
  1567. // Specifically, removing the LayerTreeFrameSink destroys the Display
  1568. // and the BeginFrameSource, but they can be on the stack (see
  1569. // https://crbug.com/829484).
  1570. MainThreadTaskRunner()->PostTask(
  1571. FROM_HERE,
  1572. base::BindOnce(&SoftwareTextureLayerLoseFrameSinkTest::NextStep,
  1573. base::Unretained(this)));
  1574. }
  1575. void NextStep() {
  1576. step_ = layer_tree_host()->SourceFrameNumber();
  1577. switch (step_) {
  1578. case 1:
  1579. // The test starts by inserting the TextureLayer to the tree.
  1580. root_->AddChild(texture_layer_);
  1581. // And registers a SharedBitmapId, which should be given to the
  1582. // LayerTreeFrameSink.
  1583. registration_ = texture_layer_->RegisterSharedBitmapId(id_, bitmap_);
  1584. // Give the TextureLayer a resource so it contributes to the frame. It
  1585. // doesn't need to register the SharedBitmapId otherwise.
  1586. texture_layer_->SetTransferableResource(
  1587. viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
  1588. viz::RGBA_8888),
  1589. base::BindOnce(
  1590. &SoftwareTextureLayerLoseFrameSinkTest::ReleaseCallback,
  1591. base::Unretained(this)));
  1592. EXPECT_FALSE(released_);
  1593. break;
  1594. case 2:
  1595. // The frame sink is lost. The host will make a new one and submit
  1596. // another frame, with the id being registered again.
  1597. layer_tree_host()->SetVisible(false);
  1598. first_frame_sink_ =
  1599. layer_tree_host()->ReleaseLayerTreeFrameSink().get();
  1600. layer_tree_host()->SetVisible(true);
  1601. texture_layer_->SetNeedsDisplay();
  1602. EXPECT_FALSE(released_);
  1603. break;
  1604. case 3:
  1605. // Even though the frame sink was lost, the software resource given to
  1606. // the TextureLayer was not lost/returned.
  1607. EXPECT_FALSE(released_);
  1608. // Release the TransferableResource before shutdown, the test ends when
  1609. // it is released.
  1610. texture_layer_->ClearClient();
  1611. }
  1612. }
  1613. void DisplayReceivedCompositorFrameOnThread(
  1614. const viz::CompositorFrame& frame) override {
  1615. switch (step_) {
  1616. case 0:
  1617. // Before commit 1, the |texture_layer_| has no SharedBitmapId yet.
  1618. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1619. verified_frames_++;
  1620. break;
  1621. case 1:
  1622. // For commit 1, we added a SharedBitmapId to |texture_layer_|.
  1623. EXPECT_EQ(1, num_frame_sinks_created_);
  1624. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1625. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id_);
  1626. verified_frames_++;
  1627. break;
  1628. case 2:
  1629. // For commit 2, we should still have the SharedBitmapId in the new
  1630. // frame sink.
  1631. EXPECT_EQ(2, num_frame_sinks_created_);
  1632. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1633. verified_frames_++;
  1634. break;
  1635. }
  1636. }
  1637. void WillCommit(const CommitState& commit_state) override {
  1638. source_frame_number_ = commit_state.source_frame_number;
  1639. }
  1640. void ReleaseCallback(const gpu::SyncToken& token, bool lost) {
  1641. // The software resource is not released when the LayerTreeFrameSink is lost
  1642. // since software resources are not destroyed by the GPU process dying. It
  1643. // is released only after we call TextureLayer::ClearClient().
  1644. EXPECT_EQ(source_frame_number_, 3);
  1645. released_ = true;
  1646. EndTest();
  1647. }
  1648. void AfterTest() override { EXPECT_EQ(3, verified_frames_); }
  1649. int step_ = 0;
  1650. int verified_frames_ = 0;
  1651. int source_frame_number_ = 0;
  1652. bool released_ = false;
  1653. viz::SharedBitmapId id_;
  1654. SharedBitmapIdRegistration registration_;
  1655. scoped_refptr<CrossThreadSharedBitmap> bitmap_;
  1656. // Keeps a pointer value of the first frame sink, which will be removed
  1657. // from the host and destroyed.
  1658. raw_ptr<void> first_frame_sink_;
  1659. };
  1660. SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerLoseFrameSinkTest);
  1661. class SoftwareTextureLayerUnregisterRegisterTest
  1662. : public SoftwareTextureLayerTest {
  1663. protected:
  1664. void BeginTest() override {
  1665. PostSetNeedsCommitToMainThread();
  1666. gfx::Size size(1, 1);
  1667. viz::ResourceFormat format = viz::RGBA_8888;
  1668. id_ = viz::SharedBitmap::GenerateId();
  1669. bitmap_ = base::MakeRefCounted<CrossThreadSharedBitmap>(
  1670. id_, viz::bitmap_allocation::AllocateSharedBitmap(size, format), size,
  1671. format);
  1672. }
  1673. void DidCommitAndDrawFrame() override {
  1674. step_ = layer_tree_host()->SourceFrameNumber();
  1675. switch (step_) {
  1676. case 1:
  1677. // The test starts by inserting the TextureLayer to the tree.
  1678. root_->AddChild(texture_layer_);
  1679. // We do a Register request, Unregister request, and then another
  1680. // Register request. The final register request should stick.
  1681. // And registers 2 SharedBitmapIds, which would be given to the
  1682. // LayerTreeFrameSink. But we unregister one.
  1683. {
  1684. // Register-Unregister-
  1685. SharedBitmapIdRegistration temp_reg =
  1686. texture_layer_->RegisterSharedBitmapId(id_, bitmap_);
  1687. }
  1688. // Register.
  1689. registration_ = texture_layer_->RegisterSharedBitmapId(id_, bitmap_);
  1690. // Give the TextureLayer a resource so it contributes to the frame. It
  1691. // doesn't need to register the SharedBitmapId otherwise.
  1692. texture_layer_->SetTransferableResource(
  1693. viz::TransferableResource::MakeSoftware(id_, gfx::Size(1, 1),
  1694. viz::RGBA_8888),
  1695. base::BindOnce([](const gpu::SyncToken&, bool) {}));
  1696. break;
  1697. case 2:
  1698. // Release the TransferableResource before shutdown.
  1699. texture_layer_->ClearClient();
  1700. break;
  1701. case 3:
  1702. EndTest();
  1703. }
  1704. }
  1705. void DisplayReceivedCompositorFrameOnThread(
  1706. const viz::CompositorFrame& frame) override {
  1707. switch (step_) {
  1708. case 0:
  1709. // Before commit 1, the |texture_layer_| has no SharedBitmapId yet.
  1710. EXPECT_EQ(0u, frame_sink_->owned_bitmaps().size());
  1711. verified_frames_++;
  1712. break;
  1713. case 1:
  1714. // For commit 1, we added 1 SharedBitmapId to |texture_layer_|.
  1715. EXPECT_EQ(1u, frame_sink_->owned_bitmaps().size());
  1716. EXPECT_EQ(*frame_sink_->owned_bitmaps().begin(), id_);
  1717. verified_frames_++;
  1718. break;
  1719. }
  1720. }
  1721. void AfterTest() override { EXPECT_EQ(2, verified_frames_); }
  1722. int step_ = 0;
  1723. int verified_frames_ = 0;
  1724. viz::SharedBitmapId id_;
  1725. SharedBitmapIdRegistration registration_;
  1726. scoped_refptr<CrossThreadSharedBitmap> bitmap_;
  1727. };
  1728. SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTextureLayerUnregisterRegisterTest);
  1729. } // namespace
  1730. } // namespace cc