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

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: Disabled shader-based rect drawing 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
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 GrGLAARectEffect;
bsalomon 2013/04/29 19:44:50 AlignedRectEffect? It seems like we've reserved AA
robertphillips 2013/05/02 13:56:39 Done.
18
19 // Axis Aligned special case
20 class GrAARectEffect : public GrEffect {
21 public:
22 static GrEffectRef* Create() {
23 GR_CREATE_STATIC_EFFECT(gAARectEffect, GrAARectEffect, ());
24 gAARectEffect->ref();
25 return gAARectEffect;
26 }
27
28 virtual ~GrAARectEffect() {}
29
30 static const char* Name() { return "AARectEdge"; }
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<GrAARectEffect>::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 GrAARectEffect() : 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(GrAARectEffect);
109
110 GrEffectRef* GrAARectEffect::TestCreate(SkMWCRandom* random,
111 GrContext* context,
112 const GrDrawTargetCaps&,
113 GrTexture* textures[]) {
114 return GrAARectEffect::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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
jvanverth1 2013/04/29 20:02:42 Is this different from 0.5*devRect.width() + 0.5?
robertphillips 2013/05/02 13:56:39 newWidth and newHeight are relative to 'dir' so th
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::shaderFillAAAARect(GrGpu* gpu,
518 GrDrawTarget* target,
519 const SkMatrix& combinedMatrix,
520 const GrRect& devRect) {
521 GrDrawState* drawState = target->drawState();
522 SkASSERT(combinedMatrix.rectStaysRect());
523
524 drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARect VertexAttribs));
525 GrAssert(sizeof(AARectVertex) == drawState->getVertexSize());
526
527 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
528 if (!geo.succeeded()) {
529 GrPrintf("Failed to get space for vertices!\n");
530 return;
531 }
532
533 AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
534
535 enum {
536 // the edge effects share this stage with glyph rendering
537 // (kGlyphMaskStage in GrTextContext) && SW path rendering
538 // (kPathMaskStage in GrSWMaskHelper)
539 kEdgeEffectStage = GrPaint::kTotalStages,
540 };
541
542 GrEffectRef* effect = GrAARectEffect::Create();
543 static const int kOffsetIndex = 1;
544 drawState->setEffect(kEdgeEffectStage, effect, kOffsetIndex)->unref();
545
546 SkRect devBounds = {
547 devRect.fLeft - SK_ScalarHalf,
548 devRect.fTop - SK_ScalarHalf,
549 devRect.fRight + SK_ScalarHalf,
550 devRect.fBottom + SK_ScalarHalf
551 };
552
553 GrPoint widthHeight = {
554 SkScalarHalf(devRect.width()) + SK_ScalarHalf,
555 SkScalarHalf(devRect.height()) + SK_ScalarHalf
556 };
557
558 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
559 verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY);
560 verts[0].fWidthHeight = widthHeight;
561
562 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
563 verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY);
564 verts[1].fWidthHeight = widthHeight;
565
566 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
567 verts[2].fOffset = widthHeight;
568 verts[2].fWidthHeight = widthHeight;
569
570 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
571 verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY);
572 verts[3].fWidthHeight = widthHeight;
573
574 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
575 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
576 target->resetIndexSource();
577 }
578
404 void GrAARectRenderer::strokeAARect(GrGpu* gpu, 579 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
405 GrDrawTarget* target, 580 GrDrawTarget* target,
406 const GrRect& devRect, 581 const GrRect& devRect,
407 const GrVec& devStrokeSize, 582 const GrVec& devStrokeSize,
408 bool useVertexCoverage) { 583 bool useVertexCoverage) {
409 GrDrawState* drawState = target->drawState(); 584 GrDrawState* drawState = target->drawState();
410 585
411 const SkScalar& dx = devStrokeSize.fX; 586 const SkScalar& dx = devStrokeSize.fX;
412 const SkScalar& dy = devStrokeSize.fY; 587 const SkScalar& dy = devStrokeSize.fY;
413 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); 588 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 // The innermost rect has full coverage 657 // The innermost rect has full coverage
483 verts += 8 * vsize; 658 verts += 8 * vsize;
484 for (int i = 0; i < 4; ++i) { 659 for (int i = 0; i < 4; ++i) {
485 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 660 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
486 } 661 }
487 662
488 target->setIndexSourceToBuffer(indexBuffer); 663 target->setIndexSourceToBuffer(indexBuffer);
489 target->drawIndexed(kTriangles_GrPrimitiveType, 664 target->drawIndexed(kTriangles_GrPrimitiveType,
490 0, 0, 16, aaStrokeRectIndexCount()); 665 0, 0, 16, aaStrokeRectIndexCount());
491 } 666 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698