blob: ae0c9b7851ef1859f80ca20790ec44221f24e496 [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
Brian Osmancf860852018-10-31 14:04:39 -0400128 NonAAFillRectOp(const Helper::MakeArgs& args, const SkPMColor4f& color,
Brian Osman936fe7d2018-10-30 15:30:35 -0400129 const SkMatrix& viewMatrix, const SkRect& rect, const SkRect* localRect,
130 const SkMatrix* localMatrix, GrAAType aaType,
131 const GrUserStencilSettings* stencilSettings)
Brian Salomonac70f842017-05-08 10:43:33 -0400132 : INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
Chris Dalton1d616352017-05-31 12:51:23 -0600133
Brian Salomon6a639042016-12-14 11:08:17 -0500134 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
bsalomon9d7f1842016-07-01 08:01:36 -0700135 RectInfo& info = fRects.push_back();
136 info.fColor = color;
137 info.fViewMatrix = viewMatrix;
138 info.fRect = rect;
139 if (localRect && localMatrix) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400140 info.fLocalQuad = GrQuad(*localRect, *localMatrix);
bsalomon9d7f1842016-07-01 08:01:36 -0700141 } else if (localRect) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400142 info.fLocalQuad = GrQuad(*localRect);
bsalomon9d7f1842016-07-01 08:01:36 -0700143 } else if (localMatrix) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400144 info.fLocalQuad = GrQuad(rect, *localMatrix);
bsalomon9d7f1842016-07-01 08:01:36 -0700145 } else {
Brian Salomona33b67c2018-05-17 10:42:14 -0400146 info.fLocalQuad = GrQuad(rect);
bsalomon9d7f1842016-07-01 08:01:36 -0700147 }
bsalomon88cf17d2016-07-08 06:40:56 -0700148 this->setTransformedBounds(fRects[0].fRect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
bsalomon9d7f1842016-07-01 08:01:36 -0700149 }
bsalomon08d14152016-06-30 12:45:18 -0700150
Brian Salomon6a639042016-12-14 11:08:17 -0500151 const char* name() const override { return "NonAAFillRectOp"; }
bsalomon08d14152016-06-30 12:45:18 -0700152
Brian Salomon7d94bb52018-10-12 14:37:19 -0400153 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400154 fHelper.visitProxies(func);
155 }
156
Brian Osman9a390ac2018-11-12 09:47:48 -0500157#ifdef SK_DEBUG
bsalomon08d14152016-06-30 12:45:18 -0700158 SkString dumpInfo() const override {
159 SkString str;
Brian Salomonac70f842017-05-08 10:43:33 -0400160 str.append(GrMeshDrawOp::dumpInfo());
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500161 str.appendf("# combined: %d\n", fRects.count());
bsalomon9d7f1842016-07-01 08:01:36 -0700162 for (int i = 0; i < fRects.count(); ++i) {
163 const RectInfo& info = fRects[i];
Brian Salomon6a639042016-12-14 11:08:17 -0500164 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
Brian Osmancf860852018-10-31 14:04:39 -0400165 info.fColor.toBytes_RGBA(), info.fRect.fLeft, info.fRect.fTop,
Brian Osman1be2b7c2018-10-29 16:07:15 -0400166 info.fRect.fRight, info.fRect.fBottom);
bsalomon08d14152016-06-30 12:45:18 -0700167 }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400168 str += fHelper.dumpInfo();
169 str += INHERITED::dumpInfo();
bsalomon08d14152016-06-30 12:45:18 -0700170 return str;
171 }
Brian Osman9a390ac2018-11-12 09:47:48 -0500172#endif
bsalomon08d14152016-06-30 12:45:18 -0700173
Brian Osman532b3f92018-07-11 10:02:07 -0400174 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Osmancf860852018-10-31 14:04:39 -0400175 SkPMColor4f* color = &fRects.front().fColor;
Brian Osman532b3f92018-07-11 10:02:07 -0400176 return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
Brian Salomonac70f842017-05-08 10:43:33 -0400177 }
178
179 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
180
181 DEFINE_OP_CLASS_ID
182
bsalomon08d14152016-06-30 12:45:18 -0700183private:
Brian Salomon91326c32017-08-09 16:02:19 -0400184 void onPrepareDraws(Target* target) override {
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400185 sk_sp<GrGeometryProcessor> gp = make_gp(target->caps().shaderCaps());
bsalomon08d14152016-06-30 12:45:18 -0700186 if (!gp) {
187 SkDebugf("Couldn't create GrGeometryProcessor\n");
188 return;
189 }
190
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500191 size_t kVertexStride = gp->vertexStride();
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;
Brian Osman1be2b7c2018-10-29 16:07:15 -0400206 // TODO4F: Preserve float colors
Brian Osmancf860852018-10-31 14:04:39 -0400207 tesselate(verts, kVertexStride, fRects[i].fColor.toBytes_RGBA(), &fRects[i].fViewMatrix,
bsalomon9d7f1842016-07-01 08:01:36 -0700208 fRects[i].fRect, &fRects[i].fLocalQuad);
bsalomon08d14152016-06-30 12:45:18 -0700209 }
Brian Salomon49348902018-06-26 09:12:38 -0400210 auto pipe = fHelper.makePipeline(target);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000211 helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState);
bsalomon08d14152016-06-30 12:45:18 -0700212 }
213
Brian Salomon7eae3e02018-08-07 14:02:38 +0000214 CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
Brian Salomon6a639042016-12-14 11:08:17 -0500215 NonAAFillRectOp* that = t->cast<NonAAFillRectOp>();
Brian Salomonac70f842017-05-08 10:43:33 -0400216 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
Brian Salomon7eae3e02018-08-07 14:02:38 +0000217 return CombineResult::kCannotCombine;
bsalomon08d14152016-06-30 12:45:18 -0700218 }
bsalomon9d7f1842016-07-01 08:01:36 -0700219 fRects.push_back_n(that->fRects.count(), that->fRects.begin());
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 {
Brian Osmancf860852018-10-31 14:04:39 -0400224 SkPMColor4f fColor;
bsalomon9d7f1842016-07-01 08:01:36 -0700225 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
Brian Osmancf860852018-10-31 14:04:39 -0400258 NonAAFillRectPerspectiveOp(const Helper::MakeArgs& args, const SkPMColor4f& color,
Brian Salomonac70f842017-05-08 10:43:33 -0400259 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
Brian Salomon7d94bb52018-10-12 14:37:19 -0400282 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400283 fHelper.visitProxies(func);
284 }
285
Brian Osman9a390ac2018-11-12 09:47:48 -0500286#ifdef SK_DEBUG
Brian Salomonac70f842017-05-08 10:43:33 -0400287 SkString dumpInfo() const override {
288 SkString str;
289 str.appendf("# combined: %d\n", fRects.count());
290 for (int i = 0; i < fRects.count(); ++i) {
Mike Klein1d746202018-01-25 17:32:51 -0500291 const RectInfo& geo = fRects[i];
Brian Salomonac70f842017-05-08 10:43:33 -0400292 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
Brian Osmancf860852018-10-31 14:04:39 -0400293 geo.fColor.toBytes_RGBA(), geo.fRect.fLeft, geo.fRect.fTop,
Brian Osman1be2b7c2018-10-29 16:07:15 -0400294 geo.fRect.fRight, geo.fRect.fBottom);
Brian Salomonac70f842017-05-08 10:43:33 -0400295 }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400296 str += fHelper.dumpInfo();
297 str += INHERITED::dumpInfo();
Brian Salomonac70f842017-05-08 10:43:33 -0400298 return str;
299 }
Brian Osman9a390ac2018-11-12 09:47:48 -0500300#endif
Brian Salomonac70f842017-05-08 10:43:33 -0400301
Brian Osman532b3f92018-07-11 10:02:07 -0400302 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Osmancf860852018-10-31 14:04:39 -0400303 SkPMColor4f* color = &fRects.front().fColor;
Brian Osman532b3f92018-07-11 10:02:07 -0400304 return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
Brian Salomonac70f842017-05-08 10:43:33 -0400305 }
306
307 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
308
309 DEFINE_OP_CLASS_ID
310
311private:
Brian Salomon91326c32017-08-09 16:02:19 -0400312 void onPrepareDraws(Target* target) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400313 sk_sp<GrGeometryProcessor> gp = make_perspective_gp(
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400314 target->caps().shaderCaps(),
315 fViewMatrix,
316 fHasLocalRect,
317 fHasLocalMatrix ? &fLocalMatrix : nullptr);
Brian Salomonac70f842017-05-08 10:43:33 -0400318 if (!gp) {
319 SkDebugf("Couldn't create GrGeometryProcessor\n");
320 return;
321 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500322 size_t vertexStride = gp->vertexStride();
Brian Salomonac70f842017-05-08 10:43:33 -0400323 int rectCount = fRects.count();
324
Brian Salomond28a79d2017-10-16 13:01:07 -0400325 sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
Brian Salomon7eae3e02018-08-07 14:02:38 +0000326 PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
327 kVertsPerRect, kIndicesPerRect, rectCount);
328 void* vertices = helper.vertices();
Brian Salomonac70f842017-05-08 10:43:33 -0400329 if (!vertices || !indexBuffer) {
330 SkDebugf("Could not allocate vertices\n");
331 return;
332 }
333
334 for (int i = 0; i < rectCount; i++) {
335 const RectInfo& info = fRects[i];
Brian Osman1be2b7c2018-10-29 16:07:15 -0400336 // TODO4F: Preserve float colors
Brian Osmancf860852018-10-31 14:04:39 -0400337 GrColor color = info.fColor.toBytes_RGBA();
Brian Salomonac70f842017-05-08 10:43:33 -0400338 intptr_t verts =
339 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
340 if (fHasLocalRect) {
341 GrQuad quad(info.fLocalRect);
Brian Osman1be2b7c2018-10-29 16:07:15 -0400342 tesselate(verts, vertexStride, color, nullptr, info.fRect, &quad);
Brian Salomonac70f842017-05-08 10:43:33 -0400343 } else {
Brian Osman1be2b7c2018-10-29 16:07:15 -0400344 tesselate(verts, vertexStride, color, nullptr, info.fRect, nullptr);
Brian Salomonac70f842017-05-08 10:43:33 -0400345 }
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());
Brian Salomon7eae3e02018-08-07 14:02:38 +0000369 return CombineResult::kMerged;
Brian Salomonac70f842017-05-08 10:43:33 -0400370 }
371
372 struct RectInfo {
373 SkRect fRect;
Brian Osmancf860852018-10-31 14:04:39 -0400374 SkPMColor4f fColor;
Brian Salomonac70f842017-05-08 10:43:33 -0400375 SkRect fLocalRect;
376 };
377
378 SkSTArray<1, RectInfo, true> fRects;
379 Helper fHelper;
380 bool fHasLocalMatrix;
381 bool fHasLocalRect;
382 SkMatrix fLocalMatrix;
383 SkMatrix fViewMatrix;
384
385 typedef GrMeshDrawOp INHERITED;
386};
387
388} // anonymous namespace
389
Brian Salomonbaaf4392017-06-15 09:59:23 -0400390namespace GrRectOpFactory {
bsalomonb8cbd202016-06-30 13:09:48 -0700391
Robert Phillips7c525e62018-06-12 10:11:12 -0400392std::unique_ptr<GrDrawOp> MakeNonAAFill(GrContext* context,
393 GrPaint&& paint,
394 const SkMatrix& viewMatrix,
395 const SkRect& rect,
396 GrAAType aaType,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400397 const GrUserStencilSettings* stencilSettings) {
398 if (viewMatrix.hasPerspective()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400399 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
400 nullptr, nullptr, aaType, stencilSettings);
Brian Salomon1ec03f32017-06-14 09:49:26 -0400401 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400402 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, nullptr, nullptr,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400403 aaType, stencilSettings);
404 }
405}
406
Robert Phillips7c525e62018-06-12 10:11:12 -0400407std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(
408 GrContext* context,
409 GrPaint&& paint,
410 const SkMatrix& viewMatrix,
411 const SkMatrix& localMatrix,
412 const SkRect& rect,
413 GrAAType aaType,
414 const GrUserStencilSettings* stencilSettings) {
415 if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) {
416 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
417 nullptr, &localMatrix, aaType, stencilSettings);
418 } else {
419 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, nullptr,
420 &localMatrix, aaType, stencilSettings);
421 }
422}
423
424std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrContext* context,
425 GrPaint&& paint,
426 const SkMatrix& viewMatrix,
427 const SkRect& rect,
428 const SkRect& localRect,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400429 GrAAType aaType) {
430 if (viewMatrix.hasPerspective()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400431 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
432 &localRect, nullptr, aaType, nullptr);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400433 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400434 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, &localRect,
435 nullptr, aaType, nullptr);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400436 }
437}
438
439} // namespace GrRectOpFactory
joshualitt9c80b5f2015-08-13 10:05:51 -0700440
441///////////////////////////////////////////////////////////////////////////////////////////////////
Brian Salomon17726632017-05-12 14:09:46 -0400442
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400443#if GR_TEST_UTILS
444
Brian Salomon17726632017-05-12 14:09:46 -0400445GR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) {
446 SkRect rect = GrTest::TestRect(random);
447 SkRect localRect = GrTest::TestRect(random);
448 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
449 SkMatrix localMatrix = GrTest::TestMatrix(random);
Brian Salomon17726632017-05-12 14:09:46 -0400450 const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context);
451 GrAAType aaType = GrAAType::kNone;
452 if (fsaaType == GrFSAAType::kUnifiedMSAA) {
453 aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone;
454 }
Brian Salomonbaaf4392017-06-15 09:59:23 -0400455 const SkRect* lr = random->nextBool() ? &localRect : nullptr;
456 const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr;
457 if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400458 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
459 lr, lm, aaType, stencil);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400460 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400461 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect,
462 lr, lm, aaType, stencil);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400463 }
Brian Salomon17726632017-05-12 14:09:46 -0400464}
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400465
466#endif