real fix for textblob use after gpu free
authorjoshualitt <joshualitt@chromium.org>
Tue, 26 May 2015 19:32:23 +0000 (12:32 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 26 May 2015 19:32:23 +0000 (12:32 -0700)
This patch addresses two issues:
1) Textblobs with abandoned strikes were not properly regenerating.
2) Provided by ericrk - GrTextBlobCache removed blobs from |fCache| during freeAll, but left
potentially released blobs in the |fBlobList|. We now remove these from
|fBlobList| as well.
BUG=skia:

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

gm/textblobuseaftergpufree.cpp [new file with mode: 0644]
src/gpu/GrAtlasTextContext.cpp
src/gpu/GrCommandBuilder.cpp
src/gpu/GrTextBlobCache.cpp

diff --git a/gm/textblobuseaftergpufree.cpp b/gm/textblobuseaftergpufree.cpp
new file mode 100644 (file)
index 0000000..127e436
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+
+#if SK_SUPPORT_GPU
+
+#include "SkCanvas.h"
+#include "SkSurface.h"
+#include "SkTextBlob.h"
+
+// This tests that we correctly regenerate textblobs after freeing all gpu resources crbug/491350
+namespace skiagm {
+class TextBlobUseAfterGpuFree : public GM {
+public:
+    TextBlobUseAfterGpuFree() { }
+
+protected:
+    SkString onShortName() override {
+        return SkString("textblobuseaftergpufree");
+    }
+
+    SkISize onISize() override {
+        return SkISize::Make(kWidth, kHeight);
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        // This GM exists to test a specific feature of the GPU backend.
+        if (NULL == canvas->getGrContext()) {
+            this->drawGpuOnlyMessage(canvas);
+            return;
+        }
+
+        const char text[] = "Hamburgefons";
+
+        SkPaint paint;
+        sk_tool_utils::set_portable_typeface(&paint);
+        paint.setTextSize(20);
+
+        SkTextBlobBuilder builder;
+
+        sk_tool_utils::add_to_text_blob(&builder, text, paint, 10, 10);
+
+        SkAutoTUnref<const SkTextBlob> blob(builder.build());
+
+        // draw textblob
+        SkRect rect = SkRect::MakeLTRB(0.f, 0.f, SkIntToScalar(kWidth), kHeight / 2.f);
+        SkPaint rectPaint;
+        rectPaint.setColor(0xffffffff);
+        canvas->drawRect(rect, rectPaint);
+        canvas->drawTextBlob(blob.get(), 10, 50, paint);
+
+        // This text should look fine
+        canvas->getGrContext()->freeGpuResources();
+        canvas->drawTextBlob(blob.get(), 10, 150, paint);
+    }
+
+private:
+    static const int kWidth = 200;
+    static const int kHeight = 200;
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM( return SkNEW(TextBlobUseAfterGpuFree); )
+}
+#endif
index 35a9164d098e8cb5719b381fa372e8bbaf620c61..750cb13fc04047d2721a66828101908d2e223eaa 100644 (file)
@@ -1592,7 +1592,8 @@ public:
             TextInfo& info = run.fSubRunInfo[args.fSubRun];
 
             uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat);
-            bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen;
+            bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen ||
+                                           run.fStrike->isAbandoned();
             bool regenerateColors;
             if (fUseDistanceFields) {
                 regenerateColors = !fUseLCDText && run.fColor != args.fColor;
index 6b56dea421dec2c8cbb5a68348016d28182e7a72..28c0cf2bdb5f58f466ea932732322c4ba7175f15 100644 (file)
@@ -33,9 +33,7 @@ GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect* rect,
         rect = &r;
     }
 
-    SkASSERT(color == GrColor_ILLEGAL ||
-             canIgnoreRect ||
-             (rect->fLeft <= rect->fRight && rect->fTop <= rect->fBottom));
+    SkASSERT(canIgnoreRect || (rect->fLeft <= rect->fRight && rect->fTop <= rect->fBottom));
 
     Clear* clr = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), Clear, (renderTarget));
     GrColorIsPMAssert(color);
index d66f432efbe28aa99c2b34a4def141af0d6a2d46..6f171779fc3cdbbb390f18aed573c88bed0ed082 100644 (file)
@@ -42,7 +42,9 @@ GrAtlasTextContext::BitmapTextBlob* GrTextBlobCache::createBlob(int glyphCount,
 void GrTextBlobCache::freeAll() {
     SkTDynamicHash<BitmapTextBlob, BitmapTextBlob::Key>::Iter iter(&fCache);
     while (!iter.done()) {
-        (&(*iter))->unref();
+        BitmapTextBlob* blob = &(*iter);
+        fBlobList.remove(blob);
+        blob->unref();
         ++iter;
     }
     fCache.rewind();