SkShader.cpp revision f2b98d67dcb6fcb3120feede9c72016fc7b3ead8
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* libs/graphics/sgl/SkShader.cpp 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Copyright 2006, The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Licensed under the Apache License, Version 2.0 (the "License"); 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** you may not use this file except in compliance with the License. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** You may obtain a copy of the License at 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** http://www.apache.org/licenses/LICENSE-2.0 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Unless required by applicable law or agreed to in writing, software 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** distributed under the License is distributed on an "AS IS" BASIS, 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** See the License for the specific language governing permissions and 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** limitations under the License. 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 20f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include "SkMallocPixelRef.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::SkShader() : fLocalMatrix(NULL) { 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::SkShader(SkFlattenableReadBuffer& buffer) 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(buffer), fLocalMatrix(NULL) { 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (buffer.readBool()) { 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.read(&matrix, sizeof(matrix)); 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com setLocalMatrix(matrix); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::~SkShader() { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fInSession); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fLocalMatrix); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::beginSession() { 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fInSession); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = true;) 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::endSession() { 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fInSession); 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fInSession = false;) 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::flatten(SkFlattenableWriteBuffer& buffer) { 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeBool(fLocalMatrix != NULL); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeMul4(fLocalMatrix, sizeof(SkMatrix)); 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkShader::getLocalMatrix(SkMatrix* localM) const { 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM) { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *localM = *fLocalMatrix; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM) { 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com localM->reset(); 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::setLocalMatrix(const SkMatrix& localM) { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (localM.isIdentity()) { 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->resetLocalMatrix(); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix == NULL) { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix)); 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fLocalMatrix = localM; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::resetLocalMatrix() { 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fLocalMatrix); 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalMatrix = NULL; 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkShader::setContext(const SkBitmap& device, 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix) { 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* m = &matrix; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix total; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceConfig = SkToU8(device.getConfig()); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaintAlpha = paint.getAlpha(); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLocalMatrix) { 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com total.setConcat(matrix, *fLocalMatrix); 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com m = &total; 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (m->invert(&fTotalInverse)) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(span16); 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->canCallShadeSpan16()); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // basically, if we get here, the subclass screwed up 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kTempColorCount (kTempColorQuadCount << 2) 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_CPU_BENDIAN 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor colors[kTempColorCount]; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((count -= kTempColorCount) >= 0) { 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, kTempColorCount); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += kTempColorCount; 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int quads = kTempColorQuadCount; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a0 = srcA[0]; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a1 = srcA[4]; 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a2 = srcA[8]; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U8CPU a3 = srcA[12]; 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4*4; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a0); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a1); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a2); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = SkToU8(a3); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--quads != 0); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count < 0); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count + kTempColorCount >= 0); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count += kTempColorCount) { 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, count); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count != 0); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (n > kTempColorCount) 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = kTempColorCount; 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(n > 0); 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->shadeSpan(x, y, colors, n); 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += n; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *alpha++ = *srcA; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcA += 4; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--n != 0); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (count > 0); 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MatrixClass mc = kLinear_MatrixClass; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.getType() & SkMatrix::kPerspective_Mask) { 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mat.fixedStepInX(0, NULL, NULL)) { 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kFixedStepInX_MatrixClass; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mc = kPerspective_MatrixClass; 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mc; 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 199f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 200f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com TileMode*, SkScalar*) { 201f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kNone_BitmapType; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com TileMode tmx, TileMode tmy) { 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorShader.h" 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 214f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::SkColorShader() { 215f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fFlags = 0; 216f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = true; 217f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = NULL; 218f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 219f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 220f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::SkColorShader(SkColor c) { 221f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fFlags = 0; 222f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fColor = c; 223f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = false; 224f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = NULL; 225f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 226f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 227f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkColorShader::~SkColorShader() { 228f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkSafeUnref(fAsABitmapPixelRef); 229f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 230f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) { 2325119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags = 0; // computed in setContext 233f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = NULL; 234f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 235f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fInheritColor = b.readU8(); 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor = b.readU32(); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) { 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write8(fInheritColor); 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write32(fColor); 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comuint8_t SkColorShader::getSpan16Alpha() const { 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkGetPackedA32(fPMColor); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix) { 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->INHERITED::setContext(device, paint, matrix)) { 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkColor c; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a; 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fInheritColor) { 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com c = paint.getColor(); 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a = SkColorGetA(c); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com c = fColor; 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha())); 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkColorGetR(c); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkColorGetG(c); 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkColorGetB(c); 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want this before we apply any alpha 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor16 = SkPack888ToRGB16(r, g, b); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a != 255) { 2808f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com r = SkMulDiv255Round(r, a); 2818f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com g = SkMulDiv255Round(g, a); 2828f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com b = SkMulDiv255Round(b, a); 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(a, r, g, b); 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2868f073382bb6a9b3998a74e6b58654476b77b4c86reed@android.com fFlags = kConstInY32_Flag; 2875b81535014f545f6498f5c8721723b81576989b1reed@android.com if (255 == a) { 2885119bdb952025a30f115b9c6a187173956e55097reed@android.com fFlags |= kOpaqueAlpha_Flag; 2895b81535014f545f6498f5c8721723b81576989b1reed@android.com if (paint.isDither() == false) { 2905b81535014f545f6498f5c8721723b81576989b1reed@android.com fFlags |= kHasSpan16_Flag; 2915b81535014f545f6498f5c8721723b81576989b1reed@android.com } 2925119bdb952025a30f115b9c6a187173956e55097reed@android.com } 2935119bdb952025a30f115b9c6a187173956e55097reed@android.com 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(span, fPMColor, count); 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16(span, fColor16, count); 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(alpha, SkGetPackedA32(fPMColor), count); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 309f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com// if we had a asAColor method, that would be more efficient... 310f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 311f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com TileMode modes[], 312f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkScalar* twoPointRadialParams) { 313f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com // we cache the pixelref, since its generateID is used in the texture cache 314f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (NULL == fAsABitmapPixelRef) { 315f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkPMColor* storage = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor)); 316f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com *storage = fPMColor; 317f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fAsABitmapPixelRef = new SkMallocPixelRef(storage, sizeof(SkPMColor), 318f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com NULL); 319f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 320f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 321f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (bitmap) { 322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com bitmap->setConfig(SkBitmap::kARGB_8888_Config, 1, 1); 323f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com bitmap->setPixelRef(fAsABitmapPixelRef); 324f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 325f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (matrix) { 326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com matrix->reset(); 327f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 328f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (modes) { 329f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com modes[0] = modes[1] = SkShader::kRepeat_TileMode; 330f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 331f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return kDefault_BitmapType; 332f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 334