SkShader.cpp revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/sgl/SkShader.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::SkShader() : fLocalMatrix(NULL) {
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = false;)
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::SkShader(SkFlattenableReadBuffer& buffer)
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : INHERITED(buffer), fLocalMatrix(NULL) {
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (buffer.readBool()) {
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkMatrix matrix;
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.read(&matrix, sizeof(matrix));
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        setLocalMatrix(matrix);
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = false;)
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::~SkShader() {
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!fInSession);
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    sk_free(fLocalMatrix);
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::beginSession() {
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!fInSession);
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = true;)
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::endSession() {
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fInSession);
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(fInSession = false;)
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::flatten(SkFlattenableWriteBuffer& buffer) {
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeBool(fLocalMatrix != NULL);
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.writeMul4(fLocalMatrix, sizeof(SkMatrix));
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkShader::getLocalMatrix(SkMatrix* localM) const {
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (localM) {
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *localM = *fLocalMatrix;
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (localM) {
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            localM->reset();
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::setLocalMatrix(const SkMatrix& localM) {
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (localM.isIdentity()) {
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->resetLocalMatrix();
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fLocalMatrix == NULL) {
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *fLocalMatrix = localM;
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::resetLocalMatrix() {
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_free(fLocalMatrix);
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fLocalMatrix = NULL;
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkShader::setContext(const SkBitmap& device,
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          const SkPaint& paint,
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          const SkMatrix& matrix) {
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkMatrix* m = &matrix;
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix        total;
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDeviceConfig = SkToU8(device.getConfig());
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaintAlpha = paint.getAlpha();
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fLocalMatrix) {
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        total.setConcat(matrix, *fLocalMatrix);
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        m = &total;
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (m->invert(&fTotalInverse)) {
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) {
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(span16);
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count > 0);
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(this->canCallShadeSpan16());
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // basically, if we get here, the subclass screwed up
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented");
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define kTempColorQuadCount 6   // balance between speed (larger) and saving stack-space
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define kTempColorCount     (kTempColorQuadCount << 2)
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_BENDIAN
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define SkU32BitShiftToByteOffset(shift)    (3 - ((shift) >> 3))
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define SkU32BitShiftToByteOffset(shift)    ((shift) >> 3)
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count > 0);
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPMColor   colors[kTempColorCount];
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((count -= kTempColorCount) >= 0) {
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->shadeSpan(x, y, colors, kTempColorCount);
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x += kTempColorCount;
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int quads = kTempColorQuadCount;
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a0 = srcA[0];
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a1 = srcA[4];
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a2 = srcA[8];
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            U8CPU a3 = srcA[12];
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcA += 4*4;
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a0);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a1);
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a2);
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = SkToU8(a3);
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--quads != 0);
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count < 0);
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count + kTempColorCount >= 0);
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count += kTempColorCount) {
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->shadeSpan(x, y, colors, count);
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = *srcA;
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcA += 4;
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--count != 0);
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int n = count;
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (n > kTempColorCount)
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            n = kTempColorCount;
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(n > 0);
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->shadeSpan(x, y, colors, n);
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x += n;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        count -= n;
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *alpha++ = *srcA;
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcA += 4;
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--n != 0);
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (count > 0);
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) {
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    MatrixClass mc = kLinear_MatrixClass;
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mat.getType() & SkMatrix::kPerspective_Mask) {
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (mat.fixedStepInX(0, NULL, NULL)) {
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            mc = kFixedStepInX_MatrixClass;
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            mc = kPerspective_MatrixClass;
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mc;
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) {
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                       TileMode tmx, TileMode tmy) {
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0);
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorShader.h"
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) {
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fInheritColor = b.readU8();
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fInheritColor) {
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = b.readU32();
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) {
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(fInheritColor);
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fInheritColor) {
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fColor);
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint32_t SkColorShader::getFlags() {
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (SkGetPackedA32(fPMColor) == 255 ? kOpaqueAlpha_Flag : 0) |
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            kHasSpan16_Flag;
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint8_t SkColorShader::getSpan16Alpha() const {
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkGetPackedA32(fPMColor);
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint,
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const SkMatrix& matrix) {
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!this->INHERITED::setContext(device, paint, matrix)) {
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkColor c;
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned a;
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fInheritColor) {
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        c = paint.getColor();
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a = SkColorGetA(c);
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        c = fColor;
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha()));
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned r = SkColorGetR(c);
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned g = SkColorGetG(c);
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned b = SkColorGetB(c);
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // we want this before we apply any alpha
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor16 = SkPack888ToRGB16(r, g, b);
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (a != 255) {
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a = SkAlpha255To256(a);
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        r = SkAlphaMul(r, a);
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        g = SkAlphaMul(g, a);
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        b = SkAlphaMul(b, a);
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPMColor = SkPackARGB32(a, r, g, b);
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    sk_memset32(span, fPMColor, count);
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    sk_memset16(span, fColor16, count);
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memset(alpha, SkGetPackedA32(fPMColor), count);
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
285