• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 maskOrigin,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 maskOrigin,
47                                                 skvx::half2 maskSize,
48                                                 skvx::half2* outPos) {
49     skgpu::UniqueKey maskKey;
50     bool hasKey = shape.hasKey();
51     if (hasKey) {
52         constexpr int kMaxSmallPathSize = 162;
53         // Try to locate or add to cached DrawAtlas
54         const TextureProxy* proxy = nullptr;
55         if (maskSize.x() <= kMaxSmallPathSize && maskSize.y() <= kMaxSmallPathSize) {
56             proxy = fSmallPathAtlasMgr.findOrCreateEntry(fRecorder,
57                                                          shape,
58                                                          transform,
59                                                          strokeRec,
60                                                          maskOrigin,
61                                                          maskSize,
62                                                          outPos);
63         }
64         if (!proxy) {
65             proxy = fCachedAtlasMgr.findOrCreateEntry(fRecorder,
66                                                       shape,
67                                                       transform,
68                                                       strokeRec,
69                                                       maskOrigin,
70                                                       maskSize,
71                                                       outPos);
72         }
73         if (proxy) {
74             return proxy;
75         }
76     }
77 
78     // try to add to uncached DrawAtlas
79     AtlasLocator loc;
80     return fUncachedAtlasMgr.addToAtlas(fRecorder,
81                                         shape,
82                                         transform,
83                                         strokeRec,
84                                         maskSize,
85                                         outPos,
86                                         &loc);
87 }
88 
89 /////////////////////////////////////////////////////////////////////////////////////////
90 
onAddToAtlas(const Shape & shape,const Transform & transform,const SkStrokeRec & strokeRec,SkIRect shapeBounds,const AtlasLocator & locator)91 bool RasterPathAtlas::RasterAtlasMgr::onAddToAtlas(const Shape& shape,
92                                                    const Transform& transform,
93                                                    const SkStrokeRec& strokeRec,
94                                                    SkIRect shapeBounds,
95                                                    const AtlasLocator& locator) {
96     // Rasterize path to backing pixmap.
97     // This pixmap will be the size of the Plot that contains the given rect, not the entire atlas,
98     // and hence the position we render at will be relative to that Plot.
99     // The value of outPos is relative to the entire texture, to be used for texture coords.
100     SkAutoPixmapStorage dst;
101     SkIPoint renderPos = fDrawAtlas->prepForRender(locator, &dst);
102 
103     RasterMaskHelper helper(&dst);
104     if (!helper.init(fDrawAtlas->plotSize())) {
105         return false;
106     }
107     // Offset to plot location and draw
108     shapeBounds.offset(renderPos.x()+kEntryPadding, renderPos.y()+kEntryPadding);
109     helper.drawShape(shape, transform, strokeRec, shapeBounds);
110 
111     return true;
112 }
113 
114 }  // namespace skgpu::graphite
115