Flutter Engine
The Flutter Engine
Functions
MtlBackendAllocationTest.mm File Reference
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/mtl/GrMtlCaps.h"
#include "tests/Test.h"
#include "tools/gpu/ManagedBackendTexture.h"
#import <Metal/Metal.h>

Go to the source code of this file.

Functions

void test_wrapping (GrDirectContext *, skiatest::Reporter *, const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, skgpu::Mipmapped, GrRenderable)> &create, GrColorType, skgpu::Mipmapped, GrRenderable)
 
void test_color_init (GrDirectContext *, skiatest::Reporter *, const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, const SkColor4f &, skgpu::Mipmapped, GrRenderable)> &create, GrColorType, const SkColor4f &, skgpu::Mipmapped, GrRenderable)
 
void test_pixmap_init (GrDirectContext *, skiatest::Reporter *, const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, const SkPixmap srcData[], int numLevels, GrSurfaceOrigin, GrRenderable)> &create, SkColorType, GrSurfaceOrigin, skgpu::Mipmapped, GrRenderable)
 
 DEF_GANESH_TEST_FOR_METAL_CONTEXT (MtlBackendAllocationTest, reporter, ctxInfo)
 

Function Documentation

◆ DEF_GANESH_TEST_FOR_METAL_CONTEXT()

DEF_GANESH_TEST_FOR_METAL_CONTEXT ( MtlBackendAllocationTest  ,
reporter  ,
ctxInfo   
)

Definition at line 50 of file MtlBackendAllocationTest.mm.

