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