summaryrefslogtreecommitdiff
path: root/libs/hwui/SkiaCanvasProxy.cpp
diff options
context:
space:
mode:
author Stan Iliev <stani@google.com> 2017-03-30 18:22:27 -0400
committer Stan Iliev <stani@google.com> 2017-04-04 15:43:12 -0400
commit0b58d9928309e2c64c7cafad287e55a8151ab19a (patch)
tree9b698e70c4dda4dcdf0c1aabe03deae6774363d3 /libs/hwui/SkiaCanvasProxy.cpp
parent7ead6c4da9e73a485965070903277dae90210c2d (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.cpp64
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[],