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 12b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrGeometryProcessor.h" 13408d6125b32c86e1f81ce60465e3bf4491e755fcjoshualitt#include "gl/builders/GrGLFullProgramBuilder.h" 14b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 15249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h" 16628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "gl/GrGLSL.h" 17628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrContext.h" 18628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrCoordTransform.h" 19e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "GrDrawTarget.h" 20628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "GrDrawTargetCaps.h" 21b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrProcessor.h" 22e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "GrGpu.h" 23e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "GrStrokeInfo.h" 24b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h" 25628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "SkGr.h" 26628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 27628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 28628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 29e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel// Returns whether or not the gpu can fast path the dash line effect. 30e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstatic bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeInfo, 31e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const GrDrawTarget& target, const SkMatrix& viewMatrix) { 32e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (target.getDrawState().getRenderTarget()->isMultisampled()) { 33e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 34e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 35e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 36e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Pts must be either horizontal or vertical in src space 37e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { 38e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 39e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 40e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 41e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // May be able to relax this to include skew. As of now cannot do perspective 42e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // because of the non uniform scaling of bloating a rect 43e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!viewMatrix.preservesRightAngles()) { 44e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 45e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 46e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 47e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!strokeInfo.isDashed() || 2 != strokeInfo.dashCount()) { 48e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 49e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 50e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 51e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); 52e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (0 == info.fIntervals[0] && 0 == info.fIntervals[1]) { 53e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 54e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 55e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 56e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); 57e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Current we do don't handle Round or Square cap dashes 58f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { 59e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 60e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 61e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 62e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return true; 63e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel} 64e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 65e61c411c1258a323a010558c08de3d9f8d170dcaegdanielnamespace { 66e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 67e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstruct DashLineVertex { 68e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint fPos; 69e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint fDashPos; 70e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel}; 71e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 72249af15fb82833d2274850c589812b6e69df0033joshualittextern const GrVertexAttrib gDashLineNoAAVertexAttribs[] = { 73249af15fb82833d2274850c589812b6e69df0033joshualitt { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding } 74249af15fb82833d2274850c589812b6e69df0033joshualitt}; 75249af15fb82833d2274850c589812b6e69df0033joshualitt 76e61c411c1258a323a010558c08de3d9f8d170dcaegdanielextern const GrVertexAttrib gDashLineVertexAttribs[] = { 77e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 78b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }, 79e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel}; 80e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 81e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel}; 82628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgstatic void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, 83628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const SkMatrix& viewMatrix, const SkPoint pts[2]) { 84628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkVector vecSrc = pts[1] - pts[0]; 85628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar magSrc = vecSrc.length(); 86628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; 87628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org vecSrc.scale(invSrc); 88628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 89628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkVector vecSrcPerp; 90628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org vecSrc.rotateCW(&vecSrcPerp); 91628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org viewMatrix.mapVectors(&vecSrc, 1); 92628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org viewMatrix.mapVectors(&vecSrcPerp, 1); 93628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 94628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // parallelScale tells how much to scale along the line parallel to the dash line 95628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // perpScale tells how much to scale in the direction perpendicular to the dash line 96628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *parallelScale = vecSrc.length(); 97628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *perpScale = vecSrcPerp.length(); 98628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 99628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 100628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org// calculates the rotation needed to aligned pts to the x axis with pts[0] < pts[1] 101628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org// Stores the rotation matrix in rotMatrix, and the mapped points in ptsRot 102628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgstatic void align_to_x_axis(const SkPoint pts[2], SkMatrix* rotMatrix, SkPoint ptsRot[2] = NULL) { 103628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkVector vec = pts[1] - pts[0]; 104628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar mag = vec.length(); 105628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar inv = mag ? SkScalarInvert(mag) : 0; 106628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 107628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org vec.scale(inv); 108628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org rotMatrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 109628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (ptsRot) { 110628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org rotMatrix->mapPoints(ptsRot, pts, 2); 111628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // correction for numerical issues if map doesn't make ptsRot exactly horizontal 112628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org ptsRot[1].fY = pts[0].fY; 113628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 114628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 115628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 116628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org// Assumes phase < sum of all intervals 117628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgstatic SkScalar calc_start_adjustment(const SkPathEffect::DashInfo& info) { 118628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkASSERT(info.fPhase < info.fIntervals[0] + info.fIntervals[1]); 119628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (info.fPhase >= info.fIntervals[0] && info.fPhase != 0) { 120628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar srcIntervalLen = info.fIntervals[0] + info.fIntervals[1]; 121628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return srcIntervalLen - info.fPhase; 122628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 123628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return 0; 124628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 125628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 126e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstatic SkScalar calc_end_adjustment(const SkPathEffect::DashInfo& info, const SkPoint pts[2], 127e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar phase, SkScalar* endingInt) { 128628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (pts[1].fX <= pts[0].fX) { 129628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return 0; 130628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 131628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar srcIntervalLen = info.fIntervals[0] + info.fIntervals[1]; 132628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar totalLen = pts[1].fX - pts[0].fX; 133628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar temp = SkScalarDiv(totalLen, srcIntervalLen); 134628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar numFullIntervals = SkScalarFloorToScalar(temp); 135e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel *endingInt = totalLen - numFullIntervals * srcIntervalLen + phase; 136628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org temp = SkScalarDiv(*endingInt, srcIntervalLen); 137628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *endingInt = *endingInt - SkScalarFloorToScalar(temp) * srcIntervalLen; 138628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (0 == *endingInt) { 139628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *endingInt = srcIntervalLen; 140628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 141628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (*endingInt > info.fIntervals[0]) { 142628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (0 == info.fIntervals[0]) { 143ad88340cf16162654ebddf4783ebb2ac56e1c3aacommit-bot@chromium.org *endingInt -= 0.01f; // make sure we capture the last zero size pnt (used if has caps) 144628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 145628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return *endingInt - info.fIntervals[0]; 146628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 147628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return 0; 148628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 149628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 150e61c411c1258a323a010558c08de3d9f8d170dcaegdanielstatic void setup_dashed_rect(const SkRect& rect, DashLineVertex* verts, int idx, const SkMatrix& matrix, 151e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar offset, SkScalar bloat, SkScalar len, SkScalar stroke) { 152628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 153e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startDashX = offset - bloat; 154e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar endDashX = offset + len + bloat; 155e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startDashY = -stroke - bloat; 156e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar endDashY = stroke + bloat; 157e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx].fDashPos = SkPoint::Make(startDashX , startDashY); 158e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY); 159e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY); 160e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY); 161628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 162e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop); 163e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom); 164e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom); 165e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel verts[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop); 166628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 167e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel matrix.mapPointsWithStride(&verts[idx].fPos, sizeof(DashLineVertex), 4); 168e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel} 169628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 170e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 171e61c411c1258a323a010558c08de3d9f8d170dcaegdanielbool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint, 172e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const GrStrokeInfo& strokeInfo, GrGpu* gpu, 173e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawTarget* target, const SkMatrix& vm) { 174e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 175e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!can_fast_path_dash(pts, strokeInfo, *target, vm)) { 176628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return false; 177628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 178628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 179e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); 180628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 181e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); 182e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 183e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); 184628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 185628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // the phase should be normalized to be [0, sum of all intervals) 186628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fIntervals[1]); 187628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 188e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar srcPhase = info.fPhase; 189628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 190628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX 191628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkMatrix srcRotInv; 192628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkPoint ptsRot[2]; 193628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) { 194e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkMatrix rotMatrix; 195e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel align_to_x_axis(pts, &rotMatrix, ptsRot); 196e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if(!rotMatrix.invert(&srcRotInv)) { 197e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrPrintf("Failed to create invertible rotation matrix!\n"); 198628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return false; 199628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 200628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } else { 201628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org srcRotInv.reset(); 202628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org memcpy(ptsRot, pts, 2 * sizeof(SkPoint)); 203628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 204628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 205628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org bool useAA = paint.isAntiAlias(); 2063b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com 207628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Scale corrections of intervals and stroke from view matrix 208628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar parallelScale; 209628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar perpScale; 210e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel calc_dash_scaling(¶llelScale, &perpScale, vm, ptsRot); 211628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 212f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel bool hasCap = SkPaint::kButt_Cap != cap && 0 != srcStrokeWidth; 213628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 214628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // We always want to at least stroke out half a pixel on each side in device space 215628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // so 0.5f / perpScale gives us this min in src space 216e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar halfSrcStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale); 217628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 218e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeAdj; 219628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (!hasCap) { 220e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel strokeAdj = 0.f; 221628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } else { 222e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel strokeAdj = halfSrcStroke; 223628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 224628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 225e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startAdj = 0; 226e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 227e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkMatrix combinedMatrix = srcRotInv; 228e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel combinedMatrix.postConcat(vm); 229e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 230e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bool lineDone = false; 231e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkRect startRect; 232e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bool hasStartRect = false; 233628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we are using AA, check to see if we are drawing a partial dash at the start. If so 234628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // draw it separately here and adjust our start point accordingly 235628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (useAA) { 236e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (srcPhase > 0 && srcPhase < info.fIntervals[0]) { 237628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkPoint startPts[2]; 238628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org startPts[0] = ptsRot[0]; 239628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org startPts[1].fY = startPts[0].fY; 240e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startPts[1].fX = SkMinScalar(startPts[0].fX + info.fIntervals[0] - srcPhase, 241628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org ptsRot[1].fX); 242628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org startRect.set(startPts, 2); 243e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.outset(strokeAdj, halfSrcStroke); 244628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 245e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasStartRect = true; 246e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startAdj = info.fIntervals[0] + info.fIntervals[1] - srcPhase; 247628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 248628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 249628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 250628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // adjustments for start and end of bounding rect so we only draw dash intervals 251628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // contained in the original line segment. 252e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startAdj += calc_start_adjustment(info); 253e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (startAdj != 0) { 254e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[0].fX += startAdj; 255e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel srcPhase = 0; 256e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 257628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar endingInterval = 0; 258e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar endAdj = calc_end_adjustment(info, ptsRot, srcPhase, &endingInterval); 259e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[1].fX -= endAdj; 260e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (ptsRot[0].fX >= ptsRot[1].fX) { 261e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineDone = true; 262628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 263628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 264e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkRect endRect; 265e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bool hasEndRect = false; 266628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we are using AA, check to see if we are drawing a partial dash at then end. If so 267628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // draw it separately here and adjust our end point accordingly 268e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (useAA && !lineDone) { 269628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we adjusted the end then we will not be drawing a partial dash at the end. 270628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // If we didn't adjust the end point then we just need to make sure the ending 271628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // dash isn't a full dash 272628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (0 == endAdj && endingInterval != info.fIntervals[0]) { 273628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkPoint endPts[2]; 274628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org endPts[1] = ptsRot[1]; 275628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org endPts[0].fY = endPts[1].fY; 2763b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com endPts[0].fX = endPts[1].fX - endingInterval; 277628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 278628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org endRect.set(endPts, 2); 279e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel endRect.outset(strokeAdj, halfSrcStroke); 280e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 281e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasEndRect = true; 282e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel endAdj = endingInterval + info.fIntervals[1]; 2833b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com 284e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[1].fX -= endAdj; 285628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (ptsRot[0].fX >= ptsRot[1].fX) { 286e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineDone = true; 287628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 288628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 289628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 290628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 291e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (startAdj != 0) { 292e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel srcPhase = 0; 293e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 294628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 295e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Change the dashing info from src space into device space 296e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar devIntervals[2]; 297e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0] = info.fIntervals[0] * parallelScale; 298e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[1] = info.fIntervals[1] * parallelScale; 299e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar devPhase = srcPhase * parallelScale; 300628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar strokeWidth = srcStrokeWidth * perpScale; 301628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 302628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if ((strokeWidth < 1.f && !useAA) || 0.f == strokeWidth) { 303628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org strokeWidth = 1.f; 304628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 305628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 306e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar halfDevStroke = strokeWidth * 0.5f; 307628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 308628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth) { 309628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // add cap to on interveal and remove from off interval 310e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0] += strokeWidth; 311e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[1] -= strokeWidth; 312628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 313e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; 314e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 315e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar bloatX = useAA ? 0.5f / parallelScale : 0.f; 316e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar bloatY = useAA ? 0.5f / perpScale : 0.f; 317e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 318e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar devBloat = useAA ? 0.5f : 0.f; 319e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 320e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawState* drawState = target->drawState(); 321e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (devIntervals[1] <= 0.f && useAA) { 322e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Case when we end up drawing a solid AA rect 323e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Reset the start rect to draw this single solid rect 324e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // but it requires to upload a new intervals uniform so we can mimic 325e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // one giant dash 326e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[0].fX -= hasStartRect ? startAdj : 0; 327e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel ptsRot[1].fX += hasEndRect ? endAdj : 0; 328e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.set(ptsRot, 2); 329e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.outset(strokeAdj, halfSrcStroke); 330e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasStartRect = true; 331e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel hasEndRect = false; 332e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineDone = true; 333e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 334e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint devicePts[2]; 335e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel vm.mapPoints(devicePts, ptsRot, 2); 336e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); 337e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasCap) { 338e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineLength += 2.f * halfDevStroke; 339e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 340e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0] = lineLength; 341e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 342e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (devIntervals[1] > 0.f || useAA) { 343e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPathEffect::DashInfo devInfo; 344e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devInfo.fPhase = devPhase; 345e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devInfo.fCount = 2; 346e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devInfo.fIntervals = devIntervals; 347b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : 348b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kFillBW_GrProcessorEdgeType; 349f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel bool isRoundCap = SkPaint::kRound_Cap == cap; 350f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap : 351f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel GrDashingEffect::kNonRound_DashCap; 352bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt drawState->setGeometryProcessor( 353b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType))->unref(); 354628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 355249af15fb82833d2274850c589812b6e69df0033joshualitt // Set up the vertex data for the line and start/end dashes 356249af15fb82833d2274850c589812b6e69df0033joshualitt drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs), 357249af15fb82833d2274850c589812b6e69df0033joshualitt sizeof(DashLineVertex)); 358249af15fb82833d2274850c589812b6e69df0033joshualitt } else { 359249af15fb82833d2274850c589812b6e69df0033joshualitt // Set up the vertex data for the line and start/end dashes 360249af15fb82833d2274850c589812b6e69df0033joshualitt drawState->setVertexAttribs<gDashLineNoAAVertexAttribs>( 361249af15fb82833d2274850c589812b6e69df0033joshualitt SK_ARRAY_COUNT(gDashLineNoAAVertexAttribs), sizeof(DashLineVertex)); 362249af15fb82833d2274850c589812b6e69df0033joshualitt } 363e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 364e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel int totalRectCnt = 0; 365e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 366e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel totalRectCnt += !lineDone ? 1 : 0; 367e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel totalRectCnt += hasStartRect ? 1 : 0; 368e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel totalRectCnt += hasEndRect ? 1 : 0; 369e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 370e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawTarget::AutoReleaseGeometry geo(target, totalRectCnt * 4, 0); 371e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!geo.succeeded()) { 372e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrPrintf("Failed to get space for vertices!\n"); 373e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return false; 374628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 375628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 376e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices()); 377e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 378e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel int curVIdx = 0; 379e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 380f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { 381f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel // need to adjust this for round caps to correctly set the dashPos attrib on vertices 382f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel startOffset -= halfDevStroke; 383f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel } 384f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 385e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Draw interior part of dashed line 386e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (!lineDone) { 387e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint devicePts[2]; 388e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel vm.mapPoints(devicePts, ptsRot, 2); 389e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); 390e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasCap) { 391e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineLength += 2.f * halfDevStroke; 392e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 393e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 394e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkRect bounds; 395e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); 396e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); 397e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat, 398e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel lineLength, halfDevStroke); 399e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel curVIdx += 4; 400e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 401e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 402e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasStartRect) { 403e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkASSERT(useAA); // so that we know bloatX and bloatY have been set 404e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel startRect.outset(bloatX, bloatY); 405e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat, 406e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0], halfDevStroke); 407e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel curVIdx += 4; 408e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 409e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 410e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (hasEndRect) { 411e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkASSERT(useAA); // so that we know bloatX and bloatY have been set 412e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel endRect.outset(bloatX, bloatY); 413e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat, 414e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel devIntervals[0], halfDevStroke); 415e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 416e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 417e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); 418e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel target->drawIndexedInstances(kTriangles_GrPrimitiveType, totalRectCnt, 4, 6); 419e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel target->resetIndexSource(); 420628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return true; 421628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 422628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 423628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 424628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 425f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielclass GLDashingCircleEffect; 426f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel/* 427f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * This effect will draw a dotted line (defined as a dashed lined with round caps and no on 428f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * interval). The radius of the dots is given by the strokeWidth and the spacing by the DashInfo. 429f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * Both of the previous two parameters are in device space. This effect also requires the setting of 430f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * a vec2 vertex attribute for the the four corners of the bounding rect. This attribute is the 431f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * "dash position" of each vertex. In other words it is the vertex coords (in device space) if we 432f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * transform the line to be horizontal, with the start of line at the origin then shifted to the 433f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * right by half the off interval. The line then goes in the positive x direction. 434f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel */ 435249af15fb82833d2274850c589812b6e69df0033joshualittclass DashingCircleEffect : public GrGeometryProcessor { 436f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielpublic: 437f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel typedef SkPathEffect::DashInfo DashInfo; 438f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 439b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, 440b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashInfo& info, 441b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkScalar radius); 442f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 443f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel virtual ~DashingCircleEffect(); 444f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 445f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel static const char* Name() { return "DashingCircleEffect"; } 446f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 447249af15fb82833d2274850c589812b6e69df0033joshualitt const GrShaderVar& inCoord() const { return fInCoord; } 448249af15fb82833d2274850c589812b6e69df0033joshualitt 449b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } 450f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 451f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar getRadius() const { return fRadius; } 452f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 453f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar getCenterX() const { return fCenterX; } 454f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 455f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar getIntervalLength() const { return fIntervalLength; } 456f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 457b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GLDashingCircleEffect GLProcessor; 458f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 459f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 460f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 461b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; 462f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 463f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielprivate: 464b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar radius); 465f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 466b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; 467f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 468b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType fEdgeType; 469249af15fb82833d2274850c589812b6e69df0033joshualitt const GrShaderVar& fInCoord; 470f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar fIntervalLength; 471f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar fRadius; 472f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar fCenterX; 473f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 474b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 475f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 476249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 477f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel}; 478f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 479f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel////////////////////////////////////////////////////////////////////////////// 480f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 481249af15fb82833d2274850c589812b6e69df0033joshualittclass GLDashingCircleEffect : public GrGLGeometryProcessor { 482f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielpublic: 483b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GLDashingCircleEffect(const GrBackendProcessorFactory&, const GrProcessor&); 484f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 48530ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLFullProgramBuilder* builder, 486b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor& geometryProcessor, 487b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 488f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const char* outputColor, 489f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const char* inputColor, 490f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const TransformedCoordsArray&, 491f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const TextureSamplerArray&) SK_OVERRIDE; 492f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 493b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 494f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 495b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 496f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 497f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielprivate: 4987510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fParamUniform; 4997510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkScalar fPrevRadius; 5007510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkScalar fPrevCenterX; 5017510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkScalar fPrevIntervalLength; 502249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 503f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel}; 504f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 505b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLDashingCircleEffect::GLDashingCircleEffect(const GrBackendProcessorFactory& factory, 506b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&) 507f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel : INHERITED (factory) { 508f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fPrevRadius = SK_ScalarMin; 509f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fPrevCenterX = SK_ScalarMin; 510f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fPrevIntervalLength = SK_ScalarMax; 511f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 512f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 51330ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLDashingCircleEffect::emitCode(GrGLFullProgramBuilder* builder, 514b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor& geometryProcessor, 515b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 516f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const char* outputColor, 517f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const char* inputColor, 518f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const TransformedCoordsArray&, 519f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const TextureSamplerArray& samplers) { 520b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashingCircleEffect& dce = geometryProcessor.cast<DashingCircleEffect>(); 521f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const char *paramName; 522f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x coord, and 523f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel // the total interval length of the dash. 52430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fParamUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 525f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel kVec3f_GrSLType, 526f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel "params", 527f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel ¶mName); 528f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 529f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel const char *vsCoordName, *fsCoordName; 530f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName); 53130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 53230ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 533249af15fb82833d2274850c589812b6e69df0033joshualitt vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dce.inCoord().c_str()); 534f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 535f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel // transforms all points so that we can compare them to our test circle 536b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 53730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n", 538f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fsCoordName, fsCoordName, paramName, paramName); 53930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName); 54030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); 54130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n"); 542b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { 54330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName); 54430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n"); 54530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n"); 546f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel } else { 54730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); 54830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n", paramName); 549f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel } 55030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, 551f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 552f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 553f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 554b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman 555b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt , const GrProcessor& processor) { 556b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); 557f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar radius = dce.getRadius(); 558f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar centerX = dce.getCenterX(); 559f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar intervalLength = dce.getIntervalLength(); 560f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fPrevIntervalLength) { 5617510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength); 562f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fPrevRadius = radius; 563f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fPrevCenterX = centerX; 564f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fPrevIntervalLength = intervalLength; 565f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel } 566f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 567f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 568b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLDashingCircleEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 569b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 570b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); 57163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(dce.getEdgeType()); 572f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 573f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 574f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel////////////////////////////////////////////////////////////////////////////// 575f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 576b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* DashingCircleEffect::Create(GrPrimitiveEdgeType edgeType, const DashInfo& info, 577b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkScalar radius) { 578f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel if (info.fCount != 2 || info.fIntervals[0] != 0) { 579f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel return NULL; 580f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel } 581f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 58255fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(DashingCircleEffect, (edgeType, info, radius)); 583f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 584f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 585f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielDashingCircleEffect::~DashingCircleEffect() {} 586f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 587f767e792b929df9a2d9f35f9c68adaa9251f4da3egdanielvoid DashingCircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 588f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel *validFlags = 0; 589f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 590f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 591b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const { 592b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendGeometryProcessorFactory<DashingCircleEffect>::getInstance(); 593f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 594f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 595b0a8a377f832c59cee939ad721e1f87d378b7142joshualittDashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, 596f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar radius) 597249af15fb82833d2274850c589812b6e69df0033joshualitt : fEdgeType(edgeType) 598249af15fb82833d2274850c589812b6e69df0033joshualitt , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord", 599249af15fb82833d2274850c589812b6e69df0033joshualitt kVec2f_GrSLType, 600249af15fb82833d2274850c589812b6e69df0033joshualitt GrShaderVar::kAttribute_TypeModifier))) { 601f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar onLen = info.fIntervals[0]; 602f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar offLen = info.fIntervals[1]; 603f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fIntervalLength = onLen + offLen; 604f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fRadius = radius; 605f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fCenterX = SkScalarHalf(offLen); 606f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 607f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 608b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool DashingCircleEffect::onIsEqual(const GrProcessor& other) const { 60949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); 610f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel return (fEdgeType == dce.fEdgeType && 611f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fIntervalLength == dce.fIntervalLength && 612f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fRadius == dce.fRadius && 613f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel fCenterX == dce.fCenterX); 614f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 615f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 616b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); 617f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 618b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, 619b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 620b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 621b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 622b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan( 623b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kGrProcessorEdgeTypeCnt)); 624f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); 625f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel DashInfo info; 626f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel info.fCount = 2; 627f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkAutoTArray<SkScalar> intervals(info.fCount); 628f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel info.fIntervals = intervals.get(); 629f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel info.fIntervals[0] = 0; 630f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel info.fIntervals[1] = random->nextRangeScalar(0, 10.f); 631f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]); 632f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 633b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return DashingCircleEffect::Create(edgeType, info, strokeWidth); 634f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel} 635f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 636f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel////////////////////////////////////////////////////////////////////////////// 637f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel 638628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgclass GLDashingLineEffect; 639628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 640f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel/* 641f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * This effect will draw a dashed line. The width of the dash is given by the strokeWidth and the 642f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * length and spacing by the DashInfo. Both of the previous two parameters are in device space. 643f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * This effect also requires the setting of a vec2 vertex attribute for the the four corners of the 644f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * bounding rect. This attribute is the "dash position" of each vertex. In other words it is the 645f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * vertex coords (in device space) if we transform the line to be horizontal, with the start of 646f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * line at the origin then shifted to the right by half the off interval. The line then goes in the 647f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel * positive x direction. 648f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel */ 649249af15fb82833d2274850c589812b6e69df0033joshualittclass DashingLineEffect : public GrGeometryProcessor { 650628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgpublic: 651628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org typedef SkPathEffect::DashInfo DashInfo; 652628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 653b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, 654b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashInfo& info, 655b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkScalar strokeWidth); 656628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 657628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual ~DashingLineEffect(); 658628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 659628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org static const char* Name() { return "DashingEffect"; } 660628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 661249af15fb82833d2274850c589812b6e69df0033joshualitt const GrShaderVar& inCoord() const { return fInCoord; } 662249af15fb82833d2274850c589812b6e69df0033joshualitt 663b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } 664628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 665628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const SkRect& getRect() const { return fRect; } 666628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 667628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar getIntervalLength() const { return fIntervalLength; } 668628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 669b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GLDashingLineEffect GLProcessor; 670628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 671628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 672628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 673b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; 674628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 675628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgprivate: 676b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth); 677628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 678b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; 679628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 680b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType fEdgeType; 681249af15fb82833d2274850c589812b6e69df0033joshualitt const GrShaderVar& fInCoord; 682628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkRect fRect; 683628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar fIntervalLength; 684628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 685b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 686628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 687249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 688628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org}; 689628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 690628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 691628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 692249af15fb82833d2274850c589812b6e69df0033joshualittclass GLDashingLineEffect : public GrGLGeometryProcessor { 693628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgpublic: 694b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GLDashingLineEffect(const GrBackendProcessorFactory&, const GrProcessor&); 695628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 69630ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLFullProgramBuilder* builder, 697b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor& geometryProcessor, 698b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 699628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char* outputColor, 700628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char* inputColor, 701628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const TransformedCoordsArray&, 702628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const TextureSamplerArray&) SK_OVERRIDE; 703628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 704b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 705628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 706b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 707628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 708628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgprivate: 7097510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fRectUniform; 7107510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fIntervalUniform; 7117510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkRect fPrevRect; 7127510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkScalar fPrevIntervalLength; 713249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 714628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org}; 715628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 716b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLDashingLineEffect::GLDashingLineEffect(const GrBackendProcessorFactory& factory, 717b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&) 718628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org : INHERITED (factory) { 719628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevRect.fLeft = SK_ScalarNaN; 720628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevIntervalLength = SK_ScalarMax; 721628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 722628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 72330ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLDashingLineEffect::emitCode(GrGLFullProgramBuilder* builder, 724b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor& geometryProcessor, 725b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 726b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const char* outputColor, 727b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const char* inputColor, 728b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const TransformedCoordsArray&, 729b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const TextureSamplerArray& samplers) { 730b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashingLineEffect& de = geometryProcessor.cast<DashingLineEffect>(); 731628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char *rectName; 732628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), 733628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // respectively. 73430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 735628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org kVec4f_GrSLType, 736628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org "rect", 737628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org &rectName); 738628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const char *intervalName; 739628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // The interval uniform's refers to the total length of the interval (on + off) 74030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fIntervalUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 741628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org kFloat_GrSLType, 742628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org "interval", 743628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org &intervalName); 744e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 745e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel const char *vsCoordName, *fsCoordName; 746e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName); 74730ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 748249af15fb82833d2274850c589812b6e69df0033joshualitt vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, de.inCoord().c_str()); 749e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 750628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // transforms all points so that we can compare them to our test rect 751b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 75230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n", 753e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel fsCoordName, fsCoordName, intervalName, intervalName); 75430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName); 755b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { 756628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // The amount of coverage removed in x and y by the edges is computed as a pair of negative 757628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // numbers, xSub and ySub. 75830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); 75930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n", rectName); 76030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n", rectName); 76130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n", rectName); 76230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n", rectName); 763628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Now compute coverage in x and y and multiply them to get the fraction of the pixel 764628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // covered. 76530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); 766628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } else { 767628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org // Assuming the bounding geometry is tight so no need to check y values 76830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); 76930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName); 77030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName); 771628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 77230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, 773628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 774628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 775628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 776b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, 777b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& processor) { 778b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashingLineEffect& de = processor.cast<DashingLineEffect>(); 779628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org const SkRect& rect = de.getRect(); 780628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar intervalLength = de.getIntervalLength(); 781628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (rect != fPrevRect || intervalLength != fPrevIntervalLength) { 7827510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, 7837510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen rect.fRight - 0.5f, rect.fBottom - 0.5f); 7847510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fIntervalUniform, intervalLength); 785628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevRect = rect; 786628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fPrevIntervalLength = intervalLength; 787628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 788628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 789628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 790b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLDashingLineEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 791b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 792b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashingLineEffect& de = processor.cast<DashingLineEffect>(); 79363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(de.getEdgeType()); 794628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 795628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 796628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 7973b9e8be760ad0e576d5145e0aecf0dc73efcd640skia.committer@gmail.com 798b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* DashingLineEffect::Create(GrPrimitiveEdgeType edgeType, 799b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const DashInfo& info, 800b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkScalar strokeWidth) { 801628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org if (info.fCount != 2) { 802628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return NULL; 803628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org } 804628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 80555fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(DashingLineEffect, (edgeType, info, strokeWidth)); 806628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 807628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 808628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgDashingLineEffect::~DashingLineEffect() {} 809628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 810628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.orgvoid DashingLineEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 811628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org *validFlags = 0; 812628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 813628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 814b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const { 815b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendGeometryProcessorFactory<DashingLineEffect>::getInstance(); 816628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 817628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 818b0a8a377f832c59cee939ad721e1f87d378b7142joshualittDashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, 819e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkScalar strokeWidth) 820249af15fb82833d2274850c589812b6e69df0033joshualitt : fEdgeType(edgeType) 821249af15fb82833d2274850c589812b6e69df0033joshualitt , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord", 822249af15fb82833d2274850c589812b6e69df0033joshualitt kVec2f_GrSLType, 823249af15fb82833d2274850c589812b6e69df0033joshualitt GrShaderVar::kAttribute_TypeModifier))) { 824628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar onLen = info.fIntervals[0]; 825628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar offLen = info.fIntervals[1]; 826628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar halfOffLen = SkScalarHalf(offLen); 827628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar halfStroke = SkScalarHalf(strokeWidth); 828628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fIntervalLength = onLen + offLen; 829628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); 830628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 831628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 832b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool DashingLineEffect::onIsEqual(const GrProcessor& other) const { 83349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const DashingLineEffect& de = other.cast<DashingLineEffect>(); 834628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org return (fEdgeType == de.fEdgeType && 835628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fRect == de.fRect && 836628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org fIntervalLength == de.fIntervalLength); 837628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 838628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 839b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); 840628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 841b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, 842b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 843b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 844b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 845b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan( 846b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kGrProcessorEdgeTypeCnt)); 847628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); 848628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org DashInfo info; 849628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fCount = 2; 850628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org SkAutoTArray<SkScalar> intervals(info.fCount); 851628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fIntervals = intervals.get(); 852628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fIntervals[0] = random->nextRangeScalar(0, 10.f); 853628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fIntervals[1] = random->nextRangeScalar(0, 10.f); 854628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]); 855628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 856b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return DashingLineEffect::Create(edgeType, info, strokeWidth); 857628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 858628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 859628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 860628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org 861b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDashingEffect::Create(GrPrimitiveEdgeType edgeType, 862b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkPathEffect::DashInfo& info, 863b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkScalar strokeWidth, 864b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrDashingEffect::DashCap cap) { 865f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel switch (cap) { 866f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel case GrDashingEffect::kRound_DashCap: 867f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(strokeWidth)); 868f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel case GrDashingEffect::kNonRound_DashCap: 869f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel return DashingLineEffect::Create(edgeType, info, strokeWidth); 870f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel default: 871f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel SkFAIL("Unexpected dashed cap."); 872f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel } 873f767e792b929df9a2d9f35f9c68adaa9251f4da3egdaniel return NULL; 874628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org} 875