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

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

Issue 13521006: First pass at Rect Effect (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: renamed isOrthogonal to preservesRightAngles Created 7 years, 8 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 | « src/core/SkMatrix.cpp ('k') | src/gpu/GrContext.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"
12 #include "GrTBackendEffectFactory.h"
11 13
12 SK_DEFINE_INST_COUNT(GrAARectRenderer) 14 SK_DEFINE_INST_COUNT(GrAARectRenderer)
13 15
16 class GrGLRectEffect;
17
18 /**
19 * 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:
21 * Center of the rect
22 * Unit vector point down the height of the rect
23 * Half width + 0.5
24 * Half height + 0.5
25 * The center and vector are stored in a vec4 varying ("RectEdge") with the
26 * center in the xy components and the vector in the zw components.
27 * The munged width and height are stored in a vec2 varying ("WidthHeight")
28 * with the width in x and the height in y.
29 */
30 class GrRectEffect : public GrEffect {
31 public:
32 static GrEffectRef* Create() {
33 static SkAutoTUnref<GrEffectRef> gRectEffectRef(
34 CreateEffectRef(AutoEffectUnref(SkNEW(GrRectEffect))));
35 gRectEffectRef.get()->ref();
36 return gRectEffectRef;
37 }
38
39 virtual ~GrRectEffect() {}
40
41 static const char* Name() { return "RectEdge"; }
42
43 virtual void getConstantColorComponents(GrColor* color,
44 uint32_t* validFlags) const SK_OVERR IDE {
45 *validFlags = 0;
46 }
47
48 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
49 return GrTBackendEffectFactory<GrRectEffect>::getInstance();
50 }
51
52 class GLEffect : public GrGLEffect {
53 public:
54 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
55 : INHERITED (factory) {}
56
57 virtual void emitCode(GrGLShaderBuilder* builder,
58 const GrDrawEffect& drawEffect,
59 EffectKey key,
60 const char* outputColor,
61 const char* inputColor,
62 const TextureSamplerArray& samplers) SK_OVERRIDE {
63 // setup the varying for the center point and the unit vector
64 // that points down the height of the rect
65 const char *vsRectEdgeName, *fsRectEdgeName;
66 builder->addVarying(kVec4f_GrSLType, "RectEdge",
67 &vsRectEdgeName, &fsRectEdgeName);
68 const SkString* attr0Name =
69 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]);
70 builder->vsCodeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_ str());
71
72 // setup the varying for width/2+.5 and height/2+.5
73 const char *vsWidthHeightName, *fsWidthHeightName;
74 builder->addVarying(kVec2f_GrSLType, "WidthHeight",
75 &vsWidthHeightName, &fsWidthHeightName);
76 const SkString* attr1Name =
77 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]);
78 builder->vsCodeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name- >c_str());
79
80 // TODO: compute these scale factors in the VS
81 // These scale factors adjust the coverage for < 1 pixel wide/high r ects
82 builder->fsCodeAppendf("\tfloat wScale = max(1.0, 2.0/(0.5+%s.x));\n ",
83 fsWidthHeightName);
84 builder->fsCodeAppendf("\tfloat hScale = max(1.0, 2.0/(0.5+%s.y));\n ",
85 fsWidthHeightName);
86
87 // Compute the coverage for the rect's width
88 builder->fsCodeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
89 builder->fragmentPosition(), fsRectEdgeName);
90 builder->fsCodeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offs et.y * %s.z);\n",
91 fsRectEdgeName, fsRectEdgeName);
92 builder->fsCodeAppendf("\tfloat coverage = clamp(wScale*(%s.x-perpDo t), 0.0, 1.0);\n",
93 fsWidthHeightName);
94
95 // Compute the coverage for the rect's height and merge with the wid th
96 builder->fsCodeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
97 fsRectEdgeName);
98 builder->fsCodeAppendf(
99 "\tcoverage = min(coverage, clamp(hScale*(%s.y-perpDot), 0.0 , 1.0));\n",
100 fsWidthHeightName);
101
102 SkString modulate;
103 GrGLSLModulate4f(&modulate, inputColor, "coverage");
104 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() );
105 }
106
107 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
108 return 0;
109 }
110
111 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& ) SK_OVERRIDE {}
112
113 private:
114 typedef GrGLEffect INHERITED;
115 };
116
117
118 private:
119 GrRectEffect::GrRectEffect() : GrEffect() {
120 this->addVertexAttrib(kVec4f_GrSLType);
121 this->addVertexAttrib(kVec2f_GrSLType);
122 }
123
124 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; }
125
126 GR_DECLARE_EFFECT_TEST;
127
128 typedef GrEffect INHERITED;
129 };
130
131
132 GR_DEFINE_EFFECT_TEST(GrRectEffect);
133
134 GrEffectRef* GrRectEffect::TestCreate(SkMWCRandom* random,
135 GrContext* context,
136 const GrDrawTargetCaps&,
137 GrTexture* textures[]) {
138 return GrRectEffect::Create();
139 }
140
141 ///////////////////////////////////////////////////////////////////////////////
142
14 namespace { 143 namespace {
15 144
16 static void aa_rect_attributes(bool useCoverage, const GrVertexAttrib** attribs, int* count) { 145 static void aa_rect_attributes(bool useCoverage, const GrVertexAttrib** attribs, int* count) {
17 static const GrVertexAttrib kCoverageAttribs[] = { 146 static const GrVertexAttrib kCoverageAttribs[] = {
18 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 147 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
19 {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kCoverage_GrVertexAttribBi nding}, 148 {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kCoverage_GrVertexAttribBi nding},
20 }; 149 };
21 static const GrVertexAttrib kColorAttribs[] = { 150 static const GrVertexAttrib kColorAttribs[] = {
22 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 151 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
23 {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBindi ng}, 152 {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBindi ng},
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 303 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
175 } 304 }
176 305
177 target->setIndexSourceToBuffer(indexBuffer); 306 target->setIndexSourceToBuffer(indexBuffer);
178 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 307 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
179 kVertsPerAAFillRect, 308 kVertsPerAAFillRect,
180 kIndicesPerAAFillRect); 309 kIndicesPerAAFillRect);
181 target->resetIndexSource(); 310 target->resetIndexSource();
182 } 311 }
183 312
313 struct RectVertex {
314 GrPoint fPos;
315 GrPoint fCenter;
316 GrPoint fDir;
317 GrPoint fWidthHeight;
318 };
319
320
321 void GrAARectRenderer::shaderFillAARect(GrGpu* gpu,
322 GrDrawTarget* target,
323 const GrRect& rect,
324 const SkMatrix& combinedMatrix,
325 const GrRect& devRect,
326 bool useVertexCoverage) {
327 GrDrawState* drawState = target->drawState();
328
329 SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY());
330 combinedMatrix.mapPoints(&center, 1);
331
332 // compute transformed (0, 1) vector
333 SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix: :kMScaleY] };
334 dir.normalize();
335
336 // compute transformed (width, 0) and (0, height) vectors
337 SkVector vec[2] = {
338 { combinedMatrix[SkMatrix::kMScaleX] * rect.width(),
339 combinedMatrix[SkMatrix::kMSkewY] * rect.width() },
340 { combinedMatrix[SkMatrix::kMSkewX] * rect.height(),
341 combinedMatrix[SkMatrix::kMScaleY] * rect.height() }
342 };
343
344 SkScalar newWidth = vec[0].length() / 2.0f + 0.5f;
345 SkScalar newHeight = vec[1].length() / 2.0f + 0.5f;
346
347 static const GrVertexAttrib kVertexAttribs[] = {
348 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
349 { kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBind ing },
350 { kVec2f_GrVertexAttribType, 3*sizeof(GrPoint), kEffect_GrVertexAttribBi nding }
351 };
352 drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
353 GrAssert(sizeof(RectVertex) == drawState->getVertexSize());
354
355 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
356 if (!geo.succeeded()) {
357 GrPrintf("Failed to get space for vertices!\n");
358 return;
359 }
360
361 RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
362
363 enum {
364 // the edge effects share this stage with glyph rendering
365 // (kGlyphMaskStage in GrTextContext) && SW path rendering
366 // (kPathMaskStage in GrSWMaskHelper)
367 kEdgeEffectStage = GrPaint::kTotalStages,
368 };
369
370 GrEffectRef* effect = GrRectEffect::Create();
371 static const int kRectAttrIndex = 1;
372 static const int kWidthIndex = 2;
373 drawState->setEffect(kEdgeEffectStage, effect, kRectAttrIndex, kWidthIndex)- >unref();
374
375 for (int i = 0; i < 4; ++i) {
376 verts[i].fCenter = center;
377 verts[i].fDir = dir;
378 verts[i].fWidthHeight.fX = newWidth;
379 verts[i].fWidthHeight.fY = newHeight;
380 }
381
382 SkRect devBounds = {
383 devRect.fLeft - SK_ScalarHalf,
384 devRect.fTop - SK_ScalarHalf,
385 devRect.fRight + SK_ScalarHalf,
386 devRect.fBottom + SK_ScalarHalf
387 };
388
389 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
390 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
391 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
392 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
393
394 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
395 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
396 target->resetIndexSource();
397 }
398
184 void GrAARectRenderer::strokeAARect(GrGpu* gpu, 399 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
185 GrDrawTarget* target, 400 GrDrawTarget* target,
186 const GrRect& devRect, 401 const GrRect& devRect,
187 const GrVec& devStrokeSize, 402 const GrVec& devStrokeSize,
188 bool useVertexCoverage) { 403 bool useVertexCoverage) {
189 GrDrawState* drawState = target->drawState(); 404 GrDrawState* drawState = target->drawState();
190 405
191 const SkScalar& dx = devStrokeSize.fX; 406 const SkScalar& dx = devStrokeSize.fX;
192 const SkScalar& dy = devStrokeSize.fY; 407 const SkScalar& dy = devStrokeSize.fY;
193 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); 408 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 // The innermost rect has full coverage 480 // The innermost rect has full coverage
266 verts += 8 * vsize; 481 verts += 8 * vsize;
267 for (int i = 0; i < 4; ++i) { 482 for (int i = 0; i < 4; ++i) {
268 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 483 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
269 } 484 }
270 485
271 target->setIndexSourceToBuffer(indexBuffer); 486 target->setIndexSourceToBuffer(indexBuffer);
272 target->drawIndexed(kTriangles_GrPrimitiveType, 487 target->drawIndexed(kTriangles_GrPrimitiveType,
273 0, 0, 16, aaStrokeRectIndexCount()); 488 0, 0, 16, aaStrokeRectIndexCount());
274 } 489 }
OLDNEW
« no previous file with comments | « src/core/SkMatrix.cpp ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698