blob: 73f91edd46e6999410f593e70faca195132b51aa [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 Salomon04e3e502020-12-16 15:55:25 -0500278 if (!surfaceContext->readPixels(dContext, actual.info(), actual.writable_addr(),
279 actual.rowBytes(), {0, 0})) {
280 // TODO: we need a better way to tell a priori if readPixels will work for an
281 // arbitrary colorType
282#if 0
283 ERRORF(reporter, "Couldn't readback from GrSurfaceContext for colorType: %d\n",
284 colorType);
285#endif
286 } else {
287 auto name = SkStringPrintf("%s::readPixels",
288 (renderableCtx == GrRenderable::kYes ? "GrSurfaceFillContext"
289 : "GrSurfaceContext"));
290 check_solid_pixmap(reporter, expectedColor, actual, colorType, label, name.c_str());
Robert Phillips7f367982019-09-26 14:01:36 -0400291 }
292 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400293}
294
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400295// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400296void test_color_init(GrDirectContext* dContext,
297 skiatest::Reporter* reporter,
Brian Salomon20f1b342020-12-15 20:23:03 -0500298 std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
299 const SkColor4f&,
300 GrMipmapped,
301 GrRenderable)> create,
Brian Salomon04e3e502020-12-16 15:55:25 -0500302 GrColorType colorType,
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400303 const SkColor4f& color,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400304 GrMipmapped mipMapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500305 GrRenderable renderable) {
306 sk_sp<ManagedBackendTexture> mbet = create(dContext, color, mipMapped, renderable);
307 if (!mbet) {
Robert Phillips459b2952019-05-23 09:38:27 -0400308 // errors here should be reported by the test_wrapping test
309 return;
310 }
311
Greg Danielb2365d82020-05-13 15:32:04 -0400312 auto checkBackendTexture = [&](const SkColor4f& testColor) {
Brian Salomon7e67dca2020-07-21 09:27:25 -0400313 if (mipMapped == GrMipmapped::kYes) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500314 SkColor4f expectedColor = get_expected_color(testColor, colorType);
Greg Danielb2365d82020-05-13 15:32:04 -0400315 SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
316 expectedColor, expectedColor, expectedColor};
Brian Salomon20f1b342020-12-15 20:23:03 -0500317 check_mipmaps(dContext, mbet->texture(), colorType, expectedColors, reporter,
318 "colorinit");
Greg Danielb2365d82020-05-13 15:32:04 -0400319 }
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400320
Greg Danielb2365d82020-05-13 15:32:04 -0400321 // The last step in this test will dirty the mipmaps so do it last
Brian Salomon20f1b342020-12-15 20:23:03 -0500322 check_base_readbacks(dContext, mbet->texture(), colorType, renderable, testColor, reporter,
Brian Salomon04e3e502020-12-16 15:55:25 -0500323 "colorinit");
Greg Danielb2365d82020-05-13 15:32:04 -0400324 };
325
326 checkBackendTexture(color);
327
Greg Danielb2365d82020-05-13 15:32:04 -0400328 SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
329
Brian Salomon04e3e502020-12-16 15:55:25 -0500330 SkColorType skColorType = GrColorTypeToSkColorType(colorType);
Brian Salomon04e3e502020-12-16 15:55:25 -0500331 // Our update method only works with SkColorTypes.
332 if (skColorType != kUnknown_SkColorType) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500333 dContext->updateBackendTexture(mbet->texture(),
334 skColorType,
335 newColor,
336 ManagedBackendTexture::ReleaseProc,
337 mbet->releaseContext());
Brian Salomon04e3e502020-12-16 15:55:25 -0500338 checkBackendTexture(newColor);
339 }
Robert Phillips459b2952019-05-23 09:38:27 -0400340}
341
Brian Salomon04e3e502020-12-16 15:55:25 -0500342// Draw the backend texture into an RGBA surface fill context, attempting to access all the mipMap
343// levels.
344static void check_mipmaps(GrDirectContext* dContext,
345 const GrBackendTexture& backendTex,
346 GrColorType colorType,
347 const SkColor4f expectedColors[6],
348 skiatest::Reporter* reporter,
349 const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400350#ifdef SK_GL
351 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400352 if (GrBackendApi::kOpenGL == dContext->backend()) {
353 GrGLGpu* glGPU = static_cast<GrGLGpu*>(dContext->priv().getGpu());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400354
Brian Salomon04e3e502020-12-16 15:55:25 -0500355 if (colorType == GrColorType::kRGBA_F32 &&
356 glGPU->ctxInfo().standard() == kGLES_GrGLStandard) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400357 return;
358 }
359 }
360#endif
361
Robert Phillips7f367982019-09-26 14:01:36 -0400362 if (isRGB(backendTex.getBackendFormat())) {
363 // readPixels is busted for the RGB backend format (skbug.com/8862)
364 // TODO: add a GrColorType::kRGB_888 to fix the situation
365 return;
366 }
367
Brian Salomon04e3e502020-12-16 15:55:25 -0500368 GrImageInfo info(GrColorType::kRGBA_8888, kUnpremul_SkAlphaType, nullptr, {32, 32});
369 auto dstFillContext = GrSurfaceFillContext::Make(dContext, info);
370 if (!dstFillContext) {
371 ERRORF(reporter, "Could not make dst fill context.");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400372 return;
373 }
374
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400375 int numMipLevels = 6;
376
Brian Salomon04e3e502020-12-16 15:55:25 -0500377 auto proxy = dContext->priv().proxyProvider()->wrapBackendTexture(backendTex,
378 kBorrow_GrWrapOwnership,
379 GrWrapCacheable::kNo,
380 kRW_GrIOType);
381 if (!proxy) {
382 ERRORF(reporter, "Could not make proxy from backend texture");
383 return;
384 }
385 auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
386 colorType);
387 GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
388
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400389 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
390 SkASSERT(rectSize >= 1);
Brian Salomon04e3e502020-12-16 15:55:25 -0500391 dstFillContext->clear(SK_PMColor4fTRANSPARENT);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400392
Brian Salomon04e3e502020-12-16 15:55:25 -0500393 SkMatrix texMatrix;
394 texMatrix.setScale(1 << i, 1 << i);
395 static constexpr GrSamplerState kNearestNearest(GrSamplerState::Filter::kNearest,
396 GrSamplerState::MipmapMode::kNearest);
397 auto fp = GrTextureEffect::Make(readView,
398 kUnpremul_SkAlphaType,
399 texMatrix,
400 kNearestNearest,
401 *dstFillContext->caps());
402 // Our swizzles for alpha color types currently produce (a, a, a, a) in the shader. Remove
403 // this once they are correctly (0, 0, 0, a).
404 if (GrColorTypeIsAlphaOnly(colorType)) {
405 auto black = GrConstColorProcessor::Make(SK_PMColor4fBLACK);
406 fp = GrBlendFragmentProcessor::Make(std::move(fp),
407 std::move(black),
408 SkBlendMode::kModulate);
409 }
410 dstFillContext->fillRectWithFP(SkIRect::MakeWH(rectSize, rectSize), std::move(fp));
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400411
412 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
413 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400414 kUnpremul_SkAlphaType);
Brian Salomon04e3e502020-12-16 15:55:25 -0500415 SkAutoPixmapStorage actual;
416 SkAssertResult(actual.tryAlloc(readbackII));
417 actual.erase(SkColors::kTransparent);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400418
Brian Salomon04e3e502020-12-16 15:55:25 -0500419 bool result = dstFillContext->readPixels(dContext,
420 actual.info(),
421 actual.writable_addr(),
422 actual.rowBytes(),
423 {0, 0});
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400424 REPORTER_ASSERT(reporter, result);
425
Robert Phillipsee946932019-12-18 11:16:17 -0500426 SkString str;
427 str.appendf("mip-level %d", i);
428
Brian Salomon04e3e502020-12-16 15:55:25 -0500429 check_solid_pixmap(reporter, expectedColors[i], actual, colorType, label, str.c_str());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400430 }
431}
432
Brian Salomon7e67dca2020-07-21 09:27:25 -0400433static int make_pixmaps(SkColorType skColorType, GrMipmapped mipMapped,
Robert Phillips7f367982019-09-26 14:01:36 -0400434 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
435 int levelSize = 32;
Brian Salomon7e67dca2020-07-21 09:27:25 -0400436 int numMipLevels = mipMapped == GrMipmapped::kYes ? 6 : 1;
Robert Phillips7f367982019-09-26 14:01:36 -0400437 for (int level = 0; level < numMipLevels; ++level) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500438 SkImageInfo ii = SkImageInfo::Make(levelSize,
439 levelSize,
440 skColorType,
441 kUnpremul_SkAlphaType);
Robert Phillips7f367982019-09-26 14:01:36 -0400442 pixmaps[level].alloc(ii);
443 pixmaps[level].erase(colors[level]);
444 levelSize /= 2;
445 }
446 return numMipLevels;
447}
448
449// Test initialization of GrBackendObjects using SkPixmaps
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400450static void test_pixmap_init(GrDirectContext* dContext,
451 skiatest::Reporter* reporter,
Brian Salomon20f1b342020-12-15 20:23:03 -0500452 std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
453 const SkPixmap srcData[],
454 int numLevels,
455 GrSurfaceOrigin,
456 GrRenderable)> create,
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400457 SkColorType skColorType,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500458 GrSurfaceOrigin origin,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400459 GrMipmapped mipMapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500460 GrRenderable renderable) {
Robert Phillips7f367982019-09-26 14:01:36 -0400461 SkAutoPixmapStorage pixmapMem[6];
462 SkColor4f colors[6] = {
463 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
464 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
465 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
466 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
467 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
468 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
469 };
470
471 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
472 SkASSERT(numMipLevels);
473
474 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
475 SkPixmap pixmaps[6];
476 for (int i = 0; i < numMipLevels; ++i) {
477 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
478 }
479
Brian Salomon20f1b342020-12-15 20:23:03 -0500480 sk_sp<ManagedBackendTexture> mbet = create(dContext, pixmaps, numMipLevels, origin, renderable);
481 if (!mbet) {
Robert Phillips7f367982019-09-26 14:01:36 -0400482 // errors here should be reported by the test_wrapping test
483 return;
484 }
485
Brian Salomon20f1b342020-12-15 20:23:03 -0500486 if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(mbet->texture().getBackendFormat())) {
Robert Phillips7f367982019-09-26 14:01:36 -0400487 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
488 return;
489 }
490
Greg Danielb2365d82020-05-13 15:32:04 -0400491 auto checkBackendTexture = [&](SkColor4f colors[6]) {
Brian Salomon04e3e502020-12-16 15:55:25 -0500492 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
Brian Salomon7e67dca2020-07-21 09:27:25 -0400493 if (mipMapped == GrMipmapped::kYes) {
Greg Danielb2365d82020-05-13 15:32:04 -0400494 SkColor4f expectedColors[6] = {
Brian Salomon04e3e502020-12-16 15:55:25 -0500495 get_expected_color(colors[0], grColorType),
496 get_expected_color(colors[1], grColorType),
497 get_expected_color(colors[2], grColorType),
498 get_expected_color(colors[3], grColorType),
499 get_expected_color(colors[4], grColorType),
500 get_expected_color(colors[5], grColorType),
Greg Danielb2365d82020-05-13 15:32:04 -0400501 };
Robert Phillips7f367982019-09-26 14:01:36 -0400502
Brian Salomon20f1b342020-12-15 20:23:03 -0500503 check_mipmaps(dContext, mbet->texture(), grColorType, expectedColors, reporter,
504 "pixmap");
Greg Danielb2365d82020-05-13 15:32:04 -0400505 }
506
507 // The last step in this test will dirty the mipmaps so do it last
Brian Salomon20f1b342020-12-15 20:23:03 -0500508 check_base_readbacks(dContext, mbet->texture(), grColorType, renderable, colors[0],
509 reporter, "pixmap");
Greg Danielb2365d82020-05-13 15:32:04 -0400510 };
511
512 checkBackendTexture(colors);
513
Greg Danielb2365d82020-05-13 15:32:04 -0400514 SkColor4f colorsNew[6] = {
515 {1.0f, 1.0f, 0.0f, 0.2f}, // Y
516 {1.0f, 0.0f, 0.0f, 1.0f}, // R
517 {0.0f, 1.0f, 0.0f, 0.9f}, // G
518 {0.0f, 0.0f, 1.0f, 0.7f}, // B
519 {0.0f, 1.0f, 1.0f, 0.5f}, // C
520 {1.0f, 0.0f, 1.0f, 0.3f}, // M
521 };
522 make_pixmaps(skColorType, mipMapped, colorsNew, pixmapMem);
523 for (int i = 0; i < numMipLevels; ++i) {
524 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
Robert Phillips7f367982019-09-26 14:01:36 -0400525 }
526
Greg Danielb2365d82020-05-13 15:32:04 -0400527 // Upload new data and make sure everything still works
Brian Salomon20f1b342020-12-15 20:23:03 -0500528 dContext->updateBackendTexture(mbet->texture(),
529 pixmaps,
530 numMipLevels,
531 origin,
532 ManagedBackendTexture::ReleaseProc,
533 mbet->releaseContext());
Greg Danielb2365d82020-05-13 15:32:04 -0400534
535 checkBackendTexture(colorsNew);
Robert Phillips7f367982019-09-26 14:01:36 -0400536}
537
Robert Phillips02dc0302019-07-02 17:58:27 -0400538enum class VkLayout {
539 kUndefined,
540 kReadOnlyOptimal,
Robert Phillips02dc0302019-07-02 17:58:27 -0400541};
542
543void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
544#if defined(SK_VULKAN) && defined(SK_DEBUG)
545 VkImageLayout expected;
546
547 switch (layout) {
548 case VkLayout::kUndefined:
549 expected = VK_IMAGE_LAYOUT_UNDEFINED;
550 break;
551 case VkLayout::kReadOnlyOptimal:
552 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
553 break;
Robert Phillips02dc0302019-07-02 17:58:27 -0400554 default:
555 SkUNREACHABLE;
556 }
557
558 GrVkImageInfo vkII;
559
560 if (backendTex.getVkImageInfo(&vkII)) {
561 SkASSERT(expected == vkII.fImageLayout);
562 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
563 }
564#endif
565}
566
567///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400568DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400569 auto context = ctxInfo.directContext();
Robert Phillips0c6daf02019-05-16 12:43:11 -0400570 const GrCaps* caps = context->priv().caps();
571
Robert Phillips459b2952019-05-23 09:38:27 -0400572 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400573 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400574
Robert Phillips0c6daf02019-05-16 12:43:11 -0400575 struct {
576 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400577 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400578 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400579 { kAlpha_8_SkColorType, kTransCol },
580 { kRGB_565_SkColorType, SkColors::kRed },
581 { kARGB_4444_SkColorType, SkColors::kGreen },
582 { kRGBA_8888_SkColorType, SkColors::kBlue },
583 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400584 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400585 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips9a30ee02020-04-29 08:58:39 -0400586 // TODO: readback is busted for *10A2 when alpha = 0.5f (perhaps premul vs. unpremul)
587 { kRGBA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
588 { kBGRA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
589 // RGB/BGR 101010x have no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400590 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Mike Kleinf7eb0542020-02-11 12:19:08 -0600591 { kBGR_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400592 { kGray_8_SkColorType, kGrayCol },
593 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
594 { kRGBA_F16_SkColorType, SkColors::kYellow },
595 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400596 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400597 { kR16G16_unorm_SkColorType, SkColors::kGreen },
598 { kA16_unorm_SkColorType, kTransCol },
599 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400600 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400601 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400602 };
603
Brian Salomon4dea72a2019-12-18 10:43:10 -0500604 static_assert(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400605
606 for (auto combo : combinations) {
607 SkColorType colorType = combo.fColorType;
608
Robert Phillips0c6daf02019-05-16 12:43:11 -0400609 if (GrBackendApi::kMetal == context->backend()) {
610 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
611 if (kRGBA_F32_SkColorType == combo.fColorType) {
612 continue;
613 }
614 }
615
Brian Salomon04e3e502020-12-16 15:55:25 -0500616 for (auto mipmapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
617 if (GrMipmapped::kYes == mipmapped && !caps->mipmapSupport()) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400618 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400619 }
620
Robert Phillipsefb9f142019-05-17 14:19:44 -0400621 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400622 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
623 renderable).isValid()) {
624 continue;
625 }
Robert Phillips7f367982019-09-26 14:01:36 -0400626
Robert Phillipsefb9f142019-05-17 14:19:44 -0400627 if (GrRenderable::kYes == renderable) {
628 if (kRGB_888x_SkColorType == combo.fColorType) {
629 // Ganesh can't perform the blends correctly when rendering this format
630 continue;
631 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400632 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400633
Robert Phillipsb04b6942019-05-21 17:24:31 -0400634 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400635 auto uninitCreateMtd = [colorType](GrDirectContext* dContext,
Brian Salomon04e3e502020-12-16 15:55:25 -0500636 GrMipmapped mipmapped,
Robert Phillipsb04b6942019-05-21 17:24:31 -0400637 GrRenderable renderable) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500638 auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
639 32, 32,
640 colorType,
641 mipmapped,
642 renderable,
643 GrProtected::kNo);
644 check_vk_layout(mbet->texture(), VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400645#ifdef SK_DEBUG
646 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400647 GrBackendFormat format = dContext->defaultBackendFormat(colorType,
648 renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500649 SkASSERT(format == mbet->texture().getBackendFormat());
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400650 }
651#endif
652
Brian Salomon20f1b342020-12-15 20:23:03 -0500653 return mbet;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400654 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400655
Robert Phillipsb04b6942019-05-21 17:24:31 -0400656 test_wrapping(context, reporter, uninitCreateMtd,
Brian Salomon20f1b342020-12-15 20:23:03 -0500657 SkColorTypeToGrColorType(colorType), mipmapped, renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400658 }
Robert Phillips459b2952019-05-23 09:38:27 -0400659
660 {
Brian Salomon20f1b342020-12-15 20:23:03 -0500661 auto createWithColorMtd = [colorType](GrDirectContext* dContext,
662 const SkColor4f& color,
663 GrMipmapped mipmapped,
664 GrRenderable renderable) {
665 auto mbet = ManagedBackendTexture::MakeWithData(dContext,
666 32, 32,
667 colorType,
668 color,
669 mipmapped,
670 renderable,
671 GrProtected::kNo);
672 check_vk_layout(mbet->texture(), VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400673
674#ifdef SK_DEBUG
675 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400676 GrBackendFormat format = dContext->defaultBackendFormat(colorType,
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400677 renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500678 SkASSERT(format == mbet->texture().getBackendFormat());
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400679 }
680#endif
681
Brian Salomon20f1b342020-12-15 20:23:03 -0500682 return mbet;
Robert Phillips459b2952019-05-23 09:38:27 -0400683 };
Robert Phillips459b2952019-05-23 09:38:27 -0400684 test_color_init(context, reporter, createWithColorMtd,
Brian Salomon04e3e502020-12-16 15:55:25 -0500685 SkColorTypeToGrColorType(colorType), combo.fColor, mipmapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500686 renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400687 }
Robert Phillips7f367982019-09-26 14:01:36 -0400688
Brian Salomonb5f880a2020-12-07 11:30:16 -0500689 for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500690 auto createWithSrcDataMtd = [](GrDirectContext* dContext,
691 const SkPixmap srcData[],
692 int numLevels,
693 GrSurfaceOrigin origin,
694 GrRenderable renderable) {
Robert Phillips9a30ee02020-04-29 08:58:39 -0400695 SkASSERT(srcData && numLevels);
Brian Salomon20f1b342020-12-15 20:23:03 -0500696 auto mbet = ManagedBackendTexture::MakeWithData(dContext,
697 srcData,
698 numLevels,
699 origin,
700 renderable,
701 GrProtected::kNo);
702 check_vk_layout(mbet->texture(), VkLayout::kReadOnlyOptimal);
Robert Phillips7f367982019-09-26 14:01:36 -0400703#ifdef SK_DEBUG
Robert Phillips9a30ee02020-04-29 08:58:39 -0400704 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400705 auto format = dContext->defaultBackendFormat(srcData[0].colorType(),
706 renderable);
Brian Salomon20f1b342020-12-15 20:23:03 -0500707 SkASSERT(format == mbet->texture().getBackendFormat());
Robert Phillips9a30ee02020-04-29 08:58:39 -0400708 }
Robert Phillips7f367982019-09-26 14:01:36 -0400709#endif
Brian Salomon20f1b342020-12-15 20:23:03 -0500710 return mbet;
Robert Phillips9a30ee02020-04-29 08:58:39 -0400711 };
Robert Phillips7f367982019-09-26 14:01:36 -0400712
Brian Salomonb5f880a2020-12-07 11:30:16 -0500713 test_pixmap_init(context,
714 reporter,
715 createWithSrcDataMtd,
716 colorType,
717 origin,
Brian Salomon04e3e502020-12-16 15:55:25 -0500718 mipmapped,
Brian Salomon20f1b342020-12-15 20:23:03 -0500719 renderable);
Robert Phillips9a30ee02020-04-29 08:58:39 -0400720 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400721 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400722 }
723 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400724}
725
Robert Phillipsefb9f142019-05-17 14:19:44 -0400726///////////////////////////////////////////////////////////////////////////////
727#ifdef SK_GL
728
Robert Phillips0c6daf02019-05-16 12:43:11 -0400729DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
730 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
731 GrGLStandard standard = glCtx->gl()->fStandard;
Robert Phillips6d344c32020-07-06 10:56:46 -0400732 auto context = ctxInfo.directContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400733 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400734
Robert Phillips459b2952019-05-23 09:38:27 -0400735 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400736 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400737
Robert Phillips0c6daf02019-05-16 12:43:11 -0400738 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400739 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400740 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400741 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400742 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400743 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
744 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400745
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400746 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
747 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400748
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400749 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
750 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
751 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillips9a30ee02020-04-29 08:58:39 -0400752 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
753 { GrColorType::kBGRA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400754 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
755 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400756
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400757 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
758 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400759
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400760 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
761 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400762
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400763 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400764
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400765 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
766 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400767
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400768 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400769 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
770 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400771
Robert Phillips429f0d32019-09-11 17:03:28 -0400772 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400773 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400774
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400775 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
776 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400777 };
778
779 for (auto combo : combinations) {
Brian Salomon0f396992020-06-19 19:51:21 -0400780 for (GrGLenum target : {GR_GL_TEXTURE_2D, GR_GL_TEXTURE_RECTANGLE}) {
781 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, target);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400782
Brian Salomon0f396992020-06-19 19:51:21 -0400783 if (!glCaps->isFormatTexturable(format)) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400784 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400785 }
786
Brian Salomon0f396992020-06-19 19:51:21 -0400787 if (GrColorType::kBGRA_8888 == combo.fColorType ||
788 GrColorType::kBGRA_1010102 == combo.fColorType) {
789 // We allow using a GL_RGBA8 or GR_GL_RGB10_A2 texture as BGRA on desktop GL but not
790 // ES
791 if (kGL_GrGLStandard != standard &&
792 (GR_GL_RGBA8 == combo.fFormat || GR_GL_RGB10_A2 == combo.fFormat)) {
793 continue;
794 }
795 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400796
Brian Salomon7e67dca2020-07-21 09:27:25 -0400797 for (auto mipMapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
798 if (GrMipmapped::kYes == mipMapped &&
Brian Salomon69100f02020-07-21 10:49:25 -0400799 (!glCaps->mipmapSupport() || target == GR_GL_TEXTURE_RECTANGLE)) {
Brian Salomon0f396992020-06-19 19:51:21 -0400800 continue;
Robert Phillipsefb9f142019-05-17 14:19:44 -0400801 }
802
Brian Salomon0f396992020-06-19 19:51:21 -0400803 for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
804 if (GrRenderable::kYes == renderable) {
805 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
806 continue;
807 }
Robert Phillips459b2952019-05-23 09:38:27 -0400808 }
809
Brian Salomon0f396992020-06-19 19:51:21 -0400810 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400811 auto uninitCreateMtd = [format](GrDirectContext* dContext,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400812 GrMipmapped mipMapped,
Brian Salomon0f396992020-06-19 19:51:21 -0400813 GrRenderable renderable) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500814 return ManagedBackendTexture::MakeWithoutData(dContext,
815 32, 32,
816 format,
817 mipMapped,
818 renderable,
819 GrProtected::kNo);
Brian Salomon0f396992020-06-19 19:51:21 -0400820 };
Greg Danielc1ad77c2020-05-06 11:40:03 -0400821
Brian Salomon0f396992020-06-19 19:51:21 -0400822 test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType,
Brian Salomon20f1b342020-12-15 20:23:03 -0500823 mipMapped, renderable);
Brian Salomon85c3d682019-11-04 15:04:54 -0500824 }
Robert Phillips459b2952019-05-23 09:38:27 -0400825
Brian Salomon0f396992020-06-19 19:51:21 -0400826 {
827 // We're creating backend textures without specifying a color type "view" of
828 // them at the public API level. Therefore, Ganesh will not apply any
829 // swizzles before writing the color to the texture. However, our validation
830 // code does rely on interpreting the texture contents via a SkColorType and
831 // therefore swizzles may be applied during the read step. Ideally we'd
832 // update our validation code to use a "raw" read that doesn't impose a
833 // color type but for now we just munge the data we upload to match the
834 // expectation.
835 GrSwizzle swizzle;
836 switch (combo.fColorType) {
837 case GrColorType::kAlpha_8:
838 swizzle = GrSwizzle("aaaa");
839 break;
840 case GrColorType::kAlpha_16:
841 swizzle = GrSwizzle("aaaa");
842 break;
843 case GrColorType::kAlpha_F16:
844 swizzle = GrSwizzle("aaaa");
845 break;
846 default:
847 break;
848 }
Brian Salomon20f1b342020-12-15 20:23:03 -0500849 auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
850 const SkColor4f& color,
851 GrMipmapped mipmapped,
852 GrRenderable renderable) {
Brian Salomon0f396992020-06-19 19:51:21 -0400853 auto swizzledColor = swizzle.applyTo(color);
Brian Salomon20f1b342020-12-15 20:23:03 -0500854 return ManagedBackendTexture::MakeWithData(dContext,
855 32, 32,
856 format,
857 swizzledColor,
858 mipmapped,
859 renderable,
860 GrProtected::kNo);
Brian Salomon0f396992020-06-19 19:51:21 -0400861 };
Brian Salomon0f396992020-06-19 19:51:21 -0400862 test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
Brian Salomon20f1b342020-12-15 20:23:03 -0500863 combo.fColor, mipMapped, renderable);
Brian Salomon0f396992020-06-19 19:51:21 -0400864 }
Robert Phillips459b2952019-05-23 09:38:27 -0400865 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400866 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400867 }
868 }
869}
870
Robert Phillipsefb9f142019-05-17 14:19:44 -0400871#endif
872
873///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400874
875#ifdef SK_VULKAN
876
877#include "src/gpu/vk/GrVkCaps.h"
878
879DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400880 auto context = ctxInfo.directContext();
Robert Phillips0c6daf02019-05-16 12:43:11 -0400881 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
882
Robert Phillips459b2952019-05-23 09:38:27 -0400883 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400884 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400885
Robert Phillips0c6daf02019-05-16 12:43:11 -0400886 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400887 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400888 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400889 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400890 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400891 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
892 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400893
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400894 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
895 // there is nothing to tell Skia to make the provided color opaque. Clients will need
896 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400897 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
898 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400899
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400900 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400901
Robert Phillips9a30ee02020-04-29 08:58:39 -0400902 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32,
903 { 0.25f, 0.5f, 0.75f, 1.0f }},
904 { GrColorType::kBGRA_1010102, VK_FORMAT_A2R10G10B10_UNORM_PACK32,
905 { 0.25f, 0.5f, 0.75f, 1.0f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400906 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400907
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400908 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
909 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400910
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400911 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400912 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
913 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
914 // the alpha channel of the color). Clients should, in general, fill all the channels
915 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400916 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400917
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400918 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
919 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400920
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400921 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400922 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
923
Robert Phillips429f0d32019-09-11 17:03:28 -0400924 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400925 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400926 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
927 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400928 };
929
930 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -0400931 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400932 continue;
933 }
934
935 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
936
Brian Salomon7e67dca2020-07-21 09:27:25 -0400937 for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
Brian Salomon69100f02020-07-21 10:49:25 -0400938 if (GrMipmapped::kYes == mipMapped && !vkCaps->mipmapSupport()) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400939 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400940 }
941
Robert Phillipsefb9f142019-05-17 14:19:44 -0400942 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400943
Robert Phillipsefb9f142019-05-17 14:19:44 -0400944 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400945 // We must also check whether we allow rendering to the format using the
946 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -0400947 if (!vkCaps->isFormatAsColorTypeRenderable(
948 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400949 continue;
950 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400951 }
952
Robert Phillipsd34691b2019-09-24 13:38:43 -0400953 {
Robert Phillipsfe4b4812020-07-17 14:15:51 -0400954 auto uninitCreateMtd = [format](GrDirectContext* dContext,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400955 GrMipmapped mipMapped,
Robert Phillips459b2952019-05-23 09:38:27 -0400956 GrRenderable renderable) {
Brian Salomon20f1b342020-12-15 20:23:03 -0500957 auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
958 32, 32,
959 format,
960 mipMapped,
961 renderable,
962 GrProtected::kNo);
963 check_vk_layout(mbet->texture(), VkLayout::kUndefined);
964 return mbet;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400965 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400966
Brian Salomon20f1b342020-12-15 20:23:03 -0500967 test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType, mipMapped,
968 renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400969 }
Robert Phillips459b2952019-05-23 09:38:27 -0400970
Robert Phillips459b2952019-05-23 09:38:27 -0400971 {
Brian Salomonb450f3b2019-07-09 09:36:51 -0400972 // We're creating backend textures without specifying a color type "view" of
973 // them at the public API level. Therefore, Ganesh will not apply any swizzles
974 // before writing the color to the texture. However, our validation code does
975 // rely on interpreting the texture contents via a SkColorType and therefore
976 // swizzles may be applied during the read step.
977 // Ideally we'd update our validation code to use a "raw" read that doesn't
978 // impose a color type but for now we just munge the data we upload to match the
979 // expectation.
980 GrSwizzle swizzle;
981 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400982 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400983 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
984 swizzle = GrSwizzle("aaaa");
985 break;
Robert Phillips429f0d32019-09-11 17:03:28 -0400986 case GrColorType::kAlpha_16:
987 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
988 swizzle = GrSwizzle("aaaa");
989 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -0400990 case GrColorType::kAlpha_F16:
991 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
992 swizzle = GrSwizzle("aaaa");
993 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400994 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400995 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
996 swizzle = GrSwizzle("bgra");
997 }
998 break;
999 default:
1000 swizzle = GrSwizzle("rgba");
1001 break;
1002 }
Greg Danielc1ad77c2020-05-06 11:40:03 -04001003
Brian Salomon20f1b342020-12-15 20:23:03 -05001004 auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
1005 const SkColor4f& color,
1006 GrMipmapped mipMapped,
1007 GrRenderable renderable) {
Brian Salomonb450f3b2019-07-09 09:36:51 -04001008 auto swizzledColor = swizzle.applyTo(color);
Brian Salomon20f1b342020-12-15 20:23:03 -05001009 auto mbet = ManagedBackendTexture::MakeWithData(dContext,
1010 32, 32,
1011 format,
1012 swizzledColor,
1013 mipMapped,
1014 renderable,
1015 GrProtected::kNo);
1016 check_vk_layout(mbet->texture(), VkLayout::kReadOnlyOptimal);
1017 return mbet;
Robert Phillips459b2952019-05-23 09:38:27 -04001018 };
Brian Salomon20f1b342020-12-15 20:23:03 -05001019 test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
1020 combo.fColor, mipMapped, renderable);
Robert Phillips459b2952019-05-23 09:38:27 -04001021 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001022 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001023 }
1024 }
1025}
1026
1027#endif