SkShader.cpp revision 7ed173b1ebac84671fb0dc1b9bd323a5e6e63771
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use of this source code is governed by a BSD-style license that can be 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * found in the LICENSE file. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkBitmapProcShader.h" 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkEmptyShader.h" 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkReadBuffer.h" 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkMallocPixelRef.h" 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkPaint.h" 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkPicture.h" 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkPictureShader.h" 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkScalar.h" 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h" 17cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root#include "SkThread.h" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkWriteBuffer.h" 19854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey 20854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey//#define SK_TRACK_SHADER_LIFETIME 212798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 222798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root#ifdef SK_TRACK_SHADER_LIFETIME 23fd7adedebf88427162a3ce27fcc9cfd3893c869dDianne Hackborn static int32_t gShaderCounter; 240ac3031c159a0904e73eb4439cdc724d8df4a6e6Dianne Hackborn#endif 252798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 26be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkeystatic inline void inc_shader_counter() { 27e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey#ifdef SK_TRACK_SHADER_LIFETIME 28e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey int32_t prev = sk_atomic_inc(&gShaderCounter); 29e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey SkDebugf("+++ shader counter %d\n", prev + 1); 30e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey#endif 31e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey} 32e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkeystatic inline void dec_shader_counter() { 33e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey#ifdef SK_TRACK_SHADER_LIFETIME 34e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey int32_t prev = sk_atomic_dec(&gShaderCounter); 35e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey SkDebugf("--- shader counter %d\n", prev - 1); 36e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey#endif 37e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey} 38e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey 39e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff SharkeySkShader::SkShader(const SkMatrix* localMatrix) { 40e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey inc_shader_counter(); 41e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey if (localMatrix) { 42e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey fLocalMatrix = *localMatrix; 43513a074de68a4772a9900e90f38e74ff92c15e7cJeff Sharkey } else { 4488d2a3c0e1b4a8c53a489db5d627beb80b1b9957Jeff Sharkey fLocalMatrix.reset(); 45be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey } 46e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey} 4773767b9d607d99b3a027619b5c6b7f1a09b7673dJeff Sharkey 486422abef786632e53337c6c298ffa64f7ddf4d90Brian CarlstromSkShader::SkShader(SkReadBuffer& buffer) : INHERITED(buffer) { 496422abef786632e53337c6c298ffa64f7ddf4d90Brian Carlstrom inc_shader_counter(); 50be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey if (buffer.readBool()) { 51be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey buffer.readMatrix(&fLocalMatrix); 5210fa67c77e11699391e27975fc2d276a0b8c7cbbNicolas Prevot } else { 536422abef786632e53337c6c298ffa64f7ddf4d90Brian Carlstrom fLocalMatrix.reset(); 54941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey } 55941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey} 56854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey 57854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff SharkeySkShader::~SkShader() { 582798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root dec_shader_counter(); 59be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn} 600c54798aac8a86fed24b14a66f09797d58ad0399Jeff Sharkey 61ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstromvoid SkShader::flatten(SkWriteBuffer& buffer) const { 62c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu this->INHERITED::flatten(buffer); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasLocalM = !fLocalMatrix.isIdentity(); 6485387d7ba36e56b291cbde87acb5a5b2200fe01cKenny Root buffer.writeBool(hasLocalM); 655b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu if (hasLocalM) { 66be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey buffer.writeMatrix(fLocalMatrix); 678a4c9721a9e09d20c63381c13fa29bd9f7cbc3e3Jeff Sharkey } 688c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn} 69fc8b7fe02630f64a1d6c8ecb06f4c250e7478f1dDianne Hackborn 70a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkeybool SkShader::computeTotalInverse(const ContextRec& rec, SkMatrix* totalInverse) const { 71cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root SkMatrix total; 72cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root total.setConcat(*rec.fMatrix, fLocalMatrix); 73ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski 743bbef521d4b07f86010ba0729a36ff8b73bcb0acBrian Carlstrom const SkMatrix* m = &total; 75be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn if (rec.fLocalMatrix) { 76fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn total.setConcat(*m, *rec.fLocalMatrix); 776422abef786632e53337c6c298ffa64f7ddf4d90Brian Carlstrom m = &total; 786422abef786632e53337c6c298ffa64f7ddf4d90Brian Carlstrom } 79ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom return m->invert(totalInverse); 80fc8b7fe02630f64a1d6c8ecb06f4c250e7478f1dDianne Hackborn} 81a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks 82a2064df6ab77f71e9187da380cbe355c5eaf5a64rich canningsSkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!this->computeTotalInverse(rec, NULL)) { 8465cde7d42d741c7d9aa2714a397b7333f688ab55Jeff Hao return NULL; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn return this->onCreateContext(rec, storage); 874528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate} 887eb599b267d00cbde891c0a87924f2f5086f4497Jeff Hao 897eb599b267d00cbde891c0a87924f2f5086f4497Jeff HaoSkShader::Context* SkShader::onCreateContext(const ContextRec& rec, void*) const { 905ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root return NULL; 91a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks} 922798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 93ecb0e637870553f9c12dc6b9178de0512563af9cDianne Hackbornsize_t SkShader::contextSize() const { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 961ccac75e1f1b97eccb916a8de04fc1012b30f6e5Suchi Amalapurapu 97a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksSkShader::Context::Context(const SkShader& shader, const ContextRec& rec) 981378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi : fShader(shader), fCTM(*rec.fMatrix) 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Because the context parameters must be valid at this point, we know that the matrix is 10149237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn // invertible. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAssertResult(fShader.computeTotalInverse(rec, &fTotalInverse)); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 104fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey 105f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate fPaintAlpha = rec.fPaint->getAlpha(); 1063a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey} 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1088946dd3355fc1dcbad872c0546e356474d4cc5deSuchi AmalapurapuSkShader::Context::~Context() {} 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) { 111c6f22499f3046684d7175e10ca42cce1492cd36fdcashman return NULL; 1121378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi} 1137767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkColorPriv.h" 115a2b6c3775ed6b8924232d6a01bae4a19740a15f8Suchi Amalapurapu 116a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyvoid SkShader::Context::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(span16); 1186c0b9da65e36543bb50833d1b54ca532d0bd3aabJeff Sharkey SkASSERT(count > 0); 119ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom SkASSERT(this->canCallShadeSpan16()); 120d746057f2414cba2bdc69257cc5be8cb681bb592Jeff Sharkey 121c4858a2ba972e86436d629c4d3f18eb49116de14Jeff Sharkey // basically, if we get here, the subclass screwed up 122a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1232798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root} 1241378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi 1250e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 126a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks#define kTempColorCount (kTempColorQuadCount << 2) 1272798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef SK_CPU_BENDIAN 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1327f7b0c759e2970178ef68805b21f06a26e24eb76Nicolas Prevot#endif 133706e8ba26bf0de19ad5f736516dae40c4c88c2d7rich cannings 1340aaa0d931716e9f57a1d84d795fab2df75092756Kenny Rootvoid SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 13505ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root SkASSERT(count > 0); 136bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima 137ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski SkPMColor colors[kTempColorCount]; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((count -= kTempColorCount) >= 0) { 140851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn this->shadeSpan(x, y, colors, kTempColorCount); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x += kTempColorCount; 1422798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 1431378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1447265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate int quads = kTempColorQuadCount; 145742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey do { 1468cd28b57ed732656d002d97879e15c5695b54fffAmith Yamasani U8CPU a0 = srcA[0]; 1472798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root U8CPU a1 = srcA[4]; 1482798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root U8CPU a2 = srcA[8]; 149c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu U8CPU a3 = srcA[12]; 1500214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu srcA += 4*4; 1510214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu *alpha++ = SkToU8(a0); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *alpha++ = SkToU8(a1); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *alpha++ = SkToU8(a2); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *alpha++ = SkToU8(a3); 1552798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root } while (--quads != 0); 156554cb0c290406f5bba34908489db5382a69d0a9arpcraig } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(count < 0); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(count + kTempColorCount >= 0); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count += kTempColorCount) { 160f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn this->shadeSpan(x, y, colors, count); 161d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root 162d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 163d02546b4151214abb2db1c88bf7debfc70bd2421Oscar Montemayor do { 16434385d352da19805ae948215e2edbeedd16b7941Elliott Hughes *alpha++ = *srcA; 16534385d352da19805ae948215e2edbeedd16b7941Elliott Hughes srcA += 4; 16634385d352da19805ae948215e2edbeedd16b7941Elliott Hughes } while (--count != 0); 167bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima } 1687265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate#if 0 169b87de28f50e9f02a365f35348f8da6cc2629bc1cJeff Sharkey do { 170ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom int n = count; 1712798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root if (n > kTempColorCount) 1722798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root n = kTempColorCount; 17378a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey SkASSERT(n > 0); 1742798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 1752798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root this->shadeSpan(x, y, colors, n); 176e9ecc8b49992840249bfb9d5d52b8824dd5de39bAmith Yamasani x += n; 1772798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root count -= n; 1782798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root 17963798c596dc757135950313eb4bb44ca58696c68Nicolas Prevot const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *alpha++ = *srcA; 182ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom srcA += 4; 183fc8b7fe02630f64a1d6c8ecb06f4c250e7478f1dDianne Hackborn } while (--n != 0); 1841c133105774835deaa99db78d9668b107246abefJeff Sharkey } while (count > 0); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MatrixClass mc = kLinear_MatrixClass; 1901c133105774835deaa99db78d9668b107246abefJeff Sharkey 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mat.hasPerspective()) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mat.fixedStepInX(0, NULL, NULL)) { 193ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom mc = kFixedStepInX_MatrixClass; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 195ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom mc = kPerspective_MatrixClass; 196d02546b4151214abb2db1c88bf7debfc70bd2421Oscar Montemayor } 19705ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root } 198a8e65fd82a323e6065ae9ae6cc8eaa130d3c1efdKenny Root return mc; 19905ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root} 200b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project////////////////////////////////////////////////////////////////////////////// 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20349237345d83e62fdb9eb8d50b13ad086636a04faDianne HackbornSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) const { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return kNone_BitmapType; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 206b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return kNone_GradientType; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 210bfed9f34c0cf7cdf7d25e6a7677e03f5a3d87e0eJeff Sharkey 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const { 212ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom return NULL; 213ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom} 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 215ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian CarlstromSkShader* SkShader::refAsALocalMatrixShader(SkMatrix*) const { 216ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom return NULL; 2170f206a149d27385ef092a34e0009a8607d663659Narayan Kamath} 2183a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey 2193f99afc0d5c25321b870f95415d7f31e2b3ec934Kenny RootSkShader* SkShader::CreateEmptyShader() { 220742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey return SkNEW(SkEmptyShader); 22166269ea6f68f2f25888ce1080c94ac782742fafcKenny Root} 222d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn 223d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne HackbornSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, 224d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn const SkMatrix* localMatrix) { 225d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return ::CreateBitmapShader(src, tmx, tmy, localMatrix, NULL); 226d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn} 227d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn 228d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne HackbornSkShader* SkShader::CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy, 229d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn const SkMatrix* localMatrix) { 230d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn return SkPictureShader::Create(src, tmx, tmy, localMatrix); 231cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root} 232cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 233d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn#ifndef SK_IGNORE_TO_STRING 234cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootvoid SkShader::toString(SkString* str) const { 235cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (!fLocalMatrix.isIdentity()) { 236cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root str->append(" "); 237c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn fLocalMatrix.toString(str); 238cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 2391bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate} 2409718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root#endif 2417767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn 2429718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root////////////////////////////////////////////////////////////////////////////// 2439718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root 2449718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root#include "SkColorShader.h" 2459718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root#include "SkUtils.h" 24605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root 247ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian CarlstromSkColorShader::SkColorShader(SkColor c) 248ff110bd61a69f7ed8602ae14b27f7befec76b2e7Narayan Kamath : fColor(c) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 251d42685d5de1dbd6d75b48d42418f370adaa4daefMike Lockwoodbool SkColorShader::isOpaque() const { 252cd0e839a2448deea50f79bddeba782c546b33893Nick Pelly return SkColorGetA(fColor) == 255; 2531abb1cb3a8fe17f7866150604c2fd73751da787eJaikumar Ganesh} 254514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 256c55f9c04427796d5b6f833fe43adffd9d7b99ad2Christopher Tate // V25_COMPATIBILITY_CODE We had a boolean to make the color shader inherit the paint's 257c55f9c04427796d5b6f833fe43adffd9d7b99ad2Christopher Tate // color. We don't support that any more. 258c55f9c04427796d5b6f833fe43adffd9d7b99ad2Christopher Tate if (b.isVersionLT(SkReadBuffer::kColorShaderNoBool_Version)) { 2598946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu if (b.readBool()) { 2608946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu SkDEBUGFAIL("We shouldn't have pictures that recorded the inherited case."); 2618946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu fColor = SK_ColorWHITE; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fColor = b.readColor(); 266af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu} 267af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu 26878d688369a2240009d3bbe4126996a973b2e2fe2Dianne Hackbornvoid SkColorShader::flatten(SkWriteBuffer& buffer) const { 269661cd52e0e1d527132eb1cae604d3e64da7ec0cbDianne Hackborn this->INHERITED::flatten(buffer); 270d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn buffer.writeColor(fColor); 27148d22323ce39f9aab003dce74456889b6414af55Mårten Kongstad} 272d5c8044e7e1f1402fdd4a035690329294ab07b33Nick Kralevich 273381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkeyuint32_t SkColorShader::ColorShaderContext::getFlags() const { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fFlags; 275399cccb85749e02f6d3e12d1d2846310e7cbfdf1Dianne Hackborn} 276111285763204cabff682b381928fd5447a5c6a90Kenny Root 2775ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Rootuint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const { 278e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return SkGetPackedA32(fPMColor); 279e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate} 280e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 281e6f81cf1f69e0683f969238f921950befba8e6c3Christopher TateSkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const { 282e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, rec)); 283e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate} 284e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 285e6f81cf1f69e0683f969238f921950befba8e6c3Christopher TateSkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader, 2867265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate const ContextRec& rec) 2877265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate : INHERITED(shader, rec) 2887265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate{ 2897265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate SkColor color = shader.fColor; 2907265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha())); 2917265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate 2927265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate unsigned r = SkColorGetR(color); 2937265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate unsigned g = SkColorGetG(color); 2947265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate unsigned b = SkColorGetB(color); 2957265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate 2967265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate // we want this before we apply any alpha 2977265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate fColor16 = SkPack888ToRGB16(r, g, b); 2985ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root 2995ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root if (a != 255) { 30036c67c236ed188a034fdf13977fbc8d4fe0023e2rich cannings r = SkMulDiv255Round(r, a); 3015ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root g = SkMulDiv255Round(g, a); 3025ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root b = SkMulDiv255Round(b, a); 3035ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root } 3045ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root fPMColor = SkPackARGB32(a, r, g, b); 3055ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root 306aa8513e171e4714809235e08a75aff3814d9a02brich cannings fFlags = kConstInY32_Flag; 3075ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root if (255 == a) { 308a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings fFlags |= kOpaqueAlpha_Flag; 309a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings if (rec.fPaint->isDither() == false) { 310a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings fFlags |= kHasSpan16_Flag; 311a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings } 312a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings } 313a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings} 314a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings 315a6cfe52eb83995b124efec5f73bcb179caadf888rich canningsvoid SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) { 316111285763204cabff682b381928fd5447a5c6a90Kenny Root sk_memset32(span, fPMColor, count); 317111285763204cabff682b381928fd5447a5c6a90Kenny Root} 318e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn 319111285763204cabff682b381928fd5447a5c6a90Kenny Rootvoid SkColorShader::ColorShaderContext::shadeSpan16(int x, int y, uint16_t span[], int count) { 320e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn sk_memset16(span, fColor16, count); 321c78a8079740bfcad2e4439ccd74da52f6dc7fae2Kenny Root} 32205ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root 32305ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Rootvoid SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 32448d22323ce39f9aab003dce74456889b6414af55Mårten Kongstad memset(alpha, SkGetPackedA32(fPMColor), count); 32548d22323ce39f9aab003dce74456889b6414af55Mårten Kongstad} 3260f206a149d27385ef092a34e0009a8607d663659Narayan Kamath 3270f206a149d27385ef092a34e0009a8607d663659Narayan Kamath// if we had a asAColor method, that would be more efficient... 3286f357d3284a833cc50a990e14b39f389b8972254Jeff BrownSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 329dd3d95f182a634acdcc1b1e8e4954234d048eb54Nick Kralevich TileMode modes[]) const { 33048d22323ce39f9aab003dce74456889b6414af55Mårten Kongstad return kNone_BitmapType; 33148d22323ce39f9aab003dce74456889b6414af55Mårten Kongstad} 33248d22323ce39f9aab003dce74456889b6414af55Mårten Kongstad 3330214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi AmalapurapuSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info) { 335ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey if (info->fColors && info->fColorCount >= 1) { 336ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey info->fColors[0] = fColor; 337ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey } 338ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey info->fColorCount = 1; 339ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey info->fTileMode = SkShader::kRepeat_TileMode; 340ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey } 341851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn return kColor_GradientType; 342ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker} 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef SK_IGNORE_TO_STRING 345d2509fd83597595914ef0627685e917380863eb6Dianne Hackbornvoid SkColorShader::toString(SkString* str) const { 346230561eef41047f04dac1a10949f4bcb43915017Brian Carlstrom str->append("SkColorShader: ("); 3477eb599b267d00cbde891c0a87924f2f5086f4497Jeff Hao 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str->append("Color: "); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str->appendHex(fColor); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519f60c08a446e38f9e2d5271546ef69ca5941eba9Jeff Hao this->INHERITED::toString(str); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str->append(")"); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3560b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 3570b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani/////////////////////////////////////////////////////////////////////////////// 3580b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 35951a573c76737733638c475f52e441c814e6645ccKenny Root#ifndef SK_IGNORE_TO_STRING 36051a573c76737733638c475f52e441c814e6645ccKenny Root#include "SkEmptyShader.h" 36151a573c76737733638c475f52e441c814e6645ccKenny Root 362ddbe50df2ca70700a46e5849347989b520d1113eKenny Rootvoid SkEmptyShader::toString(SkString* str) const { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str->append("SkEmptyShader: ("); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 365ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker this->INHERITED::toString(str); 36657dcf5b177b56195421535938544f32d8b591b42Jeff Sharkey 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str->append(")"); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 369ddbe50df2ca70700a46e5849347989b520d1113eKenny Root#endif 370ff110bd61a69f7ed8602ae14b27f7befec76b2e7Narayan Kamath