10a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger/*
20a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Copyright 2013 Google Inc.
30a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger *
40a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
50a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * found in the LICENSE file.
60a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */
70a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
80a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "gm.h"
90a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkCanvas.h"
100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkGraphics.h"
110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTypeface.h"
120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// GM to stress the GPU font cache
140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerconst char* gFamilyNames[] = {
160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    "sans-serif", "serif", "monospace"
170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerconst SkTypeface::Style gStyles[] = {
200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTypeface::kNormal, SkTypeface::kItalic
210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerconst SkScalar gTextSizes[] = {
240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    12, 14, 16, 18, 20, 22, 24, 26, 28, 30
250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#define TYPEFACE_COUNT (SK_ARRAY_COUNT(gFamilyNames)*SK_ARRAY_COUNT(gStyles))
280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic SkScalar draw_string(SkCanvas* canvas, const SkString& text, SkScalar x,
300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                           SkScalar y, const SkPaint& paint) {
310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    canvas->drawText(text.c_str(), text.size(), x, y, paint);
320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return x + paint.measureText(text.c_str(), text.size());
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass FontCacheGM : public skiagm::GM {
360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    FontCacheGM() {
380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fTypefaces[i] = NULL;
400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual ~FontCacheGM() {
440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkSafeUnref(fTypefaces[i]);
460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprotected:
500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual SkString onShortName() SK_OVERRIDE {
510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return SkString("fontcache");
520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual SkISize onISize() SK_OVERRIDE {
550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return SkISize::Make(640, 320);
560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void onOnceBeforeDraw() SK_OVERRIDE {
590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int typefaceCount = 0;
600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (size_t i = 0; i < SK_ARRAY_COUNT(gFamilyNames); ++i) {
610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            for (size_t j = 0; j < SK_ARRAY_COUNT(gStyles); ++j) {
620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                fTypefaces[typefaceCount++] = SkTypeface::CreateFromName(gFamilyNames[i],
630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                                                          gStyles[j]);
640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkScalar y = 32;
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPaint paint;
710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        paint.setAntiAlias(true);
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        paint.setLCDRenderText(true);
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        paint.setSubpixelText(true);
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkString text("Ham");
760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // draw some initial text to partially fill the GPU cache
780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (size_t i = 0; i < 2; ++i) {
790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            paint.setTypeface(fTypefaces[i]);
800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkScalar x = 20;
810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) {
830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                paint.setTextSize(gTextSizes[j]);
840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                x = draw_string(canvas, text, x, y, paint) + 19;
850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            y += 32;
870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // force a flush
900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        canvas->flush();
910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // draw again, and more to overflow the cache
930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            paint.setTypeface(fTypefaces[i]);
950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkScalar x = 20;
960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) {
980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                paint.setTextSize(gTextSizes[j]);
990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                x = draw_string(canvas, text, x, y, paint) + 19;
1000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            y += 32;
1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual uint32_t onGetFlags() const SK_OVERRIDE {
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // this GM is meant only for the GPU
1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return kGPUOnly_Flag;
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate:
1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTypeface* fTypefaces[TYPEFACE_COUNT];
1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    typedef GM INHERITED;
1140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger//////////////////////////////////////////////////////////////////////////////
1180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_GM( return SkNEW(FontCacheGM); )
120