xref: /aosp_15_r20/external/skia/src/core/SkDraw_atlas.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2019 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 "include/core/SkAlphaType.h"
9 #include "include/core/SkColor.h"
10 #include "include/core/SkMaskFilter.h"
11 #include "include/core/SkMatrix.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPath.h"
14 #include "include/core/SkPixmap.h"
15 #include "include/core/SkPoint.h"
16 #include "include/core/SkRSXform.h"
17 #include "include/core/SkRect.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkScalar.h"
20 #include "include/core/SkShader.h"
21 #include "include/core/SkSurfaceProps.h"
22 #include "src/base/SkArenaAlloc.h"
23 #include "src/core/SkBlendModePriv.h"
24 #include "src/core/SkBlenderBase.h"
25 #include "src/core/SkColorSpacePriv.h"
26 #include "src/core/SkColorSpaceXformSteps.h"
27 #include "src/core/SkCoreBlitters.h"
28 #include "src/core/SkDraw.h"
29 #include "src/core/SkEffectPriv.h"
30 #include "src/core/SkRasterClip.h"
31 #include "src/core/SkRasterPipeline.h"
32 #include "src/core/SkRasterPipelineOpContexts.h"
33 #include "src/core/SkRasterPipelineOpList.h"
34 #include "src/core/SkScan.h"
35 #include "src/core/SkSurfacePriv.h"
36 #include "src/shaders/SkShaderBase.h"
37 #include "src/shaders/SkTransformShader.h"
38 
39 #include <cstdint>
40 #include <optional>
41 
42 class SkBlender;
43 class SkBlitter;
44 enum class SkBlendMode;
45 
fill_rect(const SkMatrix & ctm,const SkRasterClip & rc,const SkRect & r,SkBlitter * blitter,SkPath * scratchPath)46 static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
47                       const SkRect& r, SkBlitter* blitter, SkPath* scratchPath) {
48     if (ctm.rectStaysRect()) {
49         SkRect dr;
50         ctm.mapRect(&dr, r);
51         SkScan::FillRect(dr, rc, blitter);
52     } else {
53         SkPoint pts[4];
54         r.toQuad(pts);
55         ctm.mapPoints(pts, pts, 4);
56 
57         scratchPath->rewind();
58         scratchPath->addPoly(pts, 4, true);
59         SkScan::FillPath(*scratchPath, rc, blitter);
60     }
61 }
62 
load_color(SkRasterPipeline_UniformColorCtx * ctx,const float rgba[])63 static void load_color(SkRasterPipeline_UniformColorCtx* ctx, const float rgba[]) {
64     // only need one of these. can I query the pipeline to know if its lowp or highp?
65     ctx->rgba[0] = SkScalarRoundToInt(rgba[0]*255); ctx->r = rgba[0];
66     ctx->rgba[1] = SkScalarRoundToInt(rgba[1]*255); ctx->g = rgba[1];
67     ctx->rgba[2] = SkScalarRoundToInt(rgba[2]*255); ctx->b = rgba[2];
68     ctx->rgba[3] = SkScalarRoundToInt(rgba[3]*255); ctx->a = rgba[3];
69 }
70 
drawAtlas(const SkRSXform xform[],const SkRect textures[],const SkColor colors[],int count,sk_sp<SkBlender> blender,const SkPaint & paint)71 void SkDraw::drawAtlas(const SkRSXform xform[],
72                        const SkRect textures[],
73                        const SkColor colors[],
74                        int count,
75                        sk_sp<SkBlender> blender,
76                        const SkPaint& paint) {
77     sk_sp<SkShader> atlasShader = paint.refShader();
78     if (!atlasShader) {
79         return;
80     }
81 
82     SkSTArenaAlloc<256> alloc;
83 
84     SkPaint p(paint);
85     p.setAntiAlias(false);  // we never respect this for drawAtlas(or drawVertices)
86     p.setStyle(SkPaint::kFill_Style);
87     p.setShader(nullptr);
88     p.setMaskFilter(nullptr);
89 
90     // The RSXForms can't contain perspective - only the CTM can.
91     const bool perspective = fCTM->hasPerspective();
92 
93     auto transformShader = alloc.make<SkTransformShader>(*as_SB(atlasShader), perspective);
94 
95     SkRasterPipeline pipeline(&alloc);
96     SkSurfaceProps props = SkSurfacePropsCopyOrDefault(fProps);
97     SkStageRec rec = {&pipeline, &alloc, fDst.colorType(), fDst.colorSpace(),
98                       p.getColor4f(), props};
99     // We pass an identity matrix here rather than the CTM. The CTM gets folded into the
100     // per-triangle matrix.
101     if (!as_SB(transformShader)->appendRootStages(rec, SkMatrix::I())) {
102         return;
103     }
104 
105     SkRasterPipeline_UniformColorCtx* uniformCtx = nullptr;
106     SkColorSpaceXformSteps steps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
107                                  rec.fDstCS, kUnpremul_SkAlphaType);
108     if (colors) {
109         // we will late-bind the values in ctx, once for each color in the loop
110         uniformCtx = alloc.make<SkRasterPipeline_UniformColorCtx>();
111         rec.fPipeline->append(SkRasterPipelineOp::uniform_color_dst, uniformCtx);
112         std::optional<SkBlendMode> bm = as_BB(blender)->asBlendMode();
113         if (!bm.has_value()) {
114             return;
115         }
116         SkBlendMode_AppendStages(*bm, rec.fPipeline);
117     }
118 
119     bool isOpaque = !colors && transformShader->isOpaque();
120     if (p.getAlphaf() != 1) {
121         rec.fPipeline->append(SkRasterPipelineOp::scale_1_float, alloc.make<float>(p.getAlphaf()));
122         isOpaque = false;
123     }
124 
125     auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc,
126                                                  fRC->clipShader());
127     if (!blitter) {
128         return;
129     }
130     SkPath scratchPath;
131 
132     for (int i = 0; i < count; ++i) {
133         if (colors) {
134             SkColor4f c4 = SkColor4f::FromColor(colors[i]);
135             steps.apply(c4.vec());
136             load_color(uniformCtx, c4.premul().vec());
137         }
138 
139         SkMatrix mx;
140         mx.setRSXform(xform[i]);
141         mx.preTranslate(-textures[i].fLeft, -textures[i].fTop);
142         mx.postConcat(*fCTM);
143         SkMatrix inv;
144         if (!mx.invert(&inv)) {
145             return;
146         }
147         if (transformShader->update(inv)) {
148             fill_rect(mx, *fRC, textures[i], blitter, &scratchPath);
149         }
150     }
151 }
152