本文整理汇总了C++中SkTLazy类的典型用法代码示例。如果您正苦于以下问题:C++ SkTLazy类的具体用法?C++ SkTLazy怎么用?C++ SkTLazy使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SkTLazy类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: INHERITED
GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStrokeInfo& origStroke)
: INHERITED(gpu, origSkPath, origStroke),
fPathID(gpu->glPathRendering()->genPaths(1)) {
// Convert a dashing to either a stroke or a fill.
const SkPath* skPath = &origSkPath;
SkTLazy<SkPath> tmpPath;
const GrStrokeInfo* stroke = &origStroke;
GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle);
if (stroke->isDashed()) {
if (stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) {
skPath = tmpPath.get();
stroke = &tmpStroke;
}
}
InitPathObject(gpu, fPathID, *skPath, *stroke);
fShouldStroke = stroke->needToApply();
fShouldFill = stroke->isFillStyle() ||
stroke->getStyle() == SkStrokeRec::kStrokeAndFill_Style;
if (fShouldStroke) {
// FIXME: try to account for stroking, without rasterizing the stroke.
fBounds.outset(stroke->getWidth(), stroke->getWidth());
}
this->registerWithCache();
}
示例2: drawPathWithMaskFilter
void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
GrDrawContext* drawContext,
const GrClip& clip,
const SkPath& origPath,
GrPaint* paint,
const SkMatrix& viewMatrix,
const SkMaskFilter* mf,
const SkPathEffect* pathEffect,
const GrStrokeInfo& origStrokeInfo,
bool pathIsMutable) {
SkPath* pathPtr = const_cast<SkPath*>(&origPath);
SkTLazy<SkPath> tmpPath;
GrStrokeInfo strokeInfo(origStrokeInfo);
if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(tmpPath.init(), *pathPtr,
&strokeInfo, nullptr)) {
pathPtr = tmpPath.get();
pathPtr->setIsVolatile(true);
pathIsMutable = true;
pathEffect = nullptr;
}
draw_path_with_mask_filter(context, drawContext, clip, paint, viewMatrix, mf, pathEffect,
strokeInfo, pathPtr, pathIsMutable);
}
示例3: SkASSERT
void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
GrDrawContext* drawContext,
const GrClip& clip,
const SkPath& origPath,
const SkPaint& paint,
const SkMatrix& origViewMatrix,
const SkMatrix* prePathMatrix,
const SkIRect& clipBounds,
bool pathIsMutable) {
SkASSERT(!pathIsMutable || origPath.isVolatile());
GrStyle style(paint);
// If we have a prematrix, apply it to the path, optimizing for the case
// where the original path can in fact be modified in place (even though
// its parameter type is const).
const SkPath* path = &origPath;
SkTLazy<SkPath> tmpPath;
SkMatrix viewMatrix = origViewMatrix;
if (prePathMatrix) {
// Styling, blurs, and shading are supposed to be applied *after* the prePathMatrix.
if (!paint.getMaskFilter() && !paint.getShader() && !style.applies()) {
viewMatrix.preConcat(*prePathMatrix);
} else {
SkPath* result = pathIsMutable ? const_cast<SkPath*>(path) : tmpPath.init();
pathIsMutable = true;
path->transform(*prePathMatrix, result);
path = result;
result->setIsVolatile(true);
}
}
// at this point we're done with prePathMatrix
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
示例4: saveLayerAlpha
int SkiaCanvas::saveLayerAlpha(float left, float top, float right, float bottom,
int alpha, SaveFlags::Flags flags) {
SkTLazy<SkPaint> alphaPaint;
if (static_cast<unsigned>(alpha) < 0xFF) {
alphaPaint.init()->setAlpha(alpha);
}
return this->saveLayer(left, top, right, bottom, alphaPaint.getMaybeNull(),
flags);
}
示例5: drawBitmapRect
bool SkMiniRecorder::drawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
const SkPaint* p, SkCanvas::SrcRectConstraint constraint) {
SkRect bounds;
if (!src) {
bm.getBounds(&bounds);
src = &bounds;
}
SkTLazy<SkPaint> defaultPaint;
if (!p) {
p = defaultPaint.init();
}
TRY_TO_STORE(DrawBitmapRectFixedSize, *p, bm, *src, dst, constraint);
}
示例6: SkASSERT
void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
GrDrawContext* drawContext,
const GrClip& clip,
const SkPath& origSrcPath,
const SkPaint& paint,
const SkMatrix& origViewMatrix,
const SkMatrix* prePathMatrix,
const SkIRect& clipBounds,
bool pathIsMutable) {
SkASSERT(!pathIsMutable || origSrcPath.isVolatile());
GrStrokeInfo strokeInfo(paint);
// comment out the line below to determine if it is the reason that the chrome mac perf bot
// has begun crashing
// strokeInfo.setResScale(SkDraw::ComputeResScaleForStroking(origViewMatrix));
// If we have a prematrix, apply it to the path, optimizing for the case
// where the original path can in fact be modified in place (even though
// its parameter type is const).
SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
SkTLazy<SkPath> tmpPath;
SkTLazy<SkPath> effectPath;
SkPathEffect* pathEffect = paint.getPathEffect();
SkMatrix viewMatrix = origViewMatrix;
if (prePathMatrix) {
// stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix.
// The pre-path-matrix also should not affect shading.
if (!paint.getMaskFilter() && !pathEffect && !paint.getShader() &&
(strokeInfo.isFillStyle() || strokeInfo.isHairlineStyle())) {
viewMatrix.preConcat(*prePathMatrix);
} else {
SkPath* result = pathPtr;
if (!pathIsMutable) {
result = tmpPath.init();
result->setIsVolatile(true);
pathIsMutable = true;
}
// should I push prePathMatrix on our MV stack temporarily, instead
// of applying it here? See SkDraw.cpp
pathPtr->transform(*prePathMatrix, result);
pathPtr = result;
}
}
// at this point we're done with prePathMatrix
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
示例7: INHERITED
GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStrokeInfo& origStroke)
: INHERITED(gpu, origSkPath, origStroke),
fPathID(gpu->glPathRendering()->genPaths(1)) {
if (origSkPath.isEmpty()) {
InitPathObjectEmptyPath(gpu, fPathID);
fShouldStroke = false;
fShouldFill = false;
} else {
const SkPath* skPath = &origSkPath;
SkTLazy<SkPath> tmpPath;
const GrStrokeInfo* stroke = &origStroke;
GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle);
if (stroke->isDashed()) {
// Skia stroking and NVPR stroking differ with respect to dashing
// pattern.
// Convert a dashing to either a stroke or a fill.
if (stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) {
skPath = tmpPath.get();
stroke = &tmpStroke;
}
}
bool didInit = false;
if (stroke->needToApply() && stroke->getCap() != SkPaint::kButt_Cap) {
// Skia stroking and NVPR stroking differ with respect to stroking
// end caps of empty subpaths.
// Convert stroke to fill if path contains empty subpaths.
didInit = InitPathObjectPathDataCheckingDegenerates(gpu, fPathID, *skPath);
if (!didInit) {
if (!tmpPath.isValid()) {
tmpPath.init();
}
SkAssertResult(stroke->applyToPath(tmpPath.get(), *skPath));
skPath = tmpPath.get();
tmpStroke.setFillStyle();
stroke = &tmpStroke;
}
}
if (!didInit) {
InitPathObjectPathData(gpu, fPathID, *skPath);
}
fShouldStroke = stroke->needToApply();
fShouldFill = stroke->isFillStyle() ||
stroke->getStyle() == SkStrokeRec::kStrokeAndFill_Style;
if (fShouldStroke) {
InitPathObjectStroke(gpu, fPathID, *stroke);
// FIXME: try to account for stroking, without rasterizing the stroke.
fBounds.outset(stroke->getWidth(), stroke->getWidth());
}
}
this->registerWithCache();
}
示例8: SkDEBUGCODE
void GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const {
GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu());
if (NULL == gpu) {
return;
}
// Make sure the path at this index hasn't been initted already.
SkDEBUGCODE(
GrGLboolean isPath;
GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index)));
SkASSERT(GR_GL_FALSE == isPath);
const SkPath* skPath = &origSkPath;
SkTLazy<SkPath> tmpPath;
const GrStrokeInfo* stroke = &fStroke;
GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle);
// Dashing must be applied to the path. However, if dashing is present,
// we must convert all the paths to fills. The GrStrokeInfo::applyDash leaves
// simple paths as strokes but converts other paths to fills.
// Thus we must stroke the strokes here, so that all paths in the
// path range are using the same style.
if (fStroke.isDashed()) {
if (!stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) {
return;
}
skPath = tmpPath.get();
stroke = &tmpStroke;
if (tmpStroke.needToApply()) {
if (!tmpStroke.applyToPath(tmpPath.get(), *tmpPath.get())) {
return;
}
tmpStroke.setFillStyle();
}
}
GrGLPath::InitPathObject(gpu, fBasePathID + index, *skPath, *stroke);
// TODO: Use a better approximation for the individual path sizes.
fGpuMemorySize += 100;
}
示例9: set_vertex_attributes
void GrDrawTarget::onDrawRect(const SkRect& rect,
const SkMatrix* matrix,
const SkRect* localRect,
const SkMatrix* localMatrix) {
GrDrawState::AutoViewMatrixRestore avmr;
if (NULL != matrix) {
avmr.set(this->drawState(), *matrix);
}
set_vertex_attributes(this->drawState(), NULL != localRect);
AutoReleaseGeometry geo(this, 4, 0);
if (!geo.succeeded()) {
GrPrintf("Failed to get space for vertices!\n");
return;
}
size_t vsize = this->drawState()->getVertexSize();
geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
if (NULL != localRect) {
GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
sizeof(GrPoint));
coords->setRectFan(localRect->fLeft, localRect->fTop,
localRect->fRight, localRect->fBottom,
vsize);
if (NULL != localMatrix) {
localMatrix->mapPointsWithStride(coords, vsize, 4);
}
}
SkTLazy<SkRect> bounds;
if (this->getDrawState().willEffectReadDstColor()) {
bounds.init();
this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect);
}
this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, bounds.getMaybeNull());
}
示例10: GetContext
GrContext* GpuTest::GetContext() {
#if SK_SUPPORT_GPU
// preserve this order, we want gGrContext destroyed after gEGLContext
static SkTLazy<SkNativeGLContext> gGLContext;
static SkAutoTUnref<GrContext> gGrContext;
if (NULL == gGrContext.get()) {
gGLContext.init();
if (gGLContext.get()->init(800, 600)) {
GrPlatform3DContext ctx = reinterpret_cast<GrPlatform3DContext>(gGLContext.get()->gl());
gGrContext.reset(GrContext::Create(kOpenGL_Shaders_GrEngine, ctx));
}
}
if (gGLContext.get()) {
gGLContext.get()->makeCurrent();
}
return gGrContext.get();
#else
return NULL;
#endif
}
示例11: onPrepareDraws
void onPrepareDraws(Target* target) const override {
#ifndef SK_IGNORE_LINEONLY_AA_CONVEX_PATH_OPTS
if (this->linesOnly()) {
this->prepareLinesOnlyDraws(target);
return;
}
#endif
int instanceCount = fGeoData.count();
SkMatrix invert;
if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
SkDebugf("Could not invert viewmatrix\n");
return;
}
// Setup GrGeometryProcessor
sk_sp<GrGeometryProcessor> quadProcessor(
QuadEdgeEffect::Make(this->color(), invert, this->usesLocalCoords()));
// TODO generate all segments for all paths and use one vertex buffer
for (int i = 0; i < instanceCount; i++) {
const Geometry& args = fGeoData[i];
// We use the fact that SkPath::transform path does subdivision based on
// perspective. Otherwise, we apply the view matrix when copying to the
// segment representation.
const SkMatrix* viewMatrix = &args.fViewMatrix;
// We avoid initializing the path unless we have to
const SkPath* pathPtr = &args.fPath;
SkTLazy<SkPath> tmpPath;
if (viewMatrix->hasPerspective()) {
SkPath* tmpPathPtr = tmpPath.init(*pathPtr);
tmpPathPtr->setIsVolatile(true);
tmpPathPtr->transform(*viewMatrix);
viewMatrix = &SkMatrix::I();
pathPtr = tmpPathPtr;
}
int vertexCount;
int indexCount;
enum {
kPreallocSegmentCnt = 512 / sizeof(Segment),
kPreallocDrawCnt = 4,
};
SkSTArray<kPreallocSegmentCnt, Segment, true> segments;
SkPoint fanPt;
if (!get_segments(*pathPtr, *viewMatrix, &segments, &fanPt, &vertexCount,
&indexCount)) {
continue;
}
const GrBuffer* vertexBuffer;
int firstVertex;
size_t vertexStride = quadProcessor->getVertexStride();
QuadVertex* verts = reinterpret_cast<QuadVertex*>(target->makeVertexSpace(
vertexStride, vertexCount, &vertexBuffer, &firstVertex));
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
const GrBuffer* indexBuffer;
int firstIndex;
uint16_t *idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
if (!idxs) {
SkDebugf("Could not allocate indices\n");
return;
}
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
create_vertices(segments, fanPt, &draws, verts, idxs);
GrMesh mesh;
for (int j = 0; j < draws.count(); ++j) {
const Draw& draw = draws[j];
mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer,
firstVertex, firstIndex, draw.fVertexCnt, draw.fIndexCnt);
target->draw(quadProcessor.get(), mesh);
firstVertex += draw.fVertexCnt;
firstIndex += draw.fIndexCnt;
}
}
}
示例12: DEF_TEST
DEF_TEST(CanvasState_test_complex_layers, reporter) {
const int WIDTH = 400;
const int HEIGHT = 400;
const int SPACER = 10;
SkRect rect = SkRect::MakeXYWH(SkIntToScalar(SPACER), SkIntToScalar(SPACER),
SkIntToScalar(WIDTH-(2*SPACER)),
SkIntToScalar((HEIGHT-(2*SPACER)) / 7));
const SkColorType colorTypes[] = {
kRGB_565_SkColorType, kN32_SkColorType
};
const int layerAlpha[] = { 255, 255, 0 };
const SkCanvas::SaveLayerFlags flags[] = {
static_cast<SkCanvas::SaveLayerFlags>(SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag),
0,
static_cast<SkCanvas::SaveLayerFlags>(SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag),
};
REPORTER_ASSERT(reporter, sizeof(layerAlpha) == sizeof(flags));
bool (*drawFn)(SkCanvasState* state, float l, float t,
float r, float b, int32_t s);
OpenLibResult openLibResult(reporter);
if (openLibResult.handle() != nullptr) {
*(void**) (&drawFn) = dlsym(openLibResult.handle(),
"complex_layers_draw_from_canvas_state");
} else {
drawFn = complex_layers_draw_from_canvas_state;
}
REPORTER_ASSERT(reporter, drawFn);
if (!drawFn) {
return;
}
for (size_t i = 0; i < SK_ARRAY_COUNT(colorTypes); ++i) {
SkBitmap bitmaps[2];
for (int j = 0; j < 2; ++j) {
bitmaps[j].allocPixels(SkImageInfo::Make(WIDTH, HEIGHT,
colorTypes[i],
kPremul_SkAlphaType));
SkCanvas canvas(bitmaps[j]);
canvas.drawColor(SK_ColorRED);
for (size_t k = 0; k < SK_ARRAY_COUNT(layerAlpha); ++k) {
SkTLazy<SkPaint> paint;
if (layerAlpha[k] != 0xFF) {
paint.init()->setAlpha(layerAlpha[k]);
}
// draw a rect within the layer's bounds and again outside the layer's bounds
canvas.saveLayer(SkCanvas::SaveLayerRec(&rect, paint.getMaybeNull(), flags[k]));
if (j) {
// Capture from the first Skia.
SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
REPORTER_ASSERT(reporter, state);
// And draw to it in the second Skia.
bool success = complex_layers_draw_from_canvas_state(state,
rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, SPACER);
REPORTER_ASSERT(reporter, success);
// And release it in the *first* Skia.
SkCanvasStateUtils::ReleaseCanvasState(state);
} else {
// Draw in the first Skia.
complex_layers_draw(&canvas, rect.fLeft, rect.fTop,
rect.fRight, rect.fBottom, SPACER);
}
canvas.restore();
// translate the canvas for the next iteration
canvas.translate(0, 2*(rect.height() + SPACER));
}
}
// now we memcmp the two bitmaps
REPORTER_ASSERT(reporter, bitmaps[0].getSize() == bitmaps[1].getSize());
REPORTER_ASSERT(reporter, !memcmp(bitmaps[0].getPixels(),
bitmaps[1].getPixels(),
bitmaps[0].getSize()));
}
}
示例13: onPrepareDraws
void onPrepareDraws(Target* target) const override {
int instanceCount = fGeoData.count();
SkMatrix invert;
if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
SkDebugf("Could not invert viewmatrix\n");
return;
}
// Setup GrGeometryProcessors
SkAutoTUnref<GrPLSGeometryProcessor> triangleProcessor(
PLSAATriangleEffect::Create(invert, this->usesLocalCoords()));
SkAutoTUnref<GrPLSGeometryProcessor> quadProcessor(
PLSQuadEdgeEffect::Create(invert, this->usesLocalCoords()));
GrResourceProvider* rp = target->resourceProvider();
for (int i = 0; i < instanceCount; ++i) {
const Geometry& args = fGeoData[i];
SkRect bounds = args.fPath.getBounds();
args.fViewMatrix.mapRect(&bounds);
bounds.fLeft = SkScalarFloorToScalar(bounds.fLeft);
bounds.fTop = SkScalarFloorToScalar(bounds.fTop);
bounds.fRight = SkScalarCeilToScalar(bounds.fRight);
bounds.fBottom = SkScalarCeilToScalar(bounds.fBottom);
triangleProcessor->setBounds(bounds);
quadProcessor->setBounds(bounds);
// We use the fact that SkPath::transform path does subdivision based on
// perspective. Otherwise, we apply the view matrix when copying to the
// segment representation.
const SkMatrix* viewMatrix = &args.fViewMatrix;
// We avoid initializing the path unless we have to
const SkPath* pathPtr = &args.fPath;
SkTLazy<SkPath> tmpPath;
if (viewMatrix->hasPerspective()) {
SkPath* tmpPathPtr = tmpPath.init(*pathPtr);
tmpPathPtr->setIsVolatile(true);
tmpPathPtr->transform(*viewMatrix);
viewMatrix = &SkMatrix::I();
pathPtr = tmpPathPtr;
}
GrVertices grVertices;
PLSVertices triVertices;
PLSVertices quadVertices;
if (!get_geometry(*pathPtr, *viewMatrix, triVertices, quadVertices, rp, bounds)) {
continue;
}
if (triVertices.count()) {
const GrVertexBuffer* triVertexBuffer;
int firstTriVertex;
size_t triStride = triangleProcessor->getVertexStride();
PLSVertex* triVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
triStride, triVertices.count(), &triVertexBuffer, &firstTriVertex));
if (!triVerts) {
SkDebugf("Could not allocate vertices\n");
return;
}
for (int i = 0; i < triVertices.count(); ++i) {
triVerts[i] = triVertices[i];
}
grVertices.init(kTriangles_GrPrimitiveType, triVertexBuffer, firstTriVertex,
triVertices.count());
target->initDraw(triangleProcessor, this->pipeline());
target->draw(grVertices);
}
if (quadVertices.count()) {
const GrVertexBuffer* quadVertexBuffer;
int firstQuadVertex;
size_t quadStride = quadProcessor->getVertexStride();
PLSVertex* quadVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
quadStride, quadVertices.count(), &quadVertexBuffer, &firstQuadVertex));
if (!quadVerts) {
SkDebugf("Could not allocate vertices\n");
return;
}
for (int i = 0; i < quadVertices.count(); ++i) {
quadVerts[i] = quadVertices[i];
}
grVertices.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex,
quadVertices.count());
target->initDraw(quadProcessor, this->pipeline());
target->draw(grVertices);
}
SkAutoTUnref<GrGeometryProcessor> finishProcessor(
PLSFinishEffect::Create(this->color(),
pathPtr->getFillType() ==
SkPath::FillType::kEvenOdd_FillType,
invert,
this->usesLocalCoords()));
const GrVertexBuffer* rectVertexBuffer;
size_t finishStride = finishProcessor->getVertexStride();
int firstRectVertex;
static const int kRectVertexCount = 6;
SkPoint* rectVerts = reinterpret_cast<SkPoint*>(target->makeVertexSpace(
//.........这里部分代码省略.........
示例14: SkTMin
void GrTextBlob::flush(GrTextTarget* target, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
const SkPaint& paint, GrColor filteredColor, const GrClip& clip,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
// GrTextBlob::makeOp only takes uint16_t values for run and subRun indices.
// Encountering something larger than this is highly unlikely, so we'll just not draw it.
int lastRun = SkTMin(fRunCount, (1 << 16)) - 1;
// For each run in the GrTextBlob we're going to churn through all the glyphs.
// Each run is broken into a path part and a Mask / DFT / ARGB part.
for (int runIndex = 0; runIndex <= lastRun; runIndex++) {
Run& run = fRuns[runIndex];
// first flush any path glyphs
if (run.fPathGlyphs.count()) {
SkPaint runPaint{paint};
runPaint.setFlags((runPaint.getFlags() & ~Run::kPaintFlagsMask) | run.fPaintFlags);
for (int i = 0; i < run.fPathGlyphs.count(); i++) {
GrTextBlob::Run::PathGlyph& pathGlyph = run.fPathGlyphs[i];
SkMatrix ctm;
const SkPath* path = &pathGlyph.fPath;
// TmpPath must be in the same scope as GrShape shape below.
SkTLazy<SkPath> tmpPath;
// The glyph positions and glyph outlines are either in device space or in source
// space based on fPreTransformed.
if (!pathGlyph.fPreTransformed) {
// Positions and outlines are in source space.
ctm = viewMatrix;
SkMatrix pathMatrix = SkMatrix::MakeScale(pathGlyph.fScale, pathGlyph.fScale);
// The origin for the blob may have changed, so figure out the delta.
SkVector originShift = SkPoint{x, y} - SkPoint{fInitialX, fInitialY};
// Shift the original glyph location in source space to the position of the new
// blob.
pathMatrix.postTranslate(originShift.x() + pathGlyph.fX,
originShift.y() + pathGlyph.fY);
// If there are shaders, blurs or styles, the path must be scaled into source
// space independently of the CTM. This allows the CTM to be correct for the
// different effects.
GrStyle style(runPaint);
bool scalePath = runPaint.getShader()
|| style.applies()
|| runPaint.getMaskFilter();
if (!scalePath) {
// Scale can be applied to CTM -- no effects.
ctm.preConcat(pathMatrix);
} else {
// Scale the outline into source space.
// Transform the path form the normalized outline to source space. This
// way the CTM will remain the same so it can be used by the effects.
SkPath* sourceOutline = tmpPath.init();
path->transform(pathMatrix, sourceOutline);
sourceOutline->setIsVolatile(true);
path = sourceOutline;
}
} else {
// Positions and outlines are in device space.
SkPoint originalOrigin = {fInitialX, fInitialY};
fInitialViewMatrix.mapPoints(&originalOrigin, 1);
SkPoint newOrigin = {x, y};
viewMatrix.mapPoints(&newOrigin, 1);
// The origin shift in device space.
SkPoint originShift = newOrigin - originalOrigin;
// Shift the original glyph location in device space to the position of the
// new blob.
ctm = SkMatrix::MakeTrans(originShift.x() + pathGlyph.fX,
originShift.y() + pathGlyph.fY);
}
// TODO: we are losing the mutability of the path here
GrShape shape(*path, paint);
target->drawShape(clip, runPaint, ctm, shape);
}
}
// then flush each subrun, if any
if (!run.fInitialized) {
continue;
}
int lastSubRun = SkTMin(run.fSubRunInfo.count(), 1 << 16) - 1;
for (int subRun = 0; subRun <= lastSubRun; subRun++) {
//.........这里部分代码省略.........
示例15: draw_path_with_mask_filter
static void draw_path_with_mask_filter(GrContext* context,
GrDrawContext* drawContext,
const GrClip& clip,
GrPaint* paint,
const SkMatrix& viewMatrix,
const SkMaskFilter* maskFilter,
const GrStyle& style,
const SkPath* path,
bool pathIsMutable) {
SkASSERT(maskFilter);
SkIRect clipBounds;
clip.getConservativeBounds(drawContext->width(), drawContext->height(), &clipBounds);
SkTLazy<SkPath> tmpPath;
SkStrokeRec::InitStyle fillOrHairline;
// We just fully apply the style here.
if (style.applies()) {
if (!style.applyToPath(tmpPath.init(), &fillOrHairline, *path,
GrStyle::MatrixToScaleFactor(viewMatrix))) {
return;
}
pathIsMutable = true;
path = tmpPath.get();
} else if (style.isSimpleHairline()) {
fillOrHairline = SkStrokeRec::kHairline_InitStyle;
} else {
SkASSERT(style.isSimpleFill());
fillOrHairline = SkStrokeRec::kFill_InitStyle;
}
// transform the path into device space
if (!viewMatrix.isIdentity()) {
SkPath* result;
if (pathIsMutable) {
result = const_cast<SkPath*>(path);
} else {
if (!tmpPath.isValid()) {
tmpPath.init();
}
result = tmpPath.get();
}
path->transform(viewMatrix, result);
path = result;
result->setIsVolatile(true);
pathIsMutable = true;
}
SkRect maskRect;
if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()),
clipBounds,
viewMatrix,
&maskRect)) {
// This mask will ultimately be drawn as a non-AA rect (see draw_mask).
// Non-AA rects have a bad habit of snapping arbitrarily. Integerize here
// so the mask draws in a reproducible manner.
SkIRect finalIRect;
maskRect.roundOut(&finalIRect);
if (clip_bounds_quick_reject(clipBounds, finalIRect)) {
// clipped out
return;
}
if (maskFilter->directFilterMaskGPU(context->textureProvider(),
drawContext,
paint,
clip,
viewMatrix,
SkStrokeRec(fillOrHairline),
*path)) {
// the mask filter was able to draw itself directly, so there's nothing
// left to do.
return;
}
sk_sp<GrTexture> mask(create_mask_GPU(context,
finalIRect,
*path,
fillOrHairline,
paint->isAntiAlias(),
drawContext->numColorSamples()));
if (mask) {
GrTexture* filtered;
if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, finalIRect, &filtered, true)) {
// filterMaskGPU gives us ownership of a ref to the result
SkAutoTUnref<GrTexture> atu(filtered);
if (draw_mask(drawContext, clip, viewMatrix, finalIRect, paint, filtered)) {
// This path is completely drawn
return;
}
}
}
}
sw_draw_with_mask_filter(drawContext, context->textureProvider(),
clip, viewMatrix, *path,
maskFilter, clipBounds, paint, fillOrHairline);
}