Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkDraw_atlas.cpp
Go to the documentation of this file.
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
13#include "include/core/SkPath.h"
17#include "include/core/SkRect.h"
28#include "src/core/SkDraw.h"
34#include "src/core/SkScan.h"
38
39#include <cstdint>
40#include <optional>
41
42class SkBlender;
43class SkBlitter;
44enum class SkBlendMode;
45
46static 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
63static 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
71void 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
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);
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;
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 }
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);
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}
static SkM44 inv(const SkM44 &m)
Definition 3d.cpp:26
int count
kUnpremul_SkAlphaType
static const uint32_t rgba[kNumPixels]
void SkBlendMode_AppendStages(SkBlendMode mode, SkRasterPipeline *p)
SkBlendMode
Definition SkBlendMode.h:38
SkBlenderBase * as_BB(SkBlender *blend)
SkColorSpace * sk_srgb_singleton()
uint32_t SkColor
Definition SkColor.h:37
SkBlitter * SkCreateRasterPipelineBlitter(const SkPixmap &, const SkPaint &, const SkMatrix &ctm, SkArenaAlloc *, sk_sp< SkShader > clipShader, const SkSurfaceProps &props)
static void fill_rect(const SkMatrix &ctm, const SkRasterClip &rc, const SkRect &r, SkBlitter *blitter, SkPath *scratchPath)
static void load_color(SkRasterPipeline_UniformColorCtx *ctx, const float rgba[])
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
SkShaderBase * as_SB(SkShader *shader)
static SkSurfaceProps SkSurfacePropsCopyOrDefault(const SkSurfaceProps *props)
static void fill_rect(SkCanvas *canvas, const SkRect &r, const SkPaint &p)
Definition blurrect.cpp:44
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
virtual std::optional< SkBlendMode > asBlendMode() const
const SkSurfaceProps * fProps
Definition SkDrawBase.h:155
const SkRasterClip * fRC
Definition SkDrawBase.h:154
SkPixmap fDst
Definition SkDrawBase.h:151
const SkMatrix * fCTM
Definition SkDrawBase.h:153
void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp< SkBlender >, const SkPaint &)
SkMatrix & postConcat(const SkMatrix &other)
Definition SkMatrix.cpp:683
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
bool rectStaysRect() const
Definition SkMatrix.h:271
SkMatrix & setRSXform(const SkRSXform &rsxForm)
Definition SkMatrix.cpp:420
static const SkMatrix & I()
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:263
bool hasPerspective() const
Definition SkMatrix.h:312
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
SkPath & addPoly(const SkPoint pts[], int count, bool close)
Definition SkPath.cpp:880
SkPath & rewind()
Definition SkPath.cpp:372
SkColorType colorType() const
Definition SkPixmap.h:173
SkColorSpace * colorSpace() const
Definition SkPixmap.cpp:61
sk_sp< SkShader > clipShader() const
void append(SkRasterPipelineOp, void *=nullptr)
static void FillRect(const SkRect &, const SkRasterClip &, SkBlitter *)
Definition SkScan.cpp:95
static void FillPath(const SkPath &, const SkIRect &, SkBlitter *)
const Paint & paint
std::vector< std::shared_ptr< FakeTexture > > textures
void apply(float rgba[4]) const
static SkRGBA4f FromColor(SkColor color)
void toQuad(SkPoint quad[4]) const
Definition SkRect.cpp:50
SkRasterPipeline * fPipeline
SkColorSpace * fDstCS