158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/*
258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Copyright 2013 Google Inc.
358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *
458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * found in the LICENSE file.
658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */
758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkBenchmark.h"
958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkCanvas.h"
1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkPaint.h"
1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTypeface.h"
1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerenum {
1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    LOOP = SkBENCHLOOP(1000),
1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    NGLYPHS = 100
1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger};
1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic SkTypeface::Encoding paint2Encoding(const SkPaint& paint) {
1958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint::TextEncoding enc = paint.getTextEncoding();
2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkASSERT(SkPaint::kGlyphID_TextEncoding != enc);
2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return (SkTypeface::Encoding)enc;
2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergertypedef void (*TypefaceProc)(const SkPaint&, const void* text, size_t len,
2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                             int glyphCount);
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void containsText_proc(const SkPaint& paint, const void* text, size_t len,
2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              int glyphCount) {
2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for (int i = 0; i < LOOP; ++i) {
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        paint.containsText(text, len);
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void textToGlyphs_proc(const SkPaint& paint, const void* text, size_t len,
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              int glyphCount) {
3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    uint16_t glyphs[NGLYPHS];
3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkASSERT(glyphCount <= NGLYPHS);
3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for (int i = 0; i < LOOP; ++i) {
4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        paint.textToGlyphs(text, len, glyphs);
4158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void charsToGlyphs_proc(const SkPaint& paint, const void* text,
4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                               size_t len, int glyphCount) {
4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTypeface::Encoding encoding = paint2Encoding(paint);
4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    uint16_t glyphs[NGLYPHS];
4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkASSERT(glyphCount <= NGLYPHS);
4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTypeface* face = paint.getTypeface();
5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for (int i = 0; i < LOOP; ++i) {
5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        face->charsToGlyphs(text, encoding, glyphs, glyphCount);
5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void charsToGlyphsNull_proc(const SkPaint& paint, const void* text,
5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                   size_t len, int glyphCount) {
5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTypeface::Encoding encoding = paint2Encoding(paint);
5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTypeface* face = paint.getTypeface();
6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for (int i = 0; i < LOOP; ++i) {
6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        face->charsToGlyphs(text, encoding, NULL, glyphCount);
6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass CMAPBench : public SkBenchmark {
6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    TypefaceProc fProc;
6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString     fName;
6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    char         fText[NGLYPHS];
7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint      fPaint;
7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerpublic:
7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    CMAPBench(void* param, TypefaceProc proc, const char name[]) : SkBenchmark(param) {
7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fProc = proc;
7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fName.printf("cmap_%s", name);
7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        for (int i = 0; i < NGLYPHS; ++i) {
7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            // we're jamming values into utf8, so we must keep it legal utf8
7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            fText[i] = 'A' + (i & 31);
8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        }
8158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fPaint.setTypeface(SkTypeface::RefDefault())->unref();
8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprotected:
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual const char* onGetName() SK_OVERRIDE {
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return fName.c_str();
8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fProc(fPaint, fText, sizeof(fText), NGLYPHS);
9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprivate:
9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    typedef SkBenchmark INHERITED;
9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger};
9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger//////////////////////////////////////////////////////////////////////////////
9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEF_BENCH( return new CMAPBench(p, containsText_proc, "paint_containsText"); )
10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEF_BENCH( return new CMAPBench(p, textToGlyphs_proc, "paint_textToGlyphs"); )
10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEF_BENCH( return new CMAPBench(p, charsToGlyphs_proc, "face_charsToGlyphs"); )
10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEF_BENCH( return new CMAPBench(p, charsToGlyphsNull_proc, "face_charsToGlyphs_null"); )
104