11fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon/* 21fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon * Copyright 2015 Google Inc. 31fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon * 41fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon * Use of this source code is governed by a BSD-style license that can be 51fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon * found in the LICENSE file. 61fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon */ 71fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 882c263f6e4452227334c349430f85ea662962a2bBrian Salomon#include "GrDrawPathOp.h" 954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon#include "GrAppliedClip.h" 1054d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon#include "GrRenderTargetContext.h" 11193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton#include "GrRenderTargetPriv.h" 1254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon#include "SkTemplates.h" 13193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton 1454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian SalomonGrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint, 1548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon GrPathRendering::FillType fill, GrAAType aaType) 1654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon : INHERITED(classID) 1754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon , fViewMatrix(viewMatrix) 1848d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon , fInputColor(paint.getColor()) 1954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon , fFillType(fill) 20611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon , fAAType(aaType) 21611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon , fPipelineSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint)) 22611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon , fProcessorSet(std::move(paint)) {} 23193d9cf8f2280cd4f8e509c6f3af6b47cea04935cdalton 2482c263f6e4452227334c349430f85ea662962a2bBrian SalomonSkString GrDrawPathOp::dumpInfo() const { 251fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon SkString string; 261dc172165b8186950fda4a269bd1b12c11947b14stephana string.printf("PATH: 0x%p", fPath.get()); 2744fbc79e069c28103a44387d11c62e049ef2967drobertphillips string.append(INHERITED::dumpInfo()); 281fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon return string; 291fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon} 301fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 31e7d30484ea8a5677a9403ccd23a9c0961df62ccdBrian Salomonvoid GrDrawPathOpBase::initPipeline(const GrOpFlushState& state, GrPipeline* pipeline) { 3254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon static constexpr GrUserStencilSettings kCoverPass{ 3354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrUserStencilSettings::StaticInit< 3454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 0x0000, 3554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrUserStencilTest::kNotEqual, 3654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 0xffff, 3754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrUserStencilOp::kZero, 3854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrUserStencilOp::kKeep, 3954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 0xffff>() 4054d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon }; 4154d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrPipeline::InitArgs args; 4254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon args.fProcessors = &this->processors(); 43611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon args.fFlags = fPipelineSRGBFlags; 44611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon if (GrAATypeIsHW(fAAType)) { 45611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon args.fFlags |= GrPipeline::kHWAntialias_Flag; 46611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon } 4754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon args.fUserStencil = &kCoverPass; 4854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon args.fAppliedClip = state.drawOpArgs().fAppliedClip; 4954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon args.fRenderTarget = state.drawOpArgs().fRenderTarget; 5054d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon args.fCaps = &state.caps(); 519bee2e5894bb8dd374392f238bc429e16f239583Robert Phillips args.fResourceProvider = state.resourceProvider(); 52bb581ce30f55360fd3a12e7f5aa1fe324b16d085Robert Phillips args.fDstProxy = state.drawOpArgs().fDstProxy; 5354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 5454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon return pipeline->init(args); 5554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon} 561fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 5754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon////////////////////////////////////////////////////////////////////////////// 5854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 5954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomonvoid init_stencil_pass_settings(const GrOpFlushState& flushState, 6054d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrPathRendering::FillType fillType, GrStencilSettings* stencil) { 6154d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon const GrAppliedClip* appliedClip = flushState.drawOpArgs().fAppliedClip; 6254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon bool stencilClip = appliedClip && appliedClip->hasStencilClip(); 6354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon stencil->reset(GrPathRendering::GetStencilPassSettings(fillType), stencilClip, 6454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon flushState.drawOpArgs().fRenderTarget->renderTargetPriv().numStencilBits()); 6554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon} 6654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 6754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon////////////////////////////////////////////////////////////////////////////// 6854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 6954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomonvoid GrDrawPathOp::onExecute(GrOpFlushState* state) { 7054d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrPipeline pipeline; 71e7d30484ea8a5677a9403ccd23a9c0961df62ccdBrian Salomon this->initPipeline(*state, &pipeline); 72e7d30484ea8a5677a9403ccd23a9c0961df62ccdBrian Salomon sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix())); 7354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 7454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrStencilSettings stencil; 7554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon init_stencil_pass_settings(*state, this->fillType(), &stencil); 7654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon state->gpu()->pathRendering()->drawPath(pipeline, *pathProc, stencil, fPath.get()); 77c48af934608bbb65650641f66adb51f2102d4274Brian Salomon} 782bf4b3a97b770811d9e0558dbbfbdb57cfafbdb7Brian Salomon 7954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon////////////////////////////////////////////////////////////////////////////// 8054d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 8182c263f6e4452227334c349430f85ea662962a2bBrian SalomonSkString GrDrawPathRangeOp::dumpInfo() const { 821fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon SkString string; 83cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton string.printf("RANGE: 0x%p COUNTS: [", fPathRange.get()); 841fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { 85cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton string.appendf("%d, ", iter.get()->fInstanceData->count()); 861fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 871fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon string.remove(string.size() - 2, 2); 881fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon string.append("]"); 8944fbc79e069c28103a44387d11c62e049ef2967drobertphillips string.append(INHERITED::dumpInfo()); 901fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon return string; 911fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon} 921fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 9382c263f6e4452227334c349430f85ea662962a2bBrian SalomonGrDrawPathRangeOp::GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, 9454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon SkScalar y, GrPaint&& paint, GrPathRendering::FillType fill, 9548d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon GrAAType aaType, GrPathRange* range, 9648d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon const InstanceData* instanceData, const SkRect& bounds) 9748d1b4c2b2c0f41a10376ed657cde043d8f11979Brian Salomon : INHERITED(ClassID(), viewMatrix, std::move(paint), fill, aaType) 9882c263f6e4452227334c349430f85ea662962a2bBrian Salomon , fPathRange(range) 9982c263f6e4452227334c349430f85ea662962a2bBrian Salomon , fTotalPathCount(instanceData->count()) 10082c263f6e4452227334c349430f85ea662962a2bBrian Salomon , fScale(scale) { 101cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton fDraws.addToHead()->set(instanceData, x, y); 10288cf17d099085b8085ab11571b5094163dbb2c84bsalomon this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); 1031fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon} 1041fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 10554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomonstatic void pre_translate_transform_values(const float* xforms, 10654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrPathRendering::PathTransformType type, int count, 10754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon SkScalar x, SkScalar y, float* dst); 10854d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 10982c263f6e4452227334c349430f85ea662962a2bBrian Salomonbool GrDrawPathRangeOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { 11082c263f6e4452227334c349430f85ea662962a2bBrian Salomon GrDrawPathRangeOp* that = t->cast<GrDrawPathRangeOp>(); 111cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton if (this->fPathRange.get() != that->fPathRange.get() || 11282c263f6e4452227334c349430f85ea662962a2bBrian Salomon this->transformType() != that->transformType() || this->fScale != that->fScale || 11382c263f6e4452227334c349430f85ea662962a2bBrian Salomon this->color() != that->color() || !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 1141fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon return false; 1151fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 11654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon if (this->processors() != that->processors()) { 1171fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon return false; 1181fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 119611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon if (this->pipelineSRGBFlags() != that->pipelineSRGBFlags()) { 120611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon return false; 121611572ce3ef9b477e15471c3f5bacb66260e4913Brian Salomon } 122cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton switch (fDraws.head()->fInstanceData->transformType()) { 123cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kNone_PathTransformType: 124cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton if (this->fDraws.head()->fX != that->fDraws.head()->fX || 125cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton this->fDraws.head()->fY != that->fDraws.head()->fY) { 126cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton return false; 127cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 128cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 129cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kTranslateX_PathTransformType: 130cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton if (this->fDraws.head()->fY != that->fDraws.head()->fY) { 131cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton return false; 132cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 133cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 134cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kTranslateY_PathTransformType: 135cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton if (this->fDraws.head()->fX != that->fDraws.head()->fX) { 136cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton return false; 137cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 138cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 13982c263f6e4452227334c349430f85ea662962a2bBrian Salomon default: 14082c263f6e4452227334c349430f85ea662962a2bBrian Salomon break; 1411fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 1421fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // TODO: Check some other things here. (winding, opaque, pathProc color, vm, ...) 1431fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // Try to combine this call with the previous DrawPaths. We do this by stenciling all the 1441fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // paths together and then covering them in a single pass. This is not equivalent to two 1451fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // separate draw calls, so we can only do it if there is no blending (no overlap would also 1461fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // work). Note that it's also possible for overlapping paths to cancel each other's winding 1471fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // numbers, and we only partially account for this by not allowing even/odd paths to be 1481fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon // combined. (Glyphs in the same font tend to wind the same direction so it works out OK.) 14954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon 1508ff8d24c83353fc421177886d82202da9ff89234cdalton if (GrPathRendering::kWinding_FillType != this->fillType() || 15154d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrPathRendering::kWinding_FillType != that->fillType()) { 15254d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon return false; 15354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon } 154a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon if (!this->processorAnalysis().canCombineOverlappedStencilAndCover()) { 1551fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon return false; 1561fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 1571fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon fTotalPathCount += that->fTotalPathCount; 158cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton while (Draw* head = that->fDraws.head()) { 159cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton Draw* draw = fDraws.addToTail(); 16018300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein draw->fInstanceData.reset(head->fInstanceData.release()); 161cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton draw->fX = head->fX; 162cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton draw->fY = head->fY; 1631fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon that->fDraws.popHead(); 1641fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 16588cf17d099085b8085ab11571b5094163dbb2c84bsalomon this->joinBounds(*that); 1661fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon return true; 1671fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon} 1681fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 1699e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomonvoid GrDrawPathRangeOp::onExecute(GrOpFlushState* state) { 170cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton const Draw& head = *fDraws.head(); 171cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton 172cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkMatrix drawMatrix(this->viewMatrix()); 173cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton drawMatrix.preScale(fScale, fScale); 174cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton drawMatrix.preTranslate(head.fX, head.fY); 175cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton 176cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkMatrix localMatrix; 177cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton localMatrix.setScale(fScale, fScale); 178cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton localMatrix.preTranslate(head.fX, head.fY); 179cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton 18082c263f6e4452227334c349430f85ea662962a2bBrian Salomon sk_sp<GrPathProcessor> pathProc( 181ecea86af4170a52cda5c64dd187ddbe157a682eeBrian Salomon GrPathProcessor::Create(this->color(), drawMatrix, localMatrix)); 182cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton 18354d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrPipeline pipeline; 18454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon this->initPipeline(*state, &pipeline); 18554d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon GrStencilSettings stencil; 18654d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon init_stencil_pass_settings(*state, this->fillType(), &stencil); 1871fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon if (fDraws.count() == 1) { 188cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton const InstanceData& instances = *head.fInstanceData; 18954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon state->gpu()->pathRendering()->drawPaths(pipeline, 1900e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel *pathProc, 19154d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon stencil, 1920e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fPathRange.get(), 1930e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel instances.indices(), 194cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton GrPathRange::kU16_PathIndexType, 195cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton instances.transformValues(), 196cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton instances.transformType(), 197cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton instances.count()); 198cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } else { 199cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton int floatsPerTransform = GrPathRendering::PathTransformSize(this->transformType()); 200cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkAutoSTMalloc<4096, float> transformStorage(floatsPerTransform * fTotalPathCount); 201cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkAutoSTMalloc<2048, uint16_t> indexStorage(fTotalPathCount); 202cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton int idx = 0; 203cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { 204cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton const Draw& draw = *iter.get(); 205cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton const InstanceData& instances = *draw.fInstanceData; 206cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton memcpy(&indexStorage[idx], instances.indices(), instances.count() * sizeof(uint16_t)); 207cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton pre_translate_transform_values(instances.transformValues(), this->transformType(), 20882c263f6e4452227334c349430f85ea662962a2bBrian Salomon instances.count(), draw.fX - head.fX, draw.fY - head.fY, 209cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton &transformStorage[floatsPerTransform * idx]); 210cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton idx += instances.count(); 211cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton 212cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton // TODO: Support mismatched transform types if we start using more types other than 2D. 213cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkASSERT(instances.transformType() == this->transformType()); 214cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 215cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkASSERT(idx == fTotalPathCount); 216cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton 21754d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon state->gpu()->pathRendering()->drawPaths(pipeline, 2180e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel *pathProc, 21954d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon stencil, 2200e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fPathRange.get(), 2210e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel indexStorage, 2220e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrPathRange::kU16_PathIndexType, 2230e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel transformStorage, 2240e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel this->transformType(), 2250e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fTotalPathCount); 2261fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 227cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton} 2281fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon 229cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdaltoninline void pre_translate_transform_values(const float* xforms, 230cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton GrPathRendering::PathTransformType type, int count, 231cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkScalar x, SkScalar y, float* dst) { 232cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton if (0 == x && 0 == y) { 233cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton memcpy(dst, xforms, count * GrPathRendering::PathTransformSize(type) * sizeof(float)); 234cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton return; 235cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 236cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton switch (type) { 237cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kNone_PathTransformType: 238cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkFAIL("Cannot pre-translate kNone_PathTransformType."); 239cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 240cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kTranslateX_PathTransformType: 241cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkASSERT(0 == y); 242cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton for (int i = 0; i < count; i++) { 243cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i] = xforms[i] + x; 244cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 245cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 246cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kTranslateY_PathTransformType: 247cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkASSERT(0 == x); 248cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton for (int i = 0; i < count; i++) { 249cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i] = xforms[i] + y; 250cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 251cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 252cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kTranslate_PathTransformType: 253cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton for (int i = 0; i < 2 * count; i += 2) { 254cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i] = xforms[i] + x; 255cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i + 1] = xforms[i + 1] + y; 256cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 257cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 258cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton case GrPathRendering::kAffine_PathTransformType: 259cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton for (int i = 0; i < 6 * count; i += 6) { 260cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i] = xforms[i]; 261cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i + 1] = xforms[i + 1]; 262cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i + 2] = xforms[i] * x + xforms[i + 1] * y + xforms[i + 2]; 263cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i + 3] = xforms[i + 3]; 264cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i + 4] = xforms[i + 4]; 265cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton dst[i + 5] = xforms[i + 3] * x + xforms[i + 4] * y + xforms[i + 5]; 266cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton } 267cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 268cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton default: 269cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton SkFAIL("Unknown transform type."); 270cdd4682f450b98bad71b8cb0772c02e0902aaa0dcdalton break; 2711fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon } 2721fcc01c4158bd68c679569e6c7cfbb302d0ce170bsalomon} 273