1c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton/* 2c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * Copyright 2014 Google Inc. 3c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * 4c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * Use of this source code is governed by a BSD-style license that can be 5c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * found in the LICENSE file. 6c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton */ 7c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 8c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "gl/GrGLPathRendering.h" 9c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "gl/GrGLUtil.h" 1039edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "gl/GrGLGpu.h" 11c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 12ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPath.h" 13ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRange.h" 14ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRendering.h" 15ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 16855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkStream.h" 17855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkTypeface.h" 18855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 19cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) 20cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->gpu()->glInterface(), RET, X) 21ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 22702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen// Number of paths to allocate per glGenPaths call. The call can be overly slow on command buffer GL 23702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen// implementation. The call has a result value, and thus waiting for the call completion is needed. 24702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunenstatic const GrGLsizei kPathIDPreallocationAmount = 65536; 25ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 2655b24afc178e641e17a5664beba7ab2b4982c91acdaltonstatic const GrGLenum gIndexType2GLType[] = { 2755b24afc178e641e17a5664beba7ab2b4982c91acdalton GR_GL_UNSIGNED_BYTE, 2855b24afc178e641e17a5664beba7ab2b4982c91acdalton GR_GL_UNSIGNED_SHORT, 2955b24afc178e641e17a5664beba7ab2b4982c91acdalton GR_GL_UNSIGNED_INT 3055b24afc178e641e17a5664beba7ab2b4982c91acdalton}; 3155b24afc178e641e17a5664beba7ab2b4982c91acdalton 3255b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(0 == GrPathRange::kU8_PathIndexType); 3355b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(1 == GrPathRange::kU16_PathIndexType); 3455b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(2 == GrPathRange::kU32_PathIndexType); 3555b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(GrPathRange::kU32_PathIndexType == GrPathRange::kLast_PathIndexType); 3655b24afc178e641e17a5664beba7ab2b4982c91acdalton 37ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic const GrGLenum gXformType2GLType[] = { 38ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_NONE, 39ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSLATE_X, 40ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSLATE_Y, 41ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSLATE_2D, 42ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSPOSE_AFFINE_2D 43ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}; 44ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 45ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(0 == GrPathRendering::kNone_PathTransformType); 46ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(1 == GrPathRendering::kTranslateX_PathTransformType); 47ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(2 == GrPathRendering::kTranslateY_PathTransformType); 48ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType); 49ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType); 50ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::kLast_PathTransformType); 51ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 52ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) { 53ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen switch (op) { 54ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen default: 55ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkFAIL("Unexpected path fill."); 56ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen /* fallthrough */; 57ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen case kIncClamp_StencilOp: 58ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return GR_GL_COUNT_UP; 59ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen case kInvert_StencilOp: 60ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return GR_GL_INVERT; 61ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 62ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 63c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 64861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonGrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu) 65702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen : GrPathRendering(gpu) 66702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen , fPreallocatedPathCount(0) { 676bb6d4075b198c5935ab6f2d71364ca7ff0153d1kkinnunen const GrGLInterface* glInterface = gpu->glInterface(); 686bb6d4075b198c5935ab6f2d71364ca7ff0153d1kkinnunen fCaps.bindFragmentInputSupport = 6996fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr != glInterface->fFunctions.fBindFragmentInputLocation; 70c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 71c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 72c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLPathRendering::~GrGLPathRendering() { 73702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (fPreallocatedPathCount > 0) { 74702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount); 75702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen } 76c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 77c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 78c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonvoid GrGLPathRendering::abandonGpuResources() { 79702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fPreallocatedPathCount = 0; 80c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 81c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 82ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::resetContext() { 83ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.invalidate(); 84ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // we don't use the model view matrix. 85505306374de4ceca7b6dfcf155fb64840c7f07a0jvanverth GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW)); 86505306374de4ceca7b6dfcf155fb64840c7f07a0jvanverth 87ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWPathStencilSettings.invalidate(); 88ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 89ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 9050b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenGrPath* GrGLPathRendering::createPath(const SkPath& inPath, const GrStrokeInfo& stroke) { 91385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GrGLPath(this->gpu(), inPath, stroke); 92ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 93ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 94855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonGrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* pathGenerator, 9550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen const GrStrokeInfo& stroke) { 96385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GrGLPathRange(this->gpu(), pathGenerator, stroke); 97855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton} 98855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 99cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunenvoid GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath* path) { 100cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen GrGLGpu* gpu = this->gpu(); 101cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen SkASSERT(gpu->caps()->shaderCaps()->pathRenderingSupport()); 102cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen gpu->flushColorWrite(false); 103cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen gpu->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); 104cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen 105cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fRenderTarget); 106cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen SkISize size = SkISize::Make(rt->width(), rt->height()); 107cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen this->setProjectionMatrix(*args.fViewMatrix, size, rt->origin()); 108cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen gpu->flushScissor(*args.fScissor, rt->getViewport(), rt->origin()); 109af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton gpu->flushHWAAState(rt, args.fUseHWAA, true); 11096fcdcc219d2a0d3579719b84b28bede76efba64halcanary gpu->flushRenderTarget(rt, nullptr); 111cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen 11250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen const GrGLPath* glPath = static_cast<const GrGLPath*>(path); 113ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 114cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen this->flushPathStencilSettings(*args.fStencil); 115ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(!fHWPathStencilSettings.isTwoSided()); 116ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 11750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode( 11850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 119ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 12092e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt 12150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen if (glPath->shouldFill()) { 12250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask)); 12392e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt } 12450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen if (glPath->shouldStroke()) { 12550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen GL_CALL(StencilStrokePath(glPath->pathID(), 0xffff, writeMask)); 12692e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt } 127ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 128ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 129cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunenvoid GrGLPathRendering::onDrawPath(const DrawPathArgs& args, const GrPath* path) { 130cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen if (!this->gpu()->flushGLState(args)) { 131cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen return; 132cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen } 13350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen const GrGLPath* glPath = static_cast<const GrGLPath*>(path); 134ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 135cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen this->flushPathStencilSettings(*args.fStencil); 136ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(!fHWPathStencilSettings.isTwoSided()); 137ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 13850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode( 13950b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 140ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 141ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 14250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen if (glPath->shouldStroke()) { 14350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen if (glPath->shouldFill()) { 14450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask)); 145ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 146cfe62e30848eadead4358b0385e57723779b762bkkinnunen GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask, 147cfe62e30848eadead4358b0385e57723779b762bkkinnunen GR_GL_BOUNDING_BOX)); 14892e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt } else { 149cfe62e30848eadead4358b0385e57723779b762bkkinnunen GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask, 150cfe62e30848eadead4358b0385e57723779b762bkkinnunen GR_GL_BOUNDING_BOX)); 151ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 152ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 153ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 154cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunenvoid GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange* pathRange, 155cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen const void* indices, PathIndexType indexType, 156cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen const float transformValues[], PathTransformType transformType, 157cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen int count) { 158cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen if (!this->gpu()->flushGLState(args)) { 159cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen return; 160cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen } 161cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen this->flushPathStencilSettings(*args.fStencil); 162cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen SkASSERT(!fHWPathStencilSettings.isTwoSided()); 163cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen 164ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 16550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRange); 166ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 167ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLenum fillMode = 168ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen gr_stencil_op_to_gl_path_rendering_fill_mode( 169ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 170ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLint writeMask = 171ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 172ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 17350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen if (glPathRange->shouldStroke()) { 17450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen if (glPathRange->shouldFill()) { 1755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilFillPathInstanced( 17650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(), 17750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen fillMode, writeMask, gXformType2GLType[transformType], 17850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen transformValues)); 179ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 180cfe62e30848eadead4358b0385e57723779b762bkkinnunen GL_CALL(StencilThenCoverStrokePathInstanced( 18150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(), 18255b24afc178e641e17a5664beba7ab2b4982c91acdalton 0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 183cfe62e30848eadead4358b0385e57723779b762bkkinnunen gXformType2GLType[transformType], transformValues)); 18492e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt } else { 185cfe62e30848eadead4358b0385e57723779b762bkkinnunen GL_CALL(StencilThenCoverFillPathInstanced( 18650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(), 18755b24afc178e641e17a5664beba7ab2b4982c91acdalton fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 188cfe62e30848eadead4358b0385e57723779b762bkkinnunen gXformType2GLType[transformType], transformValues)); 189ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 190ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 191ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 1925b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location, 1935b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLenum genMode, GrGLint components, 1945b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen const SkMatrix& matrix) { 195018fb62d12d1febf121fe265da5b6117b86a6541egdaniel float coefficients[3 * 3]; 1965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(components >= 1 && components <= 3); 1975b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 1985b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); 1995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); 2005b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); 2015b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 2025b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (components >= 2) { 2035b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); 2045b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); 2055b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); 2065b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 2075b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 2085b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (components >= 3) { 2095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); 2105b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); 2115b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); 2125b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 2135b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 2145b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients)); 215ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 216ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 217ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix, 218ee2af95db72152dfa61c841875df0594ca93437djoshualitt const SkISize& renderTargetSize, 219ee2af95db72152dfa61c841875df0594ca93437djoshualitt GrSurfaceOrigin renderTargetOrigin) { 220ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 221cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen SkASSERT(this->gpu()->glCaps().shaderCaps()->pathRenderingSupport()); 222ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 223ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && 224ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && 225ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { 226ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return; 227ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 228ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 229ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.fViewMatrix = matrix; 230ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; 231ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; 232ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 233018fb62d12d1febf121fe265da5b6117b86a6541egdaniel float glMatrix[4 * 4]; 234ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); 235505306374de4ceca7b6dfcf155fb64840c7f07a0jvanverth GL_CALL(MatrixLoadf(GR_GL_PATH_PROJECTION, glMatrix)); 236ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 237ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 238c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { 239702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen SkASSERT(range > 0); 240702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen GrGLuint firstID; 241702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (fPreallocatedPathCount >= range) { 242702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen firstID = fFirstPreallocatedPathID; 243702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fPreallocatedPathCount -= range; 244702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fFirstPreallocatedPathID += range; 245702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen return firstID; 246c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 247702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen // Allocate range + the amount to fill up preallocation amount. If succeed, either join with 248702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen // the existing preallocation range or delete the existing and use the new (potentially partial) 249702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen // preallocation range. 250702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen GrGLsizei allocAmount = range + (kPathIDPreallocationAmount - fPreallocatedPathCount); 251702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (allocAmount >= range) { 252702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen GL_CALL_RET(firstID, GenPaths(allocAmount)); 253702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen 254702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (firstID != 0) { 255702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (fPreallocatedPathCount > 0 && 256702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen firstID == fFirstPreallocatedPathID + fPreallocatedPathCount) { 257702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen firstID = fFirstPreallocatedPathID; 258702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fPreallocatedPathCount += allocAmount - range; 259702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fFirstPreallocatedPathID += range; 260702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen return firstID; 261702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen } 262702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen 263702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (allocAmount > range) { 264702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (fPreallocatedPathCount > 0) { 265702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount); 266702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen } 267702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fFirstPreallocatedPathID = firstID + range; 268702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fPreallocatedPathCount = allocAmount - range; 269702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen } 270702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen // Special case: if allocAmount == range, we have full preallocated range. 271702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen return firstID; 272702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen } 273c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 274702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen // Failed to allocate with preallocation. Remove existing preallocation and try to allocate just 275702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen // the range. 276702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (fPreallocatedPathCount > 0) { 277702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount); 278702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen fPreallocatedPathCount = 0; 279c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 280c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 281702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen GL_CALL_RET(firstID, GenPaths(range)); 282702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen if (firstID == 0) { 283702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen SkDebugf("Warning: Failed to allocate path\n"); 284702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen } 285702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen return firstID; 286c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 287c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 2885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { 289702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen GL_CALL(DeletePaths(path, range)); 290c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 291c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 29292e496f96abbd664888f0c8a7d546ab02e703bf7joshualittvoid GrGLPathRendering::flushPathStencilSettings(const GrStencilSettings& stencilSettings) { 29392e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt if (fHWPathStencilSettings != stencilSettings) { 2941517f93439bb974d871098cff632627e13524620kkinnunen SkASSERT(stencilSettings.isValid()); 2955b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen // Just the func, ref, and mask is set here. The op and write mask are params to the call 2965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen // that draws the path to the SB (glStencilFillPath) 2971517f93439bb974d871098cff632627e13524620kkinnunen const GrStencilSettings::Face kFront_Face = GrStencilSettings::kFront_Face; 2981517f93439bb974d871098cff632627e13524620kkinnunen GrStencilFunc func = stencilSettings.func(kFront_Face); 2991517f93439bb974d871098cff632627e13524620kkinnunen uint16_t funcRef = stencilSettings.funcRef(kFront_Face); 3001517f93439bb974d871098cff632627e13524620kkinnunen uint16_t funcMask = stencilSettings.funcMask(kFront_Face); 3011517f93439bb974d871098cff632627e13524620kkinnunen 3021517f93439bb974d871098cff632627e13524620kkinnunen if (!fHWPathStencilSettings.isValid() || 3031517f93439bb974d871098cff632627e13524620kkinnunen func != fHWPathStencilSettings.func(kFront_Face) || 3041517f93439bb974d871098cff632627e13524620kkinnunen funcRef != fHWPathStencilSettings.funcRef(kFront_Face) || 3051517f93439bb974d871098cff632627e13524620kkinnunen funcMask != fHWPathStencilSettings.funcMask(kFront_Face)) { 3061517f93439bb974d871098cff632627e13524620kkinnunen GL_CALL(PathStencilFunc(GrToGLStencilFunc(func), funcRef, funcMask)); 3071517f93439bb974d871098cff632627e13524620kkinnunen } 30892e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt fHWPathStencilSettings = stencilSettings; 3095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 310c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 311c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 312cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnuneninline GrGLGpu* GrGLPathRendering::gpu() { 313cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen return static_cast<GrGLGpu*>(fGpu); 314cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen} 315