50 {
51 auto dContext = ctxInfo.directContext();
52 const GrMtlCaps* mtlCaps = static_cast<const GrMtlCaps*>(dContext->priv().caps());
53
54 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
55 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
56
57 struct {
59 MTLPixelFormat fFormat;
60 SkColor4f fColor;
61 } combinations[] = {
62 { GrColorType::kRGBA_8888, MTLPixelFormatRGBA8Unorm, SkColors::kRed },
63 { GrColorType::kRGBA_8888_SRGB, MTLPixelFormatRGBA8Unorm_sRGB, SkColors::kRed },
64
65 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
66 // there is nothing to tell Skia to make the provided color opaque. Clients will need
67 // to provide an opaque initialization color in this case.
68 { GrColorType::kRGB_888x, MTLPixelFormatRGBA8Unorm, SkColors::kYellow },
69
70 { GrColorType::kBGRA_8888, MTLPixelFormatBGRA8Unorm, SkColors::kBlue },
71
72 { GrColorType::kRGBA_1010102, MTLPixelFormatRGB10A2Unorm,
73 { 0.25f, 0.5f, 0.75f, 1.0f } },
74#ifdef SK_BUILD_FOR_MAC
75 { GrColorType::kBGRA_1010102, MTLPixelFormatBGR10A2Unorm,
76 { 0.25f, 0.5f, 0.75f, 1.0f } },
77#endif
78#ifdef SK_BUILD_FOR_IOS
79 { GrColorType::kBGR_565, MTLPixelFormatB5G6R5Unorm, SkColors::kRed },
80 { GrColorType::kABGR_4444, MTLPixelFormatABGR4Unorm, SkColors::kGreen },
81#endif
82
83 { GrColorType::kAlpha_8, MTLPixelFormatA8Unorm, kTransCol },
84 { GrColorType::kAlpha_8, MTLPixelFormatR8Unorm, kTransCol },
85 { GrColorType::kGray_8, MTLPixelFormatR8Unorm, kGrayCol },
86
87 { GrColorType::kRGBA_F16_Clamped, MTLPixelFormatRGBA16Float, SkColors::kLtGray },
88 { GrColorType::kRGBA_F16, MTLPixelFormatRGBA16Float, SkColors::kYellow },
89
90 { GrColorType::kRG_88, MTLPixelFormatRG8Unorm, { 0.5f, 0.5f, 0, 1 } },
91 { GrColorType::kAlpha_F16, MTLPixelFormatR16Float, { 1.0f, 0, 0, 0.5f } },
92
93 { GrColorType::kAlpha_16, MTLPixelFormatR16Unorm, kTransCol },
94 { GrColorType::kRG_1616, MTLPixelFormatRG16Unorm, SkColors::kYellow },
95
96 { GrColorType::kRGBA_16161616, MTLPixelFormatRGBA16Unorm, SkColors::kLtGray },
97 { GrColorType::kRG_F16, MTLPixelFormatRG16Float, SkColors::kYellow },
98 };
99
100 for (auto combo : combinations) {
102
103 if (!mtlCaps->isFormatTexturable(combo.fFormat)) {
104 continue;
105 }
106
107 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
108 if (GrColorType::kRGBA_F32 == combo.fColorType) {
109 continue;
110 }
111
112 for (auto mipmapped : {skgpu::Mipmapped::kNo, skgpu::Mipmapped::kYes}) {
113 if (skgpu::Mipmapped::kYes == mipmapped && !mtlCaps->mipmapSupport()) {
114 continue;
115 }
116
117 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
118
119 if (GrRenderable::kYes == renderable) {
120 // We must also check whether we allow rendering to the format using the
121 // color type.
122 if (!mtlCaps->isFormatAsColorTypeRenderable(
123 combo.fColorType, GrBackendFormats::MakeMtl(combo.fFormat), 1)) {
124 continue;
125 }
126 }
127
128 {
129 auto uninitCreateMtd = [format](GrDirectContext* dContext,
130 skgpu::Mipmapped mipmapped,
131 GrRenderable renderable) {
132 return ManagedBackendTexture::MakeWithoutData(dContext,
133 32, 32,
134 format,
135 mipmapped,
136 renderable,
138 };
139
140 test_wrapping(dContext, reporter, uninitCreateMtd, combo.fColorType, mipmapped,
141 renderable);
142 }
143
144 {
145 // We're creating backend textures without specifying a color type "view" of
146 // them at the public API level. Therefore, Ganesh will not apply any swizzles
147 // before writing the color to the texture. However, our validation code does
148 // rely on interpreting the texture contents via a SkColorType and therefore
149 // swizzles may be applied during the read step.
150 // Ideally we'd update our validation code to use a "raw" read that doesn't
151 // impose a color type but for now we just munge the data we upload to match the
152 // expectation.
153 skgpu::Swizzle swizzle;
154 switch (combo.fColorType) {
156 swizzle = skgpu::Swizzle("aaaa");
157 break;
159 swizzle = skgpu::Swizzle("aaaa");
160 break;
162 swizzle = skgpu::Swizzle("aaaa");
163 break;
164 default:
165 break;
166 }
167
168 auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
169 const SkColor4f& color,
170 skgpu::Mipmapped mipmapped,
171 GrRenderable renderable) {
172 auto swizzledColor = swizzle.applyTo(color);
174 32, 32,
175 format,
176 swizzledColor,
177 mipmapped,
178 renderable,
180 };
181 test_color_init(dContext, reporter, createWithColorMtd, combo.fColorType,
182 combo.fColor, mipmapped, renderable);
183 }
184
186 SkColorType skColorType = GrColorTypeToSkColorType(combo.fColorType);
187 if (skColorType == kUnknown_SkColorType) {
188 break;
189 }
190
191 auto createWithSrcDataMtd = [](GrDirectContext* dContext,
192 const SkPixmap srcData[],
193 int numLevels,
194 GrSurfaceOrigin origin,
195 GrRenderable renderable) {
196 SkASSERT(srcData && numLevels);
198 srcData,
199 numLevels,
200 origin,
201 renderable,
203 };
204
205 test_pixmap_init(dContext,
206 reporter,
207 createWithSrcDataMtd,
208 skColorType,
209 origin,
210 mipmapped,
211 renderable);
212
213 }
214 }
215 }
216 }
217}
reporter
Definition: FontMgrTest.cpp:39
static constexpr SkColorType GrColorTypeToSkColorType(GrColorType ct)
Definition: GrTypesPriv.h:589
GrColorType
Definition: GrTypesPriv.h:540
GrSurfaceOrigin
Definition: GrTypes.h:147
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
void test_wrapping(GrDirectContext *, skiatest::Reporter *, const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, skgpu::Mipmapped, GrRenderable)> &create, GrColorType, skgpu::Mipmapped, GrRenderable)
void test_color_init(GrDirectContext *, skiatest::Reporter *, const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, const SkColor4f &, skgpu::Mipmapped, GrRenderable)> &create, GrColorType, const SkColor4f &, skgpu::Mipmapped, GrRenderable)
void test_pixmap_init(GrDirectContext *, skiatest::Reporter *, const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, const SkPixmap srcData[], int numLevels, GrSurfaceOrigin, GrRenderable)> &create, SkColorType, GrSurfaceOrigin, skgpu::Mipmapped, GrRenderable)
SkColorType fColorType
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
bool mipmapSupport() const
Definition: GrCaps.h:72
bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat &format, int sampleCount=1) const override
Definition: GrMtlCaps.mm:476
bool isFormatTexturable(const GrBackendFormat &, GrTextureType) const override
Definition: GrMtlCaps.mm:466
constexpr std::array< float, 4 > applyTo(std::array< float, 4 > color) const
Definition: Swizzle.h:101
DlColor color
uint32_t uint32_t * format
SK_API GrBackendFormat MakeMtl(GrMTLPixelFormat format)
constexpr SkColor4f kLtGray
Definition: SkColor.h:438
constexpr SkColor4f kGreen
Definition: SkColor.h:441
constexpr SkColor4f kRed
Definition: SkColor.h:440
constexpr SkColor4f kBlue
Definition: SkColor.h:442
constexpr SkColor4f kYellow
Definition: SkColor.h:443
SK_API sk_sp< SkPixelRef > MakeWithData(const SkImageInfo &, size_t rowBytes, sk_sp< SkData > data)
Renderable
Definition: GpuTypes.h:69
Mipmapped
Definition: GpuTypes.h:53

