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 } 46f51de259ada8dacd44eca41945b49a8dba1606aeJohn Reck#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 47f51de259ada8dacd44eca41945b49a8dba1606aeJohn Reck fGenerationID = 0; 48f51de259ada8dacd44eca41945b49a8dba1606aeJohn Reck#endif 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.orgSkShader::SkShader(SkReadBuffer& buffer) : INHERITED(buffer) { 528fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org inc_shader_counter(); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (buffer.readBool()) { 54f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.readMatrix(&fLocalMatrix); 55f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com } else { 56f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com fLocalMatrix.reset(); 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 58f51de259ada8dacd44eca41945b49a8dba1606aeJohn Reck#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 59f51de259ada8dacd44eca41945b49a8dba1606aeJohn Reck fGenerationID = 0; 60f51de259ada8dacd44eca41945b49a8dba1606aeJohn Reck#endif 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::~SkShader() { 648fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org dec_shader_counter(); 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 678b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkShader::flatten(SkWriteBuffer& buffer) const { 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 695970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org bool hasLocalM = !fLocalMatrix.isIdentity(); 70f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.writeBool(hasLocalM); 71f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com if (hasLocalM) { 72f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com buffer.writeMatrix(fLocalMatrix); 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 76ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgbool SkShader::computeTotalInverse(const ContextRec& rec, SkMatrix* totalInverse) const { 775970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org SkMatrix total; 785970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org total.setConcat(*rec.fMatrix, fLocalMatrix); 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 805970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org const SkMatrix* m = &total; 8180116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org if (rec.fLocalMatrix) { 8280116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org total.setConcat(*m, *rec.fLocalMatrix); 8380116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org m = &total; 8480116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org } 8587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return m->invert(totalInverse); 8687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 8787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 88ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const { 89ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org if (!this->computeTotalInverse(rec, NULL)) { 90ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org return NULL; 91ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org } 92ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org return this->onCreateContext(rec, storage); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9580116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.orgSkShader::Context* SkShader::onCreateContext(const ContextRec& rec, void*) const { 96f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org return NULL; 97f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org} 98f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org 99f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.orgsize_t SkShader::contextSize() const { 100f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org return 0; 101f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org} 102f3e505984d08fb96e753be2b561f479dc3a4c544commit-bot@chromium.org 103e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.orgSkShader::Context::Context(const SkShader& shader, const ContextRec& rec) 10480116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org : fShader(shader), fCTM(*rec.fMatrix) 10587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 10687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Because the context parameters must be valid at this point, we know that the matrix is 10787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // invertible. 108ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org SkAssertResult(fShader.computeTotalInverse(rec, &fTotalInverse)); 10987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 11087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 111e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org fPaintAlpha = rec.fPaint->getAlpha(); 112a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com} 113a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com 11487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::~Context() {} 11587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 11687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) { 1173bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com return NULL; 1183bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com} 1193bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkShader::Context::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(span16); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->canCallShadeSpan16()); 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // basically, if we get here, the subclass screwed up 1280c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1327c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com#define kTempColorCount (kTempColorQuadCount << 2) 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor colors[kTempColorCount]; 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((count -= kTempColorCount) >= 0) { 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, kTempColorCount); 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += kTempColorCount; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int quads = kTempColorQuadCount; 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a0 = srcA[0]; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a1 = srcA[4]; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a2 = srcA[8]; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a3 = srcA[12]; 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4*4; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a0); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a1); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a2); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a3); 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--quads != 0); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count < 0); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count + kTempColorCount >= 0); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count += kTempColorCount) { 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, count); 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n > kTempColorCount) 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = kTempColorCount; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > 0); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, n); 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += n; 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--n != 0); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (count > 0); 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) { 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MatrixClass mc = kLinear_MatrixClass; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1978d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com if (mat.hasPerspective()) { 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.fixedStepInX(0, NULL, NULL)) { 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kFixedStepInX_MatrixClass; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kPerspective_MatrixClass; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mc; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) const { 210f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kNone_BitmapType; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 213d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 214d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kNone_GradientType; 215d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 216d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org 2179de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkShader::asNewEffect(GrContext* context, const SkPaint& paint, 2189de5b514d38c5b36066bcdc14fba2f7e5196d372dandov const SkMatrix* localMatrixOrNull, GrColor* grColor, 2199de5b514d38c5b36066bcdc14fba2f7e5196d372dandov GrEffectRef** grEffect) const { 2209de5b514d38c5b36066bcdc14fba2f7e5196d372dandov return false; 22103c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com} 22203c1c359b336ad20d23ab07004cdafafd14c90a5rileya@google.com 2238fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.orgSkShader* SkShader::refAsALocalMatrixShader(SkMatrix*) const { 2248fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org return NULL; 2258fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org} 2268fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org 227ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader* SkShader::CreateEmptyShader() { 228ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org return SkNEW(SkEmptyShader); 229ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org} 230ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org 2319c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, 2329c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org const SkMatrix* localMatrix) { 2339c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org return ::CreateBitmapShader(src, tmx, tmy, localMatrix, NULL); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2365aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.orgSkShader* SkShader::CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy, 2375aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org const SkMatrix* localMatrix) { 2385aacfe9ffcf1849727dca6761b4a221bd4315f26commit-bot@chromium.org return SkPictureShader::Create(src, tmx, tmy, localMatrix); 239c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org} 240c5d9bb0f677069f62ec76373b9730e70e7352455commit-bot@chromium.org 2410f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 24276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkShader::toString(SkString* str) const { 2435970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org if (!fLocalMatrix.isIdentity()) { 24476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(" "); 2455970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org fLocalMatrix.toString(str); 24676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 24776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 24876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 24976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorShader.h" 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkColorShader::SkColorShader(SkColor c) 25676a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org : fColor(c) { 257f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 258f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 259b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.orgbool SkColorShader::isOpaque() const { 260b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org return SkColorGetA(fColor) == 255; 261b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org} 262b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org 2638b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 26476a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org // V25_COMPATIBILITY_CODE We had a boolean to make the color shader inherit the paint's 26576a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org // color. We don't support that any more. 2667ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org if (b.isVersionLT(SkReadBuffer::kColorShaderNoBool_Version)) { 26776a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org if (b.readBool()) { 26876a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org SkDEBUGFAIL("We shouldn't have pictures that recorded the inherited case."); 26976a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org fColor = SK_ColorWHITE; 27076a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org return; 27176a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org } 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 273c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fColor = b.readColor(); 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2768b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkColorShader::flatten(SkWriteBuffer& buffer) const { 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 278c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeColor(fColor); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint32_t SkColorShader::ColorShaderContext::getFlags() const { 28259ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com return fFlags; 28359ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com} 28459ccef695cef28a74ab2ea13d5a6c9017af45402reed@google.com 28587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const { 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkGetPackedA32(fPMColor); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 289ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const { 290e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, rec)); 29187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 29287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 29387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader, 294e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org const ContextRec& rec) 295e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org : INHERITED(shader, rec) 29687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 2979c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org SkColor color = shader.fColor; 298e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha())); 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned r = SkColorGetR(color); 30187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned g = SkColorGetG(color); 30287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned b = SkColorGetB(color); 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want this before we apply any alpha 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPack888ToRGB16(r, g, b); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a != 255) { 3088f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com r = SkMulDiv255Round(r, a); 3098f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com g = SkMulDiv255Round(g, a); 3108f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com b = SkMulDiv255Round(b, a); 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(a, r, g, b); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3148f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com fFlags = kConstInY32_Flag; 3155b81535014f545f6498f5c8721723b81576989b1reed@android.com if (255 == a) { 3165119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags |= kOpaqueAlpha_Flag; 317e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org if (rec.fPaint->isDither() == false) { 3185b81535014f545f6498f5c8721723b81576989b1reed@android.com fFlags |= kHasSpan16_Flag; 3195b81535014f545f6498f5c8721723b81576989b1reed@android.com } 3205119bdb952025a30f115b9c6a187173956e55097reed@android.com } 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) { 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(span, fPMColor, count); 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpan16(int x, int y, uint16_t span[], int count) { 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(span, fColor16, count); 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, SkGetPackedA32(fPMColor), count); 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 335f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// if we had a asAColor method, that would be more efficient... 336f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 33791f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com TileMode modes[]) const { 3382be9e8b407624fa696854b78b407b97a01dbb703reed@google.com return kNone_BitmapType; 339f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 340f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 341d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.orgSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 342d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info) { 343d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org if (info->fColors && info->fColorCount >= 1) { 344d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColors[0] = fColor; 345d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 346d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fColorCount = 1; 347d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org info->fTileMode = SkShader::kRepeat_TileMode; 348d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org } 349d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org return kColor_GradientType; 350d3ae77965e94e0efda496f5461cbec4533cb5b16vandebo@chromium.org} 35137a201231b8f6381938282675eb9abb50ab3b389reed@google.com 3529de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#if SK_SUPPORT_GPU 3539de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3549de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#include "SkGr.h" 3559de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3569de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint, 3579de5b514d38c5b36066bcdc14fba2f7e5196d372dandov const SkMatrix* localMatrix, GrColor* grColor, 3589de5b514d38c5b36066bcdc14fba2f7e5196d372dandov GrEffectRef** grEffect) const { 3599de5b514d38c5b36066bcdc14fba2f7e5196d372dandov *grEffect = NULL; 3609de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkColor skColor = fColor; 3619de5b514d38c5b36066bcdc14fba2f7e5196d372dandov U8CPU newA = SkMulDiv255Round(SkColorGetA(fColor), paint.getAlpha()); 3629de5b514d38c5b36066bcdc14fba2f7e5196d372dandov *grColor = SkColor2GrColor(SkColorSetA(skColor, newA)); 3639de5b514d38c5b36066bcdc14fba2f7e5196d372dandov return true; 3649de5b514d38c5b36066bcdc14fba2f7e5196d372dandov} 3659de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3669de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#else 3679de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3689de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint, 3699de5b514d38c5b36066bcdc14fba2f7e5196d372dandov const SkMatrix* localMatrix, GrColor* grColor, 3709de5b514d38c5b36066bcdc14fba2f7e5196d372dandov GrEffectRef** grEffect) const { 3719de5b514d38c5b36066bcdc14fba2f7e5196d372dandov SkDEBUGFAIL("Should not call in GPU-less build"); 3729de5b514d38c5b36066bcdc14fba2f7e5196d372dandov return false; 3739de5b514d38c5b36066bcdc14fba2f7e5196d372dandov} 3749de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3759de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#endif 3769de5b514d38c5b36066bcdc14fba2f7e5196d372dandov 3770f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 37876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkColorShader::toString(SkString* str) const { 37976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("SkColorShader: ("); 38076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 38176a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org str->append("Color: "); 38276a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org str->appendHex(fColor); 38376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 38476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 38576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 38676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 38776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 38876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 38976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 39037a201231b8f6381938282675eb9abb50ab3b389reed@google.com/////////////////////////////////////////////////////////////////////////////// 39137a201231b8f6381938282675eb9abb50ab3b389reed@google.com 39287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 39337a201231b8f6381938282675eb9abb50ab3b389reed@google.com#include "SkEmptyShader.h" 39437a201231b8f6381938282675eb9abb50ab3b389reed@google.com 39576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkEmptyShader::toString(SkString* str) const { 39676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("SkEmptyShader: ("); 39776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 39876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 39976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 40076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 40176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com} 40276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 403