aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2019-05-13 15:39:09 -0700
committerXin Li <delphij@google.com>2019-05-13 15:39:09 -0700
commit4d18e943e9b80dd4f19fcecd36eb9bf8c4f7bd9e (patch)
treee7872568520482f28a6ee8b610dc223a1f39e3cf
parent615e6b4634c6ae6ddf5ac6e5f44647cdb5f6b838 (diff)
parent8dd03c05b0e815ac308188cd6d92794f58973417 (diff)
downloadskia-temp_b_132622481_stage-aosp-master.tar.gz
DO NOT MERGE - Merge pi-platform-release (PPRL.190505.001) into stage-aosp-mastertemp_b_132622481_stage-aosp-master
Bug: 132622481 Change-Id: Ic50c50d684568ad3a24b11c082cc2ec42e541f83
-rw-r--r--gm/fontregen.cpp118
-rw-r--r--gn/gm.gni1
-rw-r--r--src/gpu/GrDrawOpAtlas.cpp5
-rw-r--r--src/gpu/GrDrawOpAtlas.h8
-rw-r--r--src/gpu/text/GrAtlasManager.cpp5
-rw-r--r--src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp5
6 files changed, 134 insertions, 8 deletions
diff --git a/gm/fontregen.cpp b/gm/fontregen.cpp
new file mode 100644
index 0000000000..3d7dbee387
--- /dev/null
+++ b/gm/fontregen.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// GM to stress TextBlob regeneration and the GPU font cache
+// It's not necessary to run this with CPU configs
+//
+// The point here is to draw a set of text that will fit in one Plot, and then some large
+// text. After a flush we draw the first set of text again with a slightly different color,
+// and then enough new large text to spill the entire atlas. What *should* happen is that
+// the Plot with the first set of text will not get overwritten by the new large text.
+
+#include "gm.h"
+
+#include "GrContext.h"
+#include "GrContextPriv.h"
+#include "GrContextOptions.h"
+#include "SkCanvas.h"
+#include "SkGraphics.h"
+#include "SkImage.h"
+#include "SkTypeface.h"
+#include "gm.h"
+
+#include "sk_tool_utils.h"
+
+static sk_sp<SkTextBlob> make_blob(const SkString& text, const SkFont& font) {
+ size_t len = text.size();
+ SkAutoTArray<SkScalar> pos(len);
+ SkAutoTArray<SkGlyphID> glyphs(len);
+
+ font.textToGlyphs(text.c_str(), len, SkTextEncoding::kUTF8, glyphs.get(), len);
+ font.getXPos(glyphs.get(), len, pos.get());
+ return SkTextBlob::MakeFromPosTextH(text.c_str(), len, pos.get(), 0, font);
+}
+
+class FontRegenGM : public skiagm::GM {
+public:
+ FontRegenGM() {
+ this->setBGColor(SK_ColorLTGRAY);
+ }
+
+ void modifyGrContextOptions(GrContextOptions* options) override {
+ options->fGlyphCacheTextureMaximumBytes = 0;
+ options->fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo;
+ }
+
+protected:
+ SkString onShortName() override {
+ SkString name("fontregen");
+ return name;
+ }
+
+ SkISize onISize() override { return SkISize::Make(kSize, kSize); }
+
+ void onOnceBeforeDraw() override {
+ auto tf = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Normal());
+
+ static const SkString kTexts[] = {
+ SkString("abcdefghijklmnopqrstuvwxyz"),
+ SkString("ABCDEFGHI"),
+ SkString("NOPQRSTUV")
+ };
+
+ SkFont font;
+ font.setEdging(SkFont::Edging::kAntiAlias);
+ font.setSubpixel(false);
+ font.setSize(80);
+ font.setTypeface(tf);
+
+ fBlobs[0] = make_blob(kTexts[0], font);
+ font.setSize(162);
+ fBlobs[1] = make_blob(kTexts[1], font);
+ fBlobs[2] = make_blob(kTexts[2], font);
+ }
+
+ void onDraw(SkCanvas* canvas) override {
+ GrRenderTargetContext* renderTargetContext =
+ canvas->internal_private_accessTopLayerRenderTargetContext();
+ if (!renderTargetContext) {
+ skiagm::GM::DrawGpuOnlyMessage(canvas);
+ return;
+ }
+
+ SkPaint paint;
+ paint.setColor(SK_ColorBLACK);
+ canvas->drawTextBlob(fBlobs[0], 10, 80, paint);
+ canvas->drawTextBlob(fBlobs[1], 10, 225, paint);
+ canvas->flush();
+
+ paint.setColor(0xFF010101);
+ canvas->drawTextBlob(fBlobs[0], 10, 305, paint);
+ canvas->drawTextBlob(fBlobs[2], 10, 465, paint);
+
+ // Debugging tool for GPU.
+ static const bool kShowAtlas = false;
+ if (kShowAtlas) {
+ if (auto ctx = canvas->getGrContext()) {
+ auto img = ctx->contextPriv().getFontAtlasImage_ForTesting(kA8_GrMaskFormat);
+ canvas->drawImage(img, 200, 0);
+ }
+ }
+ }
+
+private:
+ static constexpr SkScalar kSize = 512;
+
+ sk_sp<SkTextBlob> fBlobs[3];
+ typedef GM INHERITED;
+};
+
+constexpr SkScalar FontRegenGM::kSize;
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return new FontRegenGM())
diff --git a/gn/gm.gni b/gn/gm.gni
index bd5593973f..9b2eb848f6 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -138,6 +138,7 @@ gm_sources = [
"$_gm/flippity.cpp",
"$_gm/fontcache.cpp",
"$_gm/fontmgr.cpp",
+ "$_gm/fontregen.cpp",
"$_gm/fontscaler.cpp",
"$_gm/fontscalerdistortable.cpp",
"$_gm/gamma.cpp",
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 56dfcef56d..4e3c8b7e11 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -271,9 +271,8 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider,
for (unsigned int pageIdx = 0; pageIdx < fNumActivePages; ++pageIdx) {
Plot* plot = fPages[pageIdx].fPlotList.tail();
SkASSERT(plot);
- if ((fNumActivePages == this->maxPages() &&
- plot->lastUseToken() < target->tokenTracker()->nextTokenToFlush()) ||
- plot->flushesSinceLastUsed() >= kRecentlyUsedCount) {
+ if (fNumActivePages == this->maxPages() &&
+ plot->lastUseToken() < target->tokenTracker()->nextTokenToFlush()) {
this->processEvictionAndResetRects(plot);
SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index b849d9e067..4178f478a6 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -162,12 +162,14 @@ public:
memcpy(fPlotAlreadyUpdated, that.fPlotAlreadyUpdated, sizeof(fPlotAlreadyUpdated));
}
- void add(AtlasID id) {
+ bool add(AtlasID id) {
int index = GrDrawOpAtlas::GetPlotIndexFromID(id);
int pageIdx = GrDrawOpAtlas::GetPageIndexFromID(id);
- if (!this->find(pageIdx, index)) {
- this->set(pageIdx, index);
+ if (this->find(pageIdx, index)) {
+ return false;
}
+ this->set(pageIdx, index);
+ return true;
}
void reset() {
diff --git a/src/gpu/text/GrAtlasManager.cpp b/src/gpu/text/GrAtlasManager.cpp
index c6a60567e6..a135235429 100644
--- a/src/gpu/text/GrAtlasManager.cpp
+++ b/src/gpu/text/GrAtlasManager.cpp
@@ -108,8 +108,9 @@ void GrAtlasManager::addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpd
GrGlyph* glyph,
GrDeferredUploadToken token) {
SkASSERT(glyph);
- updater->add(glyph->fID);
- this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token);
+ if (updater->add(glyph->fID)) {
+ this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token);
+ }
}
#ifdef SK_DEBUG
diff --git a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
index f574d6f046..578556cd40 100644
--- a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
+++ b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
@@ -307,6 +307,11 @@ Regenerator::Result Regenerator::doRegen() {
fSubRun->setAtlasGeneration(fBrokenRun
? GrDrawOpAtlas::kInvalidAtlasGeneration
: fFullAtlasManager->atlasGeneration(fSubRun->maskFormat()));
+ } else {
+ // For the non-texCoords case we need to ensure that we update the associated use tokens
+ fFullAtlasManager->setUseTokenBulk(*fSubRun->bulkUseToken(),
+ fUploadTarget->tokenTracker()->nextDrawToken(),
+ fSubRun->maskFormat());
}
return result;
}