| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDashingEffect.h" | 8 #include "GrDashingEffect.h" |
| 9 | 9 |
| 10 #include "../GrAARectRenderer.h" | 10 #include "../GrAARectRenderer.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "SkGr.h" | 22 #include "SkGr.h" |
| 23 #include "gl/GrGLGeometryProcessor.h" | 23 #include "gl/GrGLGeometryProcessor.h" |
| 24 #include "gl/GrGLProcessor.h" | 24 #include "gl/GrGLProcessor.h" |
| 25 #include "gl/GrGLSL.h" | 25 #include "gl/GrGLSL.h" |
| 26 #include "gl/builders/GrGLProgramBuilder.h" | 26 #include "gl/builders/GrGLProgramBuilder.h" |
| 27 | 27 |
| 28 /////////////////////////////////////////////////////////////////////////////// | 28 /////////////////////////////////////////////////////////////////////////////// |
| 29 | 29 |
| 30 // Returns whether or not the gpu can fast path the dash line effect. | 30 // Returns whether or not the gpu can fast path the dash line effect. |
| 31 static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI
nfo, | 31 static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI
nfo, |
| 32 const GrDrawTarget& target, const SkMatrix& viewM
atrix) { | 32 const GrDrawTarget& target, const GrDrawState& ds
, |
| 33 if (target.getDrawState().getRenderTarget()->isMultisampled()) { | 33 const SkMatrix& viewMatrix) { |
| 34 if (ds.getRenderTarget()->isMultisampled()) { |
| 34 return false; | 35 return false; |
| 35 } | 36 } |
| 36 | 37 |
| 37 // Pts must be either horizontal or vertical in src space | 38 // Pts must be either horizontal or vertical in src space |
| 38 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { | 39 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { |
| 39 return false; | 40 return false; |
| 40 } | 41 } |
| 41 | 42 |
| 42 // May be able to relax this to include skew. As of now cannot do perspectiv
e | 43 // May be able to relax this to include skew. As of now cannot do perspectiv
e |
| 43 // because of the non uniform scaling of bloating a rect | 44 // because of the non uniform scaling of bloating a rect |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 164 |
| 164 static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m
atrix, | 165 static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m
atrix, |
| 165 SkPoint* verts) { | 166 SkPoint* verts) { |
| 166 verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop); | 167 verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop); |
| 167 verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom); | 168 verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom); |
| 168 verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom); | 169 verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom); |
| 169 verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop); | 170 verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop); |
| 170 matrix.mapPoints(&verts[idx], 4); | 171 matrix.mapPoints(&verts[idx], 4); |
| 171 } | 172 } |
| 172 | 173 |
| 173 bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint, | 174 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
* drawState, |
| 174 const GrStrokeInfo& strokeInfo, GrGpu* gpu, | 175 const SkPoint pts[2], const GrPaint& paint, |
| 175 GrDrawTarget* target, const SkMatrix& vm) { | 176 const GrStrokeInfo& strokeInfo, const SkMatri
x& vm) { |
| 176 | 177 |
| 177 if (!can_fast_path_dash(pts, strokeInfo, *target, vm)) { | 178 if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, vm)) { |
| 178 return false; | 179 return false; |
| 179 } | 180 } |
| 180 | 181 |
| 181 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); | 182 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); |
| 182 | 183 |
| 183 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); | 184 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
| 184 | 185 |
| 185 SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); | 186 SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); |
| 186 | 187 |
| 187 // the phase should be normalized to be [0, sum of all intervals) | 188 // the phase should be normalized to be [0, sum of all intervals) |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 devIntervals[0] += strokeWidth; | 313 devIntervals[0] += strokeWidth; |
| 313 devIntervals[1] -= strokeWidth; | 314 devIntervals[1] -= strokeWidth; |
| 314 } | 315 } |
| 315 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; | 316 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; |
| 316 | 317 |
| 317 SkScalar bloatX = useAA ? 0.5f / parallelScale : 0.f; | 318 SkScalar bloatX = useAA ? 0.5f / parallelScale : 0.f; |
| 318 SkScalar bloatY = useAA ? 0.5f / perpScale : 0.f; | 319 SkScalar bloatY = useAA ? 0.5f / perpScale : 0.f; |
| 319 | 320 |
| 320 SkScalar devBloat = useAA ? 0.5f : 0.f; | 321 SkScalar devBloat = useAA ? 0.5f : 0.f; |
| 321 | 322 |
| 322 GrDrawState* drawState = target->drawState(); | |
| 323 if (devIntervals[1] <= 0.f && useAA) { | 323 if (devIntervals[1] <= 0.f && useAA) { |
| 324 // Case when we end up drawing a solid AA rect | 324 // Case when we end up drawing a solid AA rect |
| 325 // Reset the start rect to draw this single solid rect | 325 // Reset the start rect to draw this single solid rect |
| 326 // but it requires to upload a new intervals uniform so we can mimic | 326 // but it requires to upload a new intervals uniform so we can mimic |
| 327 // one giant dash | 327 // one giant dash |
| 328 ptsRot[0].fX -= hasStartRect ? startAdj : 0; | 328 ptsRot[0].fX -= hasStartRect ? startAdj : 0; |
| 329 ptsRot[1].fX += hasEndRect ? endAdj : 0; | 329 ptsRot[1].fX += hasEndRect ? endAdj : 0; |
| 330 startRect.set(ptsRot, 2); | 330 startRect.set(ptsRot, 2); |
| 331 startRect.outset(strokeAdj, halfSrcStroke); | 331 startRect.outset(strokeAdj, halfSrcStroke); |
| 332 hasStartRect = true; | 332 hasStartRect = true; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 drawState, | 365 drawState, |
| 366 GrDefaultGeoProcFactory::kPosition_GPType))->unref(); | 366 GrDefaultGeoProcFactory::kPosition_GPType))->unref(); |
| 367 } | 367 } |
| 368 | 368 |
| 369 int totalRectCnt = 0; | 369 int totalRectCnt = 0; |
| 370 | 370 |
| 371 totalRectCnt += !lineDone ? 1 : 0; | 371 totalRectCnt += !lineDone ? 1 : 0; |
| 372 totalRectCnt += hasStartRect ? 1 : 0; | 372 totalRectCnt += hasStartRect ? 1 : 0; |
| 373 totalRectCnt += hasEndRect ? 1 : 0; | 373 totalRectCnt += hasEndRect ? 1 : 0; |
| 374 | 374 |
| 375 GrDrawTarget::AutoReleaseGeometry geo(target, totalRectCnt * 4, 0); | 375 GrDrawTarget::AutoReleaseGeometry geo(target, |
| 376 totalRectCnt * 4, |
| 377 drawState->getVertexStride(), 0); |
| 376 if (!geo.succeeded()) { | 378 if (!geo.succeeded()) { |
| 377 SkDebugf("Failed to get space for vertices!\n"); | 379 SkDebugf("Failed to get space for vertices!\n"); |
| 378 return false; | 380 return false; |
| 379 } | 381 } |
| 380 | 382 |
| 381 int curVIdx = 0; | 383 int curVIdx = 0; |
| 382 | 384 |
| 383 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { | 385 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { |
| 384 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices | 386 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices |
| 385 startOffset -= halfDevStroke; | 387 startOffset -= halfDevStroke; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffs
et, devBloat, | 433 setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffs
et, devBloat, |
| 432 devIntervals[0], halfDevStroke); | 434 devIntervals[0], halfDevStroke); |
| 433 } else { | 435 } else { |
| 434 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); | 436 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); |
| 435 setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts); | 437 setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts); |
| 436 } | 438 } |
| 437 | 439 |
| 438 } | 440 } |
| 439 | 441 |
| 440 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); | 442 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); |
| 441 target->drawIndexedInstances(kTriangles_GrPrimitiveType, totalRectCnt, 4, 6)
; | 443 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, totalRec
tCnt, 4, 6); |
| 442 target->resetIndexSource(); | 444 target->resetIndexSource(); |
| 443 return true; | 445 return true; |
| 444 } | 446 } |
| 445 | 447 |
| 446 ////////////////////////////////////////////////////////////////////////////// | 448 ////////////////////////////////////////////////////////////////////////////// |
| 447 | 449 |
| 448 class GLDashingCircleEffect; | 450 class GLDashingCircleEffect; |
| 449 /* | 451 /* |
| 450 * This effect will draw a dotted line (defined as a dashed lined with round cap
s and no on | 452 * This effect will draw a dotted line (defined as a dashed lined with round cap
s and no on |
| 451 * interval). The radius of the dots is given by the strokeWidth and the spacing
by the DashInfo. | 453 * interval). The radius of the dots is given by the strokeWidth and the spacing
by the DashInfo. |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 switch (cap) { | 874 switch (cap) { |
| 873 case GrDashingEffect::kRound_DashCap: | 875 case GrDashingEffect::kRound_DashCap: |
| 874 return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(stro
keWidth)); | 876 return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(stro
keWidth)); |
| 875 case GrDashingEffect::kNonRound_DashCap: | 877 case GrDashingEffect::kNonRound_DashCap: |
| 876 return DashingLineEffect::Create(edgeType, info, strokeWidth); | 878 return DashingLineEffect::Create(edgeType, info, strokeWidth); |
| 877 default: | 879 default: |
| 878 SkFAIL("Unexpected dashed cap."); | 880 SkFAIL("Unexpected dashed cap."); |
| 879 } | 881 } |
| 880 return NULL; | 882 return NULL; |
| 881 } | 883 } |
| OLD | NEW |