Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: src/gpu/batches/GrAAFillRectBatch.cpp

Issue 1282723004: move Stroke Rect and AAFill Rect to their own file (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/batches/GrAAFillRectBatch.h ('k') | src/gpu/batches/GrAAStrokeRectBatch.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
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
8 #include "GrAAFillRectBatch.h"
9
10 #include "GrDefaultGeoProcFactory.h"
11 #include "GrResourceKey.h"
12 #include "GrResourceProvider.h"
13
14 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
15
16 static void set_inset_fan(SkPoint* pts, size_t stride,
17 const SkRect& r, SkScalar dx, SkScalar dy) {
18 pts->setRectFan(r.fLeft + dx, r.fTop + dy,
19 r.fRight - dx, r.fBottom - dy, stride);
20 }
21
22 static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage ,
23 const SkMatrix& viewMatrix ,
24 bool usesLocalCoords,
25 bool coverageIgnored) {
26 using namespace GrDefaultGeoProcFactory;
27
28 Color color(Color::kAttribute_Type);
29 Coverage::Type coverageType;
30 // TODO remove coverage if coverage is ignored
31 /*if (coverageIgnored) {
32 coverageType = Coverage::kNone_Type;
33 } else*/ if (tweakAlphaForCoverage) {
34 coverageType = Coverage::kSolid_Type;
35 } else {
36 coverageType = Coverage::kAttribute_Type;
37 }
38 Coverage coverage(coverageType);
39 LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type :
40 LocalCoords::kUnused_Type);
41 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
42 }
43
44 void GrAAFillRectBatch::initBatchTracker(const GrPipelineInfo& init) {
45 // Handle any color overrides
46 if (!init.readsColor()) {
47 fGeoData[0].fColor = GrColor_ILLEGAL;
48 }
49 init.getOverrideColorIfSet(&fGeoData[0].fColor);
50
51 // setup batch properties
52 fBatch.fColorIgnored = !init.readsColor();
53 fBatch.fColor = fGeoData[0].fColor;
54 fBatch.fUsesLocalCoords = init.readsLocalCoords();
55 fBatch.fCoverageIgnored = !init.readsCoverage();
56 fBatch.fCanTweakAlphaForCoverage = init.canTweakAlphaForCoverage();
57 }
58
59 void GrAAFillRectBatch::generateGeometry(GrBatchTarget* batchTarget) {
60 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
61
62 SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakAlpha ForCoverage,
63 this->viewMat rix(),
64 this->usesLoc alCoords(),
65 this->coverag eIgnored()));
66 if (!gp) {
67 SkDebugf("Couldn't create GrGeometryProcessor\n");
68 return;
69 }
70
71 batchTarget->initDraw(gp, this->pipeline());
72
73 size_t vertexStride = gp->getVertexStride();
74 SkASSERT(canTweakAlphaForCoverage ?
75 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
76 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCovera geAttr));
77 int instanceCount = fGeoData.count();
78
79 SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
80 batchTarget->resourceProvider()));
81 InstancedHelper helper;
82 void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, vertex Stride,
83 indexBuffer, kVertsPerAAFillRect, kIndicesPerAA FillRect,
84 instanceCount);
85 if (!vertices || !indexBuffer) {
86 SkDebugf("Could not allocate vertices\n");
87 return;
88 }
89
90 for (int i = 0; i < instanceCount; i++) {
91 const Geometry& args = fGeoData[i];
92 this->generateAAFillRectGeometry(vertices,
93 i * kVertsPerAAFillRect * vertexStride,
94 vertexStride,
95 args.fColor,
96 args.fViewMatrix,
97 args.fRect,
98 args.fDevRect,
99 canTweakAlphaForCoverage);
100 }
101
102 helper.issueDraw(batchTarget);
103 }
104
105 const GrIndexBuffer* GrAAFillRectBatch::getIndexBuffer(GrResourceProvider* resou rceProvider) {
106 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
107
108 static const uint16_t gFillAARectIdx[] = {
109 0, 1, 5, 5, 4, 0,
110 1, 2, 6, 6, 5, 1,
111 2, 3, 7, 7, 6, 2,
112 3, 0, 4, 4, 7, 3,
113 4, 5, 6, 6, 7, 4,
114 };
115 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
116 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx,
117 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect ,
118 gAAFillRectIndexBufferKey);
119 }
120
121 bool GrAAFillRectBatch::onCombineIfPossible(GrBatch* t) {
122 if (!this->pipeline()->isEqual(*t->pipeline())) {
123 return false;
124 }
125
126 GrAAFillRectBatch* that = t->cast<GrAAFillRectBatch>();
127
128 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
129 // We apply the viewmatrix to the rect points on the cpu. However, if the p ipeline uses
130 // local coords then we won't be able to batch. We could actually upload th e viewmatrix
131 // using vertex attributes in these cases, but haven't investigated that
132 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMa trix())) {
133 return false;
134 }
135
136 if (this->color() != that->color()) {
137 fBatch.fColor = GrColor_ILLEGAL;
138 }
139
140 // In the event of two batches, one who can tweak, one who cannot, we just f all back to
141 // not tweaking
142 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) {
143 fBatch.fCanTweakAlphaForCoverage = false;
144 }
145
146 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
147 this->joinBounds(that->bounds());
148 return true;
149 }
150
151 void GrAAFillRectBatch::generateAAFillRectGeometry(void* vertices,
152 size_t offset,
153 size_t vertexStride,
154 GrColor color,
155 const SkMatrix& viewMatrix,
156 const SkRect& rect,
157 const SkRect& devRect,
158 bool tweakAlphaForCoverage) c onst {
159 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
160
161 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
162 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
163
164 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
165 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
166
167 if (viewMatrix.rectStaysRect()) {
168 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar Half);
169 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
170 } else {
171 // compute transformed (1, 0) and (0, 1) vectors
172 SkVector vec[2] = {
173 { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] },
174 { viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] }
175 };
176
177 vec[0].normalize();
178 vec[0].scale(SK_ScalarHalf);
179 vec[1].normalize();
180 vec[1].scale(SK_ScalarHalf);
181
182 // create the rotated rect
183 fan0Pos->setRectFan(rect.fLeft, rect.fTop,
184 rect.fRight, rect.fBottom, vertexStride);
185 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
186
187 // Now create the inset points and then outset the original
188 // rotated points
189
190 // TL
191 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
192 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1 ];
193 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
194 // BL
195 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
196 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1 ];
197 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
198 // BR
199 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
200 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1 ];
201 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
202 // TR
203 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
204 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1 ];
205 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
206 }
207
208 // Make verts point to vertex color and then set all the color and coverage vertex attrs
209 // values.
210 verts += sizeof(SkPoint);
211 for (int i = 0; i < 4; ++i) {
212 if (tweakAlphaForCoverage) {
213 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
214 } else {
215 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
216 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = 0;
217 }
218 }
219
220 int scale;
221 if (inset < SK_ScalarHalf) {
222 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
223 SkASSERT(scale >= 0 && scale <= 255);
224 } else {
225 scale = 0xff;
226 }
227
228 verts += 4 * vertexStride;
229
230 float innerCoverage = GrNormalizeByteToFloat(scale);
231 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
232
233 for (int i = 0; i < 4; ++i) {
234 if (tweakAlphaForCoverage) {
235 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
236 } else {
237 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
238 *reinterpret_cast<float*>(verts + i * vertexStride +
239 sizeof(GrColor)) = innerCoverage;
240 }
241 }
242 }
243
244 //////////////////////////////////////////////////////////////////////////////// ///////////////////
245
246 #ifdef GR_TEST_UTILS
247
248 #include "GrBatchTest.h"
249
250 BATCH_TEST_DEFINE(AAFillRectBatch) {
251 GrAAFillRectBatch::Geometry geo;
252 geo.fColor = GrRandomColor(random);
253 geo.fViewMatrix = GrTest::TestMatrix(random);
254 geo.fRect = GrTest::TestRect(random);
255 geo.fDevRect = GrTest::TestRect(random);
256 return GrAAFillRectBatch::Create(geo);
257 }
258
259 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrAAFillRectBatch.h ('k') | src/gpu/batches/GrAAStrokeRectBatch.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698