◆ test_color_init()

void test_color_init ( GrDirectContext dContext,
skiatest::Reporter reporter,
const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, const SkColor4f &, skgpu::Mipmapped, GrRenderable)> &  create,
GrColorType  colorType,
const SkColor4f color,
skgpu::Mipmapped  mipmapped,
GrRenderable  renderable 
)

Definition at line 368 of file BackendAllocationTest.cpp.

376 {
377 sk_sp<ManagedBackendTexture> mbet = create(dContext, color, mipmapped, renderable);
378 if (!mbet) {
379 // errors here should be reported by the test_wrapping test
380 return;
381 }
382
383 auto checkBackendTexture = [&](const SkColor4f& testColor) {
384 if (mipmapped == skgpu::Mipmapped::kYes) {
385 SkColor4f expectedColor = get_expected_color(testColor, colorType);
386 SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
387 expectedColor, expectedColor, expectedColor};
388 check_mipmaps(dContext, mbet->texture(), colorType, expectedColors, reporter,
389 "colorinit");
390 }
391
392 // The last step in this test will dirty the mipmaps so do it last
393 check_base_readbacks(dContext, mbet->texture(), colorType, renderable, testColor, reporter,
394 "colorinit");
395 };
396
397 checkBackendTexture(color);
398
399 SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
400
402 // Our update method only works with SkColorTypes.
403 if (skColorType != kUnknown_SkColorType) {
404 dContext->updateBackendTexture(mbet->texture(),
405 skColorType,
406 newColor,
407 ManagedBackendTexture::ReleaseProc,
408 mbet->releaseContext());
409 checkBackendTexture(newColor);
410 }
411}
static SkColor4f get_expected_color(SkColor4f orig, GrColorType ct)
static void check_base_readbacks(GrDirectContext *dContext, const GrBackendTexture &backendTex, GrColorType colorType, GrRenderable renderableTexture, const SkColor4f &color, skiatest::Reporter *reporter, const char *label)
static void check_mipmaps(GrDirectContext *, const GrBackendTexture &, GrColorType, const SkColor4f expectedColors[6], skiatest::Reporter *, const char *label)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
bool updateBackendTexture(const GrBackendTexture &, const SkColor4f &color, GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext)
int_closure create

