blob: 7ec5ff7c8e50700f81b27f6de2d211484b7d1b83 [file] [log] [blame]
croachrose48ede9b2006-11-08 19:24:48 +00001/* libs/graphics/sgl/SkShader.cpp
2**
3** Copyright 2006, Google Inc.
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
croachrose0f87cd82006-09-20 15:47:42 +000018#include "SkShader.h"
19#include "SkPaint.h"
20
croachrose48ede9b2006-11-08 19:24:48 +000021SkShader::SkShader() : fLocalMatrix(NULL)
croachrose0f87cd82006-09-20 15:47:42 +000022{
23}
24
25SkShader::~SkShader()
26{
croachrose48ede9b2006-11-08 19:24:48 +000027 sk_free(fLocalMatrix);
croachrose0f87cd82006-09-20 15:47:42 +000028}
29
30void SkShader::setLocalMatrix(const SkMatrix& matrix)
31{
croachrose48ede9b2006-11-08 19:24:48 +000032 if (matrix.isIdentity())
33 {
34 if (fLocalMatrix)
35 {
36 sk_free(fLocalMatrix);
37 fLocalMatrix = NULL;
38 }
39 }
40 else
41 {
42 if (fLocalMatrix == NULL)
43 fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
44 *fLocalMatrix = matrix;
45 }
croachrose0f87cd82006-09-20 15:47:42 +000046}
47
48bool SkShader::setContext(const SkBitmap& device,
croachrose48ede9b2006-11-08 19:24:48 +000049 const SkPaint& paint,
50 const SkMatrix& matrix)
croachrose0f87cd82006-09-20 15:47:42 +000051{
croachrose48ede9b2006-11-08 19:24:48 +000052 const SkMatrix* m = &matrix;
53 SkMatrix total;
croachrose0f87cd82006-09-20 15:47:42 +000054
croachrose48ede9b2006-11-08 19:24:48 +000055 fDeviceConfig = SkToU8(device.getConfig());
56 fPaintAlpha = paint.getAlpha();
57 if (fLocalMatrix)
58 {
59 total.setConcat(matrix, *fLocalMatrix);
60 m = &total;
61 }
62 if (m->invert(&fTotalInverse))
63 {
64 fInverseMapPtProc = fTotalInverse.getMapPtProc();
65 fTotalInverseClass = (uint8_t)SkShader::ComputeMatrixClass(fTotalInverse);
66 return true;
67 }
68 return false;
croachrose0f87cd82006-09-20 15:47:42 +000069}
70
71#include "SkColorPriv.h"
72
croachrose48ede9b2006-11-08 19:24:48 +000073void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count)
croachrose0f87cd82006-09-20 15:47:42 +000074{
croachrose48ede9b2006-11-08 19:24:48 +000075 SkASSERT(span16);
76 SkASSERT(count > 0);
77 SkASSERT(this->canCallShadeSpan16());
croachrose0f87cd82006-09-20 15:47:42 +000078
croachrose48ede9b2006-11-08 19:24:48 +000079 // basically, if we get here, the subclass screwed up
80 SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented");
croachrose0f87cd82006-09-20 15:47:42 +000081}
82
croachrose48ede9b2006-11-08 19:24:48 +000083#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space
84#define kTempColorCount (kTempColorQuadCount << 2)
croachrose0f87cd82006-09-20 15:47:42 +000085
86#ifdef SK_CPU_BENDIAN
croachrose48ede9b2006-11-08 19:24:48 +000087 #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3))
croachrose0f87cd82006-09-20 15:47:42 +000088#else
croachrose48ede9b2006-11-08 19:24:48 +000089 #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3)
croachrose0f87cd82006-09-20 15:47:42 +000090#endif
91
croachrose48ede9b2006-11-08 19:24:48 +000092void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count)
croachrose0f87cd82006-09-20 15:47:42 +000093{
croachrose48ede9b2006-11-08 19:24:48 +000094 SkASSERT(count > 0);
croachrose0f87cd82006-09-20 15:47:42 +000095
croachrose48ede9b2006-11-08 19:24:48 +000096 SkPMColor colors[kTempColorCount];
croachrose0f87cd82006-09-20 15:47:42 +000097
croachrose48ede9b2006-11-08 19:24:48 +000098 while ((count -= kTempColorCount) >= 0)
99 {
100 this->shadeSpan(x, y, colors, kTempColorCount);
101 x += kTempColorCount;
croachrose0f87cd82006-09-20 15:47:42 +0000102
croachrose48ede9b2006-11-08 19:24:48 +0000103 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
104 int quads = kTempColorQuadCount;
105 do {
106 U8CPU a0 = srcA[0];
107 U8CPU a1 = srcA[4];
108 U8CPU a2 = srcA[8];
109 U8CPU a3 = srcA[12];
110 srcA += 4*4;
111 *alpha++ = SkToU8(a0);
112 *alpha++ = SkToU8(a1);
113 *alpha++ = SkToU8(a2);
114 *alpha++ = SkToU8(a3);
115 } while (--quads != 0);
116 }
117 SkASSERT(count < 0);
118 SkASSERT(count + kTempColorCount >= 0);
119 if (count += kTempColorCount)
120 {
121 this->shadeSpan(x, y, colors, count);
croachrose0f87cd82006-09-20 15:47:42 +0000122
croachrose48ede9b2006-11-08 19:24:48 +0000123 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
124 do {
125 *alpha++ = *srcA;
126 srcA += 4;
127 } while (--count != 0);
128 }
croachrose0f87cd82006-09-20 15:47:42 +0000129#if 0
croachrose48ede9b2006-11-08 19:24:48 +0000130 do {
131 int n = count;
132 if (n > kTempColorCount)
133 n = kTempColorCount;
134 SkASSERT(n > 0);
croachrose0f87cd82006-09-20 15:47:42 +0000135
croachrose48ede9b2006-11-08 19:24:48 +0000136 this->shadeSpan(x, y, colors, n);
137 x += n;
138 count -= n;
croachrose0f87cd82006-09-20 15:47:42 +0000139
croachrose48ede9b2006-11-08 19:24:48 +0000140 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
141 do {
142 *alpha++ = *srcA;
143 srcA += 4;
144 } while (--n != 0);
145 } while (count > 0);
croachrose0f87cd82006-09-20 15:47:42 +0000146#endif
147}
148
149SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat)
150{
croachrose48ede9b2006-11-08 19:24:48 +0000151 MatrixClass mc = kLinear_MatrixClass;
croachrose0f87cd82006-09-20 15:47:42 +0000152
croachrose48ede9b2006-11-08 19:24:48 +0000153 if (mat.getType() & SkMatrix::kPerspective_Mask)
154 {
155 if (mat.fixedStepInX(0, NULL, NULL))
156 mc = kFixedStepInX_MatrixClass;
157 else
158 mc = kPerspective_MatrixClass;
159 }
160 return mc;
croachrose0f87cd82006-09-20 15:47:42 +0000161}
162