1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 8a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkBitmapProcShader.h" 9ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org#include "SkEmptyShader.h" 10a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkReadBuffer.h" 11a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkMallocPixelRef.h" 12a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkPaint.h" 13c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkPicture.h" 14c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org#include "SkPictureShader.h" 15d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org#include "SkScalar.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 178fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#include "SkThread.h" 188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 208fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org//#define SK_TRACK_SHADER_LIFETIME 218fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org 228fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#ifdef SK_TRACK_SHADER_LIFETIME 238fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org static int32_t gShaderCounter; 248fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#endif 258fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org 268fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.orgstatic inline void inc_shader_counter() { 278fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#ifdef SK_TRACK_SHADER_LIFETIME 288fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org int32_t prev = sk_atomic_inc(&gShaderCounter); 298fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org SkDebugf("+++ shader counter %d\n", prev + 1); 308fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#endif 318fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org} 328fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.orgstatic inline void dec_shader_counter() { 338fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#ifdef SK_TRACK_SHADER_LIFETIME 348fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org int32_t prev = sk_atomic_dec(&gShaderCounter); 358fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org SkDebugf("--- shader counter %d\n", prev - 1); 368fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org#endif 378fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org} 388fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org 399c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgSkShader::SkShader(const SkMatrix* localMatrix) { 408fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org inc_shader_counter(); 419c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org if (localMatrix) { 429c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org fLocalMatrix = *localMatrix; 439c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org } else { 449c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org fLocalMatrix.reset(); 459c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org } 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.orgSkShader::SkShader(SkReadBuffer& buffer) : INHERITED(buffer) { 498fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org inc_shader_counter(); 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (buffer.readBool()) { 51f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.readMatrix(&fLocalMatrix); 52f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com } else { 53f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com fLocalMatrix.reset(); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::~SkShader() { 588fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org dec_shader_counter(); 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 618b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkShader::flatten(SkWriteBuffer& buffer) const { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 635970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org bool hasLocalM = !fLocalMatrix.isIdentity(); 64f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.writeBool(hasLocalM); 65f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com if (hasLocalM) { 66f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.writeMatrix(fLocalMatrix); 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 70ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgbool SkShader::computeTotalInverse(const ContextRec& rec, SkMatrix* totalInverse) const { 715970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org SkMatrix total; 725970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org total.setConcat(*rec.fMatrix, fLocalMatrix); 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 745970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org const SkMatrix* m = &total; 7580116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org if (rec.fLocalMatrix) { 7680116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org total.setConcat(*m, *rec.fLocalMatrix); 7780116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org m = &total; 7880116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org } 7987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return m->invert(totalInverse); 8087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 8187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 82ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const { 83ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org if (!this->computeTotalInverse(rec, NULL)) { 84ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org return NULL; 85ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org } 86ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org return this->onCreateContext(rec, storage); 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8980116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.orgSkShader::Context* SkShader::onCreateContext(const ContextRec& rec, void*) const { 90f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org return NULL; 91f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org} 92f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org 93f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.orgsize_t SkShader::contextSize() const { 94f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org return 0; 95f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org} 96f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org 97e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.orgSkShader::Context::Context(const SkShader& shader, const ContextRec& rec) 9880116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org : fShader(shader), fCTM(*rec.fMatrix) 9987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 10087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Because the context parameters must be valid at this point, we know that the matrix is 10187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // invertible. 102ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org SkAssertResult(fShader.computeTotalInverse(rec, &fTotalInverse)); 10387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 10487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 105e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org fPaintAlpha = rec.fPaint->getAlpha(); 106a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com} 107a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com 10887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::~Context() {} 10987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 11087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) { 1113bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com return NULL; 1123bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com} 1133bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkShader::Context::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(span16); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->canCallShadeSpan16()); 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // basically, if we get here, the subclass screwed up 1220c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1267c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com#define kTempColorCount (kTempColorQuadCount << 2) 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor colors[kTempColorCount]; 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((count -= kTempColorCount) >= 0) { 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, kTempColorCount); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += kTempColorCount; 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int quads = kTempColorQuadCount; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a0 = srcA[0]; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a1 = srcA[4]; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a2 = srcA[8]; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a3 = srcA[12]; 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4*4; 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a0); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a1); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a2); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a3); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--quads != 0); 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count < 0); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count + kTempColorCount >= 0); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count += kTempColorCount) { 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, count); 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n > kTempColorCount) 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = kTempColorCount; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > 0); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, n); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += n; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--n != 0); 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (count > 0); 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) { 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MatrixClass mc = kLinear_MatrixClass; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1918d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com if (mat.hasPerspective()) { 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.fixedStepInX(0, NULL, NULL)) { 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kFixedStepInX_MatrixClass; 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kPerspective_MatrixClass; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mc; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) const { 204f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kNone_BitmapType; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 207d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 208d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kNone_GradientType; 209d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 210d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 2119de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkShader::asNewEffect(GrContext* context, const SkPaint& paint, 2129de5b514d38c5b36066bcdc14fba2f7e5196d372dandov const SkMatrix* localMatrixOrNull, GrColor* grColor, 2139de5b514d38c5b36066bcdc14fba2f7e5196d372dandov GrEffectRef** grEffect) const { 2149de5b514d38c5b36066bcdc14fba2f7e5196d372dandov return false; 21503c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com} 21603c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com 2178fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.orgSkShader* SkShader::refAsALocalMatrixShader(SkMatrix*) const { 2188fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org return NULL; 2198fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org} 2208fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org 221ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader* SkShader::CreateEmptyShader() { 222ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org return SkNEW(SkEmptyShader); 223ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org} 224ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org 2259c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, 2269c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org const SkMatrix* localMatrix) { 2279c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org return ::CreateBitmapShader(src, tmx, tmy, localMatrix, NULL); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2305aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.orgSkShader* SkShader::CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy, 2315aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org const SkMatrix* localMatrix) { 2325aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org return SkPictureShader::Create(src, tmx, tmy, localMatrix); 233c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org} 234c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org 2350f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 23676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkShader::toString(SkString* str) const { 2375970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org if (!fLocalMatrix.isIdentity()) { 23876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(" "); 2395970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org fLocalMatrix.toString(str); 24076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 24176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 24276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 24376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorShader.h" 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkColorShader::SkColorShader(SkColor c) 25076a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org : fColor(c) { 251f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 252f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 253b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.orgbool SkColorShader::isOpaque() const { 254b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org return SkColorGetA(fColor) == 255; 255b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org} 256b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org 2578b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 25876a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org // V25_COMPATIBILITY_CODE We had a boolean to make the color shader inherit the paint's 25976a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org // color. We don't support that any more. 2607ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org if (b.isVersionLT(SkReadBuffer::kColorShaderNoBool_Version)) { 26176a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org if (b.readBool()) { 26276a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org SkDEBUGFAIL("We shouldn't have pictures that recorded the inherited case."); 26376a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org fColor = SK_ColorWHITE; 26476a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org return; 26576a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org } 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 267c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fColor = b.readColor(); 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2708b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkColorShader::flatten(SkWriteBuffer& buffer) const { 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 272c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeColor(fColor); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint32_t SkColorShader::ColorShaderContext::getFlags() const { 27659ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com return fFlags; 27759ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com} 27859ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 27987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const { 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkGetPackedA32(fPMColor); 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 283ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const { 284e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, rec)); 28587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 28687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 28787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader, 288e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org const ContextRec& rec) 289e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org : INHERITED(shader, rec) 29087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 2919c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org SkColor color = shader.fColor; 292e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha())); 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned r = SkColorGetR(color); 29587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned g = SkColorGetG(color); 29687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned b = SkColorGetB(color); 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want this before we apply any alpha 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPack888ToRGB16(r, g, b); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a != 255) { 3028f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com r = SkMulDiv255Round(r, a); 3038f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com g = SkMulDiv255Round(g, a); 3048f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com b = SkMulDiv255Round(b, a); 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(a, r, g, b); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3088f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com fFlags = kConstInY32_Flag; 3095b81535014f545f6498f5c8721723b81576989b1reed@android.com if (255 == a) { 3105119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags |= kOpaqueAlpha_Flag; 311e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org if (rec.fPaint->isDither() == false) { 3125b81535014f545f6498f5c8721723b81576989b1reed@android.com fFlags |= kHasSpan16_Flag; 3135b81535014f545f6498f5c8721723b81576989b1reed@android.com } 3145119bdb952025a30f115b9c6a187173956e55097reed@android.com } 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) { 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(span, fPMColor, count); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpan16(int x, int y, uint16_t span[], int count) { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(span, fColor16, count); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, SkGetPackedA32(fPMColor), count); 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 329f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// if we had a asAColor method, that would be more efficient... 330f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 33191f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com TileMode modes[]) const { 3322be9e8b407624fa696854b78b407b97a01dbb703reed@google.com return kNone_BitmapType; 333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 334f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 335d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 336d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info) { 337d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info->fColors && info->fColorCount >= 1) { 338d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColors[0] = fColor; 339d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 340d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColorCount = 1; 341d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fTileMode = SkShader::kRepeat_TileMode; 342d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 343d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kColor_GradientType; 344d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 34537a201231b8f6381938282675eb9abb50ab3b389reed@google.com 3469de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#if SK_SUPPORT_GPU 3479de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3489de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#include "SkGr.h" 3499de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3509de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint, 3519de5b514d38c5b36066bcdc14fba2f7e5196d372dandov const SkMatrix* localMatrix, GrColor* grColor, 3529de5b514d38c5b36066bcdc14fba2f7e5196d372dandov GrEffectRef** grEffect) const { 3539de5b514d38c5b36066bcdc14fba2f7e5196d372dandov *grEffect = NULL; 3549de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkColor skColor = fColor; 3559de5b514d38c5b36066bcdc14fba2f7e5196d372dandov U8CPU newA = SkMulDiv255Round(SkColorGetA(fColor), paint.getAlpha()); 3569de5b514d38c5b36066bcdc14fba2f7e5196d372dandov *grColor = SkColor2GrColor(SkColorSetA(skColor, newA)); 3579de5b514d38c5b36066bcdc14fba2f7e5196d372dandov return true; 3589de5b514d38c5b36066bcdc14fba2f7e5196d372dandov} 3599de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3609de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#else 3619de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3629de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint, 3639de5b514d38c5b36066bcdc14fba2f7e5196d372dandov const SkMatrix* localMatrix, GrColor* grColor, 3649de5b514d38c5b36066bcdc14fba2f7e5196d372dandov GrEffectRef** grEffect) const { 3659de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkDEBUGFAIL("Should not call in GPU-less build"); 3669de5b514d38c5b36066bcdc14fba2f7e5196d372dandov return false; 3679de5b514d38c5b36066bcdc14fba2f7e5196d372dandov} 3689de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3699de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#endif 3709de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3710f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 37276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkColorShader::toString(SkString* str) const { 37376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("SkColorShader: ("); 37476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 37576a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org str->append("Color: "); 37676a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org str->appendHex(fColor); 37776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 37876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 37976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 38076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 38176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 38276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 38376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 38437a201231b8f6381938282675eb9abb50ab3b389reed@google.com/////////////////////////////////////////////////////////////////////////////// 38537a201231b8f6381938282675eb9abb50ab3b389reed@google.com 38687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 38737a201231b8f6381938282675eb9abb50ab3b389reed@google.com#include "SkEmptyShader.h" 38837a201231b8f6381938282675eb9abb50ab3b389reed@google.com 38976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkEmptyShader::toString(SkString* str) const { 39076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("SkEmptyShader: ("); 39176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 39276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 39376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 39476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 39576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 39676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 397