SampleColorFilter.cpp revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 89ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SampleCode.h" 99ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkView.h" 109ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkCanvas.h" 119ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkColorFilter.h" 129ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkDevice.h" 139ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkPaint.h" 149ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkShader.h" 159ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1679b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int inflate5To8(int x) { 1779b3b7e916d874f78208d33b00a554270c19b72areed@google.com return (x << 3) | (x >> 2); 1879b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 1979b3b7e916d874f78208d33b00a554270c19b72areed@google.com 2079b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int trunc5(int x) { 2179b3b7e916d874f78208d33b00a554270c19b72areed@google.com return x >> 3; 2279b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 2379b3b7e916d874f78208d33b00a554270c19b72areed@google.com 2479b3b7e916d874f78208d33b00a554270c19b72areed@google.com#define SK_R16_BITS 5 2579b3b7e916d874f78208d33b00a554270c19b72areed@google.com 2679b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int round5_slow(int x) { 2779b3b7e916d874f78208d33b00a554270c19b72areed@google.com int orig = x & 7; 2879b3b7e916d874f78208d33b00a554270c19b72areed@google.com int fake = x >> 5; 2979b3b7e916d874f78208d33b00a554270c19b72areed@google.com int trunc = x >> 3; 3079b3b7e916d874f78208d33b00a554270c19b72areed@google.com 3179b3b7e916d874f78208d33b00a554270c19b72areed@google.com int diff = fake - orig; 3279b3b7e916d874f78208d33b00a554270c19b72areed@google.com 3379b3b7e916d874f78208d33b00a554270c19b72areed@google.com int bias = 0; 3479b3b7e916d874f78208d33b00a554270c19b72areed@google.com if (diff > 4) { 3579b3b7e916d874f78208d33b00a554270c19b72areed@google.com bias = -1; 3679b3b7e916d874f78208d33b00a554270c19b72areed@google.com } else if (diff < -4) { 3779b3b7e916d874f78208d33b00a554270c19b72areed@google.com bias = 1; 3879b3b7e916d874f78208d33b00a554270c19b72areed@google.com } 3979b3b7e916d874f78208d33b00a554270c19b72areed@google.com return trunc + bias; 4079b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 4179b3b7e916d874f78208d33b00a554270c19b72areed@google.com 4279b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int round5_fast(int x) { 4379b3b7e916d874f78208d33b00a554270c19b72areed@google.com int result = x + 3 - (x >> 5) + (x >> 7); 4479b3b7e916d874f78208d33b00a554270c19b72areed@google.com result >>= 3; 4579b3b7e916d874f78208d33b00a554270c19b72areed@google.com 4679b3b7e916d874f78208d33b00a554270c19b72areed@google.com { 4779b3b7e916d874f78208d33b00a554270c19b72areed@google.com int r2 = round5_slow(x); 4879b3b7e916d874f78208d33b00a554270c19b72areed@google.com SkASSERT(r2 == result); 4979b3b7e916d874f78208d33b00a554270c19b72areed@google.com } 5079b3b7e916d874f78208d33b00a554270c19b72areed@google.com return result; 5179b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 5279b3b7e916d874f78208d33b00a554270c19b72areed@google.com 5379b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic void test_5bits() { 5479b3b7e916d874f78208d33b00a554270c19b72areed@google.com int e0 = 0; 5579b3b7e916d874f78208d33b00a554270c19b72areed@google.com int e1 = 0; 5679b3b7e916d874f78208d33b00a554270c19b72areed@google.com int e2 = 0; 5779b3b7e916d874f78208d33b00a554270c19b72areed@google.com int ae0 = 0; 5879b3b7e916d874f78208d33b00a554270c19b72areed@google.com int ae1 = 0; 5979b3b7e916d874f78208d33b00a554270c19b72areed@google.com int ae2 = 0; 6079b3b7e916d874f78208d33b00a554270c19b72areed@google.com for (int i = 0; i < 256; i++) { 6179b3b7e916d874f78208d33b00a554270c19b72areed@google.com int t0 = trunc5(i); 6279b3b7e916d874f78208d33b00a554270c19b72areed@google.com int t1 = round5_fast(i); 6379b3b7e916d874f78208d33b00a554270c19b72areed@google.com int t2 = trunc5(i); 6479b3b7e916d874f78208d33b00a554270c19b72areed@google.com int v0 = inflate5To8(t0); 6579b3b7e916d874f78208d33b00a554270c19b72areed@google.com int v1 = inflate5To8(t1); 6679b3b7e916d874f78208d33b00a554270c19b72areed@google.com int v2 = inflate5To8(t2); 6779b3b7e916d874f78208d33b00a554270c19b72areed@google.com int err0 = i - v0; 6879b3b7e916d874f78208d33b00a554270c19b72areed@google.com int err1 = i - v1; 6979b3b7e916d874f78208d33b00a554270c19b72areed@google.com int err2 = i - v2; 7079b3b7e916d874f78208d33b00a554270c19b72areed@google.com SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i, 7179b3b7e916d874f78208d33b00a554270c19b72areed@google.com v0, err0, v1, err1, v2, err2); 7279b3b7e916d874f78208d33b00a554270c19b72areed@google.com 7379b3b7e916d874f78208d33b00a554270c19b72areed@google.com 7479b3b7e916d874f78208d33b00a554270c19b72areed@google.com e0 += err0; 7579b3b7e916d874f78208d33b00a554270c19b72areed@google.com e1 += err1; 7679b3b7e916d874f78208d33b00a554270c19b72areed@google.com e2 += err2; 7779b3b7e916d874f78208d33b00a554270c19b72areed@google.com ae0 += SkAbs32(err0); 7879b3b7e916d874f78208d33b00a554270c19b72areed@google.com ae1 += SkAbs32(err1); 7979b3b7e916d874f78208d33b00a554270c19b72areed@google.com ae2 += SkAbs32(err2); 8079b3b7e916d874f78208d33b00a554270c19b72areed@google.com } 8179b3b7e916d874f78208d33b00a554270c19b72areed@google.com SkDebugf("--- trunc: %d %d round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2); 8279b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 8379b3b7e916d874f78208d33b00a554270c19b72areed@google.com 849ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkShader* createChecker() { 859ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkBitmap bm; 869ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); 879ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com bm.allocPixels(); 889ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com bm.lockPixels(); 899ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(0xFFFFFFFF); 909ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(0xFFCCCCCC); 919ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, 929ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkShader::kRepeat_TileMode); 939ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 949ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkMatrix m; 959ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com m.setScale(12, 12); 969ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com s->setLocalMatrix(m); 979ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return s; 989ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com} 999ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1009ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkBitmap createBitmap(int n) { 1019ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkBitmap bitmap; 1029ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com bitmap.setConfig(SkBitmap::kARGB_8888_Config, n, n); 1039ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com bitmap.allocPixels(); 1049ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com bitmap.eraseColor(0); 1059ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1069ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkCanvas canvas(bitmap); 1079ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkRect r; 1089ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n)); 1099ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.inset(SK_Scalar1, SK_Scalar1); 1109ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1119ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint paint; 1129ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setAntiAlias(true); 1139ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1149ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setColor(SK_ColorRED); 1159ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas.drawOval(r, paint); 1169ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1179ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4); 1189ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setXfermodeMode(SkXfermode::kSrc_Mode); 1199ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setColor(0x800000FF); 1209ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas.drawOval(r, paint); 1219ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1229ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return bitmap; 1239ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com} 1249ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1259ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comclass ColorFilterView : public SampleView { 1269ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkBitmap fBitmap; 1279ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkShader* fShader; 1289ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com enum { 1299ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com N = 64 1309ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com }; 1319ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.compublic: 1329ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com ColorFilterView() { 1339ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com fBitmap = createBitmap(N); 1349ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com fShader = createChecker(); 13579b3b7e916d874f78208d33b00a554270c19b72areed@google.com 13679b3b7e916d874f78208d33b00a554270c19b72areed@google.com// test_5bits(); 1379ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1389ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1399ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual ~ColorFilterView() { 1409ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com fShader->unref(); 1419ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1429ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1439ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comprotected: 1449ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com // overrides from SkEventSink 1459ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual bool onQuery(SkEvent* evt) { 1469ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com if (SampleCode::TitleQ(*evt)) { 1479ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SampleCode::TitleR(evt, "ColorFilter"); 1489ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return true; 1499ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1509ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return this->INHERITED::onQuery(evt); 1519ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1529ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1539ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual void onDrawBackground(SkCanvas* canvas) { 1549ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint paint; 1559ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setShader(fShader); 1569ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawPaint(paint); 1579ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1589ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1599ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual void onDrawContent(SkCanvas* canvas) { 1609ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com if (false) { 1619ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint p; 1629ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com p.setAntiAlias(true); 1639ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkRect r = { 20.4f, 10, 20.6f, 20 }; 1649ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawRect(r, p); 1659ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.set(30.9f, 10, 31.1f, 20); 1669ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawRect(r, p); 1679ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return; 1689ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1699ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1709ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com static const SkXfermode::Mode gModes[] = { 17197c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kClear_Mode, 1729ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrc_Mode, 1739ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDst_Mode, 17497c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kSrcOver_Mode, 17597c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kDstOver_Mode, 1769ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrcIn_Mode, 1779ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDstIn_Mode, 1789ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrcOut_Mode, 1799ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDstOut_Mode, 1809ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrcATop_Mode, 1819ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDstATop_Mode, 18297c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kXor_Mode, 18397c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kPlus_Mode, 18497c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kMultiply_Mode, 1859ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com }; 1869ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1879ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com static const SkColor gColors[] = { 1889ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0xFF000000, 1899ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0x80000000, 1909ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0xFF00FF00, 1919ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0x8000FF00, 1929ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0x00000000, 1939ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com }; 1949ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1959ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com float scale = 1.5f; 1969ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint paint; 1979ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->translate(N / 8, N / 8); 1989ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1999ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) { 2009ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) { 2019ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[y], gModes[x]); 2029ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkSafeUnref(paint.setColorFilter(cf)); 2039ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint); 2049ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 2059ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 2069ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 2079ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 2089ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 2099ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comprivate: 2109ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com typedef SampleView INHERITED; 2119ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com}; 2129ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 2139ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com////////////////////////////////////////////////////////////////////////////// 2149ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 2159ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkView* MyFactory() { return new ColorFilterView; } 2169ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkViewRegister reg(MyFactory); 2179ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 218