◆ test_pixmap_init()

void test_pixmap_init ( GrDirectContext dContext,
skiatest::Reporter reporter,
const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, const SkPixmap srcData[], int numLevels, GrSurfaceOrigin, GrRenderable)> &  create,
SkColorType  skColorType,
GrSurfaceOrigin  origin,
skgpu::Mipmapped  mipmapped,
GrRenderable  renderable 
)

Definition at line 493 of file BackendAllocationTest.cpp.

503 {
504 SkPixmap pixmaps[6];
505 std::unique_ptr<char[]> memForPixmaps;
506 constexpr SkColor4f kColors[6] = {
507 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
508 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
509 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
510 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
511 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
512 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
513 };
514
515 int numMipLevels = ToolUtils::make_pixmaps(skColorType,
517 mipmapped == skgpu::Mipmapped::kYes,
518 kColors,
519 pixmaps,
520 &memForPixmaps);
521 SkASSERT(numMipLevels);
522
523 sk_sp<ManagedBackendTexture> mbet = create(dContext, pixmaps, numMipLevels, origin, renderable);
524 if (!mbet) {
525 // errors here should be reported by the test_wrapping test
526 return;
527 }
528
529 if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(mbet->texture().getBackendFormat())) {
530 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
531 return;
532 }
533
534 auto checkBackendTexture = [&](const SkColor4f colors[6]) {
535 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
536 if (mipmapped == skgpu::Mipmapped::kYes) {
537 SkColor4f expectedColors[6] = {
538 get_expected_color(colors[0], grColorType),
539 get_expected_color(colors[1], grColorType),
540 get_expected_color(colors[2], grColorType),
541 get_expected_color(colors[3], grColorType),
542 get_expected_color(colors[4], grColorType),
543 get_expected_color(colors[5], grColorType),
544 };
545
546 check_mipmaps(dContext, mbet->texture(), grColorType, expectedColors, reporter,
547 "pixmap");
548 }
549
550 // The last step in this test will dirty the mipmaps so do it last
551 check_base_readbacks(dContext, mbet->texture(), grColorType, renderable, colors[0],
552 reporter, "pixmap");
553 };
554
555 checkBackendTexture(kColors);
556
557 constexpr SkColor4f kColorsNew[6] = {
558 {1.0f, 1.0f, 0.0f, 0.2f}, // Y
559 {1.0f, 0.0f, 0.0f, 1.0f}, // R
560 {0.0f, 1.0f, 0.0f, 0.9f}, // G
561 {0.0f, 0.0f, 1.0f, 0.7f}, // B
562 {0.0f, 1.0f, 1.0f, 0.5f}, // C
563 {1.0f, 0.0f, 1.0f, 0.3f}, // M
564 };
565 ToolUtils::make_pixmaps(skColorType,
567 mipmapped == skgpu::Mipmapped::kYes,
568 kColorsNew,
569 pixmaps,
570 &memForPixmaps);
571
572 // Upload new data and make sure everything still works
573 dContext->updateBackendTexture(mbet->texture(),
574 pixmaps,
575 numMipLevels,
576 origin,
577 ManagedBackendTexture::ReleaseProc,
578 mbet->releaseContext());
579
580 checkBackendTexture(kColorsNew);
581}
static bool isBGRA8(const GrBackendFormat &format)
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
Definition: GrTypesPriv.h:629
kUnpremul_SkAlphaType
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
PODArray< SkColor > colors
Definition: SkRecords.h:276
int make_pixmaps(SkColorType ct, SkAlphaType at, bool withMips, const SkColor4f colors[6], SkPixmap pixmaps[6], std::unique_ptr< char[]> *mem)
Definition: ToolUtils.cpp:181
const DlColor kColors[]

