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