From bd3055f95e67a55648fd84a125e939293115171b Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 13 Mar 2013 16:14:47 -0700 Subject: [PATCH] Less aggressive glyphs precaching The renderer used to pre-cache glyphs at record time. This then changed to pre-caching at the beginning of every frame. This unfortunately entails a lot of duplicate work on every frame, which amounts to 0.5 to 1ms in some stock applications. This change is somewhere in the middle: pre-caching happens the first time a DrawTextOp is deferred or every time the screen-space transform is different from the last pre-caching operation. Change-Id: Id6d9e2599d90a5b75010b0f0a28746befbf3c205 --- libs/hwui/DisplayListOp.h | 10 +++++++--- libs/hwui/Matrix.h | 8 ++++++++ libs/hwui/font/Font.cpp | 14 +++++++------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 105f45f7f27b4..4e6b5525a9145 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1169,6 +1169,7 @@ public: break; } mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom); + memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float)); } /* @@ -1179,9 +1180,11 @@ public: virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { SkPaint* paint = getPaint(renderer); FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); - const bool pureTranslate = state.mMatrix.isPureTranslate(); - const mat4 transform = renderer.findBestFontTransform(state.mMatrix); - fontRenderer.precache(paint, mText, mCount, transform); + const mat4& transform = renderer.findBestFontTransform(state.mMatrix); + if (mPrecacheTransform != transform) { + fontRenderer.precache(paint, mText, mCount, transform); + mPrecacheTransform = transform; + } } virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, @@ -1210,6 +1213,7 @@ private: float mY; const float* mPositions; float mLength; + mat4 mPrecacheTransform; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index 7b7357edf9634..75e280cf502b9 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -93,6 +93,14 @@ public: return *this; } + friend bool operator==(const Matrix4& a, const Matrix4& b) { + return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float)); + } + + friend bool operator!=(const Matrix4& a, const Matrix4& b) { + return !(a == b); + } + void loadIdentity(); void load(const float* v); diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index c932087fe4c61..02c1aa191e5cd 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -15,10 +15,12 @@ */ #define LOG_TAG "OpenGLRenderer" +#define ATRACE_TAG ATRACE_TAG_VIEW #include #include +#include #include #include @@ -261,11 +263,8 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float } CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching) { - CachedGlyphInfo* cachedGlyph = NULL; - ssize_t index = mCachedGlyphs.indexOfKey(textUnit); - if (index >= 0) { - cachedGlyph = mCachedGlyphs.valueAt(index); - + CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(textUnit); + if (cachedGlyph) { // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit, @@ -346,11 +345,13 @@ void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t le } void Font::precache(SkPaint* paint, const char* text, int numGlyphs) { + ATRACE_NAME("precacheText"); + if (numGlyphs == 0 || text == NULL) { return; } - int glyphsCount = 0; + int glyphsCount = 0; while (glyphsCount < numGlyphs) { glyph_t glyph = GET_GLYPH(text); @@ -360,7 +361,6 @@ void Font::precache(SkPaint* paint, const char* text, int numGlyphs) { } CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph, true); - glyphsCount++; } }