1/*
2 * Copyright 2018 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
8#include "src/gpu/ccpr/GrCCClipPath.h"
9
10#include "src/gpu/GrOnFlushResourceProvider.h"
11#include "src/gpu/GrProxyProvider.h"
12#include "src/gpu/GrRenderTarget.h"
13#include "src/gpu/GrTexture.h"
14#include "src/gpu/ccpr/GrCCPerFlushResources.h"
15
16void GrCCClipPath::init(
17 const SkPath& deviceSpacePath, const SkIRect& accessRect,
18 GrCCAtlas::CoverageType atlasCoverageType, const GrCaps& caps) {
19 SkASSERT(!this->isInitialized());
20
21 fAtlasLazyProxy = GrCCAtlas::MakeLazyAtlasProxy(
22 [this](GrResourceProvider* resourceProvider, const GrCCAtlas::LazyAtlasDesc& desc) {
23 SkASSERT(fHasAtlas);
24 SkASSERT(!fHasAtlasTranslate);
25
26 GrTextureProxy* textureProxy = fAtlas ? fAtlas->textureProxy() : nullptr;
27
28 if (!textureProxy || !textureProxy->instantiate(resourceProvider)) {
29 SkDEBUGCODE(fHasAtlasTranslate = true);
30 return GrSurfaceProxy::LazyCallbackResult();
31 }
32
33 sk_sp<GrTexture> texture = sk_ref_sp(textureProxy->peekTexture());
34 SkASSERT(texture);
35
36 SkDEBUGCODE(fHasAtlasTranslate = true);
37
38 // We use LazyInstantiationKeyMode::kUnsynced here because CCPR clip masks are never
39 // cached, and the clip FP proxies need to ignore any unique keys that atlas
40 // textures use for path mask caching.
41 return GrSurfaceProxy::LazyCallbackResult(
42 std::move(texture), true,
43 GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced);
44 },
45 atlasCoverageType, caps, GrSurfaceProxy::UseAllocator::kYes);
46
47 fDeviceSpacePath = deviceSpacePath;
48 fDeviceSpacePath.getBounds().roundOut(&fPathDevIBounds);
49 fAccessRect = accessRect;
50}
51
52void GrCCClipPath::accountForOwnPath(GrCCPerFlushResourceSpecs* specs) const {
53 SkASSERT(this->isInitialized());
54
55 ++specs->fNumClipPaths;
56 specs->fRenderedPathStats[GrCCPerFlushResourceSpecs::kFillIdx].statPath(fDeviceSpacePath);
57
58 SkIRect ibounds;
59 if (ibounds.intersect(fAccessRect, fPathDevIBounds)) {
60 specs->fRenderedAtlasSpecs.accountForSpace(ibounds.width(), ibounds.height());
61 }
62}
63
64void GrCCClipPath::renderPathInAtlas(GrCCPerFlushResources* resources,
65 GrOnFlushResourceProvider* onFlushRP) {
66 SkASSERT(this->isInitialized());
67 SkASSERT(!fHasAtlas);
68 fAtlas = resources->renderDeviceSpacePathInAtlas(
69 fAccessRect, fDeviceSpacePath, fPathDevIBounds, GrFillRuleForSkPath(fDeviceSpacePath),
70 &fDevToAtlasOffset);
71 SkDEBUGCODE(fHasAtlas = true);
72}
73