1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RasterPathAtlas.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Recorder.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkIPoint16.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/AtlasProvider.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/DrawContext.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Log.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RasterPathUtils.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RecorderPriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker
19*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Worker static constexpr uint32_t kDefaultAtlasDim = 4096;
22*c8dee2aaSAndroid Build Coastguard Worker
23*c8dee2aaSAndroid Build Coastguard Worker static constexpr uint32_t kSmallPathPlotWidth = 512;
24*c8dee2aaSAndroid Build Coastguard Worker static constexpr uint32_t kSmallPathPlotHeight = 256;
25*c8dee2aaSAndroid Build Coastguard Worker
RasterPathAtlas(Recorder * recorder)26*c8dee2aaSAndroid Build Coastguard Worker RasterPathAtlas::RasterPathAtlas(Recorder* recorder)
27*c8dee2aaSAndroid Build Coastguard Worker : PathAtlas(recorder, kDefaultAtlasDim, kDefaultAtlasDim)
28*c8dee2aaSAndroid Build Coastguard Worker , fCachedAtlasMgr(fWidth, fHeight, fWidth, fHeight, recorder->priv().caps())
29*c8dee2aaSAndroid Build Coastguard Worker , fSmallPathAtlasMgr(std::max(fWidth/2, kSmallPathPlotWidth),
30*c8dee2aaSAndroid Build Coastguard Worker std::max(fHeight/2, kSmallPathPlotHeight),
31*c8dee2aaSAndroid Build Coastguard Worker kSmallPathPlotWidth, kSmallPathPlotHeight,
32*c8dee2aaSAndroid Build Coastguard Worker recorder->priv().caps())
33*c8dee2aaSAndroid Build Coastguard Worker , fUncachedAtlasMgr(fWidth, fHeight, fWidth, fHeight, recorder->priv().caps()) {
34*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(recorder);
35*c8dee2aaSAndroid Build Coastguard Worker }
36*c8dee2aaSAndroid Build Coastguard Worker
recordUploads(DrawContext * dc)37*c8dee2aaSAndroid Build Coastguard Worker void RasterPathAtlas::recordUploads(DrawContext* dc) {
38*c8dee2aaSAndroid Build Coastguard Worker fCachedAtlasMgr.recordUploads(dc, fRecorder);
39*c8dee2aaSAndroid Build Coastguard Worker fSmallPathAtlasMgr.recordUploads(dc, fRecorder);
40*c8dee2aaSAndroid Build Coastguard Worker fUncachedAtlasMgr.recordUploads(dc, fRecorder);
41*c8dee2aaSAndroid Build Coastguard Worker }
42*c8dee2aaSAndroid Build Coastguard Worker
onAddShape(const Shape & shape,const Transform & transform,const SkStrokeRec & strokeRec,skvx::half2 maskSize,skvx::half2 * outPos)43*c8dee2aaSAndroid Build Coastguard Worker const TextureProxy* RasterPathAtlas::onAddShape(const Shape& shape,
44*c8dee2aaSAndroid Build Coastguard Worker const Transform& transform,
45*c8dee2aaSAndroid Build Coastguard Worker const SkStrokeRec& strokeRec,
46*c8dee2aaSAndroid Build Coastguard Worker skvx::half2 maskSize,
47*c8dee2aaSAndroid Build Coastguard Worker skvx::half2* outPos) {
48*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKey maskKey;
49*c8dee2aaSAndroid Build Coastguard Worker bool hasKey = shape.hasKey();
50*c8dee2aaSAndroid Build Coastguard Worker if (hasKey) {
51*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxSmallPathSize = 162;
52*c8dee2aaSAndroid Build Coastguard Worker // Try to locate or add to cached DrawAtlas
53*c8dee2aaSAndroid Build Coastguard Worker const TextureProxy* proxy = nullptr;
54*c8dee2aaSAndroid Build Coastguard Worker if (maskSize.x() <= kMaxSmallPathSize && maskSize.y() <= kMaxSmallPathSize) {
55*c8dee2aaSAndroid Build Coastguard Worker proxy = fSmallPathAtlasMgr.findOrCreateEntry(fRecorder,
56*c8dee2aaSAndroid Build Coastguard Worker shape,
57*c8dee2aaSAndroid Build Coastguard Worker transform,
58*c8dee2aaSAndroid Build Coastguard Worker strokeRec,
59*c8dee2aaSAndroid Build Coastguard Worker maskSize,
60*c8dee2aaSAndroid Build Coastguard Worker outPos);
61*c8dee2aaSAndroid Build Coastguard Worker }
62*c8dee2aaSAndroid Build Coastguard Worker if (!proxy) {
63*c8dee2aaSAndroid Build Coastguard Worker proxy = fCachedAtlasMgr.findOrCreateEntry(fRecorder,
64*c8dee2aaSAndroid Build Coastguard Worker shape,
65*c8dee2aaSAndroid Build Coastguard Worker transform,
66*c8dee2aaSAndroid Build Coastguard Worker strokeRec,
67*c8dee2aaSAndroid Build Coastguard Worker maskSize,
68*c8dee2aaSAndroid Build Coastguard Worker outPos);
69*c8dee2aaSAndroid Build Coastguard Worker }
70*c8dee2aaSAndroid Build Coastguard Worker if (proxy) {
71*c8dee2aaSAndroid Build Coastguard Worker return proxy;
72*c8dee2aaSAndroid Build Coastguard Worker }
73*c8dee2aaSAndroid Build Coastguard Worker }
74*c8dee2aaSAndroid Build Coastguard Worker
75*c8dee2aaSAndroid Build Coastguard Worker // try to add to uncached DrawAtlas
76*c8dee2aaSAndroid Build Coastguard Worker AtlasLocator loc;
77*c8dee2aaSAndroid Build Coastguard Worker return fUncachedAtlasMgr.addToAtlas(fRecorder,
78*c8dee2aaSAndroid Build Coastguard Worker shape,
79*c8dee2aaSAndroid Build Coastguard Worker transform,
80*c8dee2aaSAndroid Build Coastguard Worker strokeRec,
81*c8dee2aaSAndroid Build Coastguard Worker maskSize,
82*c8dee2aaSAndroid Build Coastguard Worker outPos,
83*c8dee2aaSAndroid Build Coastguard Worker &loc);
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker
86*c8dee2aaSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////////
87*c8dee2aaSAndroid Build Coastguard Worker
onAddToAtlas(const Shape & shape,const Transform & transform,const SkStrokeRec & strokeRec,SkIRect shapeBounds,const AtlasLocator & locator)88*c8dee2aaSAndroid Build Coastguard Worker bool RasterPathAtlas::RasterAtlasMgr::onAddToAtlas(const Shape& shape,
89*c8dee2aaSAndroid Build Coastguard Worker const Transform& transform,
90*c8dee2aaSAndroid Build Coastguard Worker const SkStrokeRec& strokeRec,
91*c8dee2aaSAndroid Build Coastguard Worker SkIRect shapeBounds,
92*c8dee2aaSAndroid Build Coastguard Worker const AtlasLocator& locator) {
93*c8dee2aaSAndroid Build Coastguard Worker // Rasterize path to backing pixmap.
94*c8dee2aaSAndroid Build Coastguard Worker // This pixmap will be the size of the Plot that contains the given rect, not the entire atlas,
95*c8dee2aaSAndroid Build Coastguard Worker // and hence the position we render at will be relative to that Plot.
96*c8dee2aaSAndroid Build Coastguard Worker // The value of outPos is relative to the entire texture, to be used for texture coords.
97*c8dee2aaSAndroid Build Coastguard Worker SkAutoPixmapStorage dst;
98*c8dee2aaSAndroid Build Coastguard Worker SkIPoint renderPos = fDrawAtlas->prepForRender(locator, &dst);
99*c8dee2aaSAndroid Build Coastguard Worker
100*c8dee2aaSAndroid Build Coastguard Worker RasterMaskHelper helper(&dst);
101*c8dee2aaSAndroid Build Coastguard Worker if (!helper.init(fDrawAtlas->plotSize())) {
102*c8dee2aaSAndroid Build Coastguard Worker return false;
103*c8dee2aaSAndroid Build Coastguard Worker }
104*c8dee2aaSAndroid Build Coastguard Worker // Offset to plot location and draw
105*c8dee2aaSAndroid Build Coastguard Worker shapeBounds.offset(renderPos.x()+kEntryPadding, renderPos.y()+kEntryPadding);
106*c8dee2aaSAndroid Build Coastguard Worker helper.drawShape(shape, transform, strokeRec, shapeBounds);
107*c8dee2aaSAndroid Build Coastguard Worker
108*c8dee2aaSAndroid Build Coastguard Worker return true;
109*c8dee2aaSAndroid Build Coastguard Worker }
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
112