blob: ec190c786cc419bffd42be5551efee1123783f04 [file] [log] [blame]
joshualitt9ff64252015-08-10 09:03:51 -07001/*
2 * Copyright 2015 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
joshualitt37eb1842015-08-12 06:36:57 -07008#include "GrColor.h"
joshualitt9ff64252015-08-10 09:03:51 -07009#include "GrDefaultGeoProcFactory.h"
Brian Salomondad29232016-12-01 16:40:24 -050010#include "GrMeshDrawOp.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050011#include "GrOpFlushState.h"
Brian Salomonbaaf4392017-06-15 09:59:23 -040012#include "GrRectOpFactory.h"
joshualitt9ff64252015-08-10 09:03:51 -070013#include "GrResourceKey.h"
14#include "GrResourceProvider.h"
joshualitt37eb1842015-08-12 06:36:57 -070015#include "GrTypes.h"
16#include "SkMatrix.h"
17#include "SkRect.h"
Brian Salomonbaaf4392017-06-15 09:59:23 -040018#include "ops/GrSimpleMeshDrawOpHelper.h"
joshualitt9ff64252015-08-10 09:03:51 -070019
20GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
21
Brian Salomonbaaf4392017-06-15 09:59:23 -040022static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
23 return viewMatrix.preservesRightAngles();
24}
25
26static inline void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx,
27 SkScalar dy) {
Brian Salomon6a639042016-12-14 11:08:17 -050028 pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
joshualitt9ff64252015-08-10 09:03:51 -070029}
30
joshualitt27801bf2015-08-12 12:52:47 -070031static const int kNumAAFillRectsInIndexBuffer = 256;
32static const int kVertsPerAAFillRect = 8;
33static const int kIndicesPerAAFillRect = 30;
34
cdalton397536c2016-03-25 12:15:03 -070035const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
joshualitt27801bf2015-08-12 12:52:47 -070036 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
37
Brian Salomon6a639042016-12-14 11:08:17 -050038 // clang-format off
joshualitt27801bf2015-08-12 12:52:47 -070039 static const uint16_t gFillAARectIdx[] = {
40 0, 1, 5, 5, 4, 0,
41 1, 2, 6, 6, 5, 1,
42 2, 3, 7, 7, 6, 2,
43 3, 0, 4, 4, 7, 3,
44 4, 5, 6, 6, 7, 4,
45 };
Brian Salomon6a639042016-12-14 11:08:17 -050046 // clang-format on
47
joshualitt27801bf2015-08-12 12:52:47 -070048 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
Chris Daltonff926502017-05-03 14:36:54 -040049 return resourceProvider->findOrCreatePatternedIndexBuffer(
Brian Salomon6a639042016-12-14 11:08:17 -050050 gFillAARectIdx, kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer,
51 kVertsPerAAFillRect, gAAFillRectIndexBufferKey);
joshualitt27801bf2015-08-12 12:52:47 -070052}
53
joshualittcd47b712015-08-18 07:25:38 -070054static void generate_aa_fill_rect_geometry(intptr_t verts,
55 size_t vertexStride,
56 GrColor color,
57 const SkMatrix& viewMatrix,
58 const SkRect& rect,
59 const SkRect& devRect,
Brian Salomonecea86a2017-01-04 13:25:17 -050060 bool tweakAlphaForCoverage,
joshualittcd47b712015-08-18 07:25:38 -070061 const SkMatrix* localMatrix) {
62 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
63 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
64
robertphillips0851d2d2016-06-02 05:21:34 -070065 SkScalar inset;
joshualittcd47b712015-08-18 07:25:38 -070066
67 if (viewMatrix.rectStaysRect()) {
robertphillips0851d2d2016-06-02 05:21:34 -070068 inset = SkMinScalar(devRect.width(), SK_Scalar1);
69 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
70
joshualittcd47b712015-08-18 07:25:38 -070071 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
Brian Salomon6a639042016-12-14 11:08:17 -050072 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
joshualittcd47b712015-08-18 07:25:38 -070073 } else {
74 // compute transformed (1, 0) and (0, 1) vectors
Brian Salomon6a639042016-12-14 11:08:17 -050075 SkVector vec[2] = {{viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY]},
76 {viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY]}};
joshualittcd47b712015-08-18 07:25:38 -070077
robertphillips0851d2d2016-06-02 05:21:34 -070078 SkScalar len1 = SkPoint::Normalize(&vec[0]);
joshualittcd47b712015-08-18 07:25:38 -070079 vec[0].scale(SK_ScalarHalf);
robertphillips0851d2d2016-06-02 05:21:34 -070080 SkScalar len2 = SkPoint::Normalize(&vec[1]);
joshualittcd47b712015-08-18 07:25:38 -070081 vec[1].scale(SK_ScalarHalf);
82
robertphillips0851d2d2016-06-02 05:21:34 -070083 inset = SkMinScalar(len1 * rect.width(), SK_Scalar1);
84 inset = SK_ScalarHalf * SkMinScalar(inset, len2 * rect.height());
85
joshualittcd47b712015-08-18 07:25:38 -070086 // create the rotated rect
Brian Salomon6a639042016-12-14 11:08:17 -050087 fan0Pos->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride);
joshualittcd47b712015-08-18 07:25:38 -070088 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
89
90 // Now create the inset points and then outset the original
91 // rotated points
92
93 // TL
94 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -050095 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
joshualittcd47b712015-08-18 07:25:38 -070096 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
97 // BL
98 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -050099 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
joshualittcd47b712015-08-18 07:25:38 -0700100 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
101 // BR
102 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -0500103 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
joshualittcd47b712015-08-18 07:25:38 -0700104 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
105 // TR
106 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -0500107 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
joshualittcd47b712015-08-18 07:25:38 -0700108 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
109 }
110
111 if (localMatrix) {
112 SkMatrix invViewMatrix;
113 if (!viewMatrix.invert(&invViewMatrix)) {
bsalomon4be9a302016-07-06 07:03:26 -0700114 SkDebugf("View matrix is non-invertible, local coords will be wrong.");
joshualittcd47b712015-08-18 07:25:38 -0700115 invViewMatrix = SkMatrix::I();
116 }
117 SkMatrix localCoordMatrix;
118 localCoordMatrix.setConcat(*localMatrix, invViewMatrix);
119 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) + sizeof(GrColor));
120 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
121 }
122
joshualittcd47b712015-08-18 07:25:38 -0700123 // Make verts point to vertex color and then set all the color and coverage vertex attrs
124 // values.
125 verts += sizeof(SkPoint);
126
127 // The coverage offset is always the last vertex attribute
128 intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoint);
129 for (int i = 0; i < 4; ++i) {
130 if (tweakAlphaForCoverage) {
131 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
132 } else {
133 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
134 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = 0;
135 }
136 }
137
138 int scale;
139 if (inset < SK_ScalarHalf) {
140 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
141 SkASSERT(scale >= 0 && scale <= 255);
142 } else {
143 scale = 0xff;
144 }
145
146 verts += 4 * vertexStride;
147
148 float innerCoverage = GrNormalizeByteToFloat(scale);
149 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
150
151 for (int i = 0; i < 4; ++i) {
152 if (tweakAlphaForCoverage) {
153 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
154 } else {
155 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
Brian Salomon6a639042016-12-14 11:08:17 -0500156 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = innerCoverage;
joshualittcd47b712015-08-18 07:25:38 -0700157 }
158 }
159}
Brian Salomon6a639042016-12-14 11:08:17 -0500160
Brian Salomonbaaf4392017-06-15 09:59:23 -0400161namespace {
162
163class AAFillRectOp final : public GrMeshDrawOp {
164private:
165 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
166
joshualitt2ad37be2015-08-18 10:16:01 -0700167public:
Brian Salomon25a88092016-12-01 09:36:50 -0500168 DEFINE_OP_CLASS_ID
bsalomon4be9a302016-07-06 07:03:26 -0700169
Brian Salomonbaaf4392017-06-15 09:59:23 -0400170 static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint,
171 const SkMatrix& viewMatrix,
172 const SkRect& rect,
173 const SkRect& devRect,
174 const SkMatrix* localMatrix,
175 const GrUserStencilSettings* stencil) {
176 SkASSERT(view_matrix_ok_for_aa_fill_rect(viewMatrix));
177 return Helper::FactoryHelper<AAFillRectOp>(std::move(paint), viewMatrix, rect, devRect,
178 localMatrix, stencil);
179 }
180
181 AAFillRectOp(const Helper::MakeArgs& helperArgs,
182 GrColor color,
Brian Salomon6a639042016-12-14 11:08:17 -0500183 const SkMatrix& viewMatrix,
184 const SkRect& rect,
185 const SkRect& devRect,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400186 const SkMatrix* localMatrix,
187 const GrUserStencilSettings* stencil)
188 : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage, stencil) {
bsalomon4be9a302016-07-06 07:03:26 -0700189 if (localMatrix) {
190 void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo));
191 new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix);
192 } else {
193 void* mem = fRectData.push_back_n(sizeof(RectInfo));
194 new (mem) RectInfo(color, viewMatrix, rect, devRect);
195 }
Brian Salomon6a639042016-12-14 11:08:17 -0500196 IsZeroArea zeroArea =
197 (!rect.width() || !rect.height()) ? IsZeroArea::kYes : IsZeroArea::kNo;
bsalomon88cf17d2016-07-08 06:40:56 -0700198 this->setBounds(devRect, HasAABloat::kYes, zeroArea);
bsalomon4be9a302016-07-06 07:03:26 -0700199 fRectCnt = 1;
bsalomon0fdec8a2016-07-01 06:31:25 -0700200 }
bsalomon08d14152016-06-30 12:45:18 -0700201
Brian Salomon6a639042016-12-14 11:08:17 -0500202 const char* name() const override { return "AAFillRectOp"; }
bsalomon08d14152016-06-30 12:45:18 -0700203
204 SkString dumpInfo() const override {
205 SkString str;
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400206 str.append(INHERITED::dumpInfo());
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500207 str.appendf("# combined: %d\n", fRectCnt);
bsalomon4be9a302016-07-06 07:03:26 -0700208 const RectInfo* info = this->first();
209 for (int i = 0; i < fRectCnt; ++i) {
210 const SkRect& rect = info->rect();
Brian Salomon6a639042016-12-14 11:08:17 -0500211 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
212 info->color(), rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
bsalomon4be9a302016-07-06 07:03:26 -0700213 info = this->next(info);
bsalomon08d14152016-06-30 12:45:18 -0700214 }
bsalomon08d14152016-06-30 12:45:18 -0700215 return str;
216 }
217
Brian Salomonbaaf4392017-06-15 09:59:23 -0400218 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
219
220 bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
221 GrColor color = this->first()->color();
222 bool result = fHelper.xpRequiresDstTexture(
223 caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, &color);
224 this->first()->setColor(color);
225 return result;
bsalomon08d14152016-06-30 12:45:18 -0700226 }
227
bsalomon08d14152016-06-30 12:45:18 -0700228private:
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700229 void onPrepareDraws(Target* target) const override {
bsalomon4be9a302016-07-06 07:03:26 -0700230 using namespace GrDefaultGeoProcFactory;
231
Brian Salomon3de0aee2017-01-29 09:34:17 -0500232 Color color(Color::kPremulGrColorAttribute_Type);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400233 Coverage::Type coverageType = fHelper.compatibleWithAlphaAsCoverage()
234 ? Coverage::kSolid_Type
235 : Coverage::kAttribute_Type;
236 LocalCoords lc = fHelper.usesLocalCoords() ? LocalCoords::kHasExplicit_Type
237 : LocalCoords::kUnused_Type;
Brian Salomon6a639042016-12-14 11:08:17 -0500238 sk_sp<GrGeometryProcessor> gp =
Brian Salomon8c852be2017-01-04 10:44:42 -0500239 GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I());
bsalomon08d14152016-06-30 12:45:18 -0700240 if (!gp) {
241 SkDebugf("Couldn't create GrGeometryProcessor\n");
242 return;
243 }
244
245 size_t vertexStride = gp->getVertexStride();
bsalomon08d14152016-06-30 12:45:18 -0700246
Hal Canary144caf52016-11-07 17:57:18 -0500247 sk_sp<const GrBuffer> indexBuffer(get_index_buffer(target->resourceProvider()));
Chris Dalton3809bab2017-06-13 10:55:06 -0600248 PatternHelper helper(GrPrimitiveType::kTriangles);
Brian Salomon6a639042016-12-14 11:08:17 -0500249 void* vertices =
Chris Daltonbca46e22017-05-15 11:03:26 -0600250 helper.init(target, vertexStride, indexBuffer.get(), kVertsPerAAFillRect,
251 kIndicesPerAAFillRect, fRectCnt);
bsalomon08d14152016-06-30 12:45:18 -0700252 if (!vertices || !indexBuffer) {
253 SkDebugf("Could not allocate vertices\n");
254 return;
255 }
256
bsalomon4be9a302016-07-06 07:03:26 -0700257 const RectInfo* info = this->first();
258 const SkMatrix* localMatrix = nullptr;
259 for (int i = 0; i < fRectCnt; i++) {
Brian Salomon6a639042016-12-14 11:08:17 -0500260 intptr_t verts =
261 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride;
Brian Salomonbaaf4392017-06-15 09:59:23 -0400262 if (fHelper.usesLocalCoords()) {
bsalomon4be9a302016-07-06 07:03:26 -0700263 if (info->hasLocalMatrix()) {
264 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix();
265 } else {
266 localMatrix = &SkMatrix::I();
267 }
268 }
Brian Salomon6a639042016-12-14 11:08:17 -0500269 generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), info->viewMatrix(),
Brian Salomonbaaf4392017-06-15 09:59:23 -0400270 info->rect(), info->devRect(),
271 fHelper.compatibleWithAlphaAsCoverage(), localMatrix);
bsalomon4be9a302016-07-06 07:03:26 -0700272 info = this->next(info);
bsalomon08d14152016-06-30 12:45:18 -0700273 }
Brian Salomonbaaf4392017-06-15 09:59:23 -0400274 helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
bsalomon08d14152016-06-30 12:45:18 -0700275 }
276
Brian Salomon25a88092016-12-01 09:36:50 -0500277 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
Brian Salomon6a639042016-12-14 11:08:17 -0500278 AAFillRectOp* that = t->cast<AAFillRectOp>();
Brian Salomonbaaf4392017-06-15 09:59:23 -0400279 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700280 return false;
281 }
282
bsalomon4be9a302016-07-06 07:03:26 -0700283 fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin());
284 fRectCnt += that->fRectCnt;
bsalomon88cf17d2016-07-08 06:40:56 -0700285 this->joinBounds(*that);
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700286 return true;
287 }
288
289 struct RectInfo {
bsalomon4be9a302016-07-06 07:03:26 -0700290 public:
291 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
292 const SkRect& devRect)
Brian Salomon6a639042016-12-14 11:08:17 -0500293 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {}
bsalomon4be9a302016-07-06 07:03:26 -0700294 bool hasLocalMatrix() const { return HasLocalMatrix::kYes == fHasLocalMatrix; }
295 GrColor color() const { return fColor; }
296 const SkMatrix& viewMatrix() const { return fViewMatrix; }
297 const SkRect& rect() const { return fRect; }
298 const SkRect& devRect() const { return fDevRect; }
299
300 void setColor(GrColor color) { fColor = color; }
Brian Salomon6a639042016-12-14 11:08:17 -0500301
bsalomon4be9a302016-07-06 07:03:26 -0700302 protected:
303 enum class HasLocalMatrix : uint32_t { kNo, kYes };
304
305 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
306 const SkRect& devRect, HasLocalMatrix hasLM)
307 : fHasLocalMatrix(hasLM)
308 , fColor(color)
309 , fViewMatrix(viewMatrix)
310 , fRect(rect)
311 , fDevRect(devRect) {}
312
313 HasLocalMatrix fHasLocalMatrix;
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700314 GrColor fColor;
315 SkMatrix fViewMatrix;
316 SkRect fRect;
317 SkRect fDevRect;
318 };
319
bsalomon4be9a302016-07-06 07:03:26 -0700320 struct RectWithLocalMatrixInfo : public RectInfo {
321 public:
322 RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
323 const SkRect& devRect, const SkMatrix& localMatrix)
Brian Salomon6a639042016-12-14 11:08:17 -0500324 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes)
325 , fLocalMatrix(localMatrix) {}
bsalomon4be9a302016-07-06 07:03:26 -0700326 const SkMatrix& localMatrix() const { return fLocalMatrix; }
Brian Salomon6a639042016-12-14 11:08:17 -0500327
bsalomon4be9a302016-07-06 07:03:26 -0700328 private:
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700329 SkMatrix fLocalMatrix;
bsalomon0fdec8a2016-07-01 06:31:25 -0700330 };
331
bsalomon4be9a302016-07-06 07:03:26 -0700332 RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); }
333 const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRectData.begin()); }
334 const RectInfo* next(const RectInfo* prev) const {
Brian Salomon6a639042016-12-14 11:08:17 -0500335 intptr_t next =
336 reinterpret_cast<intptr_t>(prev) +
337 (prev->hasLocalMatrix() ? sizeof(RectWithLocalMatrixInfo) : sizeof(RectInfo));
bsalomon4be9a302016-07-06 07:03:26 -0700338 return reinterpret_cast<const RectInfo*>(next);
339 }
340
bsalomon4be9a302016-07-06 07:03:26 -0700341 SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData;
Brian Salomonbaaf4392017-06-15 09:59:23 -0400342 Helper fHelper;
bsalomon4be9a302016-07-06 07:03:26 -0700343 int fRectCnt;
bsalomon08d14152016-06-30 12:45:18 -0700344
Brian Salomonbaaf4392017-06-15 09:59:23 -0400345 typedef GrMeshDrawOp INHERITED;
joshualitt147dc062015-08-12 11:51:46 -0700346};
347
Brian Salomonbaaf4392017-06-15 09:59:23 -0400348} // anonymous namespace
joshualitt9ff64252015-08-10 09:03:51 -0700349
Brian Salomonbaaf4392017-06-15 09:59:23 -0400350namespace GrRectOpFactory {
joshualitt147dc062015-08-12 11:51:46 -0700351
Brian Salomonbaaf4392017-06-15 09:59:23 -0400352std::unique_ptr<GrDrawOp> MakeAAFill(GrPaint&& paint, const SkMatrix& viewMatrix,
353 const SkRect& rect, const GrUserStencilSettings* stencil) {
354 if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
355 return nullptr;
356 }
bsalomonc55271f2015-11-09 11:55:57 -0800357 SkRect devRect;
358 viewMatrix.mapRect(&devRect, rect);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400359 return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, stencil);
bsalomonc55271f2015-11-09 11:55:57 -0800360}
361
Brian Salomonbaaf4392017-06-15 09:59:23 -0400362std::unique_ptr<GrDrawOp> MakeAAFillWithDevRect(GrPaint&& paint, const SkMatrix& viewMatrix,
363 const SkRect& rect, const SkRect& devRect) {
364 if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
365 return nullptr;
366 }
367 return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, nullptr);
368}
369
370std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrPaint&& paint, const SkMatrix& viewMatrix,
371 const SkMatrix& localMatrix,
372 const SkRect& rect) {
373 if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
374 return nullptr;
375 }
376 SkRect devRect;
377 viewMatrix.mapRect(&devRect, rect);
378 return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr);
379}
380
381std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix,
382 const SkRect& rect, const SkRect& localRect) {
383 if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
384 return nullptr;
385 }
bsalomonc55271f2015-11-09 11:55:57 -0800386 SkRect devRect;
387 viewMatrix.mapRect(&devRect, rect);
388 SkMatrix localMatrix;
389 if (!localMatrix.setRectToRect(rect, localRect, SkMatrix::kFill_ScaleToFit)) {
390 return nullptr;
391 }
Brian Salomonbaaf4392017-06-15 09:59:23 -0400392 return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr);
bsalomonc55271f2015-11-09 11:55:57 -0800393}
Brian Salomonbaaf4392017-06-15 09:59:23 -0400394
395} // namespace GrRectOpFactory
joshualitt37eb1842015-08-12 06:36:57 -0700396
joshualitt9ff64252015-08-10 09:03:51 -0700397///////////////////////////////////////////////////////////////////////////////////////////////////
398
Hal Canary6f6961e2017-01-31 13:50:44 -0500399#if GR_TEST_UTILS
joshualitt9ff64252015-08-10 09:03:51 -0700400
Brian Salomon5ec9def2016-12-20 15:34:05 -0500401#include "GrDrawOpTest.h"
joshualitt9ff64252015-08-10 09:03:51 -0700402
Brian Salomonbaaf4392017-06-15 09:59:23 -0400403GR_DRAW_OP_TEST_DEFINE(AAFillRectOp) {
404 SkMatrix viewMatrix;
405 do {
406 viewMatrix = GrTest::TestMatrixInvertible(random);
407 } while (!view_matrix_ok_for_aa_fill_rect(viewMatrix));
joshualitt090ae8e2015-08-14 09:01:21 -0700408 SkRect rect = GrTest::TestRect(random);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400409 SkRect devRect;
410 viewMatrix.mapRect(&devRect, rect);
411 const SkMatrix* localMatrix = nullptr;
412 SkMatrix m;
413 if (random->nextBool()) {
414 m = GrTest::TestMatrix(random);
415 }
416 const GrUserStencilSettings* stencil =
417 random->nextBool() ? nullptr : GrGetRandomStencil(random, context);
418 return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, localMatrix, stencil);
joshualitt9ff64252015-08-10 09:03:51 -0700419}
420
421#endif