diff options
author | 2017-03-30 18:22:27 -0400 | |
---|---|---|
committer | 2017-04-04 15:43:12 -0400 | |
commit | 0b58d9928309e2c64c7cafad287e55a8151ab19a (patch) | |
tree | 9b698e70c4dda4dcdf0c1aabe03deae6774363d3 /libs/hwui/SkiaCanvasProxy.cpp | |
parent | 7ead6c4da9e73a485965070903277dae90210c2d (diff) |
Optimize Canvas::drawGlyphs
Avoid one memcpy in Canvas::drawGlyphs for all pipelines.
Test: CTS passed with exception of SweepTests#testBasicDraws
shadowtext, which fails with and without this CL.
Change-Id: I0841232dc7a6173eb3b03f939dbde15a84186296
Diffstat (limited to 'libs/hwui/SkiaCanvasProxy.cpp')
-rw-r--r-- | libs/hwui/SkiaCanvasProxy.cpp | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp index f6e92dca2bb9..5b0f82de06be 100644 --- a/libs/hwui/SkiaCanvasProxy.cpp +++ b/libs/hwui/SkiaCanvasProxy.cpp @@ -286,7 +286,6 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x GlyphIDConverter glyphs(text, byteLength, origPaint); // compute the glyph positions - std::unique_ptr<SkPoint[]> pointStorage(new SkPoint[glyphs.count]); std::unique_ptr<SkScalar[]> glyphWidths(new SkScalar[glyphs.count]); glyphs.paint.getTextWidths(glyphs.glyphIDs, glyphs.count << 1, glyphWidths.get()); @@ -320,22 +319,33 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x xBaseline = x; yBaseline = y; } - pointStorage[0].set(xBaseline, yBaseline); - - // setup the remaining glyph positions - if (glyphs.paint.isVerticalText()) { - for (int i = 1; i < glyphs.count; i++) { - pointStorage[i].set(xBaseline, glyphWidths[i-1] + pointStorage[i-1].fY); - } - } else { - for (int i = 1; i < glyphs.count; i++) { - pointStorage[i].set(glyphWidths[i-1] + pointStorage[i-1].fX, yBaseline); - } - } static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); - mCanvas->drawGlyphs(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint, - x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0); + auto glyphFunc = [&] (uint16_t* text, float* positions) { + memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t)); + size_t posIndex = 0; + // setup the first glyph position + positions[posIndex++] = xBaseline; + positions[posIndex++] = yBaseline; + // setup the remaining glyph positions + if (glyphs.paint.isVerticalText()) { + float yPosition = yBaseline; + for (int i = 1; i < glyphs.count; i++) { + positions[posIndex++] = xBaseline; + yPosition += glyphWidths[i-1]; + positions[posIndex++] = yPosition; + } + } else { + float xPosition = xBaseline; + for (int i = 1; i < glyphs.count; i++) { + xPosition += glyphWidths[i-1]; + positions[posIndex++] = xPosition; + positions[posIndex++] = yBaseline; + } + } + }; + mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, + bounds.fRight, bounds.fBottom, 0); } void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], @@ -345,21 +355,12 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S // convert to relative positions if necessary int x, y; - const SkPoint* posArray; - std::unique_ptr<SkPoint[]> pointStorage; if (mCanvas->drawTextAbsolutePos()) { x = 0; y = 0; - posArray = pos; } else { x = pos[0].fX; y = pos[0].fY; - pointStorage.reset(new SkPoint[glyphs.count]); - for (int i = 0; i < glyphs.count; i++) { - pointStorage[i].fX = pos[i].fX - x; - pointStorage[i].fY = pos[i].fY - y; - } - posArray = pointStorage.get(); } // Compute conservative bounds. If the content has already been processed @@ -375,8 +376,19 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S } static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats"); - mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y, - bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0); + auto glyphFunc = [&] (uint16_t* text, float* positions) { + memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t)); + if (mCanvas->drawTextAbsolutePos()) { + memcpy(positions, pos, 2*glyphs.count*sizeof(float)); + } else { + for (int i = 0, posIndex = 0; i < glyphs.count; i++) { + positions[posIndex++] = pos[i].fX - x; + positions[posIndex++] = pos[i].fY - y; + } + } + }; + mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, + bounds.fRight, bounds.fBottom, 0); } void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], |