Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d64a418 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Optimize Canvas::drawGlyphs"

parents f4628d92 0b58d992
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -540,12 +540,13 @@ void RecordingCanvas::drawNinePatch(Bitmap& bitmap, const android::Res_png_9patc
}

// Text
void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
            float boundsRight, float boundsBottom, float totalAdvance) {
    if (!glyphs || !positions || glyphCount <= 0 || paint.nothingToDraw()) return;
    glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
    positions = refBuffer<float>(positions, glyphCount * 2);
void RecordingCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int glyphCount, const SkPaint& paint,
        float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
        float totalAdvance) {
    if (glyphCount <= 0 || paint.nothingToDraw()) return;
    uint16_t* glyphs = (glyph_t*)alloc().alloc<glyph_t>(glyphCount * sizeof(glyph_t));
    float* positions = (float*)alloc().alloc<float>(2 * glyphCount * sizeof(float));
    glyphFunc(glyphs, positions);

    // TODO: either must account for text shadow in bounds, or record separate ops for text shadows
    addOp(alloc().create_trivial<TextOp>(
+2 −3
Original line number Diff line number Diff line
@@ -191,9 +191,8 @@ public:
    virtual bool drawTextAbsolutePos() const override { return false; }

protected:
    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
            const SkPaint& paint, float x, float y,
            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
            float totalAdvance) override;
    virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
            const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;
+4 −8
Original line number Diff line number Diff line
@@ -679,11 +679,10 @@ void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) {
// Canvas draw operations: Text
// ----------------------------------------------------------------------------

void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int count,
        const SkPaint& paint, float x, float y,
        float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
        float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
        float totalAdvance) {
     if (!text || !positions || count <= 0 || paint.nothingToDraw()) return;
    if (count <= 0 || paint.nothingToDraw()) return;
    // Set align to left for drawing, as we don't want individual
    // glyphs centered or right-aligned; the offset above takes
    // care of all alignment.
@@ -695,10 +694,7 @@ void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int co

    SkTextBlobBuilder builder;
    const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(paintCopy, count, &bounds);
    // TODO: we could reduce the number of memcpy's if the this were exposed further up
    //       in the architecture.
    memcpy(buffer.glyphs, text, count * sizeof(uint16_t));
    memcpy(buffer.pos, positions, (count << 1) * sizeof(float));
    glyphFunc(buffer.glyphs, buffer.pos);

    sk_sp<SkTextBlob> textBlob(builder.make());
    mCanvas->drawTextBlob(textBlob, 0, 0, paintCopy);
+2 −3
Original line number Diff line number Diff line
@@ -153,9 +153,8 @@ protected:
    void reset(SkCanvas* skiaCanvas);
    void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }

    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
            const SkPaint& paint, float x, float y,
            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
            float totalAdvance) override;
    virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
            const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;
+38 −26
Original line number Diff line number Diff line
@@ -288,7 +288,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());

@@ -322,22 +321,33 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x
        xBaseline = x;
        yBaseline = y;
    }
    pointStorage[0].set(xBaseline, yBaseline);

    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
    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++) {
            pointStorage[i].set(xBaseline, glyphWidths[i-1] + pointStorage[i-1].fY);
                positions[posIndex++] = xBaseline;
                yPosition += glyphWidths[i-1];
                positions[posIndex++] = yPosition;
            }
        } else {
            float xPosition = xBaseline;
            for (int i = 1; i < glyphs.count; i++) {
            pointStorage[i].set(glyphWidths[i-1] + pointStorage[i-1].fX, yBaseline);
                xPosition += glyphWidths[i-1];
                positions[posIndex++] = xPosition;
                positions[posIndex++] = 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);
    };
    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[],
@@ -347,21 +357,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
@@ -377,8 +378,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[],
Loading