bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps& caps, const SkRect& thisBounds, const SkRect& thatBounds) const { if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) { return false; } if (fProcessors) { if (*fProcessors != *that.fProcessors) { return false; } if (fRequiresDstTexture || (fProcessors->xferProcessor() && fProcessors->xferProcessor()->xferBarrierType(caps))) { if (GrRectsTouchOrOverlap(thisBounds, thatBounds)) { return false; } } } bool result = fPipelineFlags == that.fPipelineFlags && fAAType == that.fAAType; SkASSERT(!result || fCompatibleWithAlphaAsCoveage == that.fCompatibleWithAlphaAsCoveage); SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords); return result; }
GrOp::CombineResult GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { GrAtlasTextOp* that = t->cast<GrAtlasTextOp>(); if (fProcessors != that->fProcessors) { return CombineResult::kCannotCombine; } if (!fCanCombineOnTouchOrOverlap && GrRectsTouchOrOverlap(this->bounds(), that->bounds())) { return CombineResult::kCannotCombine; } if (fMaskType != that->fMaskType) { return CombineResult::kCannotCombine; } const SkMatrix& thisFirstMatrix = fGeoData[0].fViewMatrix; const SkMatrix& thatFirstMatrix = that->fGeoData[0].fViewMatrix; if (this->usesLocalCoords() && !thisFirstMatrix.cheapEqualTo(thatFirstMatrix)) { return CombineResult::kCannotCombine; } if (fNeedsGlyphTransform != that->fNeedsGlyphTransform) { return CombineResult::kCannotCombine; } if (fNeedsGlyphTransform && (thisFirstMatrix.hasPerspective() != thatFirstMatrix.hasPerspective())) { return CombineResult::kCannotCombine; } if (this->usesDistanceFields()) { if (fDFGPFlags != that->fDFGPFlags) { return CombineResult::kCannotCombine; } if (fLuminanceColor != that->fLuminanceColor) { return CombineResult::kCannotCombine; } } else { if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->color()) { return CombineResult::kCannotCombine; } } // Keep the batch vertex buffer size below 32K so we don't have to create a special one // We use the largest possible vertex size for this static const int kVertexSize = sizeof(SkPoint) + sizeof(SkColor) + 2 * sizeof(uint16_t); static const int kMaxGlyphs = 32768 / (kVerticesPerGlyph * kVertexSize); if (this->fNumGlyphs + that->fNumGlyphs > kMaxGlyphs) { return CombineResult::kCannotCombine; } fNumGlyphs += that->numGlyphs(); // Reallocate space for geo data if necessary and then import that geo's data. int newGeoCount = that->fGeoCount + fGeoCount; // We reallocate at a rate of 1.5x to try to get better total memory usage if (newGeoCount > fGeoDataAllocSize) { int newAllocSize = fGeoDataAllocSize + fGeoDataAllocSize / 2; while (newAllocSize < newGeoCount) { newAllocSize += newAllocSize / 2; } fGeoData.realloc(newAllocSize); fGeoDataAllocSize = newAllocSize; } // We steal the ref on the blobs from the other AtlasTextOp and set its count to 0 so that // it doesn't try to unref them. memcpy(&fGeoData[fGeoCount], that->fGeoData.get(), that->fGeoCount * sizeof(Geometry)); #ifdef SK_DEBUG for (int i = 0; i < that->fGeoCount; ++i) { that->fGeoData.get()[i].fBlob = (Blob*)0x1; } #endif that->fGeoCount = 0; fGeoCount = newGeoCount; this->joinBounds(*that); return CombineResult::kMerged; }