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 */ 8b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary#include "sk_tool_utils.h" 99ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SampleCode.h" 109ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkView.h" 119ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkCanvas.h" 129ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkColorFilter.h" 139ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkDevice.h" 149ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkPaint.h" 159ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com#include "SkShader.h" 169ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1779b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int inflate5To8(int x) { 1879b3b7e916d874f78208d33b00a554270c19b72areed@google.com return (x << 3) | (x >> 2); 1979b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 2079b3b7e916d874f78208d33b00a554270c19b72areed@google.com 2179b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int trunc5(int x) { 2279b3b7e916d874f78208d33b00a554270c19b72areed@google.com return x >> 3; 2379b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 2479b3b7e916d874f78208d33b00a554270c19b72areed@google.com 2579b3b7e916d874f78208d33b00a554270c19b72areed@google.com#define SK_R16_BITS 5 2679b3b7e916d874f78208d33b00a554270c19b72areed@google.com 270e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com#ifdef SK_DEBUG 28ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.comstatic int round5_slow(int x) { 2979b3b7e916d874f78208d33b00a554270c19b72areed@google.com int orig = x & 7; 3079b3b7e916d874f78208d33b00a554270c19b72areed@google.com int fake = x >> 5; 3179b3b7e916d874f78208d33b00a554270c19b72areed@google.com int trunc = x >> 3; 3279b3b7e916d874f78208d33b00a554270c19b72areed@google.com 3379b3b7e916d874f78208d33b00a554270c19b72areed@google.com int diff = fake - orig; 3479b3b7e916d874f78208d33b00a554270c19b72areed@google.com 3579b3b7e916d874f78208d33b00a554270c19b72areed@google.com int bias = 0; 3679b3b7e916d874f78208d33b00a554270c19b72areed@google.com if (diff > 4) { 3779b3b7e916d874f78208d33b00a554270c19b72areed@google.com bias = -1; 3879b3b7e916d874f78208d33b00a554270c19b72areed@google.com } else if (diff < -4) { 3979b3b7e916d874f78208d33b00a554270c19b72areed@google.com bias = 1; 4079b3b7e916d874f78208d33b00a554270c19b72areed@google.com } 4179b3b7e916d874f78208d33b00a554270c19b72areed@google.com return trunc + bias; 4279b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 430e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com#endif 4479b3b7e916d874f78208d33b00a554270c19b72areed@google.com 4579b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic int round5_fast(int x) { 4679b3b7e916d874f78208d33b00a554270c19b72areed@google.com int result = x + 3 - (x >> 5) + (x >> 7); 4779b3b7e916d874f78208d33b00a554270c19b72areed@google.com result >>= 3; 480e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com#ifdef SK_DEBUG 4979b3b7e916d874f78208d33b00a554270c19b72areed@google.com { 5079b3b7e916d874f78208d33b00a554270c19b72areed@google.com int r2 = round5_slow(x); 5179b3b7e916d874f78208d33b00a554270c19b72areed@google.com SkASSERT(r2 == result); 5279b3b7e916d874f78208d33b00a554270c19b72areed@google.com } 530e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com#endif 5479b3b7e916d874f78208d33b00a554270c19b72areed@google.com return result; 5579b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 5679b3b7e916d874f78208d33b00a554270c19b72areed@google.com 5779b3b7e916d874f78208d33b00a554270c19b72areed@google.comstatic void test_5bits() { 5879b3b7e916d874f78208d33b00a554270c19b72areed@google.com int e0 = 0; 5979b3b7e916d874f78208d33b00a554270c19b72areed@google.com int e1 = 0; 6079b3b7e916d874f78208d33b00a554270c19b72areed@google.com int e2 = 0; 6179b3b7e916d874f78208d33b00a554270c19b72areed@google.com int ae0 = 0; 6279b3b7e916d874f78208d33b00a554270c19b72areed@google.com int ae1 = 0; 6379b3b7e916d874f78208d33b00a554270c19b72areed@google.com int ae2 = 0; 6479b3b7e916d874f78208d33b00a554270c19b72areed@google.com for (int i = 0; i < 256; i++) { 6579b3b7e916d874f78208d33b00a554270c19b72areed@google.com int t0 = trunc5(i); 6679b3b7e916d874f78208d33b00a554270c19b72areed@google.com int t1 = round5_fast(i); 6779b3b7e916d874f78208d33b00a554270c19b72areed@google.com int t2 = trunc5(i); 6879b3b7e916d874f78208d33b00a554270c19b72areed@google.com int v0 = inflate5To8(t0); 6979b3b7e916d874f78208d33b00a554270c19b72areed@google.com int v1 = inflate5To8(t1); 7079b3b7e916d874f78208d33b00a554270c19b72areed@google.com int v2 = inflate5To8(t2); 7179b3b7e916d874f78208d33b00a554270c19b72areed@google.com int err0 = i - v0; 7279b3b7e916d874f78208d33b00a554270c19b72areed@google.com int err1 = i - v1; 7379b3b7e916d874f78208d33b00a554270c19b72areed@google.com int err2 = i - v2; 7479b3b7e916d874f78208d33b00a554270c19b72areed@google.com SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i, 7579b3b7e916d874f78208d33b00a554270c19b72areed@google.com v0, err0, v1, err1, v2, err2); 76ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 7779b3b7e916d874f78208d33b00a554270c19b72areed@google.com 7879b3b7e916d874f78208d33b00a554270c19b72areed@google.com e0 += err0; 7979b3b7e916d874f78208d33b00a554270c19b72areed@google.com e1 += err1; 8079b3b7e916d874f78208d33b00a554270c19b72areed@google.com e2 += err2; 8179b3b7e916d874f78208d33b00a554270c19b72areed@google.com ae0 += SkAbs32(err0); 8279b3b7e916d874f78208d33b00a554270c19b72areed@google.com ae1 += SkAbs32(err1); 8379b3b7e916d874f78208d33b00a554270c19b72areed@google.com ae2 += SkAbs32(err2); 8479b3b7e916d874f78208d33b00a554270c19b72areed@google.com } 8579b3b7e916d874f78208d33b00a554270c19b72areed@google.com SkDebugf("--- trunc: %d %d round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2); 8679b3b7e916d874f78208d33b00a554270c19b72areed@google.com} 8779b3b7e916d874f78208d33b00a554270c19b72areed@google.com 889ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkBitmap createBitmap(int n) { 899ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkBitmap bitmap; 90a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org bitmap.allocN32Pixels(n, n); 91dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com bitmap.eraseColor(SK_ColorTRANSPARENT); 92ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 939ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkCanvas canvas(bitmap); 949ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkRect r; 959ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n)); 969ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.inset(SK_Scalar1, SK_Scalar1); 979ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 989ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint paint; 999ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setAntiAlias(true); 100ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1019ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setColor(SK_ColorRED); 1029ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas.drawOval(r, paint); 1039ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1049ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4); 1059ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setXfermodeMode(SkXfermode::kSrc_Mode); 1069ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setColor(0x800000FF); 1079ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas.drawOval(r, paint); 108ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1099ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return bitmap; 1109ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com} 1119ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1129ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comclass ColorFilterView : public SampleView { 1139ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkBitmap fBitmap; 1149ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkShader* fShader; 1159ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com enum { 1169ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com N = 64 1179ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com }; 1189ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.compublic: 1199ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com ColorFilterView() { 1209ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com fBitmap = createBitmap(N); 121b0cce2c1d37d4bf5b89da6c70062209ac4e0e643halcanary fShader = sk_tool_utils::create_checkerboard_shader( 122878fa0204bc246ec5fbaca4aa3c81aaefccc30a1halcanary 0xFFCCCCCC, 0xFFFFFFFF, 12); 123ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 12402939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com if (false) { // avoid bit rot, suppress warning 12502939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com test_5bits(); 12602939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com } 1279ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1289ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1299ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual ~ColorFilterView() { 1309ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com fShader->unref(); 1319ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1329ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1339ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comprotected: 1349ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com // overrides from SkEventSink 1359ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual bool onQuery(SkEvent* evt) { 1369ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com if (SampleCode::TitleQ(*evt)) { 1379ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SampleCode::TitleR(evt, "ColorFilter"); 1389ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return true; 1399ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1409ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return this->INHERITED::onQuery(evt); 1419ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1429ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1439ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual void onDrawBackground(SkCanvas* canvas) { 1449ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint paint; 1459ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com paint.setShader(fShader); 1469ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawPaint(paint); 1479ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1489ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1499ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com virtual void onDrawContent(SkCanvas* canvas) { 1509ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com if (false) { 1519ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint p; 1529ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com p.setAntiAlias(true); 1539ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkRect r = { 20.4f, 10, 20.6f, 20 }; 1549ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawRect(r, p); 1559ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com r.set(30.9f, 10, 31.1f, 20); 1569ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawRect(r, p); 1579ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com return; 1589ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 159ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1609ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com static const SkXfermode::Mode gModes[] = { 16197c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kClear_Mode, 1629ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrc_Mode, 1639ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDst_Mode, 16497c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kSrcOver_Mode, 16597c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kDstOver_Mode, 1669ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrcIn_Mode, 1679ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDstIn_Mode, 1689ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrcOut_Mode, 1699ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDstOut_Mode, 1709ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kSrcATop_Mode, 1719ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkXfermode::kDstATop_Mode, 17297c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kXor_Mode, 17397c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo SkXfermode::kPlus_Mode, 1748d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com SkXfermode::kModulate_Mode, 1759ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com }; 176ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1779ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com static const SkColor gColors[] = { 1789ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0xFF000000, 1799ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0x80000000, 1809ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0xFF00FF00, 1819ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0x8000FF00, 1829ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 0x00000000, 1839ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com }; 1849ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1859ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com float scale = 1.5f; 1869ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkPaint paint; 1879ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->translate(N / 8, N / 8); 1889ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 1899ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) { 1909ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) { 1919ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[y], gModes[x]); 1929ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com SkSafeUnref(paint.setColorFilter(cf)); 1939ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint); 1949ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 1959ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 196ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1979ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com } 198ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1999ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comprivate: 2009ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com typedef SampleView INHERITED; 2019ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com}; 2029ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 2039ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com////////////////////////////////////////////////////////////////////////////// 2049ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.com 2059ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkView* MyFactory() { return new ColorFilterView; } 2069ac5e228c6e1eee04d2f2c2ab89d493439ff3056reed@google.comstatic SkViewRegister reg(MyFactory); 207