22#ifdef SK_ENABLE_VELLO_SHADERS
30constexpr uint16_t kComputeAtlasDim = 4096;
36constexpr size_t kBboxAreaThreshold = 1024 * 512;
40constexpr float kCoordinateThreshold = 1e10;
45 :
PathAtlas(recorder, kComputeAtlasDim, kComputeAtlasDim)
48bool ComputePathAtlas::initializeTextureIfNeeded() {
58 return fTexture !=
nullptr;
62 const Rect& clipBounds)
const {
75 if (width *
height > kBboxAreaThreshold) {
81 if (std::fabs(unclippedSize.x()) > kCoordinateThreshold ||
82 std::fabs(unclippedSize.y()) > kCoordinateThreshold) {
91 if (!this->initializeTextureIfNeeded()) {
92 SKGPU_LOG_E(
"Failed to instantiate an atlas texture");
101 return fTexture.get();
108 return fTexture.get();
117#ifdef SK_ENABLE_VELLO_SHADERS
124 explicit VelloComputePathAtlas(
Recorder* recorder)
126 , fCachedAtlasMgr(fWidth, fHeight, recorder->
priv().caps()) {}
131 const TextureProxy* onAddShape(
const Shape&,
136 void onReset()
override {
137 fCachedAtlasMgr.onReset();
139 fUncachedScene.reset();
140 fUncachedOccupiedArea = { 0, 0 };
143 class VelloAtlasMgr :
public PathAtlas::DrawAtlasMgr {
145 VelloAtlasMgr(
size_t width,
size_t height,
const Caps* caps)
148 "VelloPathAtlas", caps) {}
153 fDrawAtlas->markUsedPlotsAsFull();
156 fOccupiedAreas[
i] = {0, 0};
161 bool onAddToAtlas(
const Shape&,
170 {0, 0}, {0, 0}, {0, 0}, {0, 0}
174 VelloAtlasMgr fCachedAtlasMgr;
178 VelloScene fUncachedScene;
181 SkISize fUncachedOccupiedArea = { 0, 0 };
187#if defined(GRAPHITE_TEST_UTILS)
199static std::unique_ptr<DispatchGroup> render_vello_scene(
Recorder* recorder,
201 const VelloScene& scene,
205 {(uint32_t)occupiedArea.
width(),
206 (uint32_t)occupiedArea.
height(),
214static void add_shape_to_scene(
const Shape& shape,
244 SkPath devicePath = shape.asPath();
257 float deviceWidth =
width * atlasTransform.maxScaleFactor();
266 float transformedWidth = 1.0f / atlasTransform.maxScaleFactor();
268 adjustedStyle.setStrokeStyle(transformedWidth);
269 scene->solidStroke(devicePath,
color, adjustedStyle, atlasTransform);
271 scene->solidStroke(devicePath,
SkColors::kRed, style, atlasTransform);
275 scene->solidFill(devicePath,
SkColors::kRed, shape.fillType(), atlasTransform);
278 scene->popClipLayer();
281bool VelloComputePathAtlas::recordDispatches(
Recorder* recorder,
283 bool addedDispatches = fCachedAtlasMgr.recordDispatches(recorder, dispatches);
285 if (this->
texture() && !fUncachedOccupiedArea.isEmpty()) {
286 SkASSERT(recorder && recorder == fRecorder);
289 std::unique_ptr<DispatchGroup> dispatchGroup =
290 render_vello_scene(recorder,
293 fUncachedOccupiedArea,
297 "# dispatches", dispatchGroup->dispatches().size());
298 dispatches->emplace_back(std::move(dispatchGroup));
301 SKGPU_LOG_E(
"VelloComputePathAtlas:: Failed to create dispatch group.");
305 return addedDispatches;
308const TextureProxy* VelloComputePathAtlas::onAddShape(
316 bool hasKey = shape.hasKey();
319 const TextureProxy* proxy = fCachedAtlasMgr.findOrCreateEntry(fRecorder,
332 const TextureProxy* texProxy = this->addRect(maskSize, &iPos);
340 if (!
all(maskSize)) {
352 add_shape_to_scene(shape,
transform, style, atlasBounds,
353 &fUncachedScene, &fUncachedOccupiedArea);
360bool VelloComputePathAtlas::VelloAtlasMgr::onAddToAtlas(
const Shape& shape,
366 const TextureProxy* texProxy = fDrawAtlas->getProxies()[index].get();
381 add_shape_to_scene(shape,
transform, style, atlasBounds,
382 &fScenes[index], &fOccupiedAreas[index]);
387bool VelloComputePathAtlas::VelloAtlasMgr::recordDispatches(
392 bool addedDispatches =
false;
393 for (
int i = 0;
i < 4; ++
i) {
394 if (!fOccupiedAreas[
i].isEmpty()) {
395 std::unique_ptr<DispatchGroup> dispatchGroup =
396 render_vello_scene(recorder,
397 fDrawAtlas->getProxies()[
i],
403 "# dispatches", dispatchGroup->dispatches().size());
404 dispatches->emplace_back(std::move(dispatchGroup));
405 addedDispatches =
true;
407 SKGPU_LOG_E(
"VelloComputePathAtlas:: Failed to create dispatch group.");
411 return addedDispatches;
418#ifdef SK_ENABLE_VELLO_SHADERS
419 return std::make_unique<VelloComputePathAtlas>(recorder);
#define SKGPU_LOG_E(fmt,...)
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
sk_sp< T > sk_ref_sp(T *obj)
#define TRACE_EVENT_SCOPE_THREAD
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
bool isHairlineStyle() const
SkScalar getWidth() const
uint32_t pageIndex() const
static constexpr auto kMaxMultitexturePages
bool addPaddedRect(int width, int height, int16_t padding, SkIPoint16 *loc)
sk_sp< TextureProxy > getAtlasTexture(Recorder *, uint16_t width, uint16_t height, SkColorType, uint16_t identifier, bool requireStorageUsage)
bool isSuitableForAtlasing(const Rect &transformedShapeBounds, const Rect &clipBounds) const override
ComputePathAtlas(Recorder *)
static std::unique_ptr< ComputePathAtlas > CreateDefault(Recorder *)
const TextureProxy * addRect(skvx::half2 maskSize, SkIPoint16 *outPos)
skia_private::STArray< 1, std::unique_ptr< DispatchGroup > > DispatchGroupList
static constexpr int kEntryPadding
AtlasProvider * atlasProvider()
const Caps * caps() const
const RendererProvider * rendererProvider() const
static AI Rect XYWH(float x, float y, float w, float h)
AI Rect makeIntersect(Rect rect) const
AI Rect makeRoundOut() const
FlPixelBufferTexturePrivate * priv
static float max(float r, float g, float b)
constexpr SkColor4f kBlack
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
SkColorType ComputeShaderCoverageMaskTargetFormat(const Caps *caps)
skgpu::graphite::DrawAtlas DrawAtlas
skgpu::graphite::Transform Transform
SIT bool all(const Vec< 1, T > &x)
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
constexpr int32_t y() const
constexpr int32_t x() const
constexpr int32_t height() const
constexpr int32_t width() const
constexpr int32_t width() const
constexpr int32_t height() const
#define TRACE_EVENT_INSTANT1(category_group, name, arg1_name, arg1_val)