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

Side by Side Diff: src/gpu/GrDrawContext.cpp

Issue 1274763002: Give strokerectbatch a proper home (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/GrBatchTest.cpp ('k') | src/gpu/GrStrokeRectBatch.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrAARectRenderer.h" 9 #include "GrAARectRenderer.h"
10 #include "GrAtlasTextContext.h" 10 #include "GrAtlasTextContext.h"
11 #include "GrBatch.h" 11 #include "GrBatch.h"
12 #include "GrBatchTest.h" 12 #include "GrBatchTest.h"
13 #include "GrDefaultGeoProcFactory.h" 13 #include "GrDefaultGeoProcFactory.h"
14 #include "GrDrawContext.h" 14 #include "GrDrawContext.h"
15 #include "GrOvalRenderer.h" 15 #include "GrOvalRenderer.h"
16 #include "GrPathRenderer.h" 16 #include "GrPathRenderer.h"
17 #include "GrRenderTarget.h" 17 #include "GrRenderTarget.h"
18 #include "GrRenderTargetPriv.h" 18 #include "GrRenderTargetPriv.h"
19 #include "GrStrokeRectBatch.h"
19 #include "GrStencilAndCoverTextContext.h" 20 #include "GrStencilAndCoverTextContext.h"
20 21
21 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) 22 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext)
22 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } 23 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; }
23 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; } 24 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; }
24 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; } 25 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; }
25 26
26 class AutoCheckFlush { 27 class AutoCheckFlush {
27 public: 28 public:
28 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); } 29 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 } 243 }
243 244
244 return true; 245 return true;
245 } 246 }
246 247
247 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po int) { 248 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po int) {
248 return point.fX >= rect.fLeft && point.fX <= rect.fRight && 249 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
249 point.fY >= rect.fTop && point.fY <= rect.fBottom; 250 point.fY >= rect.fTop && point.fY <= rect.fBottom;
250 } 251 }
251 252
252 class StrokeRectBatch : public GrBatch {
253 public:
254 struct Geometry {
255 GrColor fColor;
256 SkMatrix fViewMatrix;
257 SkRect fRect;
258 SkScalar fStrokeWidth;
259 };
260
261 static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) {
262 return SkNEW_ARGS(StrokeRectBatch, (geometry, snapToPixelCenters));
263 }
264
265 const char* name() const override { return "StrokeRectBatch"; }
266
267 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
268 // When this is called on a batch, there is only one geometry bundle
269 out->setKnownFourComponents(fGeoData[0].fColor);
270 }
271
272 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
273 out->setKnownSingleComponent(0xff);
274 }
275
276 void initBatchTracker(const GrPipelineInfo& init) override {
277 // Handle any color overrides
278 if (!init.readsColor()) {
279 fGeoData[0].fColor = GrColor_ILLEGAL;
280 }
281 init.getOverrideColorIfSet(&fGeoData[0].fColor);
282
283 // setup batch properties
284 fBatch.fColorIgnored = !init.readsColor();
285 fBatch.fColor = fGeoData[0].fColor;
286 fBatch.fUsesLocalCoords = init.readsLocalCoords();
287 fBatch.fCoverageIgnored = !init.readsCoverage();
288 }
289
290 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override {
291 SkAutoTUnref<const GrGeometryProcessor> gp;
292 {
293 using namespace GrDefaultGeoProcFactory;
294 Color color(this->color());
295 Coverage coverage(this->coverageIgnored() ? Coverage::kSolid_Type :
296 Coverage::kNone_Type);
297 LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUseP osition_Type :
298 LocalCoords::kUnus ed_Type);
299 gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoord s,
300 this->viewMatrix()));
301 }
302
303 batchTarget->initDraw(gp, pipeline);
304
305 size_t vertexStride = gp->getVertexStride();
306
307 SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
308
309 Geometry& args = fGeoData[0];
310
311 int vertexCount = kVertsPerHairlineRect;
312 if (args.fStrokeWidth > 0) {
313 vertexCount = kVertsPerStrokeRect;
314 }
315
316 const GrVertexBuffer* vertexBuffer;
317 int firstVertex;
318
319 void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount,
320 &vertexBuffer, &firstVertex);
321
322 if (!verts) {
323 SkDebugf("Could not allocate vertices\n");
324 return;
325 }
326
327 SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
328
329 GrPrimitiveType primType;
330
331 if (args.fStrokeWidth > 0) {;
332 primType = kTriangleStrip_GrPrimitiveType;
333 args.fRect.sort();
334 this->setStrokeRectStrip(vertex, args.fRect, args.fStrokeWidth);
335 } else {
336 // hairline
337 primType = kLineStrip_GrPrimitiveType;
338 vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
339 vertex[1].set(args.fRect.fRight, args.fRect.fTop);
340 vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
341 vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
342 vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
343 }
344
345 GrVertices vertices;
346 vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
347 batchTarget->draw(vertices);
348 }
349
350 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
351
352 private:
353 StrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) {
354 this->initClassID<StrokeRectBatch>();
355
356 fBatch.fHairline = geometry.fStrokeWidth == 0;
357
358 fGeoData.push_back(geometry);
359
360 // setup bounds
361 fBounds = geometry.fRect;
362 SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
363 fBounds.outset(rad, rad);
364 geometry.fViewMatrix.mapRect(&fBounds);
365
366 // If our caller snaps to pixel centers then we have to round out the bo unds
367 if (snapToPixelCenters) {
368 fBounds.roundOut();
369 }
370 }
371
372 /* create a triangle strip that strokes the specified rect. There are 8
373 unique vertices, but we repeat the last 2 to close up. Alternatively we
374 could use an indices array, and then only send 8 verts, but not sure that
375 would be faster.
376 */
377 void setStrokeRectStrip(SkPoint verts[10], const SkRect& rect, SkScalar widt h) {
378 const SkScalar rad = SkScalarHalf(width);
379 // TODO we should be able to enable this assert, but we'd have to filter these draws
380 // this is a bug
381 //SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
382
383 verts[0].set(rect.fLeft + rad, rect.fTop + rad);
384 verts[1].set(rect.fLeft - rad, rect.fTop - rad);
385 verts[2].set(rect.fRight - rad, rect.fTop + rad);
386 verts[3].set(rect.fRight + rad, rect.fTop - rad);
387 verts[4].set(rect.fRight - rad, rect.fBottom - rad);
388 verts[5].set(rect.fRight + rad, rect.fBottom + rad);
389 verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
390 verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
391 verts[8] = verts[0];
392 verts[9] = verts[1];
393 }
394
395
396 GrColor color() const { return fBatch.fColor; }
397 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
398 bool colorIgnored() const { return fBatch.fColorIgnored; }
399 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
400 bool hairline() const { return fBatch.fHairline; }
401 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
402
403 bool onCombineIfPossible(GrBatch* t) override {
404 //if (!this->pipeline()->isEqual(*t->pipeline())) {
405 // return false;
406 //}
407 // StrokeRectBatch* that = t->cast<StrokeRectBatch>();
408
409 // NonAA stroke rects cannot batch right now
410 // TODO make these batchable
411 return false;
412 }
413
414 struct BatchTracker {
415 GrColor fColor;
416 bool fUsesLocalCoords;
417 bool fColorIgnored;
418 bool fCoverageIgnored;
419 bool fHairline;
420 };
421
422 const static int kVertsPerHairlineRect = 5;
423 const static int kVertsPerStrokeRect = 10;
424
425 BatchTracker fBatch;
426 SkSTArray<1, Geometry, true> fGeoData;
427 };
428
429 void GrDrawContext::drawRect(GrRenderTarget* rt, 253 void GrDrawContext::drawRect(GrRenderTarget* rt,
430 const GrClip& clip, 254 const GrClip& clip,
431 const GrPaint& paint, 255 const GrPaint& paint,
432 const SkMatrix& viewMatrix, 256 const SkMatrix& viewMatrix,
433 const SkRect& rect, 257 const SkRect& rect,
434 const GrStrokeInfo* strokeInfo) { 258 const GrStrokeInfo* strokeInfo) {
435 RETURN_IF_ABANDONED 259 RETURN_IF_ABANDONED
436 if (strokeInfo && strokeInfo->isDashed()) { 260 if (strokeInfo && strokeInfo->isDashed()) {
437 SkPath path; 261 SkPath path;
438 path.setIsVolatile(true); 262 path.setIsVolatile(true);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 pipelineBuilder, 330 pipelineBuilder,
507 color, 331 color,
508 viewMatrix, 332 viewMatrix,
509 rect, 333 rect,
510 devBoundRect); 334 devBoundRect);
511 } 335 }
512 return; 336 return;
513 } 337 }
514 338
515 if (width >= 0) { 339 if (width >= 0) {
516 StrokeRectBatch::Geometry geometry; 340 GrStrokeRectBatch::Geometry geometry;
517 geometry.fViewMatrix = viewMatrix; 341 geometry.fViewMatrix = viewMatrix;
518 geometry.fColor = color; 342 geometry.fColor = color;
519 geometry.fRect = rect; 343 geometry.fRect = rect;
520 geometry.fStrokeWidth = width; 344 geometry.fStrokeWidth = width;
521 345
522 // Non-AA hairlines are snapped to pixel centers to make which pixels ar e hit deterministic 346 // Non-AA hairlines are snapped to pixel centers to make which pixels ar e hit deterministic
523 bool snapToPixelCenters = (0 == width && !rt->isUnifiedMultisampled()); 347 bool snapToPixelCenters = (0 == width && !rt->isUnifiedMultisampled());
524 SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry, snapToPixe lCenters)); 348 SkAutoTUnref<GrBatch> batch(GrStrokeRectBatch::Create(geometry, snapToPi xelCenters));
525 349
526 // Depending on sub-pixel coordinates and the particular GPU, we may los e a corner of 350 // Depending on sub-pixel coordinates and the particular GPU, we may los e a corner of
527 // hairline rects. We jam all the vertices to pixel centers to avoid thi s, but not when MSAA 351 // hairline rects. We jam all the vertices to pixel centers to avoid thi s, but not when MSAA
528 // is enabled because it can cause ugly artifacts. 352 // is enabled because it can cause ugly artifacts.
529 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_ Flag, 353 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_ Flag,
530 snapToPixelCenters); 354 snapToPixelCenters);
531 fDrawTarget->drawBatch(pipelineBuilder, batch); 355 fDrawTarget->drawBatch(pipelineBuilder, batch);
532 } else { 356 } else {
533 // filled BW rect 357 // filled BW rect
534 fDrawTarget->drawSimpleRect(pipelineBuilder, color, viewMatrix, rect); 358 fDrawTarget->drawSimpleRect(pipelineBuilder, color, viewMatrix, rect);
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 } 1035 }
1212 1036
1213 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch ) { 1037 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch ) {
1214 fDrawTarget->drawBatch(*pipelineBuilder, batch); 1038 fDrawTarget->drawBatch(*pipelineBuilder, batch);
1215 } 1039 }
1216 1040
1217 //////////////////////////////////////////////////////////////////////////////// /////////////////// 1041 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1218 1042
1219 #ifdef GR_TEST_UTILS 1043 #ifdef GR_TEST_UTILS
1220 1044
1221 BATCH_TEST_DEFINE(StrokeRectBatch) {
1222 StrokeRectBatch::Geometry geometry;
1223 geometry.fViewMatrix = GrTest::TestMatrix(random);
1224 geometry.fColor = GrRandomColor(random);
1225 geometry.fRect = GrTest::TestRect(random);
1226 geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f;
1227
1228 return StrokeRectBatch::Create(geometry, random->nextBool());
1229 }
1230
1231 static uint32_t seed_vertices(GrPrimitiveType type) { 1045 static uint32_t seed_vertices(GrPrimitiveType type) {
1232 switch (type) { 1046 switch (type) {
1233 case kTriangles_GrPrimitiveType: 1047 case kTriangles_GrPrimitiveType:
1234 case kTriangleStrip_GrPrimitiveType: 1048 case kTriangleStrip_GrPrimitiveType:
1235 case kTriangleFan_GrPrimitiveType: 1049 case kTriangleFan_GrPrimitiveType:
1236 return 3; 1050 return 3;
1237 case kPoints_GrPrimitiveType: 1051 case kPoints_GrPrimitiveType:
1238 return 1; 1052 return 1;
1239 case kLines_GrPrimitiveType: 1053 case kLines_GrPrimitiveType:
1240 case kLineStrip_GrPrimitiveType: 1054 case kLineStrip_GrPrimitiveType:
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 return DrawVerticesBatch::Create(geometry, type, viewMatrix, 1148 return DrawVerticesBatch::Create(geometry, type, viewMatrix,
1335 positions.begin(), vertexCount, 1149 positions.begin(), vertexCount,
1336 indices.begin(), hasIndices ? vertexCount : 0, 1150 indices.begin(), hasIndices ? vertexCount : 0,
1337 colors.begin(), 1151 colors.begin(),
1338 texCoords.begin(), 1152 texCoords.begin(),
1339 bounds); 1153 bounds);
1340 } 1154 }
1341 1155
1342 #endif 1156 #endif
1343 1157
OLDNEW
« no previous file with comments | « src/gpu/GrBatchTest.cpp ('k') | src/gpu/GrStrokeRectBatch.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698