blob: fd8a9b3c8761bbb750aeb19bb84b298b694b71c1 [file] [log] [blame]
joshualitt9c80b5f2015-08-13 10:05:51 -07001/*
Brian Salomonac70f842017-05-08 10:43:33 -04002 * Copyright 2017 Google Inc.
joshualitt9c80b5f2015-08-13 10:05:51 -07003 *
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 Salomonac70f842017-05-08 10:43:33 -04008#include "GrAppliedClip.h"
joshualitt9c80b5f2015-08-13 10:05:51 -07009#include "GrColor.h"
10#include "GrDefaultGeoProcFactory.h"
Brian Salomon17726632017-05-12 14:09:46 -040011#include "GrDrawOpTest.h"
Brian Salomondad29232016-12-01 16:40:24 -050012#include "GrMeshDrawOp.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050013#include "GrOpFlushState.h"
joshualitt9c80b5f2015-08-13 10:05:51 -070014#include "GrPrimitiveProcessor.h"
joshualittae5b2c62015-08-19 08:48:41 -070015#include "GrQuad.h"
Brian Salomonbaaf4392017-06-15 09:59:23 -040016#include "GrRectOpFactory.h"
Brian Salomondad29232016-12-01 16:40:24 -050017#include "GrResourceProvider.h"
Brian Salomonac70f842017-05-08 10:43:33 -040018#include "GrSimpleMeshDrawOpHelper.h"
reeda39667c2016-08-22 06:39:49 -070019#include "SkMatrixPriv.h"
20
Brian Salomonac70f842017-05-08 10:43:33 -040021static const int kVertsPerRect = 4;
22static const int kIndicesPerRect = 6;
joshualitt2244c272015-08-21 10:33:15 -070023
Brian Salomon53e4c3c2016-12-21 11:38:53 -050024/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
joshualitt2244c272015-08-21 10:33:15 -070025 we have explicit local coords and sometimes not. We *could* always provide explicit local
26 coords and just duplicate the positions when the caller hasn't provided a local coord rect,
27 but we haven't seen a use case which frequently switches between local rect and no local
28 rect draws.
29
30 The vertex attrib order is always pos, color, [local coords].
31 */
Ruiqi Maob609e6d2018-07-17 10:19:38 -040032static sk_sp<GrGeometryProcessor> make_gp(const GrShaderCaps* shaderCaps) {
robertphillips6abd1d12016-07-01 09:06:56 -070033 using namespace GrDefaultGeoProcFactory;
Ruiqi Maob609e6d2018-07-17 10:19:38 -040034 return GrDefaultGeoProcFactory::Make(shaderCaps,
35 Color::kPremulGrColorAttribute_Type,
36 Coverage::kSolid_Type,
37 LocalCoords::kHasExplicit_Type,
38 SkMatrix::I());
robertphillips6abd1d12016-07-01 09:06:56 -070039}
40
Ruiqi Maob609e6d2018-07-17 10:19:38 -040041static sk_sp<GrGeometryProcessor> make_perspective_gp(const GrShaderCaps* shaderCaps,
42 const SkMatrix& viewMatrix,
Brian Salomonac70f842017-05-08 10:43:33 -040043 bool hasExplicitLocalCoords,
44 const SkMatrix* localMatrix) {
45 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
46
47 using namespace GrDefaultGeoProcFactory;
48
49 // If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map
50 // the local rect on the cpu (in case the localMatrix also has perspective).
51 // Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect
52 // to generate vertex local coords
53 if (viewMatrix.hasPerspective()) {
54 LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
55 : LocalCoords::kUsePosition_Type,
56 localMatrix);
Ruiqi Maob609e6d2018-07-17 10:19:38 -040057 return GrDefaultGeoProcFactory::Make(shaderCaps, Color::kPremulGrColorAttribute_Type,
Brian Salomonac70f842017-05-08 10:43:33 -040058 Coverage::kSolid_Type, localCoords, viewMatrix);
59 } else if (hasExplicitLocalCoords) {
60 LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
Ruiqi Maob609e6d2018-07-17 10:19:38 -040061 return GrDefaultGeoProcFactory::Make(shaderCaps, Color::kPremulGrColorAttribute_Type,
Brian Salomonac70f842017-05-08 10:43:33 -040062 Coverage::kSolid_Type, localCoords, SkMatrix::I());
63 } else {
64 LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
Ruiqi Maob609e6d2018-07-17 10:19:38 -040065 return GrDefaultGeoProcFactory::MakeForDeviceSpace(shaderCaps,
66 Color::kPremulGrColorAttribute_Type,
Brian Salomonac70f842017-05-08 10:43:33 -040067 Coverage::kSolid_Type, localCoords,
68 viewMatrix);
69 }
70}
71
joshualitt2244c272015-08-21 10:33:15 -070072static void tesselate(intptr_t vertices,
73 size_t vertexStride,
74 GrColor color,
robertphillips6abd1d12016-07-01 09:06:56 -070075 const SkMatrix* viewMatrix,
joshualitt2244c272015-08-21 10:33:15 -070076 const SkRect& rect,
joshualitt8cce8f12015-08-26 06:23:39 -070077 const GrQuad* localQuad) {
joshualitt2244c272015-08-21 10:33:15 -070078 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices);
79
Brian Salomonbe3c1d22018-05-21 12:54:39 -040080 SkPointPriv::SetRectTriStrip(positions, rect, vertexStride);
joshualitt2244c272015-08-21 10:33:15 -070081
robertphillips6abd1d12016-07-01 09:06:56 -070082 if (viewMatrix) {
Brian Salomonac70f842017-05-08 10:43:33 -040083 SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerRect);
joshualitt8cce8f12015-08-26 06:23:39 -070084 }
85
86 // Setup local coords
joshualitt2244c272015-08-21 10:33:15 -070087 // TODO we should only do this if local coords are being read
joshualitt8cce8f12015-08-26 06:23:39 -070088 if (localQuad) {
joshualitt2244c272015-08-21 10:33:15 -070089 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
Brian Salomonac70f842017-05-08 10:43:33 -040090 for (int i = 0; i < kVertsPerRect; i++) {
Brian Salomon6a639042016-12-14 11:08:17 -050091 SkPoint* coords =
92 reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
joshualitt8cce8f12015-08-26 06:23:39 -070093 *coords = localQuad->point(i);
joshualitt2244c272015-08-21 10:33:15 -070094 }
95 }
96
97 static const int kColorOffset = sizeof(SkPoint);
98 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset);
99 for (int j = 0; j < 4; ++j) {
100 *vertColor = color;
Brian Salomon6a639042016-12-14 11:08:17 -0500101 vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
joshualitt2244c272015-08-21 10:33:15 -0700102 }
103}
104
Brian Salomonac70f842017-05-08 10:43:33 -0400105namespace {
bsalomon08d14152016-06-30 12:45:18 -0700106
Brian Salomonac70f842017-05-08 10:43:33 -0400107class NonAAFillRectOp final : public GrMeshDrawOp {
108private:
109 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
110
111public:
Robert Phillips7c525e62018-06-12 10:11:12 -0400112 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
113 GrPaint&& paint,
114 const SkMatrix& viewMatrix,
115 const SkRect& rect,
116 const SkRect* localRect,
117 const SkMatrix* localMatrix,
118 GrAAType aaType,
Brian Salomonac70f842017-05-08 10:43:33 -0400119 const GrUserStencilSettings* stencilSettings) {
120 SkASSERT(GrAAType::kCoverage != aaType);
Robert Phillips7c525e62018-06-12 10:11:12 -0400121 return Helper::FactoryHelper<NonAAFillRectOp>(context, std::move(paint), viewMatrix, rect,
122 localRect, localMatrix, aaType,
123 stencilSettings);
Brian Salomonac70f842017-05-08 10:43:33 -0400124 }
125
126 NonAAFillRectOp() = delete;
127
128 NonAAFillRectOp(const Helper::MakeArgs& args, GrColor color, const SkMatrix& viewMatrix,
129 const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix,
130 GrAAType aaType, const GrUserStencilSettings* stencilSettings)
131 : INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
Chris Dalton1d616352017-05-31 12:51:23 -0600132
Brian Salomon6a639042016-12-14 11:08:17 -0500133 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
bsalomon9d7f1842016-07-01 08:01:36 -0700134 RectInfo& info = fRects.push_back();
135 info.fColor = color;
136 info.fViewMatrix = viewMatrix;
137 info.fRect = rect;
138 if (localRect && localMatrix) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400139 info.fLocalQuad = GrQuad(*localRect, *localMatrix);
bsalomon9d7f1842016-07-01 08:01:36 -0700140 } else if (localRect) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400141 info.fLocalQuad = GrQuad(*localRect);
bsalomon9d7f1842016-07-01 08:01:36 -0700142 } else if (localMatrix) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400143 info.fLocalQuad = GrQuad(rect, *localMatrix);
bsalomon9d7f1842016-07-01 08:01:36 -0700144 } else {
Brian Salomona33b67c2018-05-17 10:42:14 -0400145 info.fLocalQuad = GrQuad(rect);
bsalomon9d7f1842016-07-01 08:01:36 -0700146 }
bsalomon88cf17d2016-07-08 06:40:56 -0700147 this->setTransformedBounds(fRects[0].fRect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
bsalomon9d7f1842016-07-01 08:01:36 -0700148 }
bsalomon08d14152016-06-30 12:45:18 -0700149
Brian Salomon6a639042016-12-14 11:08:17 -0500150 const char* name() const override { return "NonAAFillRectOp"; }
bsalomon08d14152016-06-30 12:45:18 -0700151
Robert Phillipsf1748f52017-09-14 14:11:24 -0400152 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400153 fHelper.visitProxies(func);
154 }
155
bsalomon08d14152016-06-30 12:45:18 -0700156 SkString dumpInfo() const override {
157 SkString str;
Brian Salomonac70f842017-05-08 10:43:33 -0400158 str.append(GrMeshDrawOp::dumpInfo());
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500159 str.appendf("# combined: %d\n", fRects.count());
bsalomon9d7f1842016-07-01 08:01:36 -0700160 for (int i = 0; i < fRects.count(); ++i) {
161 const RectInfo& info = fRects[i];
Brian Salomon6a639042016-12-14 11:08:17 -0500162 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
163 info.fColor, info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight,
164 info.fRect.fBottom);
bsalomon08d14152016-06-30 12:45:18 -0700165 }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400166 str += fHelper.dumpInfo();
167 str += INHERITED::dumpInfo();
bsalomon08d14152016-06-30 12:45:18 -0700168 return str;
169 }
170
Brian Osman532b3f92018-07-11 10:02:07 -0400171 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400172 GrColor* color = &fRects.front().fColor;
Brian Osman532b3f92018-07-11 10:02:07 -0400173 return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
Brian Salomonac70f842017-05-08 10:43:33 -0400174 }
175
176 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
177
178 DEFINE_OP_CLASS_ID
179
bsalomon08d14152016-06-30 12:45:18 -0700180private:
Brian Salomon91326c32017-08-09 16:02:19 -0400181 void onPrepareDraws(Target* target) override {
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400182 sk_sp<GrGeometryProcessor> gp = make_gp(target->caps().shaderCaps());
bsalomon08d14152016-06-30 12:45:18 -0700183 if (!gp) {
184 SkDebugf("Couldn't create GrGeometryProcessor\n");
185 return;
186 }
187
Brian Salomon92be2f72018-06-19 14:33:47 -0400188 static constexpr size_t kVertexStride =
189 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr);
190 SkASSERT(kVertexStride == gp->debugOnly_vertexStride());
191
Brian Salomonac70f842017-05-08 10:43:33 -0400192 int rectCount = fRects.count();
bsalomon08d14152016-06-30 12:45:18 -0700193
Brian Salomond28a79d2017-10-16 13:01:07 -0400194 sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
Brian Salomon7eae3e02018-08-07 14:02:38 +0000195 PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStride, indexBuffer.get(),
196 kVertsPerRect, kIndicesPerRect, rectCount);
197 void* vertices = helper.vertices();
bsalomon08d14152016-06-30 12:45:18 -0700198 if (!vertices || !indexBuffer) {
199 SkDebugf("Could not allocate vertices\n");
200 return;
201 }
202
Brian Salomonac70f842017-05-08 10:43:33 -0400203 for (int i = 0; i < rectCount; i++) {
Brian Salomon6a639042016-12-14 11:08:17 -0500204 intptr_t verts =
Brian Salomon92be2f72018-06-19 14:33:47 -0400205 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * kVertexStride;
206 tesselate(verts, kVertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
bsalomon9d7f1842016-07-01 08:01:36 -0700207 fRects[i].fRect, &fRects[i].fLocalQuad);
bsalomon08d14152016-06-30 12:45:18 -0700208 }
Brian Salomon49348902018-06-26 09:12:38 -0400209 auto pipe = fHelper.makePipeline(target);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000210 helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState);
bsalomon08d14152016-06-30 12:45:18 -0700211 }
212
Brian Salomon7eae3e02018-08-07 14:02:38 +0000213 CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
Brian Salomon6a639042016-12-14 11:08:17 -0500214 NonAAFillRectOp* that = t->cast<NonAAFillRectOp>();
Brian Salomonac70f842017-05-08 10:43:33 -0400215 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
Brian Salomon7eae3e02018-08-07 14:02:38 +0000216 return CombineResult::kCannotCombine;
bsalomon08d14152016-06-30 12:45:18 -0700217 }
bsalomon9d7f1842016-07-01 08:01:36 -0700218 fRects.push_back_n(that->fRects.count(), that->fRects.begin());
bsalomon88cf17d2016-07-08 06:40:56 -0700219 this->joinBounds(*that);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000220 return CombineResult::kMerged;
bsalomon08d14152016-06-30 12:45:18 -0700221 }
222
bsalomon9d7f1842016-07-01 08:01:36 -0700223 struct RectInfo {
224 GrColor fColor;
225 SkMatrix fViewMatrix;
226 SkRect fRect;
227 GrQuad fLocalQuad;
228 };
229
Brian Salomonac70f842017-05-08 10:43:33 -0400230 Helper fHelper;
bsalomon9d7f1842016-07-01 08:01:36 -0700231 SkSTArray<1, RectInfo, true> fRects;
Brian Salomonac70f842017-05-08 10:43:33 -0400232 typedef GrMeshDrawOp INHERITED;
joshualitt2244c272015-08-21 10:33:15 -0700233};
234
Brian Salomonac70f842017-05-08 10:43:33 -0400235// We handle perspective in the local matrix or viewmatrix with special ops.
236class NonAAFillRectPerspectiveOp final : public GrMeshDrawOp {
237private:
238 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
239
240public:
Robert Phillips7c525e62018-06-12 10:11:12 -0400241 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
242 GrPaint&& paint,
243 const SkMatrix& viewMatrix,
244 const SkRect& rect,
245 const SkRect* localRect,
246 const SkMatrix* localMatrix,
247 GrAAType aaType,
Brian Salomonac70f842017-05-08 10:43:33 -0400248 const GrUserStencilSettings* stencilSettings) {
249 SkASSERT(GrAAType::kCoverage != aaType);
Robert Phillips7c525e62018-06-12 10:11:12 -0400250 return Helper::FactoryHelper<NonAAFillRectPerspectiveOp>(context, std::move(paint),
251 viewMatrix, rect,
Brian Salomonac70f842017-05-08 10:43:33 -0400252 localRect, localMatrix, aaType,
253 stencilSettings);
254 }
255
256 NonAAFillRectPerspectiveOp() = delete;
257
258 NonAAFillRectPerspectiveOp(const Helper::MakeArgs& args, GrColor color,
259 const SkMatrix& viewMatrix, const SkRect& rect,
260 const SkRect* localRect, const SkMatrix* localMatrix,
261 GrAAType aaType, const GrUserStencilSettings* stencilSettings)
262 : INHERITED(ClassID())
263 , fHelper(args, aaType, stencilSettings)
264 , fViewMatrix(viewMatrix) {
265 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
266 RectInfo& info = fRects.push_back();
267 info.fColor = color;
268 info.fRect = rect;
269 fHasLocalRect = SkToBool(localRect);
270 fHasLocalMatrix = SkToBool(localMatrix);
271 if (fHasLocalMatrix) {
272 fLocalMatrix = *localMatrix;
273 }
274 if (fHasLocalRect) {
275 info.fLocalRect = *localRect;
276 }
277 this->setTransformedBounds(rect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
278 }
279
280 const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
281
Robert Phillipsf1748f52017-09-14 14:11:24 -0400282 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400283 fHelper.visitProxies(func);
284 }
285
Brian Salomonac70f842017-05-08 10:43:33 -0400286 SkString dumpInfo() const override {
287 SkString str;
288 str.appendf("# combined: %d\n", fRects.count());
289 for (int i = 0; i < fRects.count(); ++i) {
Mike Klein1d746202018-01-25 17:32:51 -0500290 const RectInfo& geo = fRects[i];
Brian Salomonac70f842017-05-08 10:43:33 -0400291 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
292 geo.fColor, geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight,
293 geo.fRect.fBottom);
294 }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400295 str += fHelper.dumpInfo();
296 str += INHERITED::dumpInfo();
Brian Salomonac70f842017-05-08 10:43:33 -0400297 return str;
298 }
299
Brian Osman532b3f92018-07-11 10:02:07 -0400300 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400301 GrColor* color = &fRects.front().fColor;
Brian Osman532b3f92018-07-11 10:02:07 -0400302 return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
Brian Salomonac70f842017-05-08 10:43:33 -0400303 }
304
305 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
306
307 DEFINE_OP_CLASS_ID
308
309private:
Brian Salomon91326c32017-08-09 16:02:19 -0400310 void onPrepareDraws(Target* target) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400311 sk_sp<GrGeometryProcessor> gp = make_perspective_gp(
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400312 target->caps().shaderCaps(),
313 fViewMatrix,
314 fHasLocalRect,
315 fHasLocalMatrix ? &fLocalMatrix : nullptr);
Brian Salomonac70f842017-05-08 10:43:33 -0400316 if (!gp) {
317 SkDebugf("Couldn't create GrGeometryProcessor\n");
318 return;
319 }
Brian Salomon92be2f72018-06-19 14:33:47 -0400320 size_t vertexStride = fHasLocalRect
321 ? sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
322 : sizeof(GrDefaultGeoProcFactory::PositionColorAttr);
323 SkASSERT(vertexStride == gp->debugOnly_vertexStride());
Brian Salomonac70f842017-05-08 10:43:33 -0400324
Brian Salomonac70f842017-05-08 10:43:33 -0400325 int rectCount = fRects.count();
326
Brian Salomond28a79d2017-10-16 13:01:07 -0400327 sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
Brian Salomon7eae3e02018-08-07 14:02:38 +0000328 PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
329 kVertsPerRect, kIndicesPerRect, rectCount);
330 void* vertices = helper.vertices();
Brian Salomonac70f842017-05-08 10:43:33 -0400331 if (!vertices || !indexBuffer) {
332 SkDebugf("Could not allocate vertices\n");
333 return;
334 }
335
336 for (int i = 0; i < rectCount; i++) {
337 const RectInfo& info = fRects[i];
338 intptr_t verts =
339 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
340 if (fHasLocalRect) {
341 GrQuad quad(info.fLocalRect);
342 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, &quad);
343 } else {
344 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
345 }
346 }
Brian Salomon49348902018-06-26 09:12:38 -0400347 auto pipe = fHelper.makePipeline(target);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000348 helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState);
Brian Salomonac70f842017-05-08 10:43:33 -0400349 }
350
Brian Salomon7eae3e02018-08-07 14:02:38 +0000351 CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400352 NonAAFillRectPerspectiveOp* that = t->cast<NonAAFillRectPerspectiveOp>();
353 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
Brian Salomon7eae3e02018-08-07 14:02:38 +0000354 return CombineResult::kCannotCombine;
Brian Salomonac70f842017-05-08 10:43:33 -0400355 }
356
357 // We could combine across perspective vm changes if we really wanted to.
358 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
Brian Salomon7eae3e02018-08-07 14:02:38 +0000359 return CombineResult::kCannotCombine;
Brian Salomonac70f842017-05-08 10:43:33 -0400360 }
361 if (fHasLocalRect != that->fHasLocalRect) {
Brian Salomon7eae3e02018-08-07 14:02:38 +0000362 return CombineResult::kCannotCombine;
Brian Salomonac70f842017-05-08 10:43:33 -0400363 }
364 if (fHasLocalMatrix && !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
Brian Salomon7eae3e02018-08-07 14:02:38 +0000365 return CombineResult::kCannotCombine;
Brian Salomonac70f842017-05-08 10:43:33 -0400366 }
367
368 fRects.push_back_n(that->fRects.count(), that->fRects.begin());
369 this->joinBounds(*that);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000370 return CombineResult::kMerged;
Brian Salomonac70f842017-05-08 10:43:33 -0400371 }
372
373 struct RectInfo {
374 SkRect fRect;
375 GrColor fColor;
376 SkRect fLocalRect;
377 };
378
379 SkSTArray<1, RectInfo, true> fRects;
380 Helper fHelper;
381 bool fHasLocalMatrix;
382 bool fHasLocalRect;
383 SkMatrix fLocalMatrix;
384 SkMatrix fViewMatrix;
385
386 typedef GrMeshDrawOp INHERITED;
387};
388
389} // anonymous namespace
390
Brian Salomonbaaf4392017-06-15 09:59:23 -0400391namespace GrRectOpFactory {
bsalomonb8cbd202016-06-30 13:09:48 -0700392
Robert Phillips7c525e62018-06-12 10:11:12 -0400393std::unique_ptr<GrDrawOp> MakeNonAAFill(GrContext* context,
394 GrPaint&& paint,
395 const SkMatrix& viewMatrix,
396 const SkRect& rect,
397 GrAAType aaType,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400398 const GrUserStencilSettings* stencilSettings) {
399 if (viewMatrix.hasPerspective()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400400 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
401 nullptr, nullptr, aaType, stencilSettings);
Brian Salomon1ec03f32017-06-14 09:49:26 -0400402 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400403 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, nullptr, nullptr,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400404 aaType, stencilSettings);
405 }
406}
407
Robert Phillips7c525e62018-06-12 10:11:12 -0400408std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(
409 GrContext* context,
410 GrPaint&& paint,
411 const SkMatrix& viewMatrix,
412 const SkMatrix& localMatrix,
413 const SkRect& rect,
414 GrAAType aaType,
415 const GrUserStencilSettings* stencilSettings) {
416 if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) {
417 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
418 nullptr, &localMatrix, aaType, stencilSettings);
419 } else {
420 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, nullptr,
421 &localMatrix, aaType, stencilSettings);
422 }
423}
424
425std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrContext* context,
426 GrPaint&& paint,
427 const SkMatrix& viewMatrix,
428 const SkRect& rect,
429 const SkRect& localRect,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400430 GrAAType aaType) {
431 if (viewMatrix.hasPerspective()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400432 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
433 &localRect, nullptr, aaType, nullptr);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400434 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400435 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, &localRect,
436 nullptr, aaType, nullptr);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400437 }
438}
439
440} // namespace GrRectOpFactory
joshualitt9c80b5f2015-08-13 10:05:51 -0700441
442///////////////////////////////////////////////////////////////////////////////////////////////////
Brian Salomon17726632017-05-12 14:09:46 -0400443
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400444#if GR_TEST_UTILS
445
Brian Salomon17726632017-05-12 14:09:46 -0400446GR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) {
447 SkRect rect = GrTest::TestRect(random);
448 SkRect localRect = GrTest::TestRect(random);
449 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
450 SkMatrix localMatrix = GrTest::TestMatrix(random);
Brian Salomon17726632017-05-12 14:09:46 -0400451 const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context);
452 GrAAType aaType = GrAAType::kNone;
453 if (fsaaType == GrFSAAType::kUnifiedMSAA) {
454 aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone;
455 }
Brian Salomonbaaf4392017-06-15 09:59:23 -0400456 const SkRect* lr = random->nextBool() ? &localRect : nullptr;
457 const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr;
458 if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400459 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
460 lr, lm, aaType, stencil);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400461 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400462 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect,
463 lr, lm, aaType, stencil);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400464 }
Brian Salomon17726632017-05-12 14:09:46 -0400465}
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400466
467#endif