blob: 5c585bf67f6295ae78bc42d1fc3d9e4eeb01e0a1 [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
Brian Salomon6a639042016-12-14 11:08:17 -05008#include "GrAAFillRectOp.h"
joshualitt9ff64252015-08-10 09:03:51 -07009
joshualitt37eb1842015-08-12 06:36:57 -070010#include "GrColor.h"
joshualitt9ff64252015-08-10 09:03:51 -070011#include "GrDefaultGeoProcFactory.h"
Brian Salomondad29232016-12-01 16:40:24 -050012#include "GrMeshDrawOp.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050013#include "GrOpFlushState.h"
joshualitt9ff64252015-08-10 09:03:51 -070014#include "GrResourceKey.h"
15#include "GrResourceProvider.h"
joshualitt37eb1842015-08-12 06:36:57 -070016#include "GrTypes.h"
17#include "SkMatrix.h"
18#include "SkRect.h"
joshualitt9ff64252015-08-10 09:03:51 -070019
20GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
21
Brian Salomon6a639042016-12-14 11:08:17 -050022static void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, SkScalar dy) {
23 pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
joshualitt9ff64252015-08-10 09:03:51 -070024}
25
joshualitt27801bf2015-08-12 12:52:47 -070026static const int kNumAAFillRectsInIndexBuffer = 256;
27static const int kVertsPerAAFillRect = 8;
28static const int kIndicesPerAAFillRect = 30;
29
cdalton397536c2016-03-25 12:15:03 -070030const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
joshualitt27801bf2015-08-12 12:52:47 -070031 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
32
Brian Salomon6a639042016-12-14 11:08:17 -050033 // clang-format off
joshualitt27801bf2015-08-12 12:52:47 -070034 static const uint16_t gFillAARectIdx[] = {
35 0, 1, 5, 5, 4, 0,
36 1, 2, 6, 6, 5, 1,
37 2, 3, 7, 7, 6, 2,
38 3, 0, 4, 4, 7, 3,
39 4, 5, 6, 6, 7, 4,
40 };
Brian Salomon6a639042016-12-14 11:08:17 -050041 // clang-format on
42
joshualitt27801bf2015-08-12 12:52:47 -070043 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
Brian Salomon6a639042016-12-14 11:08:17 -050044 return resourceProvider->findOrCreateInstancedIndexBuffer(
45 gFillAARectIdx, kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer,
46 kVertsPerAAFillRect, gAAFillRectIndexBufferKey);
joshualitt27801bf2015-08-12 12:52:47 -070047}
48
joshualittcd47b712015-08-18 07:25:38 -070049static void generate_aa_fill_rect_geometry(intptr_t verts,
50 size_t vertexStride,
51 GrColor color,
52 const SkMatrix& viewMatrix,
53 const SkRect& rect,
54 const SkRect& devRect,
Brian Salomonecea86a2017-01-04 13:25:17 -050055 bool tweakAlphaForCoverage,
joshualittcd47b712015-08-18 07:25:38 -070056 const SkMatrix* localMatrix) {
57 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
58 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
59
robertphillips0851d2d2016-06-02 05:21:34 -070060 SkScalar inset;
joshualittcd47b712015-08-18 07:25:38 -070061
62 if (viewMatrix.rectStaysRect()) {
robertphillips0851d2d2016-06-02 05:21:34 -070063 inset = SkMinScalar(devRect.width(), SK_Scalar1);
64 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
65
joshualittcd47b712015-08-18 07:25:38 -070066 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
Brian Salomon6a639042016-12-14 11:08:17 -050067 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
joshualittcd47b712015-08-18 07:25:38 -070068 } else {
69 // compute transformed (1, 0) and (0, 1) vectors
Brian Salomon6a639042016-12-14 11:08:17 -050070 SkVector vec[2] = {{viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY]},
71 {viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY]}};
joshualittcd47b712015-08-18 07:25:38 -070072
robertphillips0851d2d2016-06-02 05:21:34 -070073 SkScalar len1 = SkPoint::Normalize(&vec[0]);
joshualittcd47b712015-08-18 07:25:38 -070074 vec[0].scale(SK_ScalarHalf);
robertphillips0851d2d2016-06-02 05:21:34 -070075 SkScalar len2 = SkPoint::Normalize(&vec[1]);
joshualittcd47b712015-08-18 07:25:38 -070076 vec[1].scale(SK_ScalarHalf);
77
robertphillips0851d2d2016-06-02 05:21:34 -070078 inset = SkMinScalar(len1 * rect.width(), SK_Scalar1);
79 inset = SK_ScalarHalf * SkMinScalar(inset, len2 * rect.height());
80
joshualittcd47b712015-08-18 07:25:38 -070081 // create the rotated rect
Brian Salomon6a639042016-12-14 11:08:17 -050082 fan0Pos->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride);
joshualittcd47b712015-08-18 07:25:38 -070083 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
84
85 // Now create the inset points and then outset the original
86 // rotated points
87
88 // TL
89 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -050090 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
joshualittcd47b712015-08-18 07:25:38 -070091 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
92 // BL
93 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -050094 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
joshualittcd47b712015-08-18 07:25:38 -070095 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
96 // BR
97 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -050098 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
joshualittcd47b712015-08-18 07:25:38 -070099 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
100 // TR
101 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
Brian Salomon6a639042016-12-14 11:08:17 -0500102 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
joshualittcd47b712015-08-18 07:25:38 -0700103 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
104 }
105
106 if (localMatrix) {
107 SkMatrix invViewMatrix;
108 if (!viewMatrix.invert(&invViewMatrix)) {
bsalomon4be9a302016-07-06 07:03:26 -0700109 SkDebugf("View matrix is non-invertible, local coords will be wrong.");
joshualittcd47b712015-08-18 07:25:38 -0700110 invViewMatrix = SkMatrix::I();
111 }
112 SkMatrix localCoordMatrix;
113 localCoordMatrix.setConcat(*localMatrix, invViewMatrix);
114 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) + sizeof(GrColor));
115 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
116 }
117
joshualittcd47b712015-08-18 07:25:38 -0700118 // Make verts point to vertex color and then set all the color and coverage vertex attrs
119 // values.
120 verts += sizeof(SkPoint);
121
122 // The coverage offset is always the last vertex attribute
123 intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoint);
124 for (int i = 0; i < 4; ++i) {
125 if (tweakAlphaForCoverage) {
126 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
127 } else {
128 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
129 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = 0;
130 }
131 }
132
133 int scale;
134 if (inset < SK_ScalarHalf) {
135 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
136 SkASSERT(scale >= 0 && scale <= 255);
137 } else {
138 scale = 0xff;
139 }
140
141 verts += 4 * vertexStride;
142
143 float innerCoverage = GrNormalizeByteToFloat(scale);
144 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
145
146 for (int i = 0; i < 4; ++i) {
147 if (tweakAlphaForCoverage) {
148 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
149 } else {
150 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
Brian Salomon6a639042016-12-14 11:08:17 -0500151 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = innerCoverage;
joshualittcd47b712015-08-18 07:25:38 -0700152 }
153 }
154}
Brian Salomon6a639042016-12-14 11:08:17 -0500155
156class AAFillRectOp final: public GrMeshDrawOp {
joshualitt2ad37be2015-08-18 10:16:01 -0700157public:
Brian Salomon25a88092016-12-01 09:36:50 -0500158 DEFINE_OP_CLASS_ID
bsalomon4be9a302016-07-06 07:03:26 -0700159
Brian Salomon6a639042016-12-14 11:08:17 -0500160 AAFillRectOp(GrColor color,
161 const SkMatrix& viewMatrix,
162 const SkRect& rect,
163 const SkRect& devRect,
164 const SkMatrix* localMatrix)
165 : INHERITED(ClassID()) {
bsalomon4be9a302016-07-06 07:03:26 -0700166 if (localMatrix) {
167 void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo));
168 new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix);
169 } else {
170 void* mem = fRectData.push_back_n(sizeof(RectInfo));
171 new (mem) RectInfo(color, viewMatrix, rect, devRect);
172 }
Brian Salomon6a639042016-12-14 11:08:17 -0500173 IsZeroArea zeroArea =
174 (!rect.width() || !rect.height()) ? IsZeroArea::kYes : IsZeroArea::kNo;
bsalomon88cf17d2016-07-08 06:40:56 -0700175 this->setBounds(devRect, HasAABloat::kYes, zeroArea);
bsalomon4be9a302016-07-06 07:03:26 -0700176 fRectCnt = 1;
bsalomon0fdec8a2016-07-01 06:31:25 -0700177 }
bsalomon08d14152016-06-30 12:45:18 -0700178
Brian Salomon6a639042016-12-14 11:08:17 -0500179 const char* name() const override { return "AAFillRectOp"; }
bsalomon08d14152016-06-30 12:45:18 -0700180
181 SkString dumpInfo() const override {
182 SkString str;
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500183 str.appendf("# combined: %d\n", fRectCnt);
bsalomon4be9a302016-07-06 07:03:26 -0700184 const RectInfo* info = this->first();
185 for (int i = 0; i < fRectCnt; ++i) {
186 const SkRect& rect = info->rect();
Brian Salomon6a639042016-12-14 11:08:17 -0500187 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
188 info->color(), rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
bsalomon4be9a302016-07-06 07:03:26 -0700189 info = this->next(info);
bsalomon08d14152016-06-30 12:45:18 -0700190 }
Brian Salomon7c3e7182016-12-01 09:35:30 -0500191 str.append(DumpPipelineInfo(*this->pipeline()));
bsalomon08d14152016-06-30 12:45:18 -0700192 str.append(INHERITED::dumpInfo());
193 return str;
194 }
195
Brian Salomon92aee3d2016-12-21 09:20:25 -0500196 void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
bsalomon4be9a302016-07-06 07:03:26 -0700197 GrColor color;
Brian Salomon92aee3d2016-12-21 09:20:25 -0500198 if (optimizations.getOverrideColorIfSet(&color)) {
bsalomon4be9a302016-07-06 07:03:26 -0700199 this->first()->setColor(color);
200 }
Brian Salomonecea86a2017-01-04 13:25:17 -0500201 fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
202 fNeedsLocalCoords = optimizations.readsLocalCoords();
bsalomon08d14152016-06-30 12:45:18 -0700203 }
204
bsalomon08d14152016-06-30 12:45:18 -0700205private:
Brian Salomon92aee3d2016-12-21 09:20:25 -0500206 void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
207 input->pipelineColorInput()->setKnownFourComponents(this->first()->color());
208 input->pipelineCoverageInput()->setUnknownSingleComponent();
209 }
210
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700211 void onPrepareDraws(Target* target) const override {
bsalomon4be9a302016-07-06 07:03:26 -0700212 using namespace GrDefaultGeoProcFactory;
213
214 Color color(Color::kAttribute_Type);
215 Coverage::Type coverageType;
Brian Salomonecea86a2017-01-04 13:25:17 -0500216 if (fCanTweakAlphaForCoverage) {
bsalomon4be9a302016-07-06 07:03:26 -0700217 coverageType = Coverage::kSolid_Type;
218 } else {
219 coverageType = Coverage::kAttribute_Type;
220 }
Brian Salomon6a639042016-12-14 11:08:17 -0500221 LocalCoords lc =
Brian Salomonecea86a2017-01-04 13:25:17 -0500222 fNeedsLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUnused_Type;
Brian Salomon6a639042016-12-14 11:08:17 -0500223 sk_sp<GrGeometryProcessor> gp =
Brian Salomon8c852be2017-01-04 10:44:42 -0500224 GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I());
bsalomon08d14152016-06-30 12:45:18 -0700225 if (!gp) {
226 SkDebugf("Couldn't create GrGeometryProcessor\n");
227 return;
228 }
229
230 size_t vertexStride = gp->getVertexStride();
bsalomon08d14152016-06-30 12:45:18 -0700231
Hal Canary144caf52016-11-07 17:57:18 -0500232 sk_sp<const GrBuffer> indexBuffer(get_index_buffer(target->resourceProvider()));
bsalomon08d14152016-06-30 12:45:18 -0700233 InstancedHelper helper;
Brian Salomon6a639042016-12-14 11:08:17 -0500234 void* vertices =
235 helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
236 kVertsPerAAFillRect, kIndicesPerAAFillRect, fRectCnt);
bsalomon08d14152016-06-30 12:45:18 -0700237 if (!vertices || !indexBuffer) {
238 SkDebugf("Could not allocate vertices\n");
239 return;
240 }
241
bsalomon4be9a302016-07-06 07:03:26 -0700242 const RectInfo* info = this->first();
243 const SkMatrix* localMatrix = nullptr;
244 for (int i = 0; i < fRectCnt; i++) {
Brian Salomon6a639042016-12-14 11:08:17 -0500245 intptr_t verts =
246 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride;
Brian Salomonecea86a2017-01-04 13:25:17 -0500247 if (fNeedsLocalCoords) {
bsalomon4be9a302016-07-06 07:03:26 -0700248 if (info->hasLocalMatrix()) {
249 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix();
250 } else {
251 localMatrix = &SkMatrix::I();
252 }
253 }
Brian Salomon6a639042016-12-14 11:08:17 -0500254 generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), info->viewMatrix(),
Brian Salomonecea86a2017-01-04 13:25:17 -0500255 info->rect(), info->devRect(), fCanTweakAlphaForCoverage,
Brian Salomon92aee3d2016-12-21 09:20:25 -0500256 localMatrix);
bsalomon4be9a302016-07-06 07:03:26 -0700257 info = this->next(info);
bsalomon08d14152016-06-30 12:45:18 -0700258 }
259 helper.recordDraw(target, gp.get());
260 }
261
Brian Salomon25a88092016-12-01 09:36:50 -0500262 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
Brian Salomon6a639042016-12-14 11:08:17 -0500263 AAFillRectOp* that = t->cast<AAFillRectOp>();
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700264 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
265 that->bounds(), caps)) {
266 return false;
267 }
268
Brian Salomonecea86a2017-01-04 13:25:17 -0500269 SkASSERT(fNeedsLocalCoords == that->fNeedsLocalCoords);
270
Brian Salomon6a639042016-12-14 11:08:17 -0500271 // In the event of two ops, one who can tweak, one who cannot, we just fall back to not
272 // tweaking.
Brian Salomonecea86a2017-01-04 13:25:17 -0500273 if (fCanTweakAlphaForCoverage && !that->fCanTweakAlphaForCoverage) {
274 fCanTweakAlphaForCoverage = false;
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700275 }
276
bsalomon4be9a302016-07-06 07:03:26 -0700277 fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin());
278 fRectCnt += that->fRectCnt;
bsalomon88cf17d2016-07-08 06:40:56 -0700279 this->joinBounds(*that);
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700280 return true;
281 }
282
283 struct RectInfo {
bsalomon4be9a302016-07-06 07:03:26 -0700284 public:
285 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
286 const SkRect& devRect)
Brian Salomon6a639042016-12-14 11:08:17 -0500287 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {}
bsalomon4be9a302016-07-06 07:03:26 -0700288 bool hasLocalMatrix() const { return HasLocalMatrix::kYes == fHasLocalMatrix; }
289 GrColor color() const { return fColor; }
290 const SkMatrix& viewMatrix() const { return fViewMatrix; }
291 const SkRect& rect() const { return fRect; }
292 const SkRect& devRect() const { return fDevRect; }
293
294 void setColor(GrColor color) { fColor = color; }
Brian Salomon6a639042016-12-14 11:08:17 -0500295
bsalomon4be9a302016-07-06 07:03:26 -0700296 protected:
297 enum class HasLocalMatrix : uint32_t { kNo, kYes };
298
299 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
300 const SkRect& devRect, HasLocalMatrix hasLM)
301 : fHasLocalMatrix(hasLM)
302 , fColor(color)
303 , fViewMatrix(viewMatrix)
304 , fRect(rect)
305 , fDevRect(devRect) {}
306
307 HasLocalMatrix fHasLocalMatrix;
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700308 GrColor fColor;
309 SkMatrix fViewMatrix;
310 SkRect fRect;
311 SkRect fDevRect;
312 };
313
bsalomon4be9a302016-07-06 07:03:26 -0700314 struct RectWithLocalMatrixInfo : public RectInfo {
315 public:
316 RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
317 const SkRect& devRect, const SkMatrix& localMatrix)
Brian Salomon6a639042016-12-14 11:08:17 -0500318 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes)
319 , fLocalMatrix(localMatrix) {}
bsalomon4be9a302016-07-06 07:03:26 -0700320 const SkMatrix& localMatrix() const { return fLocalMatrix; }
Brian Salomon6a639042016-12-14 11:08:17 -0500321
bsalomon4be9a302016-07-06 07:03:26 -0700322 private:
benjaminwagnerd87a6b22016-07-04 11:30:01 -0700323 SkMatrix fLocalMatrix;
bsalomon0fdec8a2016-07-01 06:31:25 -0700324 };
325
bsalomon4be9a302016-07-06 07:03:26 -0700326 RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); }
327 const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRectData.begin()); }
328 const RectInfo* next(const RectInfo* prev) const {
Brian Salomon6a639042016-12-14 11:08:17 -0500329 intptr_t next =
330 reinterpret_cast<intptr_t>(prev) +
331 (prev->hasLocalMatrix() ? sizeof(RectWithLocalMatrixInfo) : sizeof(RectInfo));
bsalomon4be9a302016-07-06 07:03:26 -0700332 return reinterpret_cast<const RectInfo*>(next);
333 }
334
Brian Salomonecea86a2017-01-04 13:25:17 -0500335 bool fNeedsLocalCoords;
336 bool fCanTweakAlphaForCoverage;
bsalomon4be9a302016-07-06 07:03:26 -0700337 SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData;
338 int fRectCnt;
bsalomon08d14152016-06-30 12:45:18 -0700339
Brian Salomondad29232016-12-01 16:40:24 -0500340 typedef GrMeshDrawOp INHERITED;
joshualitt147dc062015-08-12 11:51:46 -0700341};
342
Brian Salomon6a639042016-12-14 11:08:17 -0500343namespace GrAAFillRectOp {
joshualitt9ff64252015-08-10 09:03:51 -0700344
Brian Salomonf8334782017-01-03 09:42:58 -0500345std::unique_ptr<GrDrawOp> Make(GrColor color,
346 const SkMatrix& viewMatrix,
347 const SkRect& rect,
348 const SkRect& devRect) {
349 return std::unique_ptr<GrDrawOp>(new AAFillRectOp(color, viewMatrix, rect, devRect, nullptr));
joshualitt147dc062015-08-12 11:51:46 -0700350}
351
Brian Salomonf8334782017-01-03 09:42:58 -0500352std::unique_ptr<GrDrawOp> Make(GrColor color,
353 const SkMatrix& viewMatrix,
354 const SkMatrix& localMatrix,
355 const SkRect& rect,
356 const SkRect& devRect) {
357 return std::unique_ptr<GrDrawOp>(
358 new AAFillRectOp(color, viewMatrix, rect, devRect, &localMatrix));
joshualitt9ff64252015-08-10 09:03:51 -0700359}
360
Brian Salomonf8334782017-01-03 09:42:58 -0500361std::unique_ptr<GrDrawOp> Make(GrColor color,
362 const SkMatrix& viewMatrix,
363 const SkMatrix& localMatrix,
364 const SkRect& rect) {
bsalomonc55271f2015-11-09 11:55:57 -0800365 SkRect devRect;
366 viewMatrix.mapRect(&devRect, rect);
Brian Salomon6a639042016-12-14 11:08:17 -0500367 return Make(color, viewMatrix, localMatrix, rect, devRect);
bsalomonc55271f2015-11-09 11:55:57 -0800368}
369
Brian Salomonf8334782017-01-03 09:42:58 -0500370std::unique_ptr<GrDrawOp> MakeWithLocalRect(GrColor color,
371 const SkMatrix& viewMatrix,
372 const SkRect& rect,
373 const SkRect& localRect) {
bsalomonc55271f2015-11-09 11:55:57 -0800374 SkRect devRect;
375 viewMatrix.mapRect(&devRect, rect);
376 SkMatrix localMatrix;
377 if (!localMatrix.setRectToRect(rect, localRect, SkMatrix::kFill_ScaleToFit)) {
378 return nullptr;
379 }
Brian Salomon6a639042016-12-14 11:08:17 -0500380 return Make(color, viewMatrix, localMatrix, rect, devRect);
bsalomonc55271f2015-11-09 11:55:57 -0800381}
joshualitt37eb1842015-08-12 06:36:57 -0700382};
383
joshualitt9ff64252015-08-10 09:03:51 -0700384///////////////////////////////////////////////////////////////////////////////////////////////////
385
386#ifdef GR_TEST_UTILS
387
Brian Salomon5ec9def2016-12-20 15:34:05 -0500388#include "GrDrawOpTest.h"
joshualitt9ff64252015-08-10 09:03:51 -0700389
Brian Salomon5ec9def2016-12-20 15:34:05 -0500390DRAW_OP_TEST_DEFINE(AAFillRectOp) {
joshualitt090ae8e2015-08-14 09:01:21 -0700391 GrColor color = GrRandomColor(random);
392 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
393 SkRect rect = GrTest::TestRect(random);
394 SkRect devRect = GrTest::TestRect(random);
Brian Salomon5ec9def2016-12-20 15:34:05 -0500395 return GrAAFillRectOp::Make(color, viewMatrix, rect, devRect);
joshualitt147dc062015-08-12 11:51:46 -0700396}
397
Brian Salomon5ec9def2016-12-20 15:34:05 -0500398DRAW_OP_TEST_DEFINE(AAFillRectOpLocalMatrix) {
joshualitt090ae8e2015-08-14 09:01:21 -0700399 GrColor color = GrRandomColor(random);
400 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
401 SkMatrix localMatrix = GrTest::TestMatrix(random);
402 SkRect rect = GrTest::TestRect(random);
403 SkRect devRect = GrTest::TestRect(random);
Brian Salomon5ec9def2016-12-20 15:34:05 -0500404 return GrAAFillRectOp::Make(color, viewMatrix, localMatrix, rect, devRect);
joshualitt9ff64252015-08-10 09:03:51 -0700405}
406
407#endif