1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2015 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 "GrAtlasTextOp.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrOpFlushState.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceProvider.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGlyphCache.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMathPriv.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMatrixPriv.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPoint3.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "effects/GrBitmapTextGeoProc.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "effects/GrDistanceFieldGeoProc.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "text/GrAtlasGlyphCache.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////////////// 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int kDistanceAdjustLumShift = 5; 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrAtlasTextOp::init() { 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const Geometry& geo = fGeoData[0]; 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bounds; 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot geo.fBlob->computeSubRunBounds(&bounds, geo.fRun, geo.fSubRun, geo.fViewMatrix, geo.fX, geo.fY); 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We don't have tight bounds on the glyph paths in device space. For the purposes of bounds 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // we treat this as a set of non-AA rects rendered with a texture. 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesDistanceFields()) { 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool isLCD = this->isLCD(); 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& viewMatrix = geo.fViewMatrix; 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags |= viewMatrix.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0; 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags |= viewMatrix.hasPerspective() ? kPerspective_DistanceFieldEffectFlag : 0; 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags |= fUseGammaCorrectDistanceTable ? kGammaCorrect_DistanceFieldEffectFlag : 0; 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags |= (kAliasedDistanceField_MaskType == fMaskType) 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? kAliased_DistanceFieldEffectFlag 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : 0; 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (isLCD) { 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags |= kUseLCD_DistanceFieldEffectFlag; 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags |= 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (kLCDBGRDistanceField_MaskType == fMaskType) ? kBGR_DistanceFieldEffectFlag : 0; 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkString GrAtlasTextOp::dumpInfo() const { 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString str; 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fGeoCount; ++i) { 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendf("%d: Color: 0x%08x Trans: %.2f,%.2f Runs: %d\n", 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot i, 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoData[i].fColor, 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoData[i].fX, 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoData[i].fY, 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoData[i].fBlob->runCount()); 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str += fProcessors.dumpProcessors(); 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str += INHERITED::dumpInfo(); 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return str; 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrDrawOp::FixedFunctionFlags GrAtlasTextOp::fixedFunctionFlags() const { 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return FixedFunctionFlags::kNone; 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrDrawOp::RequiresDstTexture GrAtlasTextOp::finalize(const GrCaps& caps, 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrAppliedClip* clip, 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPixelConfigIsClamped dstIsClamped) { 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProcessorAnalysisCoverage coverage; 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProcessorAnalysisColor color; 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kColorBitmapMask_MaskType == fMaskType) { 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot color.setToUnknown(); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot color.setToConstant(this->color()); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (fMaskType) { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kGrayscaleCoverageMask_MaskType: 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kAliasedDistanceField_MaskType: 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kGrayscaleDistanceField_MaskType: 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coverage = GrProcessorAnalysisCoverage::kSingleChannel; 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kLCDCoverageMask_MaskType: 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kLCDDistanceField_MaskType: 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kLCDBGRDistanceField_MaskType: 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coverage = GrProcessorAnalysisCoverage::kLCD; 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kColorBitmapMask_MaskType: 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coverage = GrProcessorAnalysisCoverage::kNone; 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto analysis = fProcessors.finalize(color, coverage, clip, false, caps, dstIsClamped, 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fGeoData[0].fColor); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUsesLocalCoords = analysis.usesLocalCoords(); 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCanCombineOnTouchOrOverlap = 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot !analysis.requiresDstTexture() && 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot !(fProcessors.xferProcessor() && fProcessors.xferProcessor()->xferBarrierType(caps)); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return analysis.requiresDstTexture() ? RequiresDstTexture::kYes : RequiresDstTexture::kNo; 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void clip_quads(const SkIRect& clipRect, char* currVertex, const char* blobVertices, 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t vertexStride, int glyphCount) { 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < glyphCount; ++i) { 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint* blobPositionLT = reinterpret_cast<const SkPoint*>(blobVertices); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint* blobPositionRB = 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot reinterpret_cast<const SkPoint*>(blobVertices + 3 * vertexStride); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // positions for bitmap glyphs are pixel boundary aligned 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect positionRect = SkIRect::MakeLTRB(SkScalarRoundToInt(blobPositionLT->fX), 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarRoundToInt(blobPositionLT->fY), 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarRoundToInt(blobPositionRB->fX), 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarRoundToInt(blobPositionRB->fY)); 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (clipRect.contains(positionRect)) { 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memcpy(currVertex, blobVertices, 4 * vertexStride); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currVertex += 4 * vertexStride; 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Pull out some more data that we'll need. 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // In the LCD case the color will be garbage, but we'll overwrite it with the texcoords 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // and it avoids a lot of conditionals. 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto color = *reinterpret_cast<const SkColor*>(blobVertices + sizeof(SkPoint)); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t coordOffset = vertexStride - 2*sizeof(uint16_t); 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto* blobCoordsLT = reinterpret_cast<const uint16_t*>(blobVertices + coordOffset); 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto* blobCoordsRB = reinterpret_cast<const uint16_t*>(blobVertices + 3 * vertexStride + 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordOffset); 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Pull out the texel coordinates and texture index bits 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t coordsRectL = blobCoordsLT[0] >> 1; 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t coordsRectT = blobCoordsLT[1] >> 1; 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t coordsRectR = blobCoordsRB[0] >> 1; 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t coordsRectB = blobCoordsRB[1] >> 1; 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t pageIndexX = blobCoordsLT[0] & 0x1; 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t pageIndexY = blobCoordsLT[1] & 0x1; 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int positionRectWidth = positionRect.width(); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int positionRectHeight = positionRect.height(); 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(positionRectWidth == (coordsRectR - coordsRectL)); 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(positionRectHeight == (coordsRectB - coordsRectT)); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Clip position and texCoords to the clipRect 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int delta; 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delta = SkTMin(SkTMax(clipRect.fLeft - positionRect.fLeft, 0), positionRectWidth); 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectL += delta; 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot positionRect.fLeft += delta; 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delta = SkTMin(SkTMax(clipRect.fTop - positionRect.fTop, 0), positionRectHeight); 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectT += delta; 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot positionRect.fTop += delta; 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delta = SkTMin(SkTMax(positionRect.fRight - clipRect.fRight, 0), positionRectWidth); 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectR -= delta; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot positionRect.fRight -= delta; 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delta = SkTMin(SkTMax(positionRect.fBottom - clipRect.fBottom, 0), positionRectHeight); 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectB -= delta; 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot positionRect.fBottom -= delta; 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Repack texel coordinates and index 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectL = coordsRectL << 1 | pageIndexX; 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectT = coordsRectT << 1 | pageIndexY; 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectR = coordsRectR << 1 | pageIndexX; 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot coordsRectB = coordsRectB << 1 | pageIndexY; 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Set new positions and coords 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint* currPosition = reinterpret_cast<SkPoint*>(currVertex); 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fX = positionRect.fLeft; 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fY = positionRect.fTop; 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *(reinterpret_cast<SkColor*>(currVertex + sizeof(SkPoint))) = color; 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t* currCoords = reinterpret_cast<uint16_t*>(currVertex + coordOffset); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[0] = coordsRectL; 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[1] = coordsRectT; 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currVertex += vertexStride; 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition = reinterpret_cast<SkPoint*>(currVertex); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fX = positionRect.fLeft; 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fY = positionRect.fBottom; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *(reinterpret_cast<SkColor*>(currVertex + sizeof(SkPoint))) = color; 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords = reinterpret_cast<uint16_t*>(currVertex + coordOffset); 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[0] = coordsRectL; 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[1] = coordsRectB; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currVertex += vertexStride; 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition = reinterpret_cast<SkPoint*>(currVertex); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fX = positionRect.fRight; 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fY = positionRect.fTop; 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *(reinterpret_cast<SkColor*>(currVertex + sizeof(SkPoint))) = color; 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords = reinterpret_cast<uint16_t*>(currVertex + coordOffset); 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[0] = coordsRectR; 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[1] = coordsRectT; 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currVertex += vertexStride; 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition = reinterpret_cast<SkPoint*>(currVertex); 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fX = positionRect.fRight; 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currPosition->fY = positionRect.fBottom; 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *(reinterpret_cast<SkColor*>(currVertex + sizeof(SkPoint))) = color; 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords = reinterpret_cast<uint16_t*>(currVertex + coordOffset); 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[0] = coordsRectR; 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currCoords[1] = coordsRectB; 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currVertex += vertexStride; 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blobVertices += 4 * vertexStride; 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrAtlasTextOp::onPrepareDraws(Target* target) { 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix. 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO actually only invert if we don't have RGBA 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix localMatrix; 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesLocalCoords() && !fGeoData[0].fViewMatrix.invert(&localMatrix)) { 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Cannot invert viewmatrix\n"); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrMaskFormat maskFormat = this->maskFormat(); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t atlasPageCount = fFontCache->getAtlasPageCount(maskFormat); 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(maskFormat); 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!atlasPageCount || !proxies[0]) { 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Could not allocate backing texture for atlas\n"); 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FlushInfo flushInfo; 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fPipeline = 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot target->makePipeline(fSRGBFlags, std::move(fProcessors), target->detachAppliedClip()); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(bool dfPerspective = false); 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesDistanceFields()) { 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fGeometryProcessor = this->setupDfProcessor(); 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(dfPerspective = fGeoData[0].fViewMatrix.hasPerspective()); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make( 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->color(), proxies, GrSamplerState::ClampNearest(), maskFormat, 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix, this->usesLocalCoords()); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fGlyphsToFlush = 0; 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t vertexStride = flushInfo.fGeometryProcessor->getVertexStride(); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(vertexStride == GrAtlasTextBlob::GetVertexStride(maskFormat, dfPerspective)); 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int glyphCount = this->numGlyphs(); 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrBuffer* vertexBuffer; 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void* vertices = target->makeVertexSpace( 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vertexStride, glyphCount * kVerticesPerGlyph, &vertexBuffer, &flushInfo.fVertexOffset); 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fIndexBuffer = target->resourceProvider()->refQuadIndexBuffer(); 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!vertices || !flushInfo.fVertexBuffer) { 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Could not allocate vertices\n"); 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char* currVertex = reinterpret_cast<char*>(vertices); 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoGlyphCache glyphCache; 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // each of these is a SubRun 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fGeoCount; i++) { 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const Geometry& args = fGeoData[i]; 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Blob* blob = args.fBlob; 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAtlasTextBlob::VertexRegenerator regenerator( 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blob, args.fRun, args.fSubRun, args.fViewMatrix, args.fX, args.fY, args.fColor, 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot target->deferredUploadTarget(), fFontCache, &glyphCache); 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAtlasTextBlob::VertexRegenerator::Result result; 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot do { 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result = regenerator.regenerate(); 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Copy regenerated vertices from the blob to our vertex buffer. 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t vertexBytes = result.fGlyphsRegenerated * kVerticesPerGlyph * vertexStride; 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (args.fClipRect.isEmpty()) { 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memcpy(currVertex, result.fFirstVertex, vertexBytes); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!dfPerspective); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clip_quads(args.fClipRect, currVertex, result.fFirstVertex, vertexStride, 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result.fGlyphsRegenerated); 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesDistanceFields() && !args.fViewMatrix.isIdentity()) { 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We always do the distance field view matrix transformation after copying rather 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // than during blob vertex generation time in the blob as handling successive 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // arbitrary transformations would be complicated and accumulate error. 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (args.fViewMatrix.hasPerspective()) { 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto* pos = reinterpret_cast<SkPoint3*>(currVertex); 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrixPriv::MapHomogeneousPointsWithStride( 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fViewMatrix, pos, vertexStride, pos, vertexStride, 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result.fGlyphsRegenerated * kVerticesPerGlyph); 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto* pos = reinterpret_cast<SkPoint*>(currVertex); 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrixPriv::MapPointsWithStride( 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fViewMatrix, pos, vertexStride, 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result.fGlyphsRegenerated * kVerticesPerGlyph); 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo.fGlyphsToFlush += result.fGlyphsRegenerated; 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!result.fFinished) { 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->flush(target, &flushInfo); 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currVertex += vertexBytes; 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } while (!result.fFinished); 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->flush(target, &flushInfo); 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const { 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGeometryProcessor* gp = flushInfo->fGeometryProcessor.get(); 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrMaskFormat maskFormat = this->maskFormat(); 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (gp->numTextureSamplers() != (int)fFontCache->getAtlasPageCount(maskFormat)) { 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // During preparation the number of atlas pages has increased. 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Update the proxies used in the GP to match. 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesDistanceFields()) { 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->isLCD()) { 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot reinterpret_cast<GrDistanceFieldLCDTextGeoProc*>(gp)->addNewProxies( 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFontCache->getProxies(maskFormat), GrSamplerState::ClampBilerp()); 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot reinterpret_cast<GrDistanceFieldA8TextGeoProc*>(gp)->addNewProxies( 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFontCache->getProxies(maskFormat), GrSamplerState::ClampBilerp()); 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot reinterpret_cast<GrBitmapTextGeoProc*>(gp)->addNewProxies( 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFontCache->getProxies(maskFormat), GrSamplerState::ClampNearest()); 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrMesh mesh(GrPrimitiveType::kTriangles); 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int maxGlyphsPerDraw = 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6); 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph, 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo->fGlyphsToFlush, maxGlyphsPerDraw); 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset); 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot target->draw(flushInfo->fGeometryProcessor.get(), flushInfo->fPipeline, mesh); 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush; 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flushInfo->fGlyphsToFlush = 0; 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrAtlasTextOp* that = t->cast<GrAtlasTextOp>(); 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fProcessors != that->fProcessors) { 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fCanCombineOnTouchOrOverlap && GrRectsTouchOrOverlap(this->bounds(), that->bounds())) { 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fMaskType != that->fMaskType) { 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& thisFirstMatrix = fGeoData[0].fViewMatrix; 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& thatFirstMatrix = that->fGeoData[0].fViewMatrix; 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesLocalCoords() && !thisFirstMatrix.cheapEqualTo(thatFirstMatrix)) { 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesDistanceFields()) { 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDFGPFlags != that->fDFGPFlags) { 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fLuminanceColor != that->fLuminanceColor) { 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->color()) { 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Keep the batch vertex buffer size below 32K so we don't have to create a special one 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We use the largest possible vertex size for this 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const int kVertexSize = sizeof(SkPoint) + sizeof(SkColor) + 2 * sizeof(uint16_t); 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const int kMaxGlyphs = 32768 / (kVerticesPerGlyph * kVertexSize); 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->fNumGlyphs + that->fNumGlyphs > kMaxGlyphs) { 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNumGlyphs += that->numGlyphs(); 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Reallocate space for geo data if necessary and then import that geo's data. 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int newGeoCount = that->fGeoCount + fGeoCount; 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We reallocate at a rate of 1.5x to try to get better total memory usage 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (newGeoCount > fGeoDataAllocSize) { 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int newAllocSize = fGeoDataAllocSize + fGeoDataAllocSize / 2; 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (newAllocSize < newGeoCount) { 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newAllocSize += newAllocSize / 2; 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoData.realloc(newAllocSize); 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoDataAllocSize = newAllocSize; 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We steal the ref on the blobs from the other AtlasTextOp and set its count to 0 so that 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // it doesn't try to unref them. 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memcpy(&fGeoData[fGeoCount], that->fGeoData.get(), that->fGeoCount * sizeof(Geometry)); 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < that->fGeoCount; ++i) { 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that->fGeoData.get()[i].fBlob = (Blob*)0x1; 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot that->fGeoCount = 0; 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGeoCount = newGeoCount; 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->joinBounds(*that); 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// TODO trying to figure out why lcd is so whack 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// (see comments in GrAtlasTextContext::ComputeCanonicalColor) 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor() const { 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const sk_sp<GrTextureProxy>* p = fFontCache->getProxies(this->maskFormat()); 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool isLCD = this->isLCD(); 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix localMatrix = SkMatrix::I(); 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->usesLocalCoords()) { 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If this fails we'll just use I(). 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool result = fGeoData[0].fViewMatrix.invert(&localMatrix); 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (void)result; 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // see if we need to create a new effect 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (isLCD) { 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float redCorrection = fDistanceAdjustTable->getAdjustment( 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColorGetR(fLuminanceColor) >> kDistanceAdjustLumShift, 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUseGammaCorrectDistanceTable); 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float greenCorrection = fDistanceAdjustTable->getAdjustment( 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColorGetG(fLuminanceColor) >> kDistanceAdjustLumShift, 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUseGammaCorrectDistanceTable); 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float blueCorrection = fDistanceAdjustTable->getAdjustment( 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColorGetB(fLuminanceColor) >> kDistanceAdjustLumShift, 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUseGammaCorrectDistanceTable); 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust = 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make( 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot redCorrection, greenCorrection, blueCorrection); 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrDistanceFieldLCDTextGeoProc::Make(p, GrSamplerState::ClampBilerp(), widthAdjust, 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags, localMatrix); 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_GAMMA_APPLY_TO_A8 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float correction = 0; 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kAliasedDistanceField_MaskType != fMaskType) { 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot U8CPU lum = SkColorSpaceLuminance::computeLuminance(SK_GAMMA_EXPONENT, 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLuminanceColor); 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot correction = fDistanceAdjustTable->getAdjustment(lum >> kDistanceAdjustLumShift, 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUseGammaCorrectDistanceTable); 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrDistanceFieldA8TextGeoProc::Make(p, GrSamplerState::ClampBilerp(), 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot correction, fDFGPFlags, localMatrix); 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrDistanceFieldA8TextGeoProc::Make(p, GrSamplerState::ClampBilerp(), 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fDFGPFlags, localMatrix); 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 456