1 /*
2 * Copyright 2021 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/BackendTexture.h"
11 #include "include/gpu/graphite/Context.h"
12 #include "include/gpu/graphite/Recorder.h"
13 #include "src/gpu/graphite/Caps.h"
14 #include "src/gpu/graphite/ContextPriv.h"
15 #include "src/gpu/graphite/ResourceTypes.h"
16
17 #include "include/core/SkColorSpace.h"
18 #include "include/core/SkSurface.h"
19
20 using namespace skgpu;
21 using namespace skgpu::graphite;
22
23 namespace {
24 const SkISize kSize = {16, 16};
25 }
26
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(BackendTextureTest,reporter,context)27 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(BackendTextureTest, reporter, context) {
28 // TODO: Remove this check once Vulkan supports creating default TexutreInfo from caps and we
29 // implement createBackendTexture.
30 if (context->backend() == BackendApi::kVulkan) {
31 return;
32 }
33
34 auto caps = context->priv().caps();
35 auto recorder = context->makeRecorder();
36
37 TextureInfo info = caps->getDefaultSampledTextureInfo(kRGBA_8888_SkColorType,
38 /*mipmapped=*/Mipmapped::kNo,
39 Protected::kNo,
40 Renderable::kNo);
41 REPORTER_ASSERT(reporter, info.isValid());
42
43 auto texture1 = recorder->createBackendTexture(kSize, info);
44 REPORTER_ASSERT(reporter, texture1.isValid());
45
46 // We make a copy to do the remaining tests so we still have texture1 to safely delete the
47 // backend object.
48 auto texture1Copy = texture1;
49 REPORTER_ASSERT(reporter, texture1Copy.isValid());
50 REPORTER_ASSERT(reporter, texture1 == texture1Copy);
51
52 auto texture2 = recorder->createBackendTexture(kSize, info);
53 REPORTER_ASSERT(reporter, texture2.isValid());
54
55 REPORTER_ASSERT(reporter, texture1Copy != texture2);
56
57 // Test state after assignment
58 texture1Copy = texture2;
59 REPORTER_ASSERT(reporter, texture1Copy.isValid());
60 REPORTER_ASSERT(reporter, texture1Copy == texture2);
61
62 BackendTexture invalidTexture;
63 REPORTER_ASSERT(reporter, !invalidTexture.isValid());
64
65 texture1Copy = invalidTexture;
66 REPORTER_ASSERT(reporter, !texture1Copy.isValid());
67
68 texture1Copy = texture1;
69 REPORTER_ASSERT(reporter, texture1Copy.isValid());
70 REPORTER_ASSERT(reporter, texture1 == texture1Copy);
71
72 recorder->deleteBackendTexture(texture1);
73 recorder->deleteBackendTexture(texture2);
74
75 // Test that deleting is safe from the Context or a different Recorder.
76 texture1 = recorder->createBackendTexture(kSize, info);
77 context->deleteBackendTexture(texture1);
78
79 auto recorder2 = context->makeRecorder();
80 texture1 = recorder->createBackendTexture(kSize, info);
81 recorder2->deleteBackendTexture(texture1);
82 }
83
84 // Tests the wrapping of a BackendTexture in an SkSurface
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(SurfaceBackendTextureTest,reporter,context)85 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(SurfaceBackendTextureTest, reporter, context) {
86 // TODO: Right now this just tests very basic combinations of surfaces. This should be expanded
87 // to cover a much broader set of things once we add more support in Graphite for different
88 // formats, color types, etc.
89
90 // TODO: Remove this check once Vulkan supports creating default TexutreInfo from caps and we
91 // implement createBackendTexture.
92 if (context->backend() == BackendApi::kVulkan) {
93 return;
94 }
95
96 auto caps = context->priv().caps();
97 std::unique_ptr<Recorder> recorder = context->makeRecorder();
98
99 TextureInfo info = caps->getDefaultSampledTextureInfo(kRGBA_8888_SkColorType,
100 /*mipmapped=*/Mipmapped::kNo,
101 Protected::kNo,
102 Renderable::kYes);
103
104 auto texture = recorder->createBackendTexture(kSize, info);
105 REPORTER_ASSERT(reporter, texture.isValid());
106
107 sk_sp<SkSurface> surface = SkSurface::MakeGraphiteFromBackendTexture(recorder.get(),
108 texture,
109 kRGBA_8888_SkColorType,
110 /*colorSpace=*/nullptr,
111 /*props=*/nullptr);
112 REPORTER_ASSERT(reporter, surface);
113
114 surface.reset();
115
116 // We should fail when trying to wrap the same texture in a surface with a non-compatible
117 // color type.
118 surface = SkSurface::MakeGraphiteFromBackendTexture(recorder.get(),
119 texture,
120 kAlpha_8_SkColorType,
121 /*colorSpace=*/nullptr,
122 /*props=*/nullptr);
123 REPORTER_ASSERT(reporter, !surface);
124
125 recorder->deleteBackendTexture(texture);
126
127 // We should fail to wrap a non-renderable texture in a surface.
128 info = caps->getDefaultSampledTextureInfo(kRGBA_8888_SkColorType,
129 /*mipmapped=*/Mipmapped::kNo,
130 Protected::kNo,
131 Renderable::kNo);
132 texture = recorder->createBackendTexture(kSize, info);
133 REPORTER_ASSERT(reporter, texture.isValid());
134
135 surface = SkSurface::MakeGraphiteFromBackendTexture(recorder.get(),
136 texture,
137 kRGBA_8888_SkColorType,
138 /*colorSpace=*/nullptr,
139 /*props=*/nullptr);
140
141 REPORTER_ASSERT(reporter, !surface);
142 recorder->deleteBackendTexture(texture);
143 }
144
145 // Tests the wrapping of a BackendTexture in an SkImage
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(ImageBackendTextureTest,reporter,context)146 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(ImageBackendTextureTest, reporter, context) {
147 // TODO: Right now this just tests very basic combinations of images. This should be expanded
148 // to cover a much broader set of things once we add more support in Graphite for different
149 // formats, color types, etc.
150
151 // TODO: Remove this check once Vulkan supports creating default TexutreInfo from caps and we
152 // implement createBackendTexture.
153 if (context->backend() == BackendApi::kVulkan) {
154 return;
155 }
156
157 const Caps* caps = context->priv().caps();
158 std::unique_ptr<Recorder> recorder = context->makeRecorder();
159
160 for (Mipmapped mipmapped : { Mipmapped::kYes, Mipmapped::kNo }) {
161 for (Renderable renderable : { Renderable::kYes, Renderable::kNo }) {
162
163 TextureInfo info = caps->getDefaultSampledTextureInfo(kRGBA_8888_SkColorType,
164 mipmapped,
165 Protected::kNo,
166 renderable);
167
168 BackendTexture texture = recorder->createBackendTexture(kSize, info);
169 REPORTER_ASSERT(reporter, texture.isValid());
170
171 sk_sp<SkImage> image = SkImage::MakeGraphiteFromBackendTexture(recorder.get(),
172 texture,
173 kRGBA_8888_SkColorType,
174 kPremul_SkAlphaType,
175 /*colorSpace=*/ nullptr);
176 REPORTER_ASSERT(reporter, image);
177 REPORTER_ASSERT(reporter, image->hasMipmaps() == (mipmapped == Mipmapped::kYes));
178
179 image.reset();
180
181 // We should fail when trying to wrap the same texture in an image with a non-compatible
182 // color type.
183 image = SkImage::MakeGraphiteFromBackendTexture(recorder.get(),
184 texture,
185 kAlpha_8_SkColorType,
186 kPremul_SkAlphaType,
187 /* colorSpace= */ nullptr);
188 REPORTER_ASSERT(reporter, !image);
189
190 recorder->deleteBackendTexture(texture);
191 }
192 }
193 }
194
195 #ifdef SK_VULKAN
DEF_GRAPHITE_TEST_FOR_VULKAN_CONTEXT(VulkanBackendTextureMutableStateTest,reporter,context)196 DEF_GRAPHITE_TEST_FOR_VULKAN_CONTEXT(VulkanBackendTextureMutableStateTest, reporter, context) {
197 VulkanTextureInfo info(/*sampleCount=*/1,
198 /*mipmapped=*/Mipmapped::kNo,
199 /*flags=*/0,
200 VK_FORMAT_R8G8B8A8_UNORM,
201 VK_IMAGE_TILING_OPTIMAL,
202 VK_IMAGE_USAGE_SAMPLED_BIT,
203 VK_SHARING_MODE_EXCLUSIVE,
204 VK_IMAGE_ASPECT_COLOR_BIT);
205
206 BackendTexture texture({16, 16},
207 info,
208 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
209 /*queueFamilyIndex=*/1,
210 VK_NULL_HANDLE);
211
212 REPORTER_ASSERT(reporter, texture.isValid());
213 REPORTER_ASSERT(reporter,
214 texture.getVkImageLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
215 REPORTER_ASSERT(reporter, texture.getVkQueueFamilyIndex() == 1);
216
217 skgpu::MutableTextureState newState(VK_IMAGE_LAYOUT_GENERAL, 0);
218 texture.setMutableState(newState);
219
220 REPORTER_ASSERT(reporter,
221 texture.getVkImageLayout() == VK_IMAGE_LAYOUT_GENERAL);
222 REPORTER_ASSERT(reporter, texture.getVkQueueFamilyIndex() == 0);
223
224 // TODO: Add to this test to check that the setMutableState calls also update values we see in
225 // wrapped VulkanTextures once we have them. Also check that updates in VulkanTexture are also
226 // visible in the getters of BackendTexture. We will need a real VkImage to do these tests.
227 }
228 #endif // SK_VULKAN
229