Fixed memory leak for nanobench and crashing in SampleApp
authordandov <dandov@google.com>
Fri, 15 Aug 2014 13:06:47 +0000 (06:06 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 15 Aug 2014 13:06:47 +0000 (06:06 -0700)
NOTREECHECKS=True

BUG=skia:2830
R=mtklein@google.com, egdaniel@google.com

Author: dandov@google.com

Review URL: https://codereview.chromium.org/469333002

src/core/SkDevice.cpp
src/utils/SkPatchUtils.cpp

index 50755c9..f4ae7b1 100644 (file)
@@ -86,10 +86,12 @@ void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const
     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) {
index d120195..a0be328 100644 (file)
@@ -204,11 +204,28 @@ bool SkPatchUtils::getVertexData(SkPatchUtils::VertexData* data, const SkPoint c
     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);