blob: fbb78eab58e725e2e652b5f40143428313ab58cb [file] [log] [blame]
Robert Phillips0c6daf02019-05-16 12:43:11 -04001/*
2 * Copyright 2019 Google Inc.
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
Robert Phillipse19babf2020-04-06 13:57:30 -04008#include "include/core/SkCanvas.h"
Mike Kleinfe0aeb32019-05-20 10:55:11 -05009#include "include/core/SkSurface.h"
Robert Phillips02dc0302019-07-02 17:58:27 -040010#include "include/core/SkSurfaceCharacterization.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040011#include "include/gpu/GrDirectContext.h"
Robert Phillips459b2952019-05-23 09:38:27 -040012#include "src/core/SkAutoPixmapStorage.h"
Adlai Hollera0693042020-10-14 11:23:11 -040013#include "src/gpu/GrDirectContextPriv.h"
Brian Salomon04e3e502020-12-16 15:55:25 -050014#include "src/gpu/GrProxyProvider.h"
15#include "src/gpu/GrSurfaceFillContext.h"
16#include "src/gpu/effects/GrBlendFragmentProcessor.h"
17#include "src/gpu/effects/generated/GrConstColorProcessor.h"
Robert Phillipsefb9f142019-05-17 14:19:44 -040018#include "src/image/SkImage_Base.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040019#include "tests/Test.h"
Robert Phillipse3b6fe42019-09-11 11:26:46 -040020#include "tests/TestUtils.h"
21#include "tools/ToolUtils.h"
Brian Salomon20f1b342020-12-15 20:23:03 -050022#include "tools/gpu/ManagedBackendTexture.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040023
Robert Phillips27eb5252019-06-03 12:59:40 -040024#ifdef SK_GL
Robert Phillipsee946932019-12-18 11:16:17 -050025#include "src/gpu/gl/GrGLCaps.h"
26#include "src/gpu/gl/GrGLDefines.h"
Robert Phillips27eb5252019-06-03 12:59:40 -040027#include "src/gpu/gl/GrGLGpu.h"
28#include "src/gpu/gl/GrGLUtil.h"
29#endif
30
Robert Phillips7f367982019-09-26 14:01:36 -040031#ifdef SK_METAL
32#include "include/gpu/mtl/GrMtlTypes.h"
33#include "src/gpu/mtl/GrMtlCppUtil.h"
34#endif
35
Brian Salomon20f1b342020-12-15 20:23:03 -050036using sk_gpu_test::ManagedBackendTexture;
Greg Danielb2365d82020-05-13 15:32:04 -040037
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -040038// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
Robert Phillipsfe4b4812020-07-17 14:15:51 -040039void test_wrapping(GrDirectContext* dContext,
40 skiatest::Reporter* reporter,
Brian Salomon20f1b342020-12-15 20:23:03 -050041 std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
42 GrMipmapped,
43 GrRenderable)> create,
Robert Phillipsfe4b4812020-07-17 14:15:51 -040044 GrColorType grColorType,
Brian Salomon7e67dca2020-07-21 09:27:25 -040045 GrMipmapped mipMapped,
Brian Salomon20f1b342020-12-15 20:23:03 -050046 GrRenderable renderable) {
Robert Phillipsfe4b4812020-07-17 14:15:51 -040047 GrResourceCache* cache = dContext->priv().getResourceCache();
Robert Phillips0c6daf02019-05-16 12:43:11 -040048
49 const int initialCount = cache->getResourceCount();
50
Brian Salomon20f1b342020-12-15 20:23:03 -050051 sk_sp<ManagedBackendTexture> mbet = create(dContext, mipMapped, renderable);
52 if (!mbet) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040053 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
54 grColorType,
Robert Phillips0c6daf02019-05-16 12:43:11 -040055 GrRenderable::kYes == renderable ? "yes" : "no");
56 return;
57 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040058
Robert Phillips0c6daf02019-05-16 12:43:11 -040059 // Skia proper should know nothing about the new backend object
60 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
61
Robert Phillipsb7f95d12019-07-26 11:13:19 -040062 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
63
Brian Salomon04e3e502020-12-16 15:55:25 -050064 // Wrapping a backendTexture in an SkImage/SkSurface requires an SkColorType
65 if (skColorType == kUnknown_SkColorType) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040066 return;
67 }
68
Robert Phillipsfe4b4812020-07-17 14:15:51 -040069 if (GrRenderable::kYes == renderable && dContext->colorTypeSupportedAsSurface(skColorType)) {
70 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(dContext,
Brian Salomon20f1b342020-12-15 20:23:03 -050071 mbet->texture(),
Robert Phillips459b2952019-05-23 09:38:27 -040072 kTopLeft_GrSurfaceOrigin,
73 0,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040074 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040075 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040076 if (!surf) {
Brian Salomon04e3e502020-12-16 15:55:25 -050077 ERRORF(reporter, "Couldn't make SkSurface from backendTexture for %s\n",
Robert Phillips9a30ee02020-04-29 08:58:39 -040078 ToolUtils::colortype_name(skColorType));
Robert Phillipsb04b6942019-05-21 17:24:31 -040079 } else {
80 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040081 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040082 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040083
Robert Phillipsb04b6942019-05-21 17:24:31 -040084 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -040085 sk_sp<SkImage> img = SkImage::MakeFromTexture(dContext,
Brian Salomon20f1b342020-12-15 20:23:03 -050086 mbet->texture(),
Robert Phillips459b2952019-05-23 09:38:27 -040087 kTopLeft_GrSurfaceOrigin,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040088 skColorType,
Brian Salomon04e3e502020-12-16 15:55:25 -050089 kUnpremul_SkAlphaType,
Robert Phillips459b2952019-05-23 09:38:27 -040090 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040091 if (!img) {
Brian Salomon04e3e502020-12-16 15:55:25 -050092 ERRORF(reporter, "Couldn't make SkImage from backendTexture for %s\n",
Robert Phillips9a30ee02020-04-29 08:58:39 -040093 ToolUtils::colortype_name(skColorType));
Robert Phillipsb04b6942019-05-21 17:24:31 -040094 } else {
95 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -040096
Robert Phillipsb04b6942019-05-21 17:24:31 -040097 GrTextureProxy* proxy = ib->peekProxy();
98 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -040099
Brian Salomon8c82a872020-07-21 12:09:58 -0400100 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipmapped());
Robert Phillipsb04b6942019-05-21 17:24:31 -0400101 REPORTER_ASSERT(reporter, proxy->isInstantiated());
Brian Salomon8c82a872020-07-21 12:09:58 -0400102 REPORTER_ASSERT(reporter, mipMapped == proxy->mipmapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -0400103
Robert Phillipsb04b6942019-05-21 17:24:31 -0400104 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400105 }
106 }
107
108 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400109}
110
Robert Phillips9a30ee02020-04-29 08:58:39 -0400111static bool isBGRA8(const GrBackendFormat& format) {
Robert Phillips7f367982019-09-26 14:01:36 -0400112 switch (format.backend()) {
Robert Phillips7f367982019-09-26 14:01:36 -0400113 case GrBackendApi::kOpenGL:
114#ifdef SK_GL
115 return format.asGLFormat() == GrGLFormat::kBGRA8;
116#else
117 return false;
118#endif
119 case GrBackendApi::kVulkan: {
120#ifdef SK_VULKAN
121 VkFormat vkFormat;
122 format.asVkFormat(&vkFormat);
123 return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
124#else
125 return false;
126#endif
127 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500128 case GrBackendApi::kMetal:
129#ifdef SK_METAL
Robert Phillips9a30ee02020-04-29 08:58:39 -0400130 return GrMtlFormatIsBGRA8(format.asMtlFormat());
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500131#else
132 return false;
133#endif
134 case GrBackendApi::kDirect3D:
135#ifdef SK_DIRECT3D
136 return false; // TODO
137#else
138 return false;
139#endif
140 case GrBackendApi::kDawn:
Stephen White36248742020-06-10 22:24:57 -0400141#ifdef SK_DAWN
142 wgpu::TextureFormat dawnFormat;
143 format.asDawnFormat(&dawnFormat);
144 return dawnFormat == wgpu::TextureFormat::BGRA8Unorm;
145#else
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500146 return false;
Stephen White36248742020-06-10 22:24:57 -0400147#endif
Robert Phillipsa27d6252019-12-10 14:48:36 -0500148 case GrBackendApi::kMock: {
149 SkImage::CompressionType compression = format.asMockCompressionType();
150 if (compression != SkImage::CompressionType::kNone) {
151 return false; // No compressed formats are BGRA
152 }
153
Robert Phillips7f367982019-09-26 14:01:36 -0400154 return format.asMockColorType() == GrColorType::kBGRA_8888;
Robert Phillipsa27d6252019-12-10 14:48:36 -0500155 }
Robert Phillips7f367982019-09-26 14:01:36 -0400156 }
157 SkUNREACHABLE;
158}
159
160static bool isRGB(const GrBackendFormat& format) {
161 switch (format.backend()) {
Robert Phillips7f367982019-09-26 14:01:36 -0400162 case GrBackendApi::kOpenGL:
163#ifdef SK_GL
164 return format.asGLFormat() == GrGLFormat::kRGB8;
165#else
166 return false;
167#endif
168 case GrBackendApi::kVulkan: {
169#ifdef SK_VULKAN
170 VkFormat vkFormat;
171 format.asVkFormat(&vkFormat);
172 return vkFormat == VK_FORMAT_R8G8B8_UNORM;
173#else
174 return false;
175#endif
176 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500177 case GrBackendApi::kMetal:
178 return false; // Metal doesn't even pretend to support this
179 case GrBackendApi::kDirect3D:
180 return false; // Not supported in Direct3D 12
181 case GrBackendApi::kDawn:
182 return false;
Robert Phillips7f367982019-09-26 14:01:36 -0400183 case GrBackendApi::kMock:
184 return false; // No GrColorType::kRGB_888
185 }
186 SkUNREACHABLE;
187}
188
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400189static void check_solid_pixmap(skiatest::Reporter* reporter,
Brian Salomon04e3e502020-12-16 15:55:25 -0500190 const SkColor4f& expected,
191 const SkPixmap& actual,
192 GrColorType ct,
193 const char* label1,
194 const char* label2) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400195 // we need 0.001f across the board just for noise
196 // we need 0.01f across the board for 1010102
Robert Phillips7f367982019-09-26 14:01:36 -0400197 const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
Robert Phillips27eb5252019-06-03 12:59:40 -0400198
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400199 auto error = std::function<ComparePixmapsErrorReporter>(
Robert Phillips7f367982019-09-26 14:01:36 -0400200 [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400201 SkASSERT(x >= 0 && y >= 0);
Brian Salomon04e3e502020-12-16 15:55:25 -0500202 ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)", GrColorTypeToStr(ct),
203 label1, label2, x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400204 });
205
Brian Salomon28a8f282019-10-24 20:07:39 -0400206 CheckSolidPixels(expected, actual, tols, error);
Robert Phillips27eb5252019-06-03 12:59:40 -0400207}
208
Brian Salomon04e3e502020-12-16 15:55:25 -0500209// Determine what color we expect if we store 'orig' in 'ct' converted back to SkColor4f.
210static SkColor4f get_expected_color(SkColor4f orig, GrColorType ct) {
211 GrImageInfo ii(ct, kUnpremul_SkAlphaType, nullptr, {1, 1});
212 std::unique_ptr<char[]> data(new char[ii.minRowBytes()]);
213 GrClearImage(ii, data.get(), ii.minRowBytes(), orig);
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400214
Brian Salomon04e3e502020-12-16 15:55:25 -0500215 // Read back to SkColor4f.
216 SkColor4f result;
217 GrImageInfo resultII(GrColorType::kRGBA_F32, kUnpremul_SkAlphaType, nullptr, {1, 1});
218 GrConvertPixels(resultII, &result.fR, sizeof(result), ii, data.get(), ii.minRowBytes());
219 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400220}
221
Brian Salomon04e3e502020-12-16 15:55:25 -0500222static void check_mipmaps(GrDirectContext*,
223 const GrBackendTexture&,
224 GrColorType,
225 const SkColor4f expectedColors[6],
226 skiatest::Reporter*,
227 const char* label);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400228
Brian Salomon04e3e502020-12-16 15:55:25 -0500229static void check_base_readbacks(GrDirectContext* dContext,
230 const GrBackendTexture& backendTex,
231 GrColorType colorType,
232 GrRenderable renderableTexture,
233 const SkColor4f& color,
234 skiatest::Reporter* reporter,
Robert Phillips7f367982019-09-26 14:01:36 -0400235 const char* label) {
236 if (isRGB(backendTex.getBackendFormat())) {
237 // readPixels is busted for the RGB backend format (skbug.com/8862)
238 // TODO: add a GrColorType::kRGB_888 to fix the situation
239 return;
240 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400241
Brian Salomon04e3e502020-12-16 15:55:25 -0500242 SkColor4f expectedColor = get_expected_color(color, colorType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400243
244 SkAutoPixmapStorage actual;
245
246 {
Brian Salomon04e3e502020-12-16 15:55:25 -0500247 SkImageInfo readBackII = SkImageInfo::Make(32, 32,
248 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400249 kUnpremul_SkAlphaType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400250
251 SkAssertResult(actual.tryAlloc(readBackII));
252 }
Brian Salomon04e3e502020-12-16 15:55:25 -0500253 for (GrRenderable renderableCtx : {GrRenderable::kNo, GrRenderable::kYes}) {
254 if (renderableCtx == GrRenderable::kYes && renderableTexture == GrRenderable::kNo) {
255 continue;
Brian Salomon0263bff2020-12-16 08:41:39 -0500256 }
Brian Salomon04e3e502020-12-16 15:55:25 -0500257 sk_sp<GrSurfaceProxy> proxy;
258 if (renderableCtx == GrRenderable::kYes) {
259 proxy = dContext->priv().proxyProvider()->wrapRenderableBackendTexture(
260 backendTex, 1, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, nullptr);
261 } else {
262 proxy = dContext->priv().proxyProvider()->wrapBackendTexture(
263 backendTex, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
264 }
265 if (!proxy) {
266 ERRORF(reporter, "Could not make proxy from backend texture");
267 return;
268 }
269 auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
270 colorType);
271 GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
272 GrColorInfo info(colorType, kUnpremul_SkAlphaType, nullptr);
273 auto surfaceContext = GrSurfaceContext::Make(dContext, readView, info);
274 if (!surfaceContext) {
275 ERRORF(reporter, "Could not create surface context for colorType: %d\n", colorType);
276 }
Brian Salomon0263bff2020-12-16 08:41:39 -0500277
Brian Salomondd4087d2020-12-23 20:36:44 -0500278 if (!surfaceContext->readPixels(dContext, actual, {0, 0})) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500279 // TODO: we need a better way to tell a priori if readPixels will work for an
280 // arbitrary colorType
281#if 0
282 ERRORF(reporter, "Couldn't readback from GrSurfaceContext for colorType: %d\n",
283 colorType);
284#endif
285 } else {
286 auto name = SkStringPrintf("%s::readPixels",
287 (renderableCtx == GrRenderable::kYes ? "GrSurfaceFillContext"
288 : "GrSurfaceContext"));
289 check_solid_pixmap(reporter, expectedColor, actual, colorType, label, name.c_str());
Robert Phillips7f367982019-09-26 14:01:36 -0400290 }
291 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400292}
293
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400294// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400295void test_color_init(GrDirectContext* dContext,
296 skiatest::Reporter* reporter,
Brian Salomon20f1b342020-12-15 20:23:03 -0500297 std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
298 const SkColor4f&,
299 GrMipmapped,
300 GrRenderable)> create,
Brian Salomon04e3e502020-12-16 15:55:25 -0500301 GrColorType colorType,
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400302 const SkColor4f& color,
Brian Salomon01ff5382020-12-15 16:06:26 -0500303 GrMipmapped mipmapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500304 GrRenderable renderable) {
Brian Salomon01ff5382020-12-15 16:06:26 -0500305 sk_sp<ManagedBackendTexture> mbet = create(dContext, color, mipmapped, renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500306 if (!mbet) {
Robert Phillips459b2952019-05-23 09:38:27 -0400307 // errors here should be reported by the test_wrapping test
308 return;
309 }
310
Greg Danielb2365d82020-05-13 15:32:04 -0400311 auto checkBackendTexture = [&](const SkColor4f& testColor) {
Brian Salomon01ff5382020-12-15 16:06:26 -0500312 if (mipmapped == GrMipmapped::kYes) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500313 SkColor4f expectedColor = get_expected_color(testColor, colorType);
Greg Danielb2365d82020-05-13 15:32:04 -0400314 SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
315 expectedColor, expectedColor, expectedColor};
Brian Salomon20f1b342020-12-15 20:23:03 -0500316 check_mipmaps(dContext, mbet->texture(), colorType, expectedColors, reporter,
317 "colorinit");
Greg Danielb2365d82020-05-13 15:32:04 -0400318 }
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400319
Greg Danielb2365d82020-05-13 15:32:04 -0400320 // The last step in this test will dirty the mipmaps so do it last
Brian Salomon20f1b342020-12-15 20:23:03 -0500321 check_base_readbacks(dContext, mbet->texture(), colorType, renderable, testColor, reporter,
Brian Salomon04e3e502020-12-16 15:55:25 -0500322 "colorinit");
Greg Danielb2365d82020-05-13 15:32:04 -0400323 };
324
325 checkBackendTexture(color);
326
Greg Danielb2365d82020-05-13 15:32:04 -0400327 SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
328
Brian Salomon04e3e502020-12-16 15:55:25 -0500329 SkColorType skColorType = GrColorTypeToSkColorType(colorType);
Brian Salomon04e3e502020-12-16 15:55:25 -0500330 // Our update method only works with SkColorTypes.
331 if (skColorType != kUnknown_SkColorType) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500332 dContext->updateBackendTexture(mbet->texture(),
333 skColorType,
334 newColor,
335 ManagedBackendTexture::ReleaseProc,
336 mbet->releaseContext());
Brian Salomon04e3e502020-12-16 15:55:25 -0500337 checkBackendTexture(newColor);
338 }
Robert Phillips459b2952019-05-23 09:38:27 -0400339}
340
Brian Salomon04e3e502020-12-16 15:55:25 -0500341// Draw the backend texture into an RGBA surface fill context, attempting to access all the mipMap
342// levels.
343static void check_mipmaps(GrDirectContext* dContext,
344 const GrBackendTexture& backendTex,
345 GrColorType colorType,
346 const SkColor4f expectedColors[6],
347 skiatest::Reporter* reporter,
348 const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400349#ifdef SK_GL
350 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400351 if (GrBackendApi::kOpenGL == dContext->backend()) {
352 GrGLGpu* glGPU = static_cast<GrGLGpu*>(dContext->priv().getGpu());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400353
Brian Salomon04e3e502020-12-16 15:55:25 -0500354 if (colorType == GrColorType::kRGBA_F32 &&
355 glGPU->ctxInfo().standard() == kGLES_GrGLStandard) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400356 return;
357 }
358 }
359#endif
360
Robert Phillips7f367982019-09-26 14:01:36 -0400361 if (isRGB(backendTex.getBackendFormat())) {
362 // readPixels is busted for the RGB backend format (skbug.com/8862)
363 // TODO: add a GrColorType::kRGB_888 to fix the situation
364 return;
365 }
366
Brian Salomon04e3e502020-12-16 15:55:25 -0500367 GrImageInfo info(GrColorType::kRGBA_8888, kUnpremul_SkAlphaType, nullptr, {32, 32});
368 auto dstFillContext = GrSurfaceFillContext::Make(dContext, info);
369 if (!dstFillContext) {
370 ERRORF(reporter, "Could not make dst fill context.");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400371 return;
372 }
373
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400374 int numMipLevels = 6;
375
Brian Salomon04e3e502020-12-16 15:55:25 -0500376 auto proxy = dContext->priv().proxyProvider()->wrapBackendTexture(backendTex,
377 kBorrow_GrWrapOwnership,
378 GrWrapCacheable::kNo,
379 kRW_GrIOType);
380 if (!proxy) {
381 ERRORF(reporter, "Could not make proxy from backend texture");
382 return;
383 }
384 auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
385 colorType);
386 GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
387
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400388 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
389 SkASSERT(rectSize >= 1);
Brian Salomon04e3e502020-12-16 15:55:25 -0500390 dstFillContext->clear(SK_PMColor4fTRANSPARENT);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400391
Brian Salomon04e3e502020-12-16 15:55:25 -0500392 SkMatrix texMatrix;
393 texMatrix.setScale(1 << i, 1 << i);
394 static constexpr GrSamplerState kNearestNearest(GrSamplerState::Filter::kNearest,
395 GrSamplerState::MipmapMode::kNearest);
396 auto fp = GrTextureEffect::Make(readView,
397 kUnpremul_SkAlphaType,
398 texMatrix,
399 kNearestNearest,
400 *dstFillContext->caps());
401 // Our swizzles for alpha color types currently produce (a, a, a, a) in the shader. Remove
402 // this once they are correctly (0, 0, 0, a).
403 if (GrColorTypeIsAlphaOnly(colorType)) {
404 auto black = GrConstColorProcessor::Make(SK_PMColor4fBLACK);
405 fp = GrBlendFragmentProcessor::Make(std::move(fp),
406 std::move(black),
407 SkBlendMode::kModulate);
408 }
409 dstFillContext->fillRectWithFP(SkIRect::MakeWH(rectSize, rectSize), std::move(fp));
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400410
411 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
412 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400413 kUnpremul_SkAlphaType);
Brian Salomon04e3e502020-12-16 15:55:25 -0500414 SkAutoPixmapStorage actual;
415 SkAssertResult(actual.tryAlloc(readbackII));
416 actual.erase(SkColors::kTransparent);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400417
Brian Salomondd4087d2020-12-23 20:36:44 -0500418 bool result = dstFillContext->readPixels(dContext, actual, {0, 0});
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400419 REPORTER_ASSERT(reporter, result);
420
Robert Phillipsee946932019-12-18 11:16:17 -0500421 SkString str;
422 str.appendf("mip-level %d", i);
423
Brian Salomon04e3e502020-12-16 15:55:25 -0500424 check_solid_pixmap(reporter, expectedColors[i], actual, colorType, label, str.c_str());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400425 }
426}
427
Brian Salomon7e67dca2020-07-21 09:27:25 -0400428static int make_pixmaps(SkColorType skColorType, GrMipmapped mipMapped,
Robert Phillips7f367982019-09-26 14:01:36 -0400429 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
430 int levelSize = 32;
Brian Salomon7e67dca2020-07-21 09:27:25 -0400431 int numMipLevels = mipMapped == GrMipmapped::kYes ? 6 : 1;
Robert Phillips7f367982019-09-26 14:01:36 -0400432 for (int level = 0; level < numMipLevels; ++level) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500433 SkImageInfo ii = SkImageInfo::Make(levelSize,
434 levelSize,
435 skColorType,
436 kUnpremul_SkAlphaType);
Robert Phillips7f367982019-09-26 14:01:36 -0400437 pixmaps[level].alloc(ii);
438 pixmaps[level].erase(colors[level]);
439 levelSize /= 2;
440 }
441 return numMipLevels;
442}
443
444// Test initialization of GrBackendObjects using SkPixmaps
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400445static void test_pixmap_init(GrDirectContext* dContext,
446 skiatest::Reporter* reporter,
Brian Salomon20f1b342020-12-15 20:23:03 -0500447 std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
448 const SkPixmap srcData[],
449 int numLevels,
450 GrSurfaceOrigin,
451 GrRenderable)> create,
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400452 SkColorType skColorType,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500453 GrSurfaceOrigin origin,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400454 GrMipmapped mipMapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500455 GrRenderable renderable) {
Robert Phillips7f367982019-09-26 14:01:36 -0400456 SkAutoPixmapStorage pixmapMem[6];
457 SkColor4f colors[6] = {
458 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
459 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
460 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
461 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
462 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
463 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
464 };
465
466 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
467 SkASSERT(numMipLevels);
468
469 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
470 SkPixmap pixmaps[6];
471 for (int i = 0; i < numMipLevels; ++i) {
472 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
473 }
474
Brian Salomon20f1b342020-12-15 20:23:03 -0500475 sk_sp<ManagedBackendTexture> mbet = create(dContext, pixmaps, numMipLevels, origin, renderable);
476 if (!mbet) {
Robert Phillips7f367982019-09-26 14:01:36 -0400477 // errors here should be reported by the test_wrapping test
478 return;
479 }
480
Brian Salomon20f1b342020-12-15 20:23:03 -0500481 if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(mbet->texture().getBackendFormat())) {
Robert Phillips7f367982019-09-26 14:01:36 -0400482 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
483 return;
484 }
485
Greg Danielb2365d82020-05-13 15:32:04 -0400486 auto checkBackendTexture = [&](SkColor4f colors[6]) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500487 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
Brian Salomon7e67dca2020-07-21 09:27:25 -0400488 if (mipMapped == GrMipmapped::kYes) {
Greg Danielb2365d82020-05-13 15:32:04 -0400489 SkColor4f expectedColors[6] = {
Brian Salomon04e3e502020-12-16 15:55:25 -0500490 get_expected_color(colors[0], grColorType),
491 get_expected_color(colors[1], grColorType),
492 get_expected_color(colors[2], grColorType),
493 get_expected_color(colors[3], grColorType),
494 get_expected_color(colors[4], grColorType),
495 get_expected_color(colors[5], grColorType),
Greg Danielb2365d82020-05-13 15:32:04 -0400496 };
Robert Phillips7f367982019-09-26 14:01:36 -0400497
Brian Salomon20f1b342020-12-15 20:23:03 -0500498 check_mipmaps(dContext, mbet->texture(), grColorType, expectedColors, reporter,
499 "pixmap");
Greg Danielb2365d82020-05-13 15:32:04 -0400500 }
501
502 // The last step in this test will dirty the mipmaps so do it last
Brian Salomon20f1b342020-12-15 20:23:03 -0500503 check_base_readbacks(dContext, mbet->texture(), grColorType, renderable, colors[0],
504 reporter, "pixmap");
Greg Danielb2365d82020-05-13 15:32:04 -0400505 };
506
507 checkBackendTexture(colors);
508
Greg Danielb2365d82020-05-13 15:32:04 -0400509 SkColor4f colorsNew[6] = {
510 {1.0f, 1.0f, 0.0f, 0.2f}, // Y
511 {1.0f, 0.0f, 0.0f, 1.0f}, // R
512 {0.0f, 1.0f, 0.0f, 0.9f}, // G
513 {0.0f, 0.0f, 1.0f, 0.7f}, // B
514 {0.0f, 1.0f, 1.0f, 0.5f}, // C
515 {1.0f, 0.0f, 1.0f, 0.3f}, // M
516 };
517 make_pixmaps(skColorType, mipMapped, colorsNew, pixmapMem);
518 for (int i = 0; i < numMipLevels; ++i) {
519 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
Robert Phillips7f367982019-09-26 14:01:36 -0400520 }
521
Greg Danielb2365d82020-05-13 15:32:04 -0400522 // Upload new data and make sure everything still works
Brian Salomon20f1b342020-12-15 20:23:03 -0500523 dContext->updateBackendTexture(mbet->texture(),
524 pixmaps,
525 numMipLevels,
526 origin,
527 ManagedBackendTexture::ReleaseProc,
528 mbet->releaseContext());
Greg Danielb2365d82020-05-13 15:32:04 -0400529
530 checkBackendTexture(colorsNew);
Robert Phillips7f367982019-09-26 14:01:36 -0400531}
532
Robert Phillips02dc0302019-07-02 17:58:27 -0400533enum class VkLayout {
534 kUndefined,
535 kReadOnlyOptimal,
Robert Phillips02dc0302019-07-02 17:58:27 -0400536};
537
538void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
539#if defined(SK_VULKAN) && defined(SK_DEBUG)
540 VkImageLayout expected;
541
542 switch (layout) {
543 case VkLayout::kUndefined:
544 expected = VK_IMAGE_LAYOUT_UNDEFINED;
545 break;
546 case VkLayout::kReadOnlyOptimal:
547 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
548 break;
Robert Phillips02dc0302019-07-02 17:58:27 -0400549 default:
550 SkUNREACHABLE;
551 }
552
553 GrVkImageInfo vkII;
554
555 if (backendTex.getVkImageInfo(&vkII)) {
556 SkASSERT(expected == vkII.fImageLayout);
557 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
558 }
559#endif
560}
561
562///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400563DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400564 auto context = ctxInfo.directContext();
Robert Phillips0c6daf02019-05-16 12:43:11 -0400565 const GrCaps* caps = context->priv().caps();
566
Robert Phillips459b2952019-05-23 09:38:27 -0400567 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400568 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400569
Robert Phillips0c6daf02019-05-16 12:43:11 -0400570 struct {
571 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400572 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400573 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400574 { kAlpha_8_SkColorType, kTransCol },
575 { kRGB_565_SkColorType, SkColors::kRed },
576 { kARGB_4444_SkColorType, SkColors::kGreen },
577 { kRGBA_8888_SkColorType, SkColors::kBlue },
578 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400579 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400580 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips9a30ee02020-04-29 08:58:39 -0400581 // TODO: readback is busted for *10A2 when alpha = 0.5f (perhaps premul vs. unpremul)
582 { kRGBA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
583 { kBGRA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
584 // RGB/BGR 101010x have no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400585 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Mike Kleinf7eb0542020-02-11 12:19:08 -0600586 { kBGR_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400587 { kGray_8_SkColorType, kGrayCol },
588 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
589 { kRGBA_F16_SkColorType, SkColors::kYellow },
590 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400591 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400592 { kR16G16_unorm_SkColorType, SkColors::kGreen },
593 { kA16_unorm_SkColorType, kTransCol },
594 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400595 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400596 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400597 };
598
Brian Salomon4dea72a2019-12-18 10:43:10 -0500599 static_assert(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400600
601 for (auto combo : combinations) {
602 SkColorType colorType = combo.fColorType;
603
Robert Phillips0c6daf02019-05-16 12:43:11 -0400604 if (GrBackendApi::kMetal == context->backend()) {
605 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
606 if (kRGBA_F32_SkColorType == combo.fColorType) {
607 continue;
608 }
609 }
610
Brian Salomon04e3e502020-12-16 15:55:25 -0500611 for (auto mipmapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
612 if (GrMipmapped::kYes == mipmapped && !caps->mipmapSupport()) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400613 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400614 }
615
Robert Phillipsefb9f142019-05-17 14:19:44 -0400616 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400617 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
618 renderable).isValid()) {
619 continue;
620 }
Robert Phillips7f367982019-09-26 14:01:36 -0400621
Robert Phillipsefb9f142019-05-17 14:19:44 -0400622 if (GrRenderable::kYes == renderable) {
623 if (kRGB_888x_SkColorType == combo.fColorType) {
624 // Ganesh can't perform the blends correctly when rendering this format
625 continue;
626 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400627 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400628
Robert Phillipsb04b6942019-05-21 17:24:31 -0400629 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400630 auto uninitCreateMtd = [colorType](GrDirectContext* dContext,
Brian Salomon04e3e502020-12-16 15:55:25 -0500631 GrMipmapped mipmapped,
Robert Phillipsb04b6942019-05-21 17:24:31 -0400632 GrRenderable renderable) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500633 auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
634 32, 32,
635 colorType,
636 mipmapped,
637 renderable,
638 GrProtected::kNo);
639 check_vk_layout(mbet->texture(), VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400640#ifdef SK_DEBUG
641 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400642 GrBackendFormat format = dContext->defaultBackendFormat(colorType,
643 renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500644 SkASSERT(format == mbet->texture().getBackendFormat());
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400645 }
646#endif
647
Brian Salomon20f1b342020-12-15 20:23:03 -0500648 return mbet;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400649 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400650
Robert Phillipsb04b6942019-05-21 17:24:31 -0400651 test_wrapping(context, reporter, uninitCreateMtd,
Brian Salomon20f1b342020-12-15 20:23:03 -0500652 SkColorTypeToGrColorType(colorType), mipmapped, renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400653 }
Robert Phillips459b2952019-05-23 09:38:27 -0400654
655 {
Brian Salomon20f1b342020-12-15 20:23:03 -0500656 auto createWithColorMtd = [colorType](GrDirectContext* dContext,
657 const SkColor4f& color,
658 GrMipmapped mipmapped,
659 GrRenderable renderable) {
660 auto mbet = ManagedBackendTexture::MakeWithData(dContext,
661 32, 32,
662 colorType,
663 color,
664 mipmapped,
665 renderable,
666 GrProtected::kNo);
667 check_vk_layout(mbet->texture(), VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400668
669#ifdef SK_DEBUG
670 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400671 GrBackendFormat format = dContext->defaultBackendFormat(colorType,
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400672 renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500673 SkASSERT(format == mbet->texture().getBackendFormat());
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400674 }
675#endif
676
Brian Salomon20f1b342020-12-15 20:23:03 -0500677 return mbet;
Robert Phillips459b2952019-05-23 09:38:27 -0400678 };
Robert Phillips459b2952019-05-23 09:38:27 -0400679 test_color_init(context, reporter, createWithColorMtd,
Brian Salomon04e3e502020-12-16 15:55:25 -0500680 SkColorTypeToGrColorType(colorType), combo.fColor, mipmapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500681 renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400682 }
Robert Phillips7f367982019-09-26 14:01:36 -0400683
Brian Salomonb5f880a2020-12-07 11:30:16 -0500684 for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500685 auto createWithSrcDataMtd = [](GrDirectContext* dContext,
686 const SkPixmap srcData[],
687 int numLevels,
688 GrSurfaceOrigin origin,
689 GrRenderable renderable) {
Robert Phillips9a30ee02020-04-29 08:58:39 -0400690 SkASSERT(srcData && numLevels);
Brian Salomon20f1b342020-12-15 20:23:03 -0500691 auto mbet = ManagedBackendTexture::MakeWithData(dContext,
692 srcData,
693 numLevels,
694 origin,
695 renderable,
696 GrProtected::kNo);
697 check_vk_layout(mbet->texture(), VkLayout::kReadOnlyOptimal);
Robert Phillips7f367982019-09-26 14:01:36 -0400698#ifdef SK_DEBUG
Robert Phillips9a30ee02020-04-29 08:58:39 -0400699 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400700 auto format = dContext->defaultBackendFormat(srcData[0].colorType(),
701 renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500702 SkASSERT(format == mbet->texture().getBackendFormat());
Robert Phillips9a30ee02020-04-29 08:58:39 -0400703 }
Robert Phillips7f367982019-09-26 14:01:36 -0400704#endif
Brian Salomon20f1b342020-12-15 20:23:03 -0500705 return mbet;
Robert Phillips9a30ee02020-04-29 08:58:39 -0400706 };
Robert Phillips7f367982019-09-26 14:01:36 -0400707
Brian Salomonb5f880a2020-12-07 11:30:16 -0500708 test_pixmap_init(context,
709 reporter,
710 createWithSrcDataMtd,
711 colorType,
712 origin,
Brian Salomon04e3e502020-12-16 15:55:25 -0500713 mipmapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500714 renderable);
Robert Phillips9a30ee02020-04-29 08:58:39 -0400715 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400716 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400717 }
718 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400719}
720
Robert Phillipsefb9f142019-05-17 14:19:44 -0400721///////////////////////////////////////////////////////////////////////////////
722#ifdef SK_GL
723
Robert Phillips0c6daf02019-05-16 12:43:11 -0400724DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
725 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
726 GrGLStandard standard = glCtx->gl()->fStandard;
Robert Phillips6d344c32020-07-06 10:56:46 -0400727 auto context = ctxInfo.directContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400728 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400729
Brian Salomon01ff5382020-12-15 16:06:26 -0500730 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
731 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1.f };
732 constexpr SkColor4f kTransGrayCol { 0.5f, 0.5f, 0.5f, .8f };
Robert Phillips459b2952019-05-23 09:38:27 -0400733
Robert Phillips0c6daf02019-05-16 12:43:11 -0400734 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400735 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400736 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400737 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400738 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400739 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
740 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400741
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400742 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
743 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400744
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400745 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
746 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
747 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillips9a30ee02020-04-29 08:58:39 -0400748 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
749 { GrColorType::kBGRA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400750 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
751 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400752
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400753 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
754 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400755
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400756 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
757 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400758
Brian Salomon01ff5382020-12-15 16:06:26 -0500759 { GrColorType::kGrayAlpha_88, GR_GL_LUMINANCE8_ALPHA8, kTransGrayCol },
760
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400761 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400762
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400763 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
764 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400765
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400766 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400767 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
768 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400769
Robert Phillips429f0d32019-09-11 17:03:28 -0400770 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400771 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400772
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400773 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
774 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400775 };
776
777 for (auto combo : combinations) {
Brian Salomon0f396992020-06-19 19:51:21 -0400778 for (GrGLenum target : {GR_GL_TEXTURE_2D, GR_GL_TEXTURE_RECTANGLE}) {
779 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, target);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400780
Brian Salomon0f396992020-06-19 19:51:21 -0400781 if (!glCaps->isFormatTexturable(format)) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400782 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400783 }
784
Brian Salomon0f396992020-06-19 19:51:21 -0400785 if (GrColorType::kBGRA_8888 == combo.fColorType ||
786 GrColorType::kBGRA_1010102 == combo.fColorType) {
787 // We allow using a GL_RGBA8 or GR_GL_RGB10_A2 texture as BGRA on desktop GL but not
788 // ES
789 if (kGL_GrGLStandard != standard &&
790 (GR_GL_RGBA8 == combo.fFormat || GR_GL_RGB10_A2 == combo.fFormat)) {
791 continue;
792 }
793 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400794
Brian Salomon7e67dca2020-07-21 09:27:25 -0400795 for (auto mipMapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
796 if (GrMipmapped::kYes == mipMapped &&
Brian Salomon69100f02020-07-21 10:49:25 -0400797 (!glCaps->mipmapSupport() || target == GR_GL_TEXTURE_RECTANGLE)) {
Brian Salomon0f396992020-06-19 19:51:21 -0400798 continue;
Robert Phillipsefb9f142019-05-17 14:19:44 -0400799 }
800
Brian Salomon0f396992020-06-19 19:51:21 -0400801 for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
802 if (GrRenderable::kYes == renderable) {
803 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
804 continue;
805 }
Robert Phillips459b2952019-05-23 09:38:27 -0400806 }
807
Brian Salomon0f396992020-06-19 19:51:21 -0400808 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400809 auto uninitCreateMtd = [format](GrDirectContext* dContext,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400810 GrMipmapped mipMapped,
Brian Salomon0f396992020-06-19 19:51:21 -0400811 GrRenderable renderable) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500812 return ManagedBackendTexture::MakeWithoutData(dContext,
813 32, 32,
814 format,
815 mipMapped,
816 renderable,
817 GrProtected::kNo);
Brian Salomon0f396992020-06-19 19:51:21 -0400818 };
Greg Danielc1ad77c2020-05-06 11:40:03 -0400819
Brian Salomon0f396992020-06-19 19:51:21 -0400820 test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType,
Brian Salomon20f1b342020-12-15 20:23:03 -0500821 mipMapped, renderable);
Brian Salomon85c3d682019-11-04 15:04:54 -0500822 }
Robert Phillips459b2952019-05-23 09:38:27 -0400823
Brian Salomon0f396992020-06-19 19:51:21 -0400824 {
825 // We're creating backend textures without specifying a color type "view" of
826 // them at the public API level. Therefore, Ganesh will not apply any
827 // swizzles before writing the color to the texture. However, our validation
828 // code does rely on interpreting the texture contents via a SkColorType and
829 // therefore swizzles may be applied during the read step. Ideally we'd
830 // update our validation code to use a "raw" read that doesn't impose a
831 // color type but for now we just munge the data we upload to match the
832 // expectation.
833 GrSwizzle swizzle;
834 switch (combo.fColorType) {
835 case GrColorType::kAlpha_8:
836 swizzle = GrSwizzle("aaaa");
837 break;
838 case GrColorType::kAlpha_16:
839 swizzle = GrSwizzle("aaaa");
840 break;
841 case GrColorType::kAlpha_F16:
842 swizzle = GrSwizzle("aaaa");
843 break;
844 default:
845 break;
846 }
Brian Salomon20f1b342020-12-15 20:23:03 -0500847 auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
848 const SkColor4f& color,
849 GrMipmapped mipmapped,
850 GrRenderable renderable) {
Brian Salomon0f396992020-06-19 19:51:21 -0400851 auto swizzledColor = swizzle.applyTo(color);
Brian Salomon20f1b342020-12-15 20:23:03 -0500852 return ManagedBackendTexture::MakeWithData(dContext,
853 32, 32,
854 format,
855 swizzledColor,
856 mipmapped,
857 renderable,
858 GrProtected::kNo);
Brian Salomon0f396992020-06-19 19:51:21 -0400859 };
Brian Salomon0f396992020-06-19 19:51:21 -0400860 test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
Brian Salomon20f1b342020-12-15 20:23:03 -0500861 combo.fColor, mipMapped, renderable);
Brian Salomon0f396992020-06-19 19:51:21 -0400862 }
Robert Phillips459b2952019-05-23 09:38:27 -0400863 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400864 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400865 }
866 }
867}
868
Robert Phillipsefb9f142019-05-17 14:19:44 -0400869#endif
870
871///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400872
873#ifdef SK_VULKAN
874
875#include "src/gpu/vk/GrVkCaps.h"
876
877DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400878 auto context = ctxInfo.directContext();
Robert Phillips0c6daf02019-05-16 12:43:11 -0400879 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
880
Robert Phillips459b2952019-05-23 09:38:27 -0400881 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400882 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400883
Robert Phillips0c6daf02019-05-16 12:43:11 -0400884 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400885 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400886 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400887 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400888 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400889 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
890 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400891
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400892 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
893 // there is nothing to tell Skia to make the provided color opaque. Clients will need
894 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400895 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
896 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400897
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400898 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400899
Robert Phillips9a30ee02020-04-29 08:58:39 -0400900 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32,
901 { 0.25f, 0.5f, 0.75f, 1.0f }},
902 { GrColorType::kBGRA_1010102, VK_FORMAT_A2R10G10B10_UNORM_PACK32,
903 { 0.25f, 0.5f, 0.75f, 1.0f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400904 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400905
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400906 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
907 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400908
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400909 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400910 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
911 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
912 // the alpha channel of the color). Clients should, in general, fill all the channels
913 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400914 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400915
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400916 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
917 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400918
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400919 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400920 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
921
Robert Phillips429f0d32019-09-11 17:03:28 -0400922 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400923 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400924 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
925 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400926 };
927
928 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -0400929 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400930 continue;
931 }
932
933 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
934
Brian Salomon7e67dca2020-07-21 09:27:25 -0400935 for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
Brian Salomon69100f02020-07-21 10:49:25 -0400936 if (GrMipmapped::kYes == mipMapped && !vkCaps->mipmapSupport()) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400937 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400938 }
939
Robert Phillipsefb9f142019-05-17 14:19:44 -0400940 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400941
Robert Phillipsefb9f142019-05-17 14:19:44 -0400942 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400943 // We must also check whether we allow rendering to the format using the
944 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -0400945 if (!vkCaps->isFormatAsColorTypeRenderable(
946 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400947 continue;
948 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400949 }
950
Robert Phillipsd34691b2019-09-24 13:38:43 -0400951 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400952 auto uninitCreateMtd = [format](GrDirectContext* dContext,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400953 GrMipmapped mipMapped,
Robert Phillips459b2952019-05-23 09:38:27 -0400954 GrRenderable renderable) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500955 auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
956 32, 32,
957 format,
958 mipMapped,
959 renderable,
960 GrProtected::kNo);
961 check_vk_layout(mbet->texture(), VkLayout::kUndefined);
962 return mbet;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400963 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400964
Brian Salomon20f1b342020-12-15 20:23:03 -0500965 test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType, mipMapped,
966 renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400967 }
Robert Phillips459b2952019-05-23 09:38:27 -0400968
Robert Phillips459b2952019-05-23 09:38:27 -0400969 {
Brian Salomonb450f3b2019-07-09 09:36:51 -0400970 // We're creating backend textures without specifying a color type "view" of
971 // them at the public API level. Therefore, Ganesh will not apply any swizzles
972 // before writing the color to the texture. However, our validation code does
973 // rely on interpreting the texture contents via a SkColorType and therefore
974 // swizzles may be applied during the read step.
975 // Ideally we'd update our validation code to use a "raw" read that doesn't
976 // impose a color type but for now we just munge the data we upload to match the
977 // expectation.
978 GrSwizzle swizzle;
979 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400980 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400981 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
982 swizzle = GrSwizzle("aaaa");
983 break;
Robert Phillips429f0d32019-09-11 17:03:28 -0400984 case GrColorType::kAlpha_16:
985 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
986 swizzle = GrSwizzle("aaaa");
987 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -0400988 case GrColorType::kAlpha_F16:
989 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
990 swizzle = GrSwizzle("aaaa");
991 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400992 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400993 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
994 swizzle = GrSwizzle("bgra");
995 }
996 break;
997 default:
998 swizzle = GrSwizzle("rgba");
999 break;
1000 }
Greg Danielc1ad77c2020-05-06 11:40:03 -04001001
Brian Salomon20f1b342020-12-15 20:23:03 -05001002 auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
1003 const SkColor4f& color,
1004 GrMipmapped mipMapped,
1005 GrRenderable renderable) {
Brian Salomonb450f3b2019-07-09 09:36:51 -04001006 auto swizzledColor = swizzle.applyTo(color);
Brian Salomon20f1b342020-12-15 20:23:03 -05001007 auto mbet = ManagedBackendTexture::MakeWithData(dContext,
1008 32, 32,
1009 format,
1010 swizzledColor,
1011 mipMapped,
1012 renderable,
1013 GrProtected::kNo);
1014 check_vk_layout(mbet->texture(), VkLayout::kReadOnlyOptimal);
1015 return mbet;
Robert Phillips459b2952019-05-23 09:38:27 -04001016 };
Brian Salomon20f1b342020-12-15 20:23:03 -05001017 test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
1018 combo.fColor, mipMapped, renderable);
Robert Phillips459b2952019-05-23 09:38:27 -04001019 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001020 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001021 }
1022 }
1023}
1024
1025#endif