SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
// It automatically adjusts lodX and lodY in case it exceeds the number of indices.
- SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height());
- this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
- data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
- paint);
+ // If it fails to generate the vertices, then we do not draw.
+ if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
+ this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
+ data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
+ paint);
+ }
}
bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
if (lodX < 1 || lodY < 1 || NULL == cubics || NULL == data) {
return false;
}
-
- // number of indices is limited by size of uint16_t, so we clamp it to avoid overflow
- data->fVertexCount = SkMin32((lodX + 1) * (lodY + 1), 65536);
- lodX = SkMin32(lodX, 255);
- lodY = SkMin32(lodY, 255);
+
+ // check for overflow in multiplication
+ const int64_t lodX64 = (lodX + 1),
+ lodY64 = (lodY + 1),
+ mult64 = lodX64 * lodY64;
+ if (mult64 > SK_MaxS32) {
+ return false;
+ }
+ data->fVertexCount = SkToS32(mult64);
+
+ // it is recommended to generate draw calls of no more than 65536 indices, so we never generate
+ // more than 60000 indices. To accomplish that we resize the LOD and vertex count
+ if (data->fVertexCount > 10000 || lodX > 200 || lodY > 200) {
+ SkScalar weightX = static_cast<SkScalar>(lodX) / (lodX + lodY);
+ SkScalar weightY = static_cast<SkScalar>(lodY) / (lodX + lodY);
+
+ // 200 comes from the 100 * 2 which is the max value of vertices because of the limit of
+ // 60000 indices ( sqrt(60000 / 6) that comes from data->fIndexCount = lodX * lodY * 6)
+ lodX = static_cast<int>(weightX * 200);
+ lodY = static_cast<int>(weightY * 200);
+ data->fVertexCount = (lodX + 1) * (lodY + 1);
+ }
data->fIndexCount = lodX * lodY * 6;
data->fPoints = SkNEW_ARRAY(SkPoint, data->fVertexCount);