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/GrGLNameAllocator.h" 10c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "gl/GrGLUtil.h" 11ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "gl/GrGpuGL.h" 12c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 13ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPath.h" 14ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRange.h" 15ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRendering.h" 16ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 17855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkStream.h" 18855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkTypeface.h" 19855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 20ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) 21ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X) 22ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 23ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 24ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic const GrGLenum gXformType2GLType[] = { 25ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_NONE, 26ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSLATE_X, 27ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSLATE_Y, 28ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSLATE_2D, 29ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_TRANSPOSE_AFFINE_2D 30ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}; 31ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 32ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(0 == GrPathRendering::kNone_PathTransformType); 33ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(1 == GrPathRendering::kTranslateX_PathTransformType); 34ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(2 == GrPathRendering::kTranslateY_PathTransformType); 35ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType); 36ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType); 37ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::kLast_PathTransformType); 38ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 39ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) { 40ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen switch (op) { 41ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen default: 42ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkFAIL("Unexpected path fill."); 43ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen /* fallthrough */; 44ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen case kIncClamp_StencilOp: 45ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return GR_GL_COUNT_UP; 46ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen case kInvert_StencilOp: 47ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return GR_GL_INVERT; 48ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 49ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 50c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 51ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu) 52ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen : fGpu(gpu) { 535b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen const GrGLInterface* glInterface = gpu->glInterface(); 545b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fCaps.stencilThenCoverSupport = 55149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton NULL != glInterface->fFunctions.fStencilThenCoverFillPath && 56149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton NULL != glInterface->fFunctions.fStencilThenCoverStrokePath && 57149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced && 58149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced; 595b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fCaps.fragmentInputGenSupport = 60ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen kGLES_GrGLStandard == glInterface->fStandard && 61149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton NULL != glInterface->fFunctions.fProgramPathFragmentInputGen; 62149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton fCaps.glyphLoadingSupport = 63149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton NULL != glInterface->fFunctions.fPathMemoryGlyphIndexArray; 64ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen 65ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen if (!fCaps.fragmentInputGenSupport) { 66ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords()); 67ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen } 68c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 69c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 70c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLPathRendering::~GrGLPathRendering() { 71c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 72c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 73c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonvoid GrGLPathRendering::abandonGpuResources() { 74c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton fPathNameAllocator.reset(NULL); 75c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 76c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 77ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::resetContext() { 78ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.invalidate(); 79ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // we don't use the model view matrix. 80ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen GrGLenum matrixMode = 81ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_MODELVIEW : GR_GL_MODELVIEW; 82ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen GL_CALL(MatrixLoadIdentity(matrixMode)); 83ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen 84ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen if (!caps().fragmentInputGenSupport) { 85ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { 86ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); 87ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen fHWPathTexGenSettings[i].fMode = GR_GL_NONE; 88ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen fHWPathTexGenSettings[i].fNumComponents = 0; 89ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen } 90ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen fHWActivePathTexGenSets = 0; 91ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 92ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWPathStencilSettings.invalidate(); 93ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 94ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 95ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& stroke) { 96ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke)); 97ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 98ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 99855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonGrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* pathGenerator, 100855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const SkStrokeRec& stroke) { 101855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton return SkNEW_ARGS(GrGLPathRange, (fGpu, pathGenerator, stroke)); 102855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton} 103855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 104855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonGrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface, 105855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const SkDescriptor* desc, 106855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const SkStrokeRec& stroke) { 107855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton if (NULL != desc || !caps().glyphLoadingSupport) { 108855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton return GrPathRendering::createGlyphs(typeface, desc, stroke); 109855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton } 110855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 111855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton if (NULL == typeface) { 112855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton typeface = SkTypeface::GetDefaultTypeface(); 113855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton SkASSERT(NULL != typeface); 114855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton } 115855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 116855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton int faceIndex; 117855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton SkAutoTUnref<SkStream> fontStream(typeface->openStream(&faceIndex)); 118855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 119855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const size_t fontDataLength = fontStream->getLength(); 120855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton if (0 == fontDataLength) { 121855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton return GrPathRendering::createGlyphs(typeface, NULL, stroke); 122855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton } 123855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 124855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton SkTArray<uint8_t> fontTempBuffer; 125855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const void* fontData = fontStream->getMemoryBase(); 126855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton if (NULL == fontData) { 127855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton // TODO: Find a more efficient way to pass the font data (e.g. open file descriptor). 128855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fontTempBuffer.reset(fontDataLength); 129855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fontStream->read(&fontTempBuffer.front(), fontDataLength); 130855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fontData = &fontTempBuffer.front(); 131855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton } 132855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 133855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const size_t numPaths = typeface->countGlyphs(); 134855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const GrGLuint basePathID = this->genPaths(numPaths); 135544c5b8c4d86362e6f8411c9112ea4c3149df81dcdalton SkAutoTUnref<GrGLPath> templatePath(SkNEW_ARGS(GrGLPath, (fGpu, SkPath(), stroke))); 136855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 137855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton GrGLenum status; 138855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton GL_CALL_RET(status, PathMemoryGlyphIndexArray(basePathID, GR_GL_STANDARD_FONT_FORMAT, 139544c5b8c4d86362e6f8411c9112ea4c3149df81dcdalton fontDataLength, fontData, faceIndex, 0, 140544c5b8c4d86362e6f8411c9112ea4c3149df81dcdalton numPaths, templatePath->pathID(), 141855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton SkPaint::kCanonicalTextSizeForPaths)); 142855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 143855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton if (GR_GL_FONT_GLYPHS_AVAILABLE != status) { 144855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton this->deletePaths(basePathID, numPaths); 145855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton return GrPathRendering::createGlyphs(typeface, NULL, stroke); 146855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton } 147855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 148855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton // This is a crude approximation. We may want to consider giving this class 149855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton // a pseudo PathGenerator whose sole purpose is to track the approximate gpu 150855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton // memory size. 151855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton const size_t gpuMemorySize = fontDataLength / 4; 152855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton return SkNEW_ARGS(GrGLPathRange, (fGpu, basePathID, numPaths, gpuMemorySize, stroke)); 153ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 154ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 155ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) { 156ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 15749f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fGpu->drawState()->getRenderTarget()); 15849f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); 159ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 160ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->flushPathStencilSettings(fill); 161ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(!fHWPathStencilSettings.isTwoSided()); 162ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 163ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLenum fillMode = 164ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 165ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 1665b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilFillPath(id, fillMode, writeMask)); 167ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 168ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 169ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) { 170ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 17149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fGpu->drawState()->getRenderTarget()); 17249f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); 173ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 174ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->flushPathStencilSettings(fill); 175ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(!fHWPathStencilSettings.isTwoSided()); 176ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 177ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen const SkStrokeRec& stroke = path->getStroke(); 178ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 179ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill); 180ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 181ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLenum fillMode = 182ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 183ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 184ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 185ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (nonInvertedFill == fill) { 186ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (stroke.needToApply()) { 187ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 1885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilFillPath(id, fillMode, writeMask)); 189ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 190ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX); 191ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } else { 192ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX); 193ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 194ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } else { 195ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 1965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilFillPath(id, fillMode, writeMask)); 197ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 198ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (stroke.needToApply()) { 1995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); 200ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 201ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 202ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrDrawState* drawState = fGpu->drawState(); 203ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrDrawState::AutoViewMatrixRestore avmr; 204ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkRect bounds = SkRect::MakeLTRB(0, 0, 205ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkIntToScalar(drawState->getRenderTarget()->width()), 206ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkIntToScalar(drawState->getRenderTarget()->height())); 207ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkMatrix vmi; 208ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // mapRect through persp matrix may not be correct 209ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { 210ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen vmi.mapRect(&bounds); 211ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // theoretically could set bloat = 0, instead leave it because of matrix inversion 212ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // precision. 213ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; 214ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen bounds.outset(bloat, bloat); 215ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } else { 216ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen avmr.setIdentity(drawState); 217ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 218ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 219ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fGpu->drawSimpleRect(bounds); 220ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 221ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 222ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 223ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, 224ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen const float transforms[], PathTransformType transformsType, 225ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkPath::FillType fill) { 226ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(fGpu->caps()->pathRenderingSupport()); 22749f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fGpu->drawState()->getRenderTarget()); 22849f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); 229ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 230ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID(); 231ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 232ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->flushPathStencilSettings(fill); 233ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(!fHWPathStencilSettings.isTwoSided()); 234ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 235ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen const SkStrokeRec& stroke = pathRange->getStroke(); 236ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 237ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkPath::FillType nonInvertedFill = 238ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkPath::ConvertToNonInverseFillType(fill); 239ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 240ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLenum fillMode = 241ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen gr_stencil_op_to_gl_path_rendering_fill_mode( 242ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 243ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLint writeMask = 244ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 245ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 246ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (nonInvertedFill == fill) { 247ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (stroke.needToApply()) { 248ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 2495b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilFillPathInstanced( 2505b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, 2515b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen writeMask, gXformType2GLType[transformsType], 2525b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen transforms)); 253ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 254ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->stencilThenCoverStrokePathInstanced( 255ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask, 256ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 257ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen gXformType2GLType[transformsType], transforms); 258ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } else { 259ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen this->stencilThenCoverFillPathInstanced( 260ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask, 261ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 262ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen gXformType2GLType[transformsType], transforms); 263ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 264ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } else { 265ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 2665b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilFillPathInstanced( 267ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, 268ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen writeMask, gXformType2GLType[transformsType], 2695b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen transforms)); 270ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 271ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (stroke.needToApply()) { 2725b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilStrokePathInstanced( 273ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, 274ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen writeMask, gXformType2GLType[transformsType], 2755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen transforms)); 276ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 277ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 278ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrDrawState* drawState = fGpu->drawState(); 279ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrDrawState::AutoViewMatrixRestore avmr; 280ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkRect bounds = SkRect::MakeLTRB(0, 0, 281ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkIntToScalar(drawState->getRenderTarget()->width()), 282ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkIntToScalar(drawState->getRenderTarget()->height())); 283ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkMatrix vmi; 284ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // mapRect through persp matrix may not be correct 285ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { 286ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen vmi.mapRect(&bounds); 287ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // theoretically could set bloat = 0, instead leave it because of matrix inversion 288ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen // precision. 289ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; 290ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen bounds.outset(bloat, bloat); 291ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } else { 292ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen avmr.setIdentity(drawState); 293ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 294ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 295ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fGpu->drawSimpleRect(bounds); 296ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 297ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 298ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 2995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents components, 3005b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen const GrGLfloat* coefficients) { 3015b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(components >= kS_PathTexGenComponents && 3025b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen components <= kSTR_PathTexGenComponents); 3035b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx); 304ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 3055b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode && 3065b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen components == fHWPathTexGenSettings[unitIdx].fNumComponents && 3075b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients, 3085b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3 * components * sizeof(GrGLfloat))) { 3095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen return; 310ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 3115b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3125b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fGpu->setTextureUnit(unitIdx); 3135b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3145b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fHWPathTexGenSettings[unitIdx].fNumComponents = components; 3155b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components, coefficients)); 3165b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3175b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients, 3185b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3 * components * sizeof(GrGLfloat)); 3195b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen} 3205b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3215b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents components, 3225b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen const SkMatrix& matrix) { 3235b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLfloat coefficients[3 * 3]; 3245b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(components >= kS_PathTexGenComponents && 3255b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen components <= kSTR_PathTexGenComponents); 3265b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3275b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); 3285b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); 3295b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); 3305b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3315b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (components >= kST_PathTexGenComponents) { 3325b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); 3335b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); 3345b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); 3355b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 3365b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3375b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (components >= kSTR_PathTexGenComponents) { 3385b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); 3395b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); 3405b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); 3415b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 3425b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3435b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen this->enablePathTexGen(unitIdx, components, coefficients); 3445b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen} 3455b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3465b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) { 3475b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSets); 3485b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3495b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen // Only write the inactive path tex gens, since active path tex gens were 3505b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen // written when they were enabled. 3515b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3525b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkDEBUGCODE( 3535b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen for (int i = 0; i < numUsedTexCoordSets; i++) { 3545b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); 3555b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 3565b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen ); 3575b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3585b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) { 3595b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); 3605b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3615b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fGpu->setTextureUnit(i); 3625b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); 3635b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fHWPathTexGenSettings[i].fNumComponents = 0; 3645b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 3655b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3665b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fHWActivePathTexGenSets = numUsedTexCoordSets; 3675b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen} 3685b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3695b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location, 3705b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLenum genMode, GrGLint components, 3715b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen const SkMatrix& matrix) { 3725b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(caps().fragmentInputGenSupport); 3735b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLfloat coefficients[3 * 3]; 3745b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(components >= 1 && components <= 3); 3755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3765b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); 3775b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); 3785b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); 3795b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3805b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (components >= 2) { 3815b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); 3825b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); 3835b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); 3845b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 3855b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3865b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (components >= 3) { 3875b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); 3885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); 3895b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); 3905b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 3915b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 3925b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients)); 393ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 394ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 395ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix, 396ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen const SkISize& renderTargetSize, 397ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrSurfaceOrigin renderTargetOrigin) { 398ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 399ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen SkASSERT(fGpu->glCaps().pathRenderingSupport()); 400ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 401ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && 402ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && 403ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { 404ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen return; 405ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen } 406ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 407ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.fViewMatrix = matrix; 408ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; 409ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; 410ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 411ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen GrGLfloat glMatrix[4 * 4]; 412ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); 413ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen GrGLenum matrixMode = 414ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_PROJECTION : GR_GL_PROJECTION; 415ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen GL_CALL(MatrixLoadf(matrixMode, glMatrix)); 416ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen} 417ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen 418c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { 419c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton if (range > 1) { 420c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLuint name; 421c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL_RET(name, GenPaths(range)); 422c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton return name; 423c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 424c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 425c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton if (NULL == fPathNameAllocator.get()) { 426c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton static const int range = 65536; 427c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLuint firstName; 428c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL_RET(firstName, GenPaths(range)); 429c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range))); 430c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 431c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 432c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // When allocating names one at a time, pull from a client-side pool of 433c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // available names in order to save a round trip to the GL server. 434c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLuint name = fPathNameAllocator->allocateName(); 435c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 436c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton if (0 == name) { 437c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // Our reserved path names are all in use. Fall back on GenPaths. 438c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL_RET(name, GenPaths(1)); 439c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 440c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 441c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton return name; 442c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 443c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 4445b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { 445c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton if (range > 1) { 446c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // It is not supported to delete names in ranges that were allocated 447c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // individually using GrGLPathNameAllocator. 448c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton SkASSERT(NULL == fPathNameAllocator.get() || 449c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton path + range <= fPathNameAllocator->firstName() || 450c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton path >= fPathNameAllocator->endName()); 451c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(DeletePaths(path, range)); 452c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton return; 453c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 454c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 455c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton if (NULL == fPathNameAllocator.get() || 456c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton path < fPathNameAllocator->firstName() || 457c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton path >= fPathNameAllocator->endName()) { 458c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // If we aren't inside fPathNameAllocator's range then this name was 459c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // generated by the GenPaths fallback (or else was never allocated). 460c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(DeletePaths(path, 1)); 461c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton return; 462c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton } 463c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 464c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton // Make the path empty to save memory, but don't free the name in the driver. 465c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL)); 466c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton fPathNameAllocator->free(path); 467c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 468c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 4695b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) { 4705b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrStencilSettings pathStencilSettings; 4715b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings); 4725b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (fHWPathStencilSettings != pathStencilSettings) { 4735b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen // Just the func, ref, and mask is set here. The op and write mask are params to the call 4745b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen // that draws the path to the SB (glStencilFillPath) 4755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLenum func = 4765b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront_Face)); 4775b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSettings::kFront_Face), 4785b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen pathStencilSettings.funcMask(GrStencilSettings::kFront_Face))); 479c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 4805b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen fHWPathStencilSettings = pathStencilSettings; 4815b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 482c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 483c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 4845b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, 485c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLuint mask, GrGLenum coverMode) { 4865b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (caps().stencilThenCoverSupport) { 4875b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode)); 4885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen return; 4895b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 490c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(StencilFillPath(path, fillMode, mask)); 491c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(CoverFillPath(path, coverMode)); 492c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 493c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 4945b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference, 495c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLuint mask, GrGLenum coverMode) { 4965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (caps().stencilThenCoverSupport) { 4975b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode)); 4985b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen return; 4995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 500c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(StencilStrokePath(path, reference, mask)); 501c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(CoverStrokePath(path, coverMode)); 502c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 503c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 5045b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverFillPathInstanced( 505c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, 506c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, 507c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GrGLenum transformType, const GrGLfloat *transformValues) { 5085b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (caps().stencilThenCoverSupport) { 5095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode, 5105b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen mask, coverMode, transformType, transformValues)); 5115b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen return; 5125b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 513c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, 514c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton fillMode, mask, transformType, transformValues)); 515c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, 516c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton coverMode, transformType, transformValues)); 517c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 518c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton 5195b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverStrokePathInstanced( 5205b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, 5215b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, 5225b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLenum transformType, const GrGLfloat *transformValues) { 5235b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen if (caps().stencilThenCoverSupport) { 5245b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, 5255b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen reference, mask, coverMode, transformType, 5265b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen transformValues)); 5275b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen return; 5285b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen } 5295b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen 530c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, 531c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton reference, mask, transformType, transformValues)); 532c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, 533c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton coverMode, transformType, transformValues)); 534c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton} 535