1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTextureOp.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrAppliedClip.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrCaps.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrDrawOpTest.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGeometryProcessor.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrMeshDrawOp.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrOpFlushState.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrQuad.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceProvider.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrShaderCaps.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexturePriv.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTextureProxy.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMathPriv.h" 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPoint.h" 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPoint3.h" 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLColorSpaceXformHelper.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLFragmentShaderBuilder.h" 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLGeometryProcessor.h" 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLVarying.h" 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLVertexGeoBuilder.h" 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace { 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Geometry Processor that draws a texture modulated by a vertex color (though, this is meant to be 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the same value across all vertices of a quad and uses flat interpolation when available). This is 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * used by TextureOp below. 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass TextureGeometryProcessor : public GrGeometryProcessor { 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct Vertex { 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fPosition; 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fTextureCoords; 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor fColor; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct AAVertex { 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fPosition; 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fTextureCoords; 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint3 fEdges[4]; 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor fColor; 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct MultiTextureVertex { 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fPosition; 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fTextureIdx; 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fTextureCoords; 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor fColor; 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct AAMultiTextureVertex { 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fPosition; 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fTextureIdx; 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint fTextureCoords; 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint3 fEdges[4]; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor fColor; 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Maximum number of textures supported by this op. Must also be checked against the caps 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // limit. These numbers were based on some limited experiments on a HP Z840 and Pixel XL 2016 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // and could probably use more tuning. 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_BUILD_FOR_ANDROID 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr int kMaxTextures = 4; 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr int kMaxTextures = 8; 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int SupportsMultitexture(const GrShaderCaps& caps) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return caps.integerSupport() && caps.maxFragmentSamplers() > 1; 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static sk_sp<GrGeometryProcessor> Make(sk_sp<GrTextureProxy> proxies[], int proxyCnt, 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrColorSpaceXform> csxf, bool coverageAA, 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrSamplerState::Filter filters[], 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrShaderCaps& caps) { 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We use placement new to avoid always allocating space for kMaxTextures TextureSampler 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // instances. 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int samplerCnt = NumSamplersToUse(proxyCnt, caps); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = sizeof(TextureGeometryProcessor) + sizeof(TextureSampler) * (samplerCnt - 1); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* mem = GrGeometryProcessor::operator new(size); 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return sk_sp<TextureGeometryProcessor>(new (mem) TextureGeometryProcessor( 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot proxies, proxyCnt, samplerCnt, std::move(csxf), coverageAA, filters, caps)); 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ~TextureGeometryProcessor() override { 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int cnt = this->numTextureSamplers(); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 1; i < cnt; ++i) { 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSamplers[i].~TextureSampler(); 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name() const override { return "TextureGeometryProcessor"; } 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get())); 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot b->add32(static_cast<uint32_t>(this->usesCoverageEdgeAA())); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override { 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot class GLSLProcessor : public GrGLSLGeometryProcessor { 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot public: 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FPCoordTransformIter&& transformIter) override { 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const auto& textureGP = proc.cast<TextureGeometryProcessor>(); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fColorSpaceXformHelper.isValid()) { 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fColorSpaceXformHelper.setData(pdman, textureGP.fColorSpaceXform.get()); 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot private: 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const auto& textureGP = args.fGP.cast<TextureGeometryProcessor>(); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fColorSpaceXformHelper.emitCode( 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fUniformHandler, textureGP.fColorSpaceXform.get()); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->setNoPerspective(); 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->emitAttributes(textureGP); 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writeOutputPosition(args.fVertBuilder, gpArgs, textureGP.fPositions.fName); 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->emitTransforms(args.fVertBuilder, 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler, 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fUniformHandler, 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot textureGP.fTextureCoords.asShaderVar(), 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFPCoordTransformHandler); 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (args.fShaderCaps->preferFlatInterpolation()) { 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fColors, 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fOutputColor); 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addPassThroughAttribute(&textureGP.fColors, 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fOutputColor); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppend("float2 texCoord;"); 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureCoords, 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "texCoord"); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (textureGP.numTextureSamplers() > 1) { 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(args.fShaderCaps->integerSupport()); 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppend("int texIdx;"); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (args.fShaderCaps->flatInterpolationSupport()) { 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fTextureIdx, 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "texIdx"); 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureIdx, 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "texIdx"); 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppend("switch (texIdx) {"); 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < textureGP.numTextureSamplers(); ++i) { 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppendf("case %d: %s = ", i, args.fOutputColor); 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->appendTextureLookupAndModulate(args.fOutputColor, 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fTexSamplers[i], 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "texCoord", 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kFloat2_GrSLType, 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fColorSpaceXformHelper); 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppend("; break;"); 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppend("}"); 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor); 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->appendTextureLookupAndModulate(args.fOutputColor, 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fTexSamplers[0], 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "texCoord", 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kFloat2_GrSLType, 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fColorSpaceXformHelper); 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppend(";"); 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (textureGP.usesCoverageEdgeAA()) { 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* aaDistName = nullptr; 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // When interpolation is innacurate we perform the evaluation of the edge 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // equations in the fragment shader rather than interpolating values computed 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // in the vertex shader. 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!args.fShaderCaps->interpolantsAreInaccurate()) { 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLVarying aaDistVarying(kFloat4_GrSLType, 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLVarying::Scope::kVertToFrag); 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addVarying("aaDists", &aaDistVarying); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVertBuilder->codeAppendf( 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot R"(%s = float4(dot(aaEdge0.xy, %s.xy) + aaEdge0.z, 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dot(aaEdge1.xy, %s.xy) + aaEdge1.z, 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dot(aaEdge2.xy, %s.xy) + aaEdge2.z, 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dot(aaEdge3.xy, %s.xy) + aaEdge3.z);)", 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaDistVarying.vsOut(), textureGP.fPositions.fName, 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot textureGP.fPositions.fName, textureGP.fPositions.fName, 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot textureGP.fPositions.fName); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaDistName = aaDistVarying.fsIn(); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLVarying aaEdgeVarying[4]{ 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag}, 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag}, 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag}, 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot {kFloat3_GrSLType, GrGLSLVarying::Scope::kVertToFrag} 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 4; ++i) { 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString name; 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name.printf("aaEdge%d", i); 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVaryingHandler->addVarying(name.c_str(), &aaEdgeVarying[i]); 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fVertBuilder->codeAppendf( 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "%s = aaEdge%d;", aaEdgeVarying[i].vsOut(), i); 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppendf( 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot R"(float4 aaDists = float4(dot(%s.xy, sk_FragCoord.xy) + %s.z, 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dot(%s.xy, sk_FragCoord.xy) + %s.z, 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dot(%s.xy, sk_FragCoord.xy) + %s.z, 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dot(%s.xy, sk_FragCoord.xy) + %s.z);)", 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaEdgeVarying[0].fsIn(), aaEdgeVarying[0].fsIn(), 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaEdgeVarying[1].fsIn(), aaEdgeVarying[1].fsIn(), 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaEdgeVarying[2].fsIn(), aaEdgeVarying[2].fsIn(), 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaEdgeVarying[3].fsIn(), aaEdgeVarying[3].fsIn()); 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaDistName = "aaDists"; 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppendf( 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "float mindist = min(min(%s.x, %s.y), min(%s.z, %s.w));", 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaDistName, aaDistName, aaDistName, aaDistName); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppendf("%s = float4(clamp(mindist, 0, 1));", 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fOutputCoverage); 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLColorSpaceXformHelper fColorSpaceXformHelper; 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new GLSLProcessor; 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool usesCoverageEdgeAA() const { return SkToBool(fAAEdges[0].isInitialized()); } 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This exists to reduce the number of shaders generated. It does some rounding of sampler 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // counts. 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int NumSamplersToUse(int numRealProxies, const GrShaderCaps& caps) { 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(numRealProxies > 0 && numRealProxies <= kMaxTextures && 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot numRealProxies <= caps.maxFragmentSamplers()); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (1 == numRealProxies) { 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 1; 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (numRealProxies <= 4) { 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 4; 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Round to the next power of 2 and then clamp to kMaxTextures and the max allowed by caps. 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkTMin(SkNextPow2(numRealProxies), SkTMin(kMaxTextures, caps.maxFragmentSamplers())); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextureGeometryProcessor(sk_sp<GrTextureProxy> proxies[], int proxyCnt, int samplerCnt, 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrColorSpaceXform> csxf, bool coverageAA, 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrSamplerState::Filter filters[], const GrShaderCaps& caps) 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(kTextureGeometryProcessor_ClassID), fColorSpaceXform(std::move(csxf)) { 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(proxyCnt > 0 && samplerCnt >= proxyCnt); 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPositions = this->addVertexAttrib("position", kFloat2_GrVertexAttribType); 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSamplers[0].reset(std::move(proxies[0]), filters[0]); 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fSamplers[0]); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 1; i < proxyCnt; ++i) { 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This class has one sampler built in, the rest come from memory this processor was 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // placement-newed into and so haven't been constructed. 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (&fSamplers[i]) TextureSampler(std::move(proxies[i]), filters[i]); 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fSamplers[i]); 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (samplerCnt > 1) { 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Here we initialize any extra samplers by repeating the last one samplerCnt - proxyCnt 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // times. 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureProxy* dupeProxy = fSamplers[proxyCnt - 1].proxy(); 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = proxyCnt; i < samplerCnt; ++i) { 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new (&fSamplers[i]) TextureSampler(sk_ref_sp(dupeProxy), filters[proxyCnt - 1]); 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fSamplers[i]); 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(caps.integerSupport()); 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTextureIdx = this->addVertexAttrib("textureIdx", kInt_GrVertexAttribType); 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTextureCoords = this->addVertexAttrib("textureCoords", kFloat2_GrVertexAttribType); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (coverageAA) { 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAAEdges[0] = this->addVertexAttrib("aaEdge0", kFloat3_GrVertexAttribType); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAAEdges[1] = this->addVertexAttrib("aaEdge1", kFloat3_GrVertexAttribType); 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAAEdges[2] = this->addVertexAttrib("aaEdge2", kFloat3_GrVertexAttribType); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAAEdges[3] = this->addVertexAttrib("aaEdge3", kFloat3_GrVertexAttribType); 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fColors = this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType); 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Attribute fPositions; 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Attribute fTextureIdx; 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Attribute fTextureCoords; 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Attribute fColors; 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Attribute fAAEdges[4]; 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrColorSpaceXform> fColorSpaceXform; 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextureSampler fSamplers[1]; 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GrGeometryProcessor INHERITED; 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace { 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This is a class soley so it can be partially specialized (functions cannot be). 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate<GrAA, typename Vertex> class VertexAAHandler; 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate<typename Vertex> class VertexAAHandler<GrAA::kNo, Vertex> { 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static void AssignPositionsAndTexCoords(Vertex* vertices, const GrQuad& quad, 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& texRect) { 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[0].fPosition = quad.point(0); 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[0].fTextureCoords = {texRect.fLeft, texRect.fTop}; 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[1].fPosition = quad.point(1); 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[1].fTextureCoords = {texRect.fLeft, texRect.fBottom}; 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[2].fPosition = quad.point(2); 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[2].fTextureCoords = {texRect.fRight, texRect.fTop}; 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[3].fPosition = quad.point(3); 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[3].fTextureCoords = {texRect.fRight, texRect.fBottom}; 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate<typename Vertex> class VertexAAHandler<GrAA::kYes, Vertex> { 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static void AssignPositionsAndTexCoords(Vertex* vertices, const GrQuad& quad, 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& texRect) { 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We compute the four edge equations for quad, then outset them and compute a new quad 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // as the intersection points of the outset edges. 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // GrQuad is in tristip order but we want the points to be in a fan order, so swap 2 and 3. 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f xs(quad.point(0).fX, quad.point(1).fX, quad.point(3).fX, quad.point(2).fX); 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f ys(quad.point(0).fY, quad.point(1).fY, quad.point(3).fY, quad.point(2).fY); 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f xsrot = SkNx_shuffle<1, 2, 3, 0>(xs); 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f ysrot = SkNx_shuffle<1, 2, 3, 0>(ys); 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f normXs = ysrot - ys; 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f normYs = xs - xsrot; 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f ds = xsrot * ys - ysrot * xs; 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f invNormLengths = (normXs * normXs + normYs * normYs).rsqrt(); 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float test = normXs[0] * xs[2] + normYs[0] * ys[2] + ds[0]; 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Make sure the edge equations have their normals facing into the quad in device space 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (test < 0) { 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot invNormLengths = -invNormLengths; 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot normXs *= invNormLengths; 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot normYs *= invNormLengths; 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ds *= invNormLengths; 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Here is the bloat. This makes our edge equations compute coverage without requiring a 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // half pixel offset and is also used to compute the bloated quad that will cover all 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // pixels. 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ds += Sk4f(0.5f); 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 4; ++i) { 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int j = 0; j < 4; ++j) { 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[j].fEdges[i].fX = normXs[i]; 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[j].fEdges[i].fY = normYs[i]; 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[j].fEdges[i].fZ = ds[i]; 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Reverse the process to compute the points of the bloated quad from the edge equations. 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This time the inputs don't have 1s as their third coord and we want to homogenize rather 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // than normalize the output since we need a GrQuad with 2D points. 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xsrot = SkNx_shuffle<3, 0, 1, 2>(normXs); 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ysrot = SkNx_shuffle<3, 0, 1, 2>(normYs); 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Sk4f dsrot = SkNx_shuffle<3, 0, 1, 2>(ds); 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xs = ysrot * ds - normYs * dsrot; 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ys = normXs * dsrot - xsrot * ds; 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ds = xsrot * normYs - ysrot * normXs; 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ds = ds.invert(); 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xs *= ds; 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ys *= ds; 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Go back to tri strip order when writing out the bloated quad to vertex positions. 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[0].fPosition = {xs[0], ys[0]}; 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[1].fPosition = {xs[1], ys[1]}; 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[3].fPosition = {xs[2], ys[2]}; 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[2].fPosition = {xs[3], ys[3]}; 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot AssignTexCoords(vertices, quad, texRect); 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static void AssignTexCoords(Vertex* vertices, const GrQuad& quad, const SkRect& tex) { 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix q = SkMatrix::MakeAll(quad.point(0).fX, quad.point(1).fX, quad.point(2).fX, 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.point(0).fY, quad.point(1).fY, quad.point(2).fY, 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1.f, 1.f, 1.f); 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix qinv; 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!q.invert(&qinv)) { 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix t = SkMatrix::MakeAll(tex.fLeft, tex.fLeft, tex.fRight, 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tex.fTop, tex.fBottom, tex.fTop, 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1.f, 1.f, 1.f); 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix map; 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot map.setConcat(t, qinv); 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrixPriv::MapPointsWithStride(map, &vertices[0].fTextureCoords, sizeof(Vertex), 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &vertices[0].fPosition, sizeof(Vertex), 4); 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename Vertex, bool IsMultiTex> struct TexIdAssigner; 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename Vertex> struct TexIdAssigner<Vertex, true> { 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static void Assign(Vertex* vertices, int textureIdx) { 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[0].fTextureIdx = textureIdx; 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[1].fTextureIdx = textureIdx; 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[2].fTextureIdx = textureIdx; 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[3].fTextureIdx = textureIdx; 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename Vertex> struct TexIdAssigner<Vertex, false> { 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static void Assign(Vertex* vertices, int textureIdx) {} 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} // anonymous namespace 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename Vertex, bool IsMultiTex, GrAA AA> 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void tessellate_quad(const GrQuad& devQuad, const SkRect& srcRect, GrColor color, 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceOrigin origin, Vertex* vertices, SkScalar iw, SkScalar ih, 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int textureIdx) { 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect texRect = { 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot iw * srcRect.fLeft, 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ih * srcRect.fTop, 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot iw * srcRect.fRight, 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ih * srcRect.fBottom 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (origin == kBottomLeft_GrSurfaceOrigin) { 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texRect.fTop = 1.f - texRect.fTop; 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texRect.fBottom = 1.f - texRect.fBottom; 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot VertexAAHandler<AA, Vertex>::AssignPositionsAndTexCoords(vertices, devQuad, texRect); 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[0].fColor = color; 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[1].fColor = color; 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[2].fColor = color; 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices[3].fColor = color; 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TexIdAssigner<Vertex, IsMultiTex>::Assign(vertices, textureIdx); 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Op that implements GrTextureOp::Make. It draws textured quads. Each quad can modulate against a 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the texture by color. The blend with the destination is always src-over. The edges are non-AA. 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass TextureOp final : public GrMeshDrawOp { 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static std::unique_ptr<GrDrawOp> Make(sk_sp<GrTextureProxy> proxy, 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSamplerState::Filter filter, GrColor color, 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& srcRect, const SkRect& dstRect, 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAAType aaType, const SkMatrix& viewMatrix, 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrColorSpaceXform> csxf, bool allowSRBInputs) { 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return std::unique_ptr<GrDrawOp>(new TextureOp(std::move(proxy), filter, color, srcRect, 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dstRect, aaType, viewMatrix, std::move(csxf), 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot allowSRBInputs)); 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ~TextureOp() override { 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fFinalized) { 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxies = this->proxies(); 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fProxyCnt; ++i) { 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot proxies[i]->completedRead(); 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fProxyCnt > 1) { 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delete[] reinterpret_cast<const char*>(proxies); 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(1 == fProxyCnt); 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxy0->unref(); 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name() const override { return "TextureOp"; } 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void visitProxies(const VisitProxyFunc& func) const override { 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxies = this->proxies(); 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fProxyCnt; ++i) { 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot func(proxies[i]); 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString dumpInfo() const override { 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString str; 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendf("AllowSRGBInputs: %d\n", fAllowSRGBInputs); 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendf("# draws: %d\n", fDraws.count()); 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxies = this->proxies(); 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fProxyCnt; ++i) { 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendf("Proxy ID %d: %d, Filter: %d\n", i, proxies[i]->uniqueID().asUInt(), 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<int>(this->filters()[i])); 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fDraws.count(); ++i) { 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const Draw& draw = fDraws[i]; 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendf( 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "%d: Color: 0x%08x, ProxyIdx: %d, TexRect [L: %.2f, T: %.2f, R: %.2f, B: %.2f] " 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Quad [(%.2f, %.2f), (%.2f, %.2f), (%.2f, %.2f), (%.2f, %.2f)]\n", 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot i, draw.fColor, draw.fTextureIdx, draw.fSrcRect.fLeft, draw.fSrcRect.fTop, 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fSrcRect.fRight, draw.fSrcRect.fBottom, draw.fQuad.points()[0].fX, 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fQuad.points()[0].fY, draw.fQuad.points()[1].fX, draw.fQuad.points()[1].fY, 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fQuad.points()[2].fX, draw.fQuad.points()[2].fY, draw.fQuad.points()[3].fX, 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fQuad.points()[3].fY); 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str += INHERITED::dumpInfo(); 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return str; 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip, 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPixelConfigIsClamped dstIsClamped) override { 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fFinalized); 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(1 == fProxyCnt); 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFinalized = true; 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxy0->addPendingRead(); 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxy0->unref(); 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return RequiresDstTexture::kNo; 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FixedFunctionFlags fixedFunctionFlags() const override { 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->aaType() == GrAAType::kMSAA ? FixedFunctionFlags::kUsesHWAA 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : FixedFunctionFlags::kNone; 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot DEFINE_OP_CLASS_ID 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This is used in a heursitic for choosing a code path. We don't care what happens with 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // really large rects, infs, nans, etc. 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if defined(__clang__) && (__clang_major__ * 1000 + __clang_minor__) >= 3007 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot__attribute__((no_sanitize("float-cast-overflow"))) 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t RectSizeAsSizeT(const SkRect& rect) {; 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return static_cast<size_t>(SkTMax(rect.width(), 1.f) * SkTMax(rect.height(), 1.f)); 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr int kMaxTextures = TextureGeometryProcessor::kMaxTextures; 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextureOp(sk_sp<GrTextureProxy> proxy, GrSamplerState::Filter filter, GrColor color, 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& srcRect, const SkRect& dstRect, GrAAType aaType, 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& viewMatrix, sk_sp<GrColorSpaceXform> csxf, bool allowSRGBInputs) 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(ClassID()) 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fColorSpaceXform(std::move(csxf)) 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fProxy0(proxy.release()) 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fFilter0(filter) 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fProxyCnt(1) 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fAAType(static_cast<unsigned>(aaType)) 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fFinalized(0) 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fAllowSRGBInputs(allowSRGBInputs ? 1 : 0) { 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(aaType != GrAAType::kMixedSamples); 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Draw& draw = fDraws.push_back(); 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fSrcRect = srcRect; 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fTextureIdx = 0; 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fColor = color; 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fQuad.setFromMappedRect(dstRect, viewMatrix); 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bounds; 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.setBounds(draw.fQuad.points(), 4); 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxApproxDstPixelArea = RectSizeAsSizeT(bounds); 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onPrepareDraws(Target* target) override { 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> proxiesSPs[kMaxTextures]; 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxies = this->proxies(); 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto filters = this->filters(); 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fProxyCnt; ++i) { 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!proxies[i]->instantiate(target->resourceProvider())) { 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot proxiesSPs[i] = sk_ref_sp(proxies[i]); 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool coverageAA = GrAAType::kCoverage == this->aaType(); 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrGeometryProcessor> gp = 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextureGeometryProcessor::Make(proxiesSPs, fProxyCnt, std::move(fColorSpaceXform), 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coverageAA, filters, *target->caps().shaderCaps()); 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPipeline::InitArgs args; 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fProxy = target->proxy(); 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fCaps = &target->caps(); 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fResourceProvider = target->resourceProvider(); 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFlags = 0; 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fAllowSRGBInputs) { 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFlags |= GrPipeline::kAllowSRGBInputs_Flag; 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (GrAAType::kMSAA == this->aaType()) { 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fFlags |= GrPipeline::kHWAntialias_Flag; 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrPipeline* pipeline = target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot target->detachAppliedClip()); 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int vstart; 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrBuffer* vbuffer; 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* vdata = target->makeVertexSpace(gp->getVertexStride(), 4 * fDraws.count(), &vbuffer, 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &vstart); 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!vdata) { 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Could not allocate vertices\n"); 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (1 == fProxyCnt) { 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceOrigin origin = proxies[0]->origin(); 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTexture* texture = proxies[0]->priv().peekTexture(); 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float iw = 1.f / texture->width(); 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float ih = 1.f / texture->height(); 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (coverageAA) { 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(gp->getVertexStride() == sizeof(TextureGeometryProcessor::AAVertex)); 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto vertices = static_cast<TextureGeometryProcessor::AAVertex*>(vdata); 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fDraws.count(); ++i) { 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tessellate_quad<TextureGeometryProcessor::AAVertex, false, GrAA::kYes>( 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws[i].fQuad, fDraws[i].fSrcRect, fDraws[i].fColor, origin, 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices + 4 * i, iw, ih, 0); 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(gp->getVertexStride() == sizeof(TextureGeometryProcessor::Vertex)); 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto vertices = static_cast<TextureGeometryProcessor::Vertex*>(vdata); 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fDraws.count(); ++i) { 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tessellate_quad<TextureGeometryProcessor::Vertex, false, GrAA::kNo>( 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws[i].fQuad, fDraws[i].fSrcRect, fDraws[i].fColor, origin, 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices + 4 * i, iw, ih, 0); 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTexture* textures[kMaxTextures]; 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float iw[kMaxTextures]; 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float ih[kMaxTextures]; 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int t = 0; t < fProxyCnt; ++t) { 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot textures[t] = proxies[t]->priv().peekTexture(); 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot iw[t] = 1.f / textures[t]->width(); 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ih[t] = 1.f / textures[t]->height(); 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (coverageAA) { 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(gp->getVertexStride() == 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sizeof(TextureGeometryProcessor::AAMultiTextureVertex)); 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto vertices = static_cast<TextureGeometryProcessor::AAMultiTextureVertex*>(vdata); 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fDraws.count(); ++i) { 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto tidx = fDraws[i].fTextureIdx; 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceOrigin origin = proxies[tidx]->origin(); 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tessellate_quad<TextureGeometryProcessor::AAMultiTextureVertex, true, 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAA::kYes>(fDraws[i].fQuad, fDraws[i].fSrcRect, 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws[i].fColor, origin, vertices + 4 * i, 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot iw[tidx], ih[tidx], tidx); 624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(gp->getVertexStride() == 627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sizeof(TextureGeometryProcessor::MultiTextureVertex)); 628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto vertices = static_cast<TextureGeometryProcessor::MultiTextureVertex*>(vdata); 629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fDraws.count(); ++i) { 630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto tidx = fDraws[i].fTextureIdx; 631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceOrigin origin = proxies[tidx]->origin(); 632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tessellate_quad<TextureGeometryProcessor::MultiTextureVertex, true, GrAA::kNo>( 633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws[i].fQuad, fDraws[i].fSrcRect, fDraws[i].fColor, origin, 634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertices + 4 * i, iw[tidx], ih[tidx], tidx); 635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPrimitiveType primitiveType = 639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws.count() > 1 ? GrPrimitiveType::kTriangles : GrPrimitiveType::kTriangleStrip; 640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrMesh mesh(primitiveType); 641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDraws.count() > 1) { 642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<const GrBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer(); 643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ibuffer) { 644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Could not allocate quad indices\n"); 645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mesh.setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(), 648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrResourceProvider::QuadCountOfQuadBuffer()); 649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mesh.setNonIndexedNonInstanced(4); 651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mesh.setVertexData(vbuffer, vstart); 653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot target->draw(gp.get(), pipeline, mesh); 654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { 657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const auto* that = t->cast<TextureOp>(); 658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const auto& shaderCaps = *caps.shaderCaps(); 659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get())) { 660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->aaType() != that->aaType()) { 663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Because of an issue where GrColorSpaceXform adds the same function every time it is used 666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // in a texture lookup, we only allow multiple textures when there is no transform. 667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (TextureGeometryProcessor::SupportsMultitexture(shaderCaps) && !fColorSpaceXform && 668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxApproxDstPixelArea <= shaderCaps.disableImageMultitexturingDstRectAreaThreshold() && 669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that->fMaxApproxDstPixelArea <= 670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot shaderCaps.disableImageMultitexturingDstRectAreaThreshold()) { 671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int map[kMaxTextures]; 672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int numNewProxies = this->mergeProxies(that, map, shaderCaps); 673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (numNewProxies < 0) { 674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (1 == fProxyCnt && numNewProxies) { 677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* mem = new char[(sizeof(GrSamplerState::Filter) + sizeof(GrTextureProxy*)) * 678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kMaxTextures]; 679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxies = reinterpret_cast<GrTextureProxy**>(mem); 680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto filters = reinterpret_cast<GrSamplerState::Filter*>(proxies + kMaxTextures); 681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot proxies[0] = fProxy0; 682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot filters[0] = fFilter0; 683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxyArray = proxies; 684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxyCnt += numNewProxies; 686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thisProxies = fProxyArray; 687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thatProxies = that->proxies(); 688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thatFilters = that->filters(); 689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thisFilters = reinterpret_cast<GrSamplerState::Filter*>(thisProxies + 690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kMaxTextures); 691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < that->fProxyCnt; ++i) { 692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (map[i] < 0) { 693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot thatProxies[i]->addPendingRead(); 694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot thisProxies[-map[i]] = thatProxies[i]; 696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot thisFilters[-map[i]] = thatFilters[i]; 697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot map[i] = -map[i]; 698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstNewDraw = fDraws.count(); 701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws.push_back_n(that->fDraws.count(), that->fDraws.begin()); 702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = firstNewDraw; i < fDraws.count(); ++i) { 703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws[i].fTextureIdx = map[fDraws[i].fTextureIdx]; 704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We can get here when one of the ops is already multitextured but the other cannot 707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // be because of the dst rect size. 708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fProxyCnt > 1 || that->fProxyCnt > 1) { 709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fProxy0->uniqueID() != that->fProxy0->uniqueID() || fFilter0 != that->fFilter0) { 712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDraws.push_back_n(that->fDraws.count(), that->fDraws.begin()); 715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->joinBounds(*that); 717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxApproxDstPixelArea = SkTMax(that->fMaxApproxDstPixelArea, fMaxApproxDstPixelArea); 718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** 722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Determines a mapping of indices from that's proxy array to this's proxy array. A negative map 723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * value means that's proxy should be added to this's proxy array at the absolute value of 724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * the map entry. If it is determined that the ops shouldn't combine their proxies then a 725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * negative value is returned. Otherwise, return value indicates the number of proxies that have 726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * to be added to this op or, equivalently, the number of negative entries in map. 727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int mergeProxies(const TextureOp* that, int map[kMaxTextures], const GrShaderCaps& caps) const { 729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::fill_n(map, kMaxTextures, -kMaxTextures); 730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int sharedProxyCnt = 0; 731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thisProxies = this->proxies(); 732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thisFilters = this->filters(); 733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thatProxies = that->proxies(); 734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto thatFilters = that->filters(); 735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fProxyCnt; ++i) { 736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int j = 0; j < that->fProxyCnt; ++j) { 737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (thisProxies[i]->uniqueID() == thatProxies[j]->uniqueID()) { 738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (thisFilters[i] != thatFilters[j]) { 739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // In GL we don't currently support using the same texture with different 740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // samplers. If we added support for sampler objects and a cap bit to know 741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // it's ok to use different filter modes then we could support this. 742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Otherwise, we could also only allow a single filter mode for each op 743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // instance. 744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return -1; 745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot map[j] = i; 747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++sharedProxyCnt; 748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int actualMaxTextures = SkTMin(caps.maxFragmentSamplers(), kMaxTextures); 753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int newProxyCnt = that->fProxyCnt - sharedProxyCnt; 754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (newProxyCnt + fProxyCnt > actualMaxTextures) { 755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return -1; 756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPixelConfig config = thisProxies[0]->config(); 758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int nextSlot = fProxyCnt; 759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int j = 0; j < that->fProxyCnt; ++j) { 760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We want to avoid making many shaders because of different permutations of shader 761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // based swizzle and sampler types. The approach taken here is to require the configs to 762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // be the same and to only allow already instantiated proxies that have the most 763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // common sampler type. Otherwise we don't merge. 764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (thatProxies[j]->config() != config) { 765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return -1; 766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (GrTexture* tex = thatProxies[j]->priv().peekTexture()) { 768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (tex->texturePriv().samplerType() != kTexture2DSampler_GrSLType) { 769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return -1; 770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (map[j] < 0) { 773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot map[j] = -(nextSlot++); 774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return newProxyCnt; 777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAAType aaType() const { return static_cast<GrAAType>(fAAType); } 780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureProxy* const* proxies() const { return fProxyCnt > 1 ? fProxyArray : &fProxy0; } 782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrSamplerState::Filter* filters() const { 784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fProxyCnt > 1) { 785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return reinterpret_cast<const GrSamplerState::Filter*>(fProxyArray + kMaxTextures); 786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return &fFilter0; 788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct Draw { 791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect fSrcRect; 792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fTextureIdx; 793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrQuad fQuad; 794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor fColor; 795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSTArray<1, Draw, true> fDraws; 797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrColorSpaceXform> fColorSpaceXform; 798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Initially we store a single proxy ptr and a single filter. If we grow to have more than 799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // one proxy we instead store pointers to dynamically allocated arrays of size kMaxTextures 800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // followed by kMaxTextures filters. 801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot union { 802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureProxy* fProxy0; 803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureProxy** fProxyArray; 804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t fMaxApproxDstPixelArea; 806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSamplerState::Filter fFilter0; 807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint8_t fProxyCnt; 808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned fAAType : 2; 809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Used to track whether fProxy is ref'ed or has a pending IO after finalize() is called. 810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned fFinalized : 1; 811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned fAllowSRGBInputs : 1; 812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GrMeshDrawOp INHERITED; 814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int TextureGeometryProcessor::kMaxTextures; 817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int TextureOp::kMaxTextures; 818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} // anonymous namespace 820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace GrTextureOp { 822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrDrawOp> Make(sk_sp<GrTextureProxy> proxy, GrSamplerState::Filter filter, 824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor color, const SkRect& srcRect, const SkRect& dstRect, 825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAAType aaType, const SkMatrix& viewMatrix, 826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrColorSpaceXform> csxf, bool allowSRGBInputs) { 827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!viewMatrix.hasPerspective()); 828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return TextureOp::Make(std::move(proxy), filter, color, srcRect, dstRect, aaType, viewMatrix, 829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(csxf), allowSRGBInputs); 830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} // namespace GrTextureOp 833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_TEST_UTILS 835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h" 836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextPriv.h" 837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrProxyProvider.h" 838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGR_DRAW_OP_TEST_DEFINE(TextureOp) { 840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceDesc desc; 841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fConfig = kRGBA_8888_GrPixelConfig; 842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fHeight = random->nextULessThan(90) + 10; 843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fWidth = random->nextULessThan(90) + 10; 844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fOrigin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin; 845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBackingFit fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact; 846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); 848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kNo); 849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect = GrTest::TestRect(random); 851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect srcRect; 852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot srcRect.fLeft = random->nextRangeScalar(0.f, proxy->width() / 2.f); 853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot srcRect.fRight = random->nextRangeScalar(0.f, proxy->width()) + proxy->width() / 2.f; 854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot srcRect.fTop = random->nextRangeScalar(0.f, proxy->height() / 2.f); 855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot srcRect.fBottom = random->nextRangeScalar(0.f, proxy->height()) + proxy->height() / 2.f; 856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random); 857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrColor color = SkColorToPremulGrColor(random->nextU()); 858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSamplerState::Filter filter = (GrSamplerState::Filter)random->nextULessThan( 859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<uint32_t>(GrSamplerState::Filter::kMipMap) + 1); 860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto csxf = GrTest::TestColorXform(random); 861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool allowSRGBInputs = random->nextBool(); 862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAAType aaType = GrAAType::kNone; 863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (random->nextBool()) { 864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aaType = (fsaaType == GrFSAAType::kUnifiedMSAA) ? GrAAType::kMSAA : GrAAType::kCoverage; 865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrTextureOp::Make(std::move(proxy), filter, color, srcRect, rect, aaType, viewMatrix, 867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(csxf), allowSRGBInputs); 868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 871