xref: /third_party/skia/gm/manypathatlases.cpp (revision cb93a386)
1/*
2 * Copyright 2019 Google LLC.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm/gm.h"
9
10#include "include/core/SkPath.h"
11#include "include/gpu/GrContextOptions.h"
12#include "include/gpu/GrRecordingContext.h"
13#include "src/gpu/GrDirectContextPriv.h"
14#include "src/gpu/GrDrawingManager.h"
15#include "src/gpu/GrRecordingContextPriv.h"
16#include "tools/ToolUtils.h"
17
18namespace skiagm {
19
20/**
21 * This test originally ensured that the ccpr path cache preserved fill rules properly. CCRP is gone
22 * now, but we decided to keep the test.
23 */
24class ManyPathAtlasesGM : public GpuGM {
25public:
26    ManyPathAtlasesGM(int maxAtlasSize) : fMaxAtlasSize(maxAtlasSize) {}
27private:
28    SkString onShortName() override { return SkStringPrintf("manypathatlases_%i", fMaxAtlasSize); }
29    SkISize onISize() override { return SkISize::Make(128, 128); }
30
31    void modifyGrContextOptions(GrContextOptions* ctxOptions) override {
32        // This will test the case where the atlas runs out of room if fMaxAtlasSize is small.
33        ctxOptions->fMaxTextureAtlasSize = fMaxAtlasSize;
34    }
35
36    DrawResult onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) override {
37        canvas->clear({1,1,0,1});
38
39        // Flush the context to make the DAG empty. This will test the case where we try to add an
40        // atlas task to an empty DAG.
41        if (auto dContext = rContext->asDirectContext()) {
42            dContext->flush();
43        }
44
45        SkPath clip = SkPath().moveTo(-50, 20)
46                              .cubicTo(-50, -20, 50, -20, 50, 40)
47                              .cubicTo(20, 0, -20, 0, -50, 20);
48        clip.transform(SkMatrix::Translate(64, 70));
49        for (int i = 0; i < 4; ++i) {
50            SkPath rotatedClip = clip;
51            rotatedClip.transform(SkMatrix::RotateDeg(30 * i + 128, {64, 70}));
52            rotatedClip.setIsVolatile(true);
53            canvas->clipPath(rotatedClip, SkClipOp::kDifference, true);
54        }
55        SkPath path = SkPath().moveTo(20, 0)
56                              .lineTo(108, 0).cubicTo(108, 20, 108, 20, 128, 20)
57                              .lineTo(128, 108).cubicTo(108, 108, 108, 108, 108, 128)
58                              .lineTo(20, 128).cubicTo(20, 108, 20, 108, 0, 108)
59                              .lineTo(0, 20).cubicTo(20, 20, 20, 20, 20, 0);
60        path.setIsVolatile(true);
61        SkPaint teal;
62        teal.setColor4f({.03f, .91f, .87f, 1});
63        teal.setAntiAlias(true);
64        canvas->drawPath(path, teal);
65        return DrawResult::kOk;
66    }
67
68    const int fMaxAtlasSize;
69};
70
71DEF_GM( return new ManyPathAtlasesGM(128); )  // Atlas runs out of room.
72DEF_GM( return new ManyPathAtlasesGM(2048); )  // Atlas does not run out of room.
73
74}  // namespace skiagm
75