xref: /aosp_15_r20/external/skia/tests/graphite/RecorderTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "tests/Test.h"
9 
10 #include "include/gpu/graphite/Context.h"
11 #include "include/gpu/graphite/Recorder.h"
12 #include "src/gpu/SkBackingFit.h"
13 #include "src/gpu/graphite/Device.h"
14 #include "src/gpu/graphite/RecorderPriv.h"
15 
16 using namespace skgpu::graphite;
17 using Mipmapped = skgpu::Mipmapped;
18 
19 // Tests to make sure the managing of back pointers between Recorder and Device all work properly.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecorderDevicePtrTest,reporter,context,CtsEnforcement::kApiLevel_V)20 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecorderDevicePtrTest, reporter, context,
21                                    CtsEnforcement::kApiLevel_V) {
22     std::unique_ptr<Recorder> recorder = context->makeRecorder();
23 
24     SkImageInfo info = SkImageInfo::Make({16, 16}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
25 
26     // Add multiple devices to later test different patterns of destruction.
27     sk_sp<Device> device1 = Device::Make(recorder.get(),
28                                          info,
29                                          skgpu::Budgeted::kYes,
30                                          Mipmapped::kNo,
31                                          SkBackingFit::kExact,
32                                          SkSurfaceProps(),
33                                          LoadOp::kClear,
34                                          "RecorderTestTexture");
35     sk_sp<Device> device2 = Device::Make(recorder.get(),
36                                          info,
37                                          skgpu::Budgeted::kYes,
38                                          Mipmapped::kNo,
39                                          SkBackingFit::kExact,
40                                          SkSurfaceProps(),
41                                          LoadOp::kClear,
42                                          "RecorderTestTexture");
43     sk_sp<Device> device3 = Device::Make(recorder.get(),
44                                          info,
45                                          skgpu::Budgeted::kYes,
46                                          Mipmapped::kNo,
47                                          SkBackingFit::kExact,
48                                          SkSurfaceProps(),
49                                          LoadOp::kClear,
50                                          "RecorderTestTexture");
51     sk_sp<Device> device4 = Device::Make(recorder.get(),
52                                          info,
53                                          skgpu::Budgeted::kYes,
54                                          Mipmapped::kNo,
55                                          SkBackingFit::kExact,
56                                          SkSurfaceProps(),
57                                          LoadOp::kClear,
58                                          "RecorderTestTexture");
59     REPORTER_ASSERT(reporter, device1->recorder() == recorder.get());
60     REPORTER_ASSERT(reporter, device2->recorder() == recorder.get());
61     REPORTER_ASSERT(reporter, device3->recorder() == recorder.get());
62     REPORTER_ASSERT(reporter, device4->recorder() == recorder.get());
63     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device1.get()));
64     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device2.get()));
65     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device3.get()));
66     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device4.get()));
67 
68     // Test freeing a device in the middle, marking it as immutable as ~Surface() our FilterResult
69     // would when done with the device.
70     device2->setImmutable();
71     REPORTER_ASSERT(reporter, device2->recorder() == nullptr);
72     REPORTER_ASSERT(reporter, device2->unique()); // Only the test holds a ref now
73     REPORTER_ASSERT(reporter, !recorder->priv().deviceIsRegistered(device2.get()));
74     device2.reset();
75 
76     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device1.get()));
77     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device3.get()));
78     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device4.get()));
79 
80     // Test freeing a device that wasn't marked as immutable, which should have its ref dropped
81     // automatically when the recorder flushes.
82     Device* dev4Ptr = device4.get();
83     device4.reset();
84     REPORTER_ASSERT(reporter, dev4Ptr->unique()); // The recorder holds a ref still
85     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(dev4Ptr));
86     recorder->priv().flushTrackedDevices(); // should delete device4 now
87     REPORTER_ASSERT(reporter, !recorder->priv().deviceIsRegistered(dev4Ptr));
88 
89     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device1.get()));
90     REPORTER_ASSERT(reporter, recorder->priv().deviceIsRegistered(device3.get()));
91 
92     // Delete the recorder and make sure remaining devices no longer have a valid recorder.
93     recorder.reset();
94     REPORTER_ASSERT(reporter, device1->recorder() == nullptr);
95     REPORTER_ASSERT(reporter, device3->recorder() == nullptr);
96 
97     // Make sure freeing Devices after recorder doesn't cause any crash. This would get checked
98     // naturually when these devices go out of scope, but manually reseting will give us a better
99     // stack trace if something does go wrong.
100     device1.reset();
101     device3.reset();
102 }
103