◆ test_wrapping()

void test_wrapping ( GrDirectContext dContext,
skiatest::Reporter reporter,
const std::function< sk_sp< ManagedBackendTexture >(GrDirectContext *, skgpu::Mipmapped, GrRenderable)> &  create,
GrColorType  grColorType,
skgpu::Mipmapped  mipmapped,
GrRenderable  renderable 
)

Definition at line 97 of file BackendAllocationTest.cpp.

103 {
105
106 const int initialCount = cache->getResourceCount();
107
108 sk_sp<ManagedBackendTexture> mbet = create(dContext, mipmapped, renderable);
109 if (!mbet) {
110 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
111 (int)grColorType,
112 GrRenderable::kYes == renderable ? "yes" : "no");
113 return;
114 }
115
116 // Skia proper should know nothing about the new backend object
117 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
118
119 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
120
121 // Wrapping a backendTexture in an SkImage/SkSurface requires an SkColorType
122 if (skColorType == kUnknown_SkColorType) {
123 return;
124 }
125
126 // As we transition to using attachments instead of GrTextures and GrRenderTargets individual
127 // proxy instansiations may add multiple things to the cache. There would be an entry for the
128 // GrTexture/GrRenderTarget and entries for one or more attachments.
129 int cacheEntriesPerProxy = 1;
130 // We currently only have attachments on the vulkan and metal backends
131 if (dContext->backend() == GrBackend::kVulkan || dContext->backend() == GrBackend::kMetal) {
132 // If we ever make a rt with multisamples this would have an additional
133 // attachment as well.
134 cacheEntriesPerProxy++;
135 }
136
137 if (GrRenderable::kYes == renderable && dContext->colorTypeSupportedAsSurface(skColorType)) {
139 mbet->texture(),
141 0,
142 skColorType,
143 nullptr,
144 nullptr);
145 if (!surf) {
146 ERRORF(reporter, "Couldn't make SkSurface from backendTexture for %s\n",
147 ToolUtils::colortype_name(skColorType));
148 } else {
150 initialCount + cacheEntriesPerProxy == cache->getResourceCount());
151 }
152 }
153
154 {
156 mbet->texture(),
158 skColorType,
160 nullptr);
161 if (!img) {
162 ERRORF(reporter, "Couldn't make SkImage from backendTexture for %s\n",
163 ToolUtils::colortype_name(skColorType));
164 } else {
165 GrTextureProxy* proxy = sk_gpu_test::GetTextureImageProxy(img.get(), dContext);
167
168 REPORTER_ASSERT(reporter, mipmapped == proxy->proxyMipmapped());
170 REPORTER_ASSERT(reporter, mipmapped == proxy->mipmapped());
171
173 initialCount + cacheEntriesPerProxy == cache->getResourceCount());
174 }
175 }
176
177 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
178}
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define ERRORF(r,...)
Definition: Test.h:293
SK_API GrBackendApi backend() const
GrResourceCache * getResourceCache()
SK_API bool colorTypeSupportedAsSurface(SkColorType colorType) const
GrDirectContextPriv priv()
bool isInstantiated() const
skgpu::Mipmapped proxyMipmapped() const
skgpu::Mipmapped mipmapped() const
T * get() const
Definition: SkRefCnt.h:303
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
const char * colortype_name(SkColorType ct)
Definition: ToolUtils.cpp:65
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition: switches.h:191
GrTextureProxy * GetTextureImageProxy(SkImage *image, GrRecordingContext *rContext)
Definition: ProxyUtils.cpp:32