1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2018 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h"
9cb93a386Sopenharmony_ci#include "include/core/SkColor.h"
10cb93a386Sopenharmony_ci#include "include/core/SkColorSpace.h"
11cb93a386Sopenharmony_ci#include "include/core/SkFont.h"
12cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h"
13cb93a386Sopenharmony_ci#include "include/core/SkMatrix.h"
14cb93a386Sopenharmony_ci#include "include/core/SkPaint.h"
15cb93a386Sopenharmony_ci#include "include/core/SkPoint.h"
16cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h"
17cb93a386Sopenharmony_ci#include "include/core/SkSize.h"
18cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
19cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h"
20cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
21cb93a386Sopenharmony_ci#include "include/private/GrTypesPriv.h"
22cb93a386Sopenharmony_ci#include "src/core/SkIPoint16.h"
23cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
24cb93a386Sopenharmony_ci#include "src/gpu/GrDeferredUpload.h"
25cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
26cb93a386Sopenharmony_ci#include "src/gpu/GrDrawOpAtlas.h"
27cb93a386Sopenharmony_ci#include "src/gpu/GrDrawingManager.h"
28cb93a386Sopenharmony_ci#include "src/gpu/GrMemoryPool.h"
29cb93a386Sopenharmony_ci#include "src/gpu/GrOnFlushResourceProvider.h"
30cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h"
31cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h"
32cb93a386Sopenharmony_ci#include "src/gpu/GrXferProcessor.h"
33cb93a386Sopenharmony_ci#include "src/gpu/ops/AtlasTextOp.h"
34cb93a386Sopenharmony_ci#include "src/gpu/ops/GrDrawOp.h"
35cb93a386Sopenharmony_ci#include "src/gpu/ops/GrOp.h"
36cb93a386Sopenharmony_ci#include "src/gpu/text/GrAtlasManager.h"
37cb93a386Sopenharmony_ci#include "tests/Test.h"
38cb93a386Sopenharmony_ci#include "tools/gpu/GrContextFactory.h"
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci#include <memory>
41cb93a386Sopenharmony_ci#include <utility>
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ciclass GrResourceProvider;
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_cistatic const int kNumPlots = 2;
46cb93a386Sopenharmony_cistatic const int kPlotSize = 32;
47cb93a386Sopenharmony_cistatic const int kAtlasSize = kNumPlots * kPlotSize;
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ciint GrDrawOpAtlas::numAllocated_TestingOnly() const {
50cb93a386Sopenharmony_ci    int count = 0;
51cb93a386Sopenharmony_ci    for (uint32_t i = 0; i < this->maxPages(); ++i) {
52cb93a386Sopenharmony_ci        if (fViews[i].proxy()->isInstantiated()) {
53cb93a386Sopenharmony_ci            ++count;
54cb93a386Sopenharmony_ci        }
55cb93a386Sopenharmony_ci    }
56cb93a386Sopenharmony_ci
57cb93a386Sopenharmony_ci    return count;
58cb93a386Sopenharmony_ci}
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_civoid GrAtlasManager::setMaxPages_TestingOnly(uint32_t maxPages) {
61cb93a386Sopenharmony_ci    for (int i = 0; i < kMaskFormatCount; i++) {
62cb93a386Sopenharmony_ci        if (fAtlases[i]) {
63cb93a386Sopenharmony_ci            fAtlases[i]->setMaxPages_TestingOnly(maxPages);
64cb93a386Sopenharmony_ci        }
65cb93a386Sopenharmony_ci    }
66cb93a386Sopenharmony_ci}
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_civoid GrDrawOpAtlas::setMaxPages_TestingOnly(uint32_t maxPages) {
69cb93a386Sopenharmony_ci    SkASSERT(!fNumActivePages);
70cb93a386Sopenharmony_ci
71cb93a386Sopenharmony_ci    fMaxPages = maxPages;
72cb93a386Sopenharmony_ci}
73cb93a386Sopenharmony_ci
74cb93a386Sopenharmony_ciclass AssertOnEvict : public GrDrawOpAtlas::EvictionCallback {
75cb93a386Sopenharmony_cipublic:
76cb93a386Sopenharmony_ci    void evict(GrDrawOpAtlas::PlotLocator) override {
77cb93a386Sopenharmony_ci        SkASSERT(0); // The unit test shouldn't exercise this code path
78cb93a386Sopenharmony_ci    }
79cb93a386Sopenharmony_ci};
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_cistatic void check(skiatest::Reporter* r, GrDrawOpAtlas* atlas,
82cb93a386Sopenharmony_ci                  uint32_t expectedActive, uint32_t expectedMax, int expectedAlloced) {
83cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, expectedActive == atlas->numActivePages());
84cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, expectedMax == atlas->maxPages());
85cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, expectedAlloced == atlas->numAllocated_TestingOnly());
86cb93a386Sopenharmony_ci}
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ciclass TestingUploadTarget : public GrDeferredUploadTarget {
89cb93a386Sopenharmony_cipublic:
90cb93a386Sopenharmony_ci    TestingUploadTarget() { }
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci    const GrTokenTracker* tokenTracker() final { return &fTokenTracker; }
93cb93a386Sopenharmony_ci    GrTokenTracker* writeableTokenTracker() { return &fTokenTracker; }
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci    GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) final {
96cb93a386Sopenharmony_ci        SkASSERT(0); // this test shouldn't invoke this code path
97cb93a386Sopenharmony_ci        return fTokenTracker.nextDrawToken();
98cb93a386Sopenharmony_ci    }
99cb93a386Sopenharmony_ci
100cb93a386Sopenharmony_ci    GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&& upload) final {
101cb93a386Sopenharmony_ci        return fTokenTracker.nextTokenToFlush();
102cb93a386Sopenharmony_ci    }
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_ci    void issueDrawToken() { fTokenTracker.issueDrawToken(); }
105cb93a386Sopenharmony_ci    void flushToken() { fTokenTracker.flushToken(); }
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ciprivate:
108cb93a386Sopenharmony_ci    GrTokenTracker fTokenTracker;
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci    using INHERITED = GrDeferredUploadTarget;
111cb93a386Sopenharmony_ci};
112cb93a386Sopenharmony_ci
113cb93a386Sopenharmony_cistatic bool fill_plot(GrDrawOpAtlas* atlas,
114cb93a386Sopenharmony_ci                      GrResourceProvider* resourceProvider,
115cb93a386Sopenharmony_ci                      GrDeferredUploadTarget* target,
116cb93a386Sopenharmony_ci                      GrDrawOpAtlas::AtlasLocator* atlasLocator,
117cb93a386Sopenharmony_ci                      int alpha) {
118cb93a386Sopenharmony_ci    SkImageInfo ii = SkImageInfo::MakeA8(kPlotSize, kPlotSize);
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_ci    SkBitmap data;
121cb93a386Sopenharmony_ci    data.allocPixels(ii);
122cb93a386Sopenharmony_ci    data.eraseARGB(alpha, 0, 0, 0);
123cb93a386Sopenharmony_ci
124cb93a386Sopenharmony_ci    GrDrawOpAtlas::ErrorCode code;
125cb93a386Sopenharmony_ci    code = atlas->addToAtlas(resourceProvider, target, kPlotSize, kPlotSize,
126cb93a386Sopenharmony_ci                             data.getAddr(0, 0), atlasLocator);
127cb93a386Sopenharmony_ci    return GrDrawOpAtlas::ErrorCode::kSucceeded == code;
128cb93a386Sopenharmony_ci}
129cb93a386Sopenharmony_ci
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci// This is a basic DrawOpAtlas test. It simply verifies that multitexture atlases correctly
132cb93a386Sopenharmony_ci// add and remove pages. Note that this is simulating flush-time behavior.
133cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(BasicDrawOpAtlas, reporter, ctxInfo) {
134cb93a386Sopenharmony_ci    auto context = ctxInfo.directContext();
135cb93a386Sopenharmony_ci    auto proxyProvider = context->priv().proxyProvider();
136cb93a386Sopenharmony_ci    auto resourceProvider = context->priv().resourceProvider();
137cb93a386Sopenharmony_ci    auto drawingManager = context->priv().drawingManager();
138cb93a386Sopenharmony_ci    const GrCaps* caps = context->priv().caps();
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ci    GrOnFlushResourceProvider onFlushResourceProvider(drawingManager);
141cb93a386Sopenharmony_ci    TestingUploadTarget uploadTarget;
142cb93a386Sopenharmony_ci
143cb93a386Sopenharmony_ci    GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
144cb93a386Sopenharmony_ci                                                           GrRenderable::kNo);
145cb93a386Sopenharmony_ci
146cb93a386Sopenharmony_ci    AssertOnEvict evictor;
147cb93a386Sopenharmony_ci    GrDrawOpAtlas::GenerationCounter counter;
148cb93a386Sopenharmony_ci
149cb93a386Sopenharmony_ci    std::unique_ptr<GrDrawOpAtlas> atlas = GrDrawOpAtlas::Make(
150cb93a386Sopenharmony_ci                                                proxyProvider,
151cb93a386Sopenharmony_ci                                                format,
152cb93a386Sopenharmony_ci                                                GrColorType::kAlpha_8,
153cb93a386Sopenharmony_ci                                                kAtlasSize, kAtlasSize,
154cb93a386Sopenharmony_ci                                                kAtlasSize/kNumPlots, kAtlasSize/kNumPlots,
155cb93a386Sopenharmony_ci                                                &counter,
156cb93a386Sopenharmony_ci                                                GrDrawOpAtlas::AllowMultitexturing::kYes,
157cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
158cb93a386Sopenharmony_ci                                                4,
159cb93a386Sopenharmony_ci#endif
160cb93a386Sopenharmony_ci                                                &evictor);
161cb93a386Sopenharmony_ci    check(reporter, atlas.get(), 0, 4, 0);
162cb93a386Sopenharmony_ci
163cb93a386Sopenharmony_ci    // Fill up the first level
164cb93a386Sopenharmony_ci    GrDrawOpAtlas::AtlasLocator atlasLocators[kNumPlots * kNumPlots];
165cb93a386Sopenharmony_ci    for (int i = 0; i < kNumPlots * kNumPlots; ++i) {
166cb93a386Sopenharmony_ci        bool result = fill_plot(
167cb93a386Sopenharmony_ci                atlas.get(), resourceProvider, &uploadTarget, &atlasLocators[i], i * 32);
168cb93a386Sopenharmony_ci        REPORTER_ASSERT(reporter, result);
169cb93a386Sopenharmony_ci        check(reporter, atlas.get(), 1, 4, 1);
170cb93a386Sopenharmony_ci    }
171cb93a386Sopenharmony_ci
172cb93a386Sopenharmony_ci    atlas->instantiate(&onFlushResourceProvider);
173cb93a386Sopenharmony_ci    check(reporter, atlas.get(), 1, 4, 1);
174cb93a386Sopenharmony_ci
175cb93a386Sopenharmony_ci    // Force allocation of a second level
176cb93a386Sopenharmony_ci    GrDrawOpAtlas::AtlasLocator atlasLocator;
177cb93a386Sopenharmony_ci    bool result = fill_plot(atlas.get(), resourceProvider, &uploadTarget, &atlasLocator, 4 * 32);
178cb93a386Sopenharmony_ci    REPORTER_ASSERT(reporter, result);
179cb93a386Sopenharmony_ci    check(reporter, atlas.get(), 2, 4, 2);
180cb93a386Sopenharmony_ci
181cb93a386Sopenharmony_ci    // Simulate a lot of draws using only the first plot. The last texture should be compacted.
182cb93a386Sopenharmony_ci    for (int i = 0; i < 512; ++i) {
183cb93a386Sopenharmony_ci        atlas->setLastUseToken(atlasLocators[0], uploadTarget.tokenTracker()->nextDrawToken());
184cb93a386Sopenharmony_ci        uploadTarget.issueDrawToken();
185cb93a386Sopenharmony_ci        uploadTarget.flushToken();
186cb93a386Sopenharmony_ci        atlas->compact(uploadTarget.tokenTracker()->nextTokenToFlush());
187cb93a386Sopenharmony_ci    }
188cb93a386Sopenharmony_ci
189cb93a386Sopenharmony_ci    check(reporter, atlas.get(), 1, 4, 1);
190cb93a386Sopenharmony_ci}
191cb93a386Sopenharmony_ci
192cb93a386Sopenharmony_ci#if SK_GPU_V1
193cb93a386Sopenharmony_ci#include "src/gpu/v1/SurfaceDrawContext_v1.h"
194cb93a386Sopenharmony_ci
195cb93a386Sopenharmony_ci// This test verifies that the AtlasTextOp::onPrepare method correctly handles a failure
196cb93a386Sopenharmony_ci// when allocating an atlas page.
197cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrAtlasTextOpPreparation, reporter, ctxInfo) {
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci    auto dContext = ctxInfo.directContext();
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci    auto gpu = dContext->priv().getGpu();
202cb93a386Sopenharmony_ci    auto resourceProvider = dContext->priv().resourceProvider();
203cb93a386Sopenharmony_ci
204cb93a386Sopenharmony_ci    auto sdc = skgpu::v1::SurfaceDrawContext::Make(dContext, GrColorType::kRGBA_8888, nullptr,
205cb93a386Sopenharmony_ci                                                   SkBackingFit::kApprox, {32, 32},
206cb93a386Sopenharmony_ci                                                   SkSurfaceProps());
207cb93a386Sopenharmony_ci
208cb93a386Sopenharmony_ci    SkPaint paint;
209cb93a386Sopenharmony_ci    paint.setColor(SK_ColorRED);
210cb93a386Sopenharmony_ci
211cb93a386Sopenharmony_ci    SkFont font;
212cb93a386Sopenharmony_ci    font.setEdging(SkFont::Edging::kAlias);
213cb93a386Sopenharmony_ci
214cb93a386Sopenharmony_ci    const char* text = "a";
215cb93a386Sopenharmony_ci    SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
216cb93a386Sopenharmony_ci
217cb93a386Sopenharmony_ci    GrOp::Owner op = skgpu::v1::AtlasTextOp::CreateOpTestingOnly(sdc.get(), paint,
218cb93a386Sopenharmony_ci                                                                 font, matrixProvider,
219cb93a386Sopenharmony_ci                                                                 text, 16, 16);
220cb93a386Sopenharmony_ci    if (!op) {
221cb93a386Sopenharmony_ci        return;
222cb93a386Sopenharmony_ci    }
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_ci    auto atlasTextOp = (skgpu::v1::AtlasTextOp*)op.get();
225cb93a386Sopenharmony_ci    atlasTextOp->finalize(*dContext->priv().caps(), nullptr, GrClampType::kAuto);
226cb93a386Sopenharmony_ci
227cb93a386Sopenharmony_ci    TestingUploadTarget uploadTarget;
228cb93a386Sopenharmony_ci
229cb93a386Sopenharmony_ci    GrOpFlushState flushState(gpu, resourceProvider, uploadTarget.writeableTokenTracker());
230cb93a386Sopenharmony_ci
231cb93a386Sopenharmony_ci    GrSurfaceProxyView surfaceView = sdc->writeSurfaceView();
232cb93a386Sopenharmony_ci    GrOpFlushState::OpArgs opArgs(op.get(),
233cb93a386Sopenharmony_ci                                  surfaceView,
234cb93a386Sopenharmony_ci                                  false /*usesMSAASurface*/,
235cb93a386Sopenharmony_ci                                  nullptr,
236cb93a386Sopenharmony_ci                                  GrDstProxyView(),
237cb93a386Sopenharmony_ci                                  GrXferBarrierFlags::kNone,
238cb93a386Sopenharmony_ci                                  GrLoadOp::kLoad);
239cb93a386Sopenharmony_ci
240cb93a386Sopenharmony_ci    // Modify the atlas manager so it can't allocate any pages. This will force a failure
241cb93a386Sopenharmony_ci    // in the preparation of the text op
242cb93a386Sopenharmony_ci    auto atlasManager = dContext->priv().getAtlasManager();
243cb93a386Sopenharmony_ci    unsigned int numProxies;
244cb93a386Sopenharmony_ci    atlasManager->getViews(kA8_GrMaskFormat, &numProxies);
245cb93a386Sopenharmony_ci    atlasManager->setMaxPages_TestingOnly(0);
246cb93a386Sopenharmony_ci
247cb93a386Sopenharmony_ci    flushState.setOpArgs(&opArgs);
248cb93a386Sopenharmony_ci    op->prepare(&flushState);
249cb93a386Sopenharmony_ci    flushState.setOpArgs(nullptr);
250cb93a386Sopenharmony_ci}
251cb93a386Sopenharmony_ci#endif // SK_GPU_V1
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_civoid test_atlas_config(skiatest::Reporter* reporter, int maxTextureSize, size_t maxBytes,
254cb93a386Sopenharmony_ci                       GrMaskFormat maskFormat, SkISize expectedDimensions,
255cb93a386Sopenharmony_ci                       SkISize expectedPlotDimensions) {
256cb93a386Sopenharmony_ci    GrDrawOpAtlasConfig config(maxTextureSize, maxBytes);
257cb93a386Sopenharmony_ci    REPORTER_ASSERT(reporter, config.atlasDimensions(maskFormat) == expectedDimensions);
258cb93a386Sopenharmony_ci    REPORTER_ASSERT(reporter, config.plotDimensions(maskFormat) == expectedPlotDimensions);
259cb93a386Sopenharmony_ci}
260cb93a386Sopenharmony_ci
261cb93a386Sopenharmony_ciDEF_GPUTEST(GrDrawOpAtlasConfig_Basic, reporter, options) {
262cb93a386Sopenharmony_ci    // 1/4 MB
263cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 256 * 1024, kARGB_GrMaskFormat,
264cb93a386Sopenharmony_ci                      { 256, 256 }, { 256, 256 });
265cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 256 * 1024, kA8_GrMaskFormat,
266cb93a386Sopenharmony_ci                      { 512, 512 }, { 256, 256 });
267cb93a386Sopenharmony_ci    // 1/2 MB
268cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 512 * 1024, kARGB_GrMaskFormat,
269cb93a386Sopenharmony_ci                      { 512, 256 }, { 256, 256 });
270cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
271cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 512 * 1024, kA8_GrMaskFormat,
272cb93a386Sopenharmony_ci                      { 1024, 512 }, { 512, 256 });
273cb93a386Sopenharmony_ci#else
274cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 512 * 1024, kA8_GrMaskFormat,
275cb93a386Sopenharmony_ci                      { 1024, 512 }, { 256, 256 });
276cb93a386Sopenharmony_ci#endif
277cb93a386Sopenharmony_ci    // 1 MB
278cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 1024 * 1024, kARGB_GrMaskFormat,
279cb93a386Sopenharmony_ci                      { 512, 512 }, { 256, 256 });
280cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
281cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 1024 * 1024, kA8_GrMaskFormat,
282cb93a386Sopenharmony_ci                      { 1024, 1024 }, { 512, 512 });
283cb93a386Sopenharmony_ci#else
284cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 1024 * 1024, kA8_GrMaskFormat,
285cb93a386Sopenharmony_ci                      { 1024, 1024 }, { 256, 256 });
286cb93a386Sopenharmony_ci#endif
287cb93a386Sopenharmony_ci    // 2 MB
288cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 2 * 1024 * 1024, kARGB_GrMaskFormat,
289cb93a386Sopenharmony_ci                      { 1024, 512 }, { 256, 256 });
290cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
291cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 2 * 1024 * 1024, kA8_GrMaskFormat,
292cb93a386Sopenharmony_ci                      { 2048, 1024 }, { 512, 512 });
293cb93a386Sopenharmony_ci#else
294cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 2 * 1024 * 1024, kA8_GrMaskFormat,
295cb93a386Sopenharmony_ci                      { 2048, 1024 }, { 512, 256 });
296cb93a386Sopenharmony_ci#endif
297cb93a386Sopenharmony_ci    // 4 MB
298cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 4 * 1024 * 1024, kARGB_GrMaskFormat,
299cb93a386Sopenharmony_ci                      { 1024, 1024 }, { 256, 256 });
300cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 4 * 1024 * 1024, kA8_GrMaskFormat,
301cb93a386Sopenharmony_ci                      { 2048, 2048 }, { 512, 512 });
302cb93a386Sopenharmony_ci    // 8 MB
303cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 8 * 1024 * 1024, kARGB_GrMaskFormat,
304cb93a386Sopenharmony_ci                      { 2048, 1024 }, { 256, 256 });
305cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 8 * 1024 * 1024, kA8_GrMaskFormat,
306cb93a386Sopenharmony_ci                      { 2048, 2048 }, { 512, 512 });
307cb93a386Sopenharmony_ci    // 16 MB (should be same as 8 MB)
308cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 16 * 1024 * 1024, kARGB_GrMaskFormat,
309cb93a386Sopenharmony_ci                      { 2048, 1024 }, { 256, 256 });
310cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 16 * 1024 * 1024, kA8_GrMaskFormat,
311cb93a386Sopenharmony_ci                      { 2048, 2048 }, { 512, 512 });
312cb93a386Sopenharmony_ci
313cb93a386Sopenharmony_ci    // 4MB, restricted texture size
314cb93a386Sopenharmony_ci    test_atlas_config(reporter, 1024, 8 * 1024 * 1024, kARGB_GrMaskFormat,
315cb93a386Sopenharmony_ci                      { 1024, 1024 }, { 256, 256 });
316cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
317cb93a386Sopenharmony_ci    test_atlas_config(reporter, 1024, 8 * 1024 * 1024, kA8_GrMaskFormat,
318cb93a386Sopenharmony_ci                      { 1024, 1024 }, { 512, 512 });
319cb93a386Sopenharmony_ci#else
320cb93a386Sopenharmony_ci    test_atlas_config(reporter, 1024, 8 * 1024 * 1024, kA8_GrMaskFormat,
321cb93a386Sopenharmony_ci                      { 1024, 1024 }, { 256, 256 });
322cb93a386Sopenharmony_ci#endif
323cb93a386Sopenharmony_ci
324cb93a386Sopenharmony_ci    // 3 MB (should be same as 2 MB)
325cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 3 * 1024 * 1024, kARGB_GrMaskFormat,
326cb93a386Sopenharmony_ci                      { 1024, 512 }, { 256, 256 });
327cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
328cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 3 * 1024 * 1024, kA8_GrMaskFormat,
329cb93a386Sopenharmony_ci                      { 2048, 1024 }, { 512, 512 });
330cb93a386Sopenharmony_ci#else
331cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 3 * 1024 * 1024, kA8_GrMaskFormat,
332cb93a386Sopenharmony_ci                      { 2048, 1024 }, { 512, 256 });
333cb93a386Sopenharmony_ci#endif
334cb93a386Sopenharmony_ci
335cb93a386Sopenharmony_ci    // minimum size
336cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 0, kARGB_GrMaskFormat,
337cb93a386Sopenharmony_ci                      { 256, 256 }, { 256, 256 });
338cb93a386Sopenharmony_ci    test_atlas_config(reporter, 65536, 0, kA8_GrMaskFormat,
339cb93a386Sopenharmony_ci                      { 512, 512 }, { 256, 256 });
340cb93a386Sopenharmony_ci}
341