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

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

Issue 14314004: Axis aligned shader-based rect drawing (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Addressed code review issues (renaming & API change) Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « include/gpu/GrAARectRenderer.h ('k') | src/gpu/GrClipMaskManager.cpp » ('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 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrAARectRenderer.h" 8 #include "GrAARectRenderer.h"
9 #include "GrRefCnt.h" 9 #include "GrRefCnt.h"
10 #include "GrGpu.h" 10 #include "GrGpu.h"
11 #include "gl/GrGLEffect.h" 11 #include "gl/GrGLEffect.h"
12 #include "GrTBackendEffectFactory.h" 12 #include "GrTBackendEffectFactory.h"
13 13
14 SK_DEFINE_INST_COUNT(GrAARectRenderer) 14 SK_DEFINE_INST_COUNT(GrAARectRenderer)
15 15
16 ///////////////////////////////////////////////////////////////////////////////
17 class GrGLAlignedRectEffect;
18
19 // Axis Aligned special case
20 class GrAlignedRectEffect : public GrEffect {
21 public:
22 static GrEffectRef* Create() {
23 GR_CREATE_STATIC_EFFECT(gAlignedRectEffect, GrAlignedRectEffect, ());
24 gAlignedRectEffect->ref();
25 return gAlignedRectEffect;
26 }
27
28 virtual ~GrAlignedRectEffect() {}
29
30 static const char* Name() { return "AlignedRectEdge"; }
31
32 virtual void getConstantColorComponents(GrColor* color,
33 uint32_t* validFlags) const SK_OVERR IDE {
34 *validFlags = 0;
35 }
36
37 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
38 return GrTBackendEffectFactory<GrAlignedRectEffect>::getInstance();
39 }
40
41 class GLEffect : public GrGLEffect {
42 public:
43 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
44 : INHERITED (factory) {}
45
46 virtual void emitCode(GrGLShaderBuilder* builder,
47 const GrDrawEffect& drawEffect,
48 EffectKey key,
49 const char* outputColor,
50 const char* inputColor,
51 const TextureSamplerArray& samplers) SK_OVERRIDE {
52 // setup the varying for the Axis aligned rect effect
53 // xy -> interpolated offset
54 // zw -> w/2+0.5, h/2+0.5
55 const char *vsRectName, *fsRectName;
56 builder->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectNam e);
57 const SkString* attr0Name =
58 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]);
59 builder->vsCodeAppendf("\t%s = %s;\n", vsRectName, attr0Name->c_str( ));
60
61 // TODO: compute these scale factors in the VS
62 // These scale factors adjust the coverage for < 1 pixel wide/high r ects
63 builder->fsCodeAppendf("\tfloat wScale = max(1.0, 2.0/(0.5+%s.z));\n ",
64 fsRectName);
65 builder->fsCodeAppendf("\tfloat hScale = max(1.0, 2.0/(0.5+%s.w));\n ",
66 fsRectName);
67
68 // Compute the coverage for the rect's width
69 builder->fsCodeAppendf("\tfloat coverage = clamp(wScale*(%s.z-abs(%s .x)), 0.0, 1.0);\n",
70 fsRectName,
71 fsRectName);
72
73 // Compute the coverage for the rect's height and merge with the wid th
74 builder->fsCodeAppendf(
75 "\tcoverage = min(coverage, clamp(hScale*(%s.w-abs(%s.y)), 0 .0, 1.0));\n",
76 fsRectName,
77 fsRectName);
78
79 SkString modulate;
80 GrGLSLModulatef<4>(&modulate, inputColor, "coverage");
81 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() );
82 }
83
84 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
85 return 0;
86 }
87
88 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& ) SK_OVERRIDE {}
89
90 private:
91 typedef GrGLEffect INHERITED;
92 };
93
94
95 private:
96 GrAlignedRectEffect() : GrEffect() {
97 this->addVertexAttrib(kVec4f_GrSLType);
98 }
99
100 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; }
101
102 GR_DECLARE_EFFECT_TEST;
103
104 typedef GrEffect INHERITED;
105 };
106
107
108 GR_DEFINE_EFFECT_TEST(GrAlignedRectEffect);
109
110 GrEffectRef* GrAlignedRectEffect::TestCreate(SkMWCRandom* random,
111 GrContext* context,
112 const GrDrawTargetCaps&,
113 GrTexture* textures[]) {
114 return GrAlignedRectEffect::Create();
115 }
116
117 ///////////////////////////////////////////////////////////////////////////////
16 class GrGLRectEffect; 118 class GrGLRectEffect;
17 119
18 /** 120 /**
19 * The output of this effect is a modulation of the input color and coverage 121 * The output of this effect is a modulation of the input color and coverage
20 * for an arbitrarily oriented rect. The rect is specified as: 122 * for an arbitrarily oriented rect. The rect is specified as:
21 * Center of the rect 123 * Center of the rect
22 * Unit vector point down the height of the rect 124 * Unit vector point down the height of the rect
23 * Half width + 0.5 125 * Half width + 0.5
24 * Half height + 0.5 126 * Half height + 0.5
25 * The center and vector are stored in a vec4 varying ("RectEdge") with the 127 * The center and vector are stored in a vec4 varying ("RectEdge") with the
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 bool updated = 352 bool updated =
251 #endif 353 #endif
252 fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 354 fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx,
253 sizeof(gStrokeAARectIdx)); 355 sizeof(gStrokeAARectIdx));
254 GR_DEBUGASSERT(updated); 356 GR_DEBUGASSERT(updated);
255 } 357 }
256 } 358 }
257 return fAAStrokeRectIndexBuffer; 359 return fAAStrokeRectIndexBuffer;
258 } 360 }
259 361
260 void GrAARectRenderer::fillAARect(GrGpu* gpu, 362 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu,
261 GrDrawTarget* target, 363 GrDrawTarget* target,
262 const GrRect& devRect, 364 const GrRect& devRect,
263 bool useVertexCoverage) { 365 bool useVertexCoverage) {
264 GrDrawState* drawState = target->drawState(); 366 GrDrawState* drawState = target->drawState();
265 367
266 set_aa_rect_vertex_attributes(drawState, useVertexCoverage); 368 set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
267 369
268 GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0); 370 GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
269 if (!geo.succeeded()) { 371 if (!geo.succeeded()) {
270 GrPrintf("Failed to get space for vertices!\n"); 372 GrPrintf("Failed to get space for vertices!\n");
271 return; 373 return;
272 } 374 }
273 375
(...skipping 30 matching lines...) Expand all
304 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 406 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
305 } 407 }
306 408
307 target->setIndexSourceToBuffer(indexBuffer); 409 target->setIndexSourceToBuffer(indexBuffer);
308 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 410 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
309 kVertsPerAAFillRect, 411 kVertsPerAAFillRect,
310 kIndicesPerAAFillRect); 412 kIndicesPerAAFillRect);
311 target->resetIndexSource(); 413 target->resetIndexSource();
312 } 414 }
313 415
416 namespace {
417
418 // Rotated
314 struct RectVertex { 419 struct RectVertex {
315 GrPoint fPos; 420 GrPoint fPos;
316 GrPoint fCenter; 421 GrPoint fCenter;
317 GrPoint fDir; 422 GrPoint fDir;
318 GrPoint fWidthHeight; 423 GrPoint fWidthHeight;
319 }; 424 };
320 425
321 namespace { 426 // Rotated
322
323 extern const GrVertexAttrib gAARectVertexAttribs[] = { 427 extern const GrVertexAttrib gAARectVertexAttribs[] = {
324 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind ing }, 428 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind ing },
325 { kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBindin g }, 429 { kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBindin g },
326 { kVec2f_GrVertexAttribType, 3*sizeof(GrPoint), kEffect_GrVertexAttribBindin g } 430 { kVec2f_GrVertexAttribType, 3*sizeof(GrPoint), kEffect_GrVertexAttribBindin g }
327 }; 431 };
328 432
433 // Axis Aligned
434 struct AARectVertex {
435 GrPoint fPos;
436 GrPoint fOffset;
437 GrPoint fWidthHeight;
438 };
439
440 // Axis Aligned
441 extern const GrVertexAttrib gAAAARectVertexAttribs[] = {
442 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind ing },
443 { kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBindin g },
444 };
445
329 }; 446 };
330 447
331 void GrAARectRenderer::shaderFillAARect(GrGpu* gpu, 448 void GrAARectRenderer::shaderFillAARect(GrGpu* gpu,
332 GrDrawTarget* target, 449 GrDrawTarget* target,
333 const GrRect& rect, 450 const GrRect& rect,
334 const SkMatrix& combinedMatrix, 451 const SkMatrix& combinedMatrix,
335 const GrRect& devRect, 452 const GrRect& devRect) {
336 bool useVertexCoverage) {
337 GrDrawState* drawState = target->drawState(); 453 GrDrawState* drawState = target->drawState();
338 454
339 SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY()); 455 SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY());
340 combinedMatrix.mapPoints(&center, 1); 456 combinedMatrix.mapPoints(&center, 1);
341 457
342 // compute transformed (0, 1) vector 458 // compute transformed (0, 1) vector
343 SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix: :kMScaleY] }; 459 SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix: :kMScaleY] };
344 dir.normalize(); 460 dir.normalize();
345 461
346 // compute transformed (width, 0) and (0, height) vectors 462 // compute transformed (width, 0) and (0, height) vectors
347 SkVector vec[2] = { 463 SkVector vec[2] = {
348 { combinedMatrix[SkMatrix::kMScaleX] * rect.width(), 464 { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
349 combinedMatrix[SkMatrix::kMSkewY] * rect.width() }, 465 { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] }
350 { combinedMatrix[SkMatrix::kMSkewX] * rect.height(),
351 combinedMatrix[SkMatrix::kMScaleY] * rect.height() }
352 }; 466 };
353 467
354 SkScalar newWidth = vec[0].length() / 2.0f + 0.5f; 468 SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_Scalar Half;
355 SkScalar newHeight = vec[1].length() / 2.0f + 0.5f; 469 SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_Scal arHalf;
356
357 drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVert exAttribs)); 470 drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVert exAttribs));
358 GrAssert(sizeof(RectVertex) == drawState->getVertexSize()); 471 GrAssert(sizeof(RectVertex) == drawState->getVertexSize());
359 472
360 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); 473 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
361 if (!geo.succeeded()) { 474 if (!geo.succeeded()) {
362 GrPrintf("Failed to get space for vertices!\n"); 475 GrPrintf("Failed to get space for vertices!\n");
363 return; 476 return;
364 } 477 }
365 478
366 RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices()); 479 RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
(...skipping 27 matching lines...) Expand all
394 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop); 507 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
395 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom); 508 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
396 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom); 509 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
397 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop); 510 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
398 511
399 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); 512 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
400 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); 513 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
401 target->resetIndexSource(); 514 target->resetIndexSource();
402 } 515 }
403 516
517 void GrAARectRenderer::shaderFillAlignedAARect(GrGpu* gpu,
518 GrDrawTarget* target,
519 const GrRect& rect,
520 const SkMatrix& combinedMatrix,
521 const GrRect& devRect) {
522 GrDrawState* drawState = target->drawState();
523 SkASSERT(combinedMatrix.rectStaysRect());
524
525 drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARect VertexAttribs));
526 GrAssert(sizeof(AARectVertex) == drawState->getVertexSize());
527
528 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
529 if (!geo.succeeded()) {
530 GrPrintf("Failed to get space for vertices!\n");
531 return;
532 }
533
534 AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
535
536 enum {
537 // the edge effects share this stage with glyph rendering
538 // (kGlyphMaskStage in GrTextContext) && SW path rendering
539 // (kPathMaskStage in GrSWMaskHelper)
540 kEdgeEffectStage = GrPaint::kTotalStages,
541 };
542
543 GrEffectRef* effect = GrAlignedRectEffect::Create();
544 static const int kOffsetIndex = 1;
545 drawState->setEffect(kEdgeEffectStage, effect, kOffsetIndex)->unref();
546
547 SkRect devBounds = {
548 devRect.fLeft - SK_ScalarHalf,
549 devRect.fTop - SK_ScalarHalf,
550 devRect.fRight + SK_ScalarHalf,
551 devRect.fBottom + SK_ScalarHalf
552 };
553
554 GrPoint widthHeight = {
555 SkScalarHalf(devRect.width()) + SK_ScalarHalf,
556 SkScalarHalf(devRect.height()) + SK_ScalarHalf
557 };
558
559 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
560 verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY);
561 verts[0].fWidthHeight = widthHeight;
562
563 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
564 verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY);
565 verts[1].fWidthHeight = widthHeight;
566
567 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
568 verts[2].fOffset = widthHeight;
569 verts[2].fWidthHeight = widthHeight;
570
571 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
572 verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY);
573 verts[3].fWidthHeight = widthHeight;
574
575 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
576 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
577 target->resetIndexSource();
578 }
579
404 void GrAARectRenderer::strokeAARect(GrGpu* gpu, 580 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
405 GrDrawTarget* target, 581 GrDrawTarget* target,
406 const GrRect& devRect, 582 const GrRect& devRect,
407 const GrVec& devStrokeSize, 583 const GrVec& devStrokeSize,
408 bool useVertexCoverage) { 584 bool useVertexCoverage) {
409 GrDrawState* drawState = target->drawState(); 585 GrDrawState* drawState = target->drawState();
410 586
411 const SkScalar& dx = devStrokeSize.fX; 587 const SkScalar& dx = devStrokeSize.fX;
412 const SkScalar& dy = devStrokeSize.fY; 588 const SkScalar& dy = devStrokeSize.fY;
413 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); 589 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
414 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); 590 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);
415 591
416 SkScalar spare; 592 SkScalar spare;
417 { 593 {
418 SkScalar w = devRect.width() - dx; 594 SkScalar w = devRect.width() - dx;
419 SkScalar h = devRect.height() - dy; 595 SkScalar h = devRect.height() - dy;
420 spare = GrMin(w, h); 596 spare = GrMin(w, h);
421 } 597 }
422 598
423 if (spare <= 0) { 599 if (spare <= 0) {
424 GrRect r(devRect); 600 GrRect r(devRect);
425 r.inset(-rx, -ry); 601 r.inset(-rx, -ry);
426 this->fillAARect(gpu, target, r, useVertexCoverage); 602 this->fillAARect(gpu, target, r, SkMatrix::I(), r, useVertexCoverage);
427 return; 603 return;
428 } 604 }
429 605
430 set_aa_rect_vertex_attributes(drawState, useVertexCoverage); 606 set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
431 607
432 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); 608 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
433 if (!geo.succeeded()) { 609 if (!geo.succeeded()) {
434 GrPrintf("Failed to get space for vertices!\n"); 610 GrPrintf("Failed to get space for vertices!\n");
435 return; 611 return;
436 } 612 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 // The innermost rect has full coverage 658 // The innermost rect has full coverage
483 verts += 8 * vsize; 659 verts += 8 * vsize;
484 for (int i = 0; i < 4; ++i) { 660 for (int i = 0; i < 4; ++i) {
485 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 661 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
486 } 662 }
487 663
488 target->setIndexSourceToBuffer(indexBuffer); 664 target->setIndexSourceToBuffer(indexBuffer);
489 target->drawIndexed(kTriangles_GrPrimitiveType, 665 target->drawIndexed(kTriangles_GrPrimitiveType,
490 0, 0, 16, aaStrokeRectIndexCount()); 666 0, 0, 16, aaStrokeRectIndexCount());
491 } 667 }
OLDNEW
« no previous file with comments | « include/gpu/GrAARectRenderer.h ('k') | src/gpu/GrClipMaskManager.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698