SkShader.cpp revision 37a201231b8f6381938282675eb9abb50ab3b389
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* libs/graphics/sgl/SkShader.cpp 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Copyright 2006, The Android Open Source Project 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Licensed under the Apache License, Version 2.0 (the "License"); 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** you may not use this file except in compliance with the License. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** You may obtain a copy of the License at 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** http://www.apache.org/licenses/LICENSE-2.0 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Unless required by applicable law or agreed to in writing, software 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** distributed under the License is distributed on an "AS IS" BASIS, 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** See the License for the specific language governing permissions and 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci** limitations under the License. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkScalar.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkShader.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkPaint.h" 21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "SkMallocPixelRef.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkShader::SkShader() : fLocalMatrix(NULL) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkDEBUGCODE(fInSession = false;) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkShader::SkShader(SkFlattenableReadBuffer& buffer) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : INHERITED(buffer), fLocalMatrix(NULL) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer.readBool()) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix matrix; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkReadMatrix(&buffer, &matrix); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setLocalMatrix(matrix); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkDEBUGCODE(fInSession = false;) 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkShader::~SkShader() { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(!fInSession); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sk_free(fLocalMatrix); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::beginSession() { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(!fInSession); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkDEBUGCODE(fInSession = true;) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::endSession() { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(fInSession); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkDEBUGCODE(fInSession = false;) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::flatten(SkFlattenableWriteBuffer& buffer) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->INHERITED::flatten(buffer); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buffer.writeBool(fLocalMatrix != NULL); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fLocalMatrix) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkWriteMatrix(&buffer, *fLocalMatrix); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkShader::getLocalMatrix(SkMatrix* localM) const { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fLocalMatrix) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (localM) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *localM = *fLocalMatrix; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (localM) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) localM->reset(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::setLocalMatrix(const SkMatrix& localM) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (localM.isIdentity()) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->resetLocalMatrix(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fLocalMatrix == NULL) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fLocalMatrix = localM; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::resetLocalMatrix() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fLocalMatrix) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sk_free(fLocalMatrix); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fLocalMatrix = NULL; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool SkShader::setContext(const SkBitmap& device, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkPaint& paint, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkMatrix& matrix) { 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SkMatrix* m = &matrix; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMatrix total; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fDeviceConfig = SkToU8(device.getConfig()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fPaintAlpha = paint.getAlpha(); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fLocalMatrix) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total.setConcat(matrix, *fLocalMatrix); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m = &total; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (m->invert(&fTotalInverse)) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkColorPriv.h" 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(span16); 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SkASSERT(count > 0); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SkASSERT(this->canCallShadeSpan16()); 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // basically, if we get here, the subclass screwed up 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented"); 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define kTempColorCount (kTempColorQuadCount << 2) 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifdef SK_CPU_BENDIAN 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(count > 0); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPMColor colors[kTempColorCount]; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((count -= kTempColorCount) >= 0) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->shadeSpan(x, y, colors, kTempColorCount); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += kTempColorCount; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int quads = kTempColorQuadCount; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) U8CPU a0 = srcA[0]; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) U8CPU a1 = srcA[4]; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) U8CPU a2 = srcA[8]; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) U8CPU a3 = srcA[12]; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srcA += 4*4; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *alpha++ = SkToU8(a0); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *alpha++ = SkToU8(a1); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *alpha++ = SkToU8(a2); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *alpha++ = SkToU8(a3); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (--quads != 0); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(count < 0); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(count + kTempColorCount >= 0); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count += kTempColorCount) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->shadeSpan(x, y, colors, count); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *alpha++ = *srcA; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srcA += 4; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (--count != 0); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if 0 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) do { 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int n = count; 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (n > kTempColorCount) 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci n = kTempColorCount; 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SkASSERT(n > 0); 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this->shadeSpan(x, y, colors, n); 173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) x += n; 174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) count -= n; 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) do { 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *alpha++ = *srcA; 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) srcA += 4; 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } while (--n != 0); 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } while (count > 0); 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MatrixClass mc = kLinear_MatrixClass; 187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (mat.hasPerspective()) { 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (mat.fixedStepInX(0, NULL, NULL)) { 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) mc = kFixedStepInX_MatrixClass; 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) mc = kPerspective_MatrixClass; 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return mc; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TileMode*, SkScalar*) const { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kNone_BitmapType; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kNone_GradientType; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TileMode tmx, TileMode tmy) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkColorShader.h" 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkUtils.h" 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColorShader::SkColorShader() { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fFlags = 0; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fInheritColor = true; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fAsABitmapPixelRef = NULL; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColorShader::SkColorShader(SkColor c) { 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fFlags = 0; 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fColor = c; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fInheritColor = false; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fAsABitmapPixelRef = NULL; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColorShader::~SkColorShader() { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkSafeUnref(fAsABitmapPixelRef); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) { 237 fFlags = 0; // computed in setContext 238 fAsABitmapPixelRef = NULL; 239 240 fInheritColor = b.readU8(); 241 if (fInheritColor) { 242 return; 243 } 244 fColor = b.readU32(); 245} 246 247void SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) { 248 this->INHERITED::flatten(buffer); 249 buffer.write8(fInheritColor); 250 if (fInheritColor) { 251 return; 252 } 253 buffer.write32(fColor); 254} 255 256uint8_t SkColorShader::getSpan16Alpha() const { 257 return SkGetPackedA32(fPMColor); 258} 259 260bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 261 const SkMatrix& matrix) { 262 if (!this->INHERITED::setContext(device, paint, matrix)) { 263 return false; 264 } 265 266 unsigned a; 267 268 if (fInheritColor) { 269 fColor = paint.getColor(); 270 a = SkColorGetA(fColor); 271 } else { 272 a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha())); 273 } 274 275 unsigned r = SkColorGetR(fColor); 276 unsigned g = SkColorGetG(fColor); 277 unsigned b = SkColorGetB(fColor); 278 279 // we want this before we apply any alpha 280 fColor16 = SkPack888ToRGB16(r, g, b); 281 282 if (a != 255) { 283 r = SkMulDiv255Round(r, a); 284 g = SkMulDiv255Round(g, a); 285 b = SkMulDiv255Round(b, a); 286 } 287 fPMColor = SkPackARGB32(a, r, g, b); 288 289 fFlags = kConstInY32_Flag; 290 if (255 == a) { 291 fFlags |= kOpaqueAlpha_Flag; 292 if (paint.isDither() == false) { 293 fFlags |= kHasSpan16_Flag; 294 } 295 } 296 297 return true; 298} 299 300void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 301 sk_memset32(span, fPMColor, count); 302} 303 304void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 305 sk_memset16(span, fColor16, count); 306} 307 308void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 309 memset(alpha, SkGetPackedA32(fPMColor), count); 310} 311 312// if we had a asAColor method, that would be more efficient... 313SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 314 TileMode modes[], 315 SkScalar* twoPointRadialParams) const { 316 // we cache the pixelref, since its generateID is used in the texture cache 317 if (NULL == fAsABitmapPixelRef) { 318 SkPMColor* storage = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor)); 319 *storage = fPMColor; 320 fAsABitmapPixelRef = new SkMallocPixelRef(storage, sizeof(SkPMColor), 321 NULL); 322 } 323 324 if (bitmap) { 325 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 1, 1); 326 bitmap->setPixelRef(fAsABitmapPixelRef); 327 } 328 if (matrix) { 329 matrix->reset(); 330 } 331 if (modes) { 332 modes[0] = modes[1] = SkShader::kRepeat_TileMode; 333 } 334 return kDefault_BitmapType; 335} 336 337SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 338 if (info) { 339 if (info->fColors && info->fColorCount >= 1) { 340 info->fColors[0] = fColor; 341 } 342 info->fColorCount = 1; 343 info->fTileMode = SkShader::kRepeat_TileMode; 344 } 345 return kColor_GradientType; 346} 347 348/////////////////////////////////////////////////////////////////////////////// 349 350#include "SkEmptyShader.h" 351 352SkEmptyShader::SkEmptyShader() {} 353SkEmptyShader::SkEmptyShader(SkFlattenableReadBuffer& b) : INHERITED(b) {} 354 355uint32_t SkEmptyShader::getFlags() { return 0; } 356uint8_t SkEmptyShader::getSpan16Alpha() const { return 0; } 357bool SkEmptyShader::setContext(const SkBitmap& device, const SkPaint& paint, 358 const SkMatrix& matrix) { 359 return false; 360} 361void SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) {} 362void SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) {} 363void SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {} 364 365SkFlattenable::Factory SkEmptyShader::getFactory() { return NULL; } 366void SkEmptyShader::flatten(SkFlattenableWriteBuffer& buffer) { 367 this->INHERITED::flatten(buffer); 368} 369 370