• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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/GrCCAtlas.h"
9 
10 #include "src/gpu/GrOnFlushResourceProvider.h"
11 #include "src/gpu/ccpr/GrCCPathCache.h"
12 
choose_initial_atlas_size(const GrCCAtlas::Specs & specs)13 static SkISize choose_initial_atlas_size(const GrCCAtlas::Specs& specs) {
14     // Begin with the first pow2 dimensions whose area is theoretically large enough to contain the
15     // pending paths, favoring height over width if necessary.
16     int log2area = SkNextLog2(std::max(specs.fApproxNumPixels, 1));
17     int height = 1 << ((log2area + 1) / 2);
18     int width = 1 << (log2area / 2);
19 
20     width = SkTPin(width, specs.fMinTextureSize, specs.fMaxPreferredTextureSize);
21     height = SkTPin(height, specs.fMinTextureSize, specs.fMaxPreferredTextureSize);
22 
23     return SkISize::Make(width, height);
24 }
25 
choose_max_atlas_size(const GrCCAtlas::Specs & specs,const GrCaps & caps)26 static int choose_max_atlas_size(const GrCCAtlas::Specs& specs, const GrCaps& caps) {
27     return (std::max(specs.fMinHeight, specs.fMinWidth) <= specs.fMaxPreferredTextureSize) ?
28             specs.fMaxPreferredTextureSize : caps.maxRenderTargetSize();
29 }
30 
GrCCAtlas(CoverageType coverageType,const Specs & specs,const GrCaps & caps)31 GrCCAtlas::GrCCAtlas(CoverageType coverageType, const Specs& specs, const GrCaps& caps)
32         : GrDynamicAtlas(CoverageTypeToColorType(coverageType),
33                          CoverageTypeHasInternalMultisample(coverageType),
34                          choose_initial_atlas_size(specs), choose_max_atlas_size(specs, caps), caps)
35         , fCoverageType(coverageType) {
36     SkASSERT(specs.fMaxPreferredTextureSize > 0);
37 }
38 
~GrCCAtlas()39 GrCCAtlas::~GrCCAtlas() {
40 }
41 
setFillBatchID(int id)42 void GrCCAtlas::setFillBatchID(int id) {
43     // This can't be called anymore once makeRenderTargetContext() has been called.
44     SkASSERT(!this->isInstantiated());
45     fFillBatchID = id;
46 }
47 
setStrokeBatchID(int id)48 void GrCCAtlas::setStrokeBatchID(int id) {
49     // This can't be called anymore once makeRenderTargetContext() has been called.
50     SkASSERT(!this->isInstantiated());
51     fStrokeBatchID = id;
52 }
53 
setEndStencilResolveInstance(int idx)54 void GrCCAtlas::setEndStencilResolveInstance(int idx) {
55     // This can't be called anymore once makeRenderTargetContext() has been called.
56     SkASSERT(!this->isInstantiated());
57     fEndStencilResolveInstance = idx;
58 }
59 
next_atlas_unique_id()60 static uint32_t next_atlas_unique_id() {
61     static std::atomic<uint32_t> nextID;
62     return nextID++;
63 }
64 
refOrMakeCachedAtlas(GrOnFlushResourceProvider * onFlushRP)65 sk_sp<GrCCCachedAtlas> GrCCAtlas::refOrMakeCachedAtlas(GrOnFlushResourceProvider* onFlushRP) {
66     if (!fCachedAtlas) {
67         static const GrUniqueKey::Domain kAtlasDomain = GrUniqueKey::GenerateDomain();
68 
69         GrUniqueKey atlasUniqueKey;
70         GrUniqueKey::Builder builder(&atlasUniqueKey, kAtlasDomain, 1, "CCPR Atlas");
71         builder[0] = next_atlas_unique_id();
72         builder.finish();
73 
74         onFlushRP->assignUniqueKeyToProxy(atlasUniqueKey, this->textureProxy());
75 
76         fCachedAtlas = sk_make_sp<GrCCCachedAtlas>(fCoverageType, atlasUniqueKey,
77                                                    sk_ref_sp(this->textureProxy()));
78     }
79 
80     SkASSERT(fCachedAtlas->coverageType() == fCoverageType);
81     SkASSERT(fCachedAtlas->getOnFlushProxy() == this->textureProxy());
82     return fCachedAtlas;
83 }
84 
addRect(const SkIRect & devIBounds,SkIVector * devToAtlasOffset)85 GrCCAtlas* GrCCAtlasStack::addRect(const SkIRect& devIBounds, SkIVector* devToAtlasOffset) {
86     GrCCAtlas* retiredAtlas = nullptr;
87     if (fAtlases.empty() || !fAtlases.back().addRect(devIBounds, devToAtlasOffset)) {
88         // The retired atlas is out of room and can't grow any bigger.
89         retiredAtlas = !fAtlases.empty() ? &fAtlases.back() : nullptr;
90         fAtlases.emplace_back(fCoverageType, fSpecs, *fCaps);
91         SkASSERT(devIBounds.width() <= fSpecs.fMinWidth);
92         SkASSERT(devIBounds.height() <= fSpecs.fMinHeight);
93         SkAssertResult(fAtlases.back().addRect(devIBounds, devToAtlasOffset));
94     }
95     return retiredAtlas;
96 }
97