1628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org/* 2628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * Copyright 2014 Google Inc. 3628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * 4628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * found in the LICENSE file. 6628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org */ 7628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 8628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrDashingEffect.h" 9628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 10e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "../GrAARectRenderer.h" 11e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 12e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "effects/GrVertexEffect.h" 13628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "gl/GrGLEffect.h" 14e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "gl/GrGLVertexEffect.h" 15628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "gl/GrGLSL.h" 16628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrContext.h" 17628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrCoordTransform.h" 18e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "GrDrawTarget.h" 19628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrDrawTargetCaps.h" 20628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrEffect.h" 21e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "GrGpu.h" 22e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "GrStrokeInfo.h" 23628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrTBackendEffectFactory.h" 24628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "SkGr.h" 25628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 26628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 27628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 28e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel// Returns whether or not the gpu can fast path the dash line effect. 29e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstatic bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeInfo, 30e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const GrDrawTarget& target, const SkMatrix& viewMatrix) { 31e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (target.getDrawState().getRenderTarget()->isMultisampled()) { 32e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 33e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 34e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 35e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Pts must be either horizontal or vertical in src space 36e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { 37e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 38e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 39e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 40e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // May be able to relax this to include skew. As of now cannot do perspective 41e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // because of the non uniform scaling of bloating a rect 42e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!viewMatrix.preservesRightAngles()) { 43e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 44e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 45e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 46e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!strokeInfo.isDashed() || 2 != strokeInfo.dashCount()) { 47e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 48e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 49e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 50e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); 51e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (0 == info.fIntervals[0] && 0 == info.fIntervals[1]) { 52e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 53e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 54e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 55e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); 56e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Current we do don't handle Round or Square cap dashes 57e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (SkPaint::kRound_Cap == cap) { 58e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 59e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 60e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 61e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return true; 62e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel} 63e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 64e61c411c1258a323a010558c08de3d9f8d170dcaegdanielnamespace { 65e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 66e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstruct DashLineVertex { 67e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint fPos; 68e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint fDashPos; 69e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel}; 70e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 71e61c411c1258a323a010558c08de3d9f8d170dcaegdanielextern const GrVertexAttrib gDashLineVertexAttribs[] = { 72e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 73e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel { kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding }, 74e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel}; 75e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 76e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel}; 77628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgstatic void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, 78628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const SkMatrix& viewMatrix, const SkPoint pts[2]) { 79628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkVector vecSrc = pts[1] - pts[0]; 80628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar magSrc = vecSrc.length(); 81628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; 82628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org vecSrc.scale(invSrc); 83628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 84628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkVector vecSrcPerp; 85628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org vecSrc.rotateCW(&vecSrcPerp); 86628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org viewMatrix.mapVectors(&vecSrc, 1); 87628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org viewMatrix.mapVectors(&vecSrcPerp, 1); 88628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 89628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // parallelScale tells how much to scale along the line parallel to the dash line 90628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // perpScale tells how much to scale in the direction perpendicular to the dash line 91628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *parallelScale = vecSrc.length(); 92628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *perpScale = vecSrcPerp.length(); 93628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 94628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 95628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org// calculates the rotation needed to aligned pts to the x axis with pts[0] < pts[1] 96628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org// Stores the rotation matrix in rotMatrix, and the mapped points in ptsRot 97628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgstatic void align_to_x_axis(const SkPoint pts[2], SkMatrix* rotMatrix, SkPoint ptsRot[2] = NULL) { 98628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkVector vec = pts[1] - pts[0]; 99628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar mag = vec.length(); 100628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar inv = mag ? SkScalarInvert(mag) : 0; 101628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 102628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org vec.scale(inv); 103628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org rotMatrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 104628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (ptsRot) { 105628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org rotMatrix->mapPoints(ptsRot, pts, 2); 106628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // correction for numerical issues if map doesn't make ptsRot exactly horizontal 107628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org ptsRot[1].fY = pts[0].fY; 108628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 109628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 110628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 111628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org// Assumes phase < sum of all intervals 112628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgstatic SkScalar calc_start_adjustment(const SkPathEffect::DashInfo& info) { 113628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkASSERT(info.fPhase < info.fIntervals[0] + info.fIntervals[1]); 114628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (info.fPhase >= info.fIntervals[0] && info.fPhase != 0) { 115628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar srcIntervalLen = info.fIntervals[0] + info.fIntervals[1]; 116628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return srcIntervalLen - info.fPhase; 117628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 118628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return 0; 119628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 120628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 121e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstatic SkScalar calc_end_adjustment(const SkPathEffect::DashInfo& info, const SkPoint pts[2], 122e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar phase, SkScalar* endingInt) { 123628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (pts[1].fX <= pts[0].fX) { 124628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return 0; 125628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 126628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar srcIntervalLen = info.fIntervals[0] + info.fIntervals[1]; 127628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar totalLen = pts[1].fX - pts[0].fX; 128628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar temp = SkScalarDiv(totalLen, srcIntervalLen); 129628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar numFullIntervals = SkScalarFloorToScalar(temp); 130e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel *endingInt = totalLen - numFullIntervals * srcIntervalLen + phase; 131628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org temp = SkScalarDiv(*endingInt, srcIntervalLen); 132628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *endingInt = *endingInt - SkScalarFloorToScalar(temp) * srcIntervalLen; 133628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (0 == *endingInt) { 134628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *endingInt = srcIntervalLen; 135628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 136628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (*endingInt > info.fIntervals[0]) { 137628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (0 == info.fIntervals[0]) { 138ad88340cf16162654ebddf4783ebb2ac56e1c3aacommit-bot@chromium.org *endingInt -= 0.01f; // make sure we capture the last zero size pnt (used if has caps) 139628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 140628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return *endingInt - info.fIntervals[0]; 141628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 142628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return 0; 143628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 144628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 145e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstatic void setup_dashed_rect(const SkRect& rect, DashLineVertex* verts, int idx, const SkMatrix& matrix, 146e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar offset, SkScalar bloat, SkScalar len, SkScalar stroke) { 147628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 148e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startDashX = offset - bloat; 149e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar endDashX = offset + len + bloat; 150e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startDashY = -stroke - bloat; 151e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar endDashY = stroke + bloat; 152e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx].fDashPos = SkPoint::Make(startDashX , startDashY); 153e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY); 154e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY); 155e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY); 156628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 157e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop); 158e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom); 159e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom); 160e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop); 161628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 162e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel matrix.mapPointsWithStride(&verts[idx].fPos, sizeof(DashLineVertex), 4); 163e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel} 164628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 165e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 166e61c411c1258a323a010558c08de3d9f8d170dcaegdanielbool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint, 167e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const GrStrokeInfo& strokeInfo, GrGpu* gpu, 168e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawTarget* target, const SkMatrix& vm) { 169e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 170e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!can_fast_path_dash(pts, strokeInfo, *target, vm)) { 171628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return false; 172628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 173628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 174e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); 175628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 176e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); 177e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 178e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); 179628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 180628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // the phase should be normalized to be [0, sum of all intervals) 181628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fIntervals[1]); 182628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 183e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar srcPhase = info.fPhase; 184628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 185628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX 186628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkMatrix srcRotInv; 187628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkPoint ptsRot[2]; 188628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) { 189e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkMatrix rotMatrix; 190e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel align_to_x_axis(pts, &rotMatrix, ptsRot); 191e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if(!rotMatrix.invert(&srcRotInv)) { 192e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrPrintf("Failed to create invertible rotation matrix!\n"); 193628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return false; 194628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 195628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } else { 196628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org srcRotInv.reset(); 197628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org memcpy(ptsRot, pts, 2 * sizeof(SkPoint)); 198628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 199628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 200628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org bool useAA = paint.isAntiAlias(); 2013b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com 202628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Scale corrections of intervals and stroke from view matrix 203628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar parallelScale; 204628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar perpScale; 205e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel calc_dash_scaling(¶llelScale, &perpScale, vm, ptsRot); 206628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 207628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org bool hasCap = SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth; 208628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 209628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // We always want to at least stroke out half a pixel on each side in device space 210628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // so 0.5f / perpScale gives us this min in src space 211e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar halfSrcStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale); 212628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 213e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeAdj; 214628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (!hasCap) { 215e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel strokeAdj = 0.f; 216628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } else { 217e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel strokeAdj = halfSrcStroke; 218628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 219628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 220e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startAdj = 0; 221e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 222e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkMatrix combinedMatrix = srcRotInv; 223e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel combinedMatrix.postConcat(vm); 224e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 225e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bool lineDone = false; 226e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkRect startRect; 227e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bool hasStartRect = false; 228628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we are using AA, check to see if we are drawing a partial dash at the start. If so 229628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // draw it separately here and adjust our start point accordingly 230628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (useAA) { 231e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (srcPhase > 0 && srcPhase < info.fIntervals[0]) { 232628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkPoint startPts[2]; 233628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org startPts[0] = ptsRot[0]; 234628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org startPts[1].fY = startPts[0].fY; 235e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startPts[1].fX = SkMinScalar(startPts[0].fX + info.fIntervals[0] - srcPhase, 236628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org ptsRot[1].fX); 237628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org startRect.set(startPts, 2); 238e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.outset(strokeAdj, halfSrcStroke); 239628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 240e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasStartRect = true; 241e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startAdj = info.fIntervals[0] + info.fIntervals[1] - srcPhase; 242628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 243628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 244628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 245628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // adjustments for start and end of bounding rect so we only draw dash intervals 246628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // contained in the original line segment. 247e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startAdj += calc_start_adjustment(info); 248e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (startAdj != 0) { 249e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[0].fX += startAdj; 250e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel srcPhase = 0; 251e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 252628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar endingInterval = 0; 253e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar endAdj = calc_end_adjustment(info, ptsRot, srcPhase, &endingInterval); 254e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[1].fX -= endAdj; 255e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (ptsRot[0].fX >= ptsRot[1].fX) { 256e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineDone = true; 257628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 258628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 259e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkRect endRect; 260e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bool hasEndRect = false; 261628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we are using AA, check to see if we are drawing a partial dash at then end. If so 262628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // draw it separately here and adjust our end point accordingly 263e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (useAA && !lineDone) { 264628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we adjusted the end then we will not be drawing a partial dash at the end. 265628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we didn't adjust the end point then we just need to make sure the ending 266628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // dash isn't a full dash 267628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (0 == endAdj && endingInterval != info.fIntervals[0]) { 268628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkPoint endPts[2]; 269628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org endPts[1] = ptsRot[1]; 270628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org endPts[0].fY = endPts[1].fY; 2713b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com endPts[0].fX = endPts[1].fX - endingInterval; 272628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 273628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org endRect.set(endPts, 2); 274e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel endRect.outset(strokeAdj, halfSrcStroke); 275e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 276e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasEndRect = true; 277e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel endAdj = endingInterval + info.fIntervals[1]; 2783b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com 279e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[1].fX -= endAdj; 280628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (ptsRot[0].fX >= ptsRot[1].fX) { 281e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineDone = true; 282628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 283628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 284628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 285628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 286e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (startAdj != 0) { 287e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel srcPhase = 0; 288e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 289628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 290e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Change the dashing info from src space into device space 291e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar devIntervals[2]; 292e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0] = info.fIntervals[0] * parallelScale; 293e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[1] = info.fIntervals[1] * parallelScale; 294e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar devPhase = srcPhase * parallelScale; 295628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar strokeWidth = srcStrokeWidth * perpScale; 296628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 297628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if ((strokeWidth < 1.f && !useAA) || 0.f == strokeWidth) { 298628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org strokeWidth = 1.f; 299628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 300628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 301e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar halfDevStroke = strokeWidth * 0.5f; 302628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 303628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth) { 304628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // add cap to on interveal and remove from off interval 305e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0] += strokeWidth; 306e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[1] -= strokeWidth; 307628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 308e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; 309e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 310e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar bloatX = useAA ? 0.5f / parallelScale : 0.f; 311e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar bloatY = useAA ? 0.5f / perpScale : 0.f; 312e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 313e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar devBloat = useAA ? 0.5f : 0.f; 314e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 315e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawState* drawState = target->drawState(); 316e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (devIntervals[1] <= 0.f && useAA) { 317e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Case when we end up drawing a solid AA rect 318e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Reset the start rect to draw this single solid rect 319e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // but it requires to upload a new intervals uniform so we can mimic 320e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // one giant dash 321e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[0].fX -= hasStartRect ? startAdj : 0; 322e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[1].fX += hasEndRect ? endAdj : 0; 323e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.set(ptsRot, 2); 324e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.outset(strokeAdj, halfSrcStroke); 325e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasStartRect = true; 326e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasEndRect = false; 327e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineDone = true; 328e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 329e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint devicePts[2]; 330e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel vm.mapPoints(devicePts, ptsRot, 2); 331e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); 332e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasCap) { 333e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineLength += 2.f * halfDevStroke; 334e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 335e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0] = lineLength; 336e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 337e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (devIntervals[1] > 0.f || useAA) { 338e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPathEffect::DashInfo devInfo; 339e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devInfo.fPhase = devPhase; 340e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devInfo.fCount = 2; 341e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devInfo.fIntervals = devIntervals; 342628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrEffectEdgeType edgeType= useAA ? kFillAA_GrEffectEdgeType : 343628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org kFillBW_GrEffectEdgeType; 344e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel drawState->addCoverageEffect( 345e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDashingEffect::Create(edgeType, devInfo, strokeWidth), 1)->unref(); 346628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 347628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 348e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Set up the vertex data for the line and start/end dashes 349e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs)); 350e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 351e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel int totalRectCnt = 0; 352e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 353e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel totalRectCnt += !lineDone ? 1 : 0; 354e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel totalRectCnt += hasStartRect ? 1 : 0; 355e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel totalRectCnt += hasEndRect ? 1 : 0; 356e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 357e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawTarget::AutoReleaseGeometry geo(target, totalRectCnt * 4, 0); 358e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!geo.succeeded()) { 359e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrPrintf("Failed to get space for vertices!\n"); 360e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 361628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 362628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 363e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices()); 364e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 365e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel int curVIdx = 0; 366e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 367e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Draw interior part of dashed line 368e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!lineDone) { 369e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint devicePts[2]; 370e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel vm.mapPoints(devicePts, ptsRot, 2); 371e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); 372e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasCap) { 373e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineLength += 2.f * halfDevStroke; 374e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 375e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 376e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkRect bounds; 377e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); 378e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); 379e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat, 380e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineLength, halfDevStroke); 381e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel curVIdx += 4; 382e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 383e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 384e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasStartRect) { 385e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkASSERT(useAA); // so that we know bloatX and bloatY have been set 386e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.outset(bloatX, bloatY); 387e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat, 388e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0], halfDevStroke); 389e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel curVIdx += 4; 390e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 391e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 392e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasEndRect) { 393e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkASSERT(useAA); // so that we know bloatX and bloatY have been set 394e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel endRect.outset(bloatX, bloatY); 395e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat, 396e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0], halfDevStroke); 397e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 398e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 399e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); 400e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel target->drawIndexedInstances(kTriangles_GrPrimitiveType, totalRectCnt, 4, 6); 401e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel target->resetIndexSource(); 402628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return true; 403628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 404628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 405628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 406628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 407628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgclass GLDashingLineEffect; 408628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 409e61c411c1258a323a010558c08de3d9f8d170dcaegdanielclass DashingLineEffect : public GrVertexEffect { 410628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgpublic: 411628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org typedef SkPathEffect::DashInfo DashInfo; 412628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 413628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org /** 414628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * The effect calculates the coverage for the case of a horizontal line in device space. 415628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * The matrix that is passed in should be able to convert a line in source space to a 416628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * horizontal line in device space. Additionally, the coord transform matrix should translate 417628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * the the start of line to origin, and the shift it along the positive x-axis by the phase 418628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org * and half the off interval. 419628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org */ 420628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org static GrEffectRef* Create(GrEffectEdgeType edgeType, const DashInfo& info, 421e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeWidth); 422628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 423628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual ~DashingLineEffect(); 424628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 425628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org static const char* Name() { return "DashingEffect"; } 426628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 427628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrEffectEdgeType getEdgeType() const { return fEdgeType; } 428628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 429628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const SkRect& getRect() const { return fRect; } 430628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 431628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar getIntervalLength() const { return fIntervalLength; } 432628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 433628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org typedef GLDashingLineEffect GLEffect; 434628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 435628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 436628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 437628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 438628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 439628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgprivate: 440e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth); 441628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 442628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; 443628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 444628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrEffectEdgeType fEdgeType; 445628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkRect fRect; 446628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar fIntervalLength; 447628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 448628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GR_DECLARE_EFFECT_TEST; 449628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 450628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org typedef GrEffect INHERITED; 451628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org}; 452628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 453628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 454628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 455e61c411c1258a323a010558c08de3d9f8d170dcaegdanielclass GLDashingLineEffect : public GrGLVertexEffect { 456628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgpublic: 457628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GLDashingLineEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 458628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 459e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel virtual void emitCode(GrGLFullShaderBuilder* builder, 460628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const GrDrawEffect& drawEffect, 461628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org EffectKey key, 462628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char* outputColor, 463628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char* inputColor, 464628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const TransformedCoordsArray&, 465628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const TextureSamplerArray&) SK_OVERRIDE; 466628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 467628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); 468628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 469628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; 470628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 471628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgprivate: 472628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrGLUniformManager::UniformHandle fRectUniform; 473628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrGLUniformManager::UniformHandle fIntervalUniform; 474628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkRect fPrevRect; 475628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar fPrevIntervalLength; 476e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel typedef GrGLVertexEffect INHERITED; 477628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org}; 478628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 4793b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.comGLDashingLineEffect::GLDashingLineEffect(const GrBackendEffectFactory& factory, 480628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const GrDrawEffect& drawEffect) 481628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org : INHERITED (factory) { 482628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevRect.fLeft = SK_ScalarNaN; 483628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevIntervalLength = SK_ScalarMax; 484628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 485628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 486628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 487e61c411c1258a323a010558c08de3d9f8d170dcaegdanielvoid GLDashingLineEffect::emitCode(GrGLFullShaderBuilder* builder, 488628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const GrDrawEffect& drawEffect, 489628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org EffectKey key, 490628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char* outputColor, 491628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char* inputColor, 492e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const TransformedCoordsArray&, 493628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const TextureSamplerArray& samplers) { 494628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>(); 495628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char *rectName; 496628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), 497628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // respectively. 498628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 499628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org kVec4f_GrSLType, 500628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org "rect", 501628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org &rectName); 502628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char *intervalName; 503628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // The interval uniform's refers to the total length of the interval (on + off) 504628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fIntervalUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 505628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org kFloat_GrSLType, 506628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org "interval", 507628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org &intervalName); 508e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 509e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const char *vsCoordName, *fsCoordName; 510e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName); 511e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const SkString* attr0Name = 512e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); 513e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str()); 514e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 515628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // transforms all points so that we can compare them to our test rect 516628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n", 517e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel fsCoordName, fsCoordName, intervalName, intervalName); 518e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName); 519628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (GrEffectEdgeTypeIsAA(de.getEdgeType())) { 520628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // The amount of coverage removed in x and y by the edges is computed as a pair of negative 521628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // numbers, xSub and ySub. 522628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); 523628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n", rectName); 524628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n", rectName); 525628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n", rectName); 526628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n", rectName); 527628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Now compute coverage in x and y and multiply them to get the fraction of the pixel 528628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // covered. 529628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); 530628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } else { 531628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Assuming the bounding geometry is tight so no need to check y values 532628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n"); 533628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName); 534628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName); 535628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 536628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, 537628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 538628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 539628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 540628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgvoid GLDashingLineEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { 541628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>(); 542628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const SkRect& rect = de.getRect(); 543628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar intervalLength = de.getIntervalLength(); 544628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (rect != fPrevRect || intervalLength != fPrevIntervalLength) { 545628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, 546628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org rect.fRight - 0.5f, rect.fBottom - 0.5f); 547628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org uman.set1f(fIntervalUniform, intervalLength); 548628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevRect = rect; 549628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevIntervalLength = intervalLength; 550628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 551628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 552628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 553628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgGrGLEffect::EffectKey GLDashingLineEffect::GenKey(const GrDrawEffect& drawEffect, 554628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const GrGLCaps&) { 555628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>(); 556628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return de.getEdgeType(); 557628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 558628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 559628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 5603b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com 561628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgGrEffectRef* DashingLineEffect::Create(GrEffectEdgeType edgeType, const DashInfo& info, 562e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeWidth) { 563628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (info.fCount != 2) { 564628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return NULL; 565628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 566628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 567628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(DashingLineEffect, 568e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel (edgeType, info, strokeWidth)))); 569628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 570628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 571628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgDashingLineEffect::~DashingLineEffect() {} 572628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 573628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgvoid DashingLineEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 574628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *validFlags = 0; 575628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 576628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 577628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgconst GrBackendEffectFactory& DashingLineEffect::getFactory() const { 578628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return GrTBackendEffectFactory<DashingLineEffect>::getInstance(); 579628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 580628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 581628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgDashingLineEffect::DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info, 582e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeWidth) 583e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel : fEdgeType(edgeType) { 584628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar onLen = info.fIntervals[0]; 585628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar offLen = info.fIntervals[1]; 586628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar halfOffLen = SkScalarHalf(offLen); 587628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar halfStroke = SkScalarHalf(strokeWidth); 588628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fIntervalLength = onLen + offLen; 589628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); 590628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 591e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel this->addVertexAttrib(kVec2f_GrSLType); 592628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 593628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 594628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgbool DashingLineEffect::onIsEqual(const GrEffect& other) const { 595628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const DashingLineEffect& de = CastEffect<DashingLineEffect>(other); 596628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return (fEdgeType == de.fEdgeType && 597628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fRect == de.fRect && 598628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fIntervalLength == de.fIntervalLength); 599628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 600628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 601628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(DashingLineEffect); 602628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 603628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgGrEffectRef* DashingLineEffect::TestCreate(SkRandom* random, 604628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrContext*, 605628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const GrDrawTargetCaps& caps, 606628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrTexture*[]) { 607628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrEffectRef* effect; 608628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(random->nextULessThan( 609628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org kGrEffectEdgeTypeCnt)); 610628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); 611628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org DashInfo info; 612628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fCount = 2; 613628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkAutoTArray<SkScalar> intervals(info.fCount); 614628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fIntervals = intervals.get(); 615628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fIntervals[0] = random->nextRangeScalar(0, 10.f); 616628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fIntervals[1] = random->nextRangeScalar(0, 10.f); 617628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]); 618628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 619e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel effect = DashingLineEffect::Create(edgeType, info, strokeWidth); 620628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return effect; 621628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 622628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 623628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 624628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 625628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgGrEffectRef* GrDashingEffect::Create(GrEffectEdgeType edgeType, const SkPathEffect::DashInfo& info, 626e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeWidth) { 627e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return DashingLineEffect::Create(edgeType, info, strokeWidth); 628628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 629