OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrSWMaskHelper.h" | 8 #include "GrSWMaskHelper.h" |
9 | 9 |
10 #include "GrDrawState.h" | 10 #include "GrDrawState.h" |
11 #include "GrDrawTargetCaps.h" | 11 #include "GrDrawTargetCaps.h" |
12 #include "GrGpu.h" | 12 #include "GrGpu.h" |
13 | 13 |
14 #include "SkData.h" | 14 #include "SkData.h" |
15 #include "SkStrokeRec.h" | 15 #include "SkStrokeRec.h" |
16 #include "SkTextureCompressor.h" | |
17 | 16 |
18 // TODO: try to remove this #include | 17 // TODO: try to remove this #include |
19 #include "GrContext.h" | 18 #include "GrContext.h" |
20 | 19 |
21 namespace { | 20 namespace { |
22 | 21 |
23 /* | 22 /* |
24 * Convert a boolean operation into a transfer mode code | 23 * Convert a boolean operation into a transfer mode code |
25 */ | 24 */ |
26 SkXfermode::Mode op_to_mode(SkRegion::Op op) { | 25 SkXfermode::Mode op_to_mode(SkRegion::Op op) { |
27 | 26 |
28 static const SkXfermode::Mode modeMap[] = { | 27 static const SkXfermode::Mode modeMap[] = { |
29 SkXfermode::kDstOut_Mode, // kDifference_Op | 28 SkXfermode::kDstOut_Mode, // kDifference_Op |
30 SkXfermode::kModulate_Mode, // kIntersect_Op | 29 SkXfermode::kModulate_Mode, // kIntersect_Op |
31 SkXfermode::kSrcOver_Mode, // kUnion_Op | 30 SkXfermode::kSrcOver_Mode, // kUnion_Op |
32 SkXfermode::kXor_Mode, // kXOR_Op | 31 SkXfermode::kXor_Mode, // kXOR_Op |
33 SkXfermode::kClear_Mode, // kReverseDifference_Op | 32 SkXfermode::kClear_Mode, // kReverseDifference_Op |
34 SkXfermode::kSrc_Mode, // kReplace_Op | 33 SkXfermode::kSrc_Mode, // kReplace_Op |
35 }; | 34 }; |
36 | 35 |
37 return modeMap[op]; | 36 return modeMap[op]; |
38 } | 37 } |
39 | 38 |
| 39 static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) { |
| 40 static const GrPixelConfig configMap[] = { |
| 41 kLATC_GrPixelConfig, // kLATC_Format, |
| 42 kR11_EAC_GrPixelConfig, // kR11_EAC_Format, |
| 43 kASTC_12x12_GrPixelConfig // kASTC_12x12_Format, |
| 44 }; |
| 45 GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); |
| 46 GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); |
| 47 GR_STATIC_ASSERT(2 == SkTextureCompressor::kASTC_12x12_Format); |
| 48 GR_STATIC_ASSERT(SK_ARRAY_COUNT(configMap) == SkTextureCompressor::kFormatCn
t); |
| 49 |
| 50 return configMap[fmt]; |
| 51 } |
| 52 |
40 } | 53 } |
41 | 54 |
42 /** | 55 /** |
43 * Draw a single rect element of the clip stack into the accumulation bitmap | 56 * Draw a single rect element of the clip stack into the accumulation bitmap |
44 */ | 57 */ |
45 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, | 58 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, |
46 bool antiAlias, uint8_t alpha) { | 59 bool antiAlias, uint8_t alpha) { |
47 SkPaint paint; | 60 SkPaint paint; |
48 | 61 |
49 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); | 62 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 fMatrix = *matrix; | 108 fMatrix = *matrix; |
96 } else { | 109 } else { |
97 fMatrix.setIdentity(); | 110 fMatrix.setIdentity(); |
98 } | 111 } |
99 | 112 |
100 // Now translate so the bound's UL corner is at the origin | 113 // Now translate so the bound's UL corner is at the origin |
101 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, | 114 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, |
102 -resultBounds.fTop * SK_Scalar1); | 115 -resultBounds.fTop * SK_Scalar1); |
103 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), | 116 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), |
104 resultBounds.height()); | 117 resultBounds.height()); |
| 118 |
105 #if GR_COMPRESS_ALPHA_MASK | 119 #if GR_COMPRESS_ALPHA_MASK |
| 120 fCompressedFormat = SkTextureCompressor::kR11_EAC_Format; |
| 121 |
106 // Make sure that the width is a multiple of 16 so that we can use | 122 // Make sure that the width is a multiple of 16 so that we can use |
107 // specialized SIMD instructions that compress 4 blocks at a time. | 123 // specialized SIMD instructions that compress 4 blocks at a time. |
108 const int cmpWidth = (bounds.fRight + 15) & ~15; | 124 int dimX, dimY; |
109 const int cmpHeight = (bounds.fBottom + 3) & ~3; | 125 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); |
| 126 const int cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); |
| 127 const int cmpHeight = dimY * ((bounds.fRight + (dimY - 1)) / dimY); |
110 #else | 128 #else |
111 const int cmpWidth = bounds.fRight; | 129 const int cmpWidth = bounds.fRight; |
112 const int cmpHeight = bounds.fBottom; | 130 const int cmpHeight = bounds.fBottom; |
113 #endif | 131 #endif |
114 | 132 |
115 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { | 133 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { |
116 return false; | 134 return false; |
117 } | 135 } |
118 | 136 |
119 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | 137 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); |
120 | 138 |
121 sk_bzero(&fDraw, sizeof(fDraw)); | 139 sk_bzero(&fDraw, sizeof(fDraw)); |
122 fRasterClip.setRect(bounds); | 140 fRasterClip.setRect(bounds); |
123 fDraw.fRC = &fRasterClip; | 141 fDraw.fRC = &fRasterClip; |
124 fDraw.fClip = &fRasterClip.bwRgn(); | 142 fDraw.fClip = &fRasterClip.bwRgn(); |
125 fDraw.fMatrix = &fMatrix; | 143 fDraw.fMatrix = &fMatrix; |
126 fDraw.fBitmap = &fBM; | 144 fDraw.fBitmap = &fBM; |
127 return true; | 145 return true; |
128 } | 146 } |
129 | 147 |
130 /** | 148 /** |
131 * Get a texture (from the texture cache) of the correct size & format. | 149 * Get a texture (from the texture cache) of the correct size & format. |
132 * Return true on success; false on failure. | 150 * Return true on success; false on failure. |
133 */ | 151 */ |
134 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { | 152 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
135 GrTextureDesc desc; | 153 GrTextureDesc desc; |
136 desc.fWidth = fBM.width(); | 154 desc.fWidth = fBM.width(); |
137 desc.fHeight = fBM.height(); | 155 desc.fHeight = fBM.height(); |
138 desc.fConfig = kAlpha_8_GrPixelConfig; | |
139 | 156 |
140 #if GR_COMPRESS_ALPHA_MASK | 157 #if GR_COMPRESS_ALPHA_MASK |
141 static const int kCompressedBlockSize = 4; | |
142 static const GrPixelConfig kCompressedConfig = kR11_EAC_GrPixelConfig; | |
143 | 158 |
144 if (desc.fWidth % kCompressedBlockSize == 0 && | 159 #ifdef SK_DEBUG |
145 desc.fHeight % kCompressedBlockSize == 0) { | 160 int dimX, dimY; |
146 desc.fConfig = kCompressedConfig; | 161 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); |
147 } | 162 SkASSERT((desc.fWidth % dimX) == 0); |
| 163 SkASSERT((desc.fHeight % dimY) == 0); |
| 164 #endif |
| 165 |
| 166 desc.fConfig = fmt_to_config(fCompressedFormat); |
148 | 167 |
149 // If this config isn't supported then we should fall back to A8 | 168 // If this config isn't supported then we should fall back to A8 |
150 if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { | 169 if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { |
151 desc.fConfig = kAlpha_8_GrPixelConfig; | 170 desc.fConfig = kAlpha_8_GrPixelConfig; |
152 } | 171 } |
| 172 #else |
| 173 desc.fConfig = kAlpha_8_GrPixelConfig; |
153 #endif | 174 #endif |
154 | 175 |
155 texture->set(fContext, desc); | 176 texture->set(fContext, desc); |
156 return NULL != texture->texture(); | 177 return NULL != texture->texture(); |
157 } | 178 } |
158 | 179 |
159 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de
sc, | 180 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de
sc, |
160 const void *data, int rowbytes) { | 181 const void *data, int rowbytes) { |
161 // If we aren't reusing scratch textures we don't need to flush before | 182 // If we aren't reusing scratch textures we don't need to flush before |
162 // writing since no one else will be using 'texture' | 183 // writing since no one else will be using 'texture' |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 maskMatrix.preConcat(drawState->getViewMatrix()); | 293 maskMatrix.preConcat(drawState->getViewMatrix()); |
273 | 294 |
274 drawState->addCoverageEffect( | 295 drawState->addCoverageEffect( |
275 GrSimpleTextureEffect::Create(texture, | 296 GrSimpleTextureEffect::Create(texture, |
276 maskMatrix, | 297 maskMatrix, |
277 GrTextureParams::kNone_Fi
lterMode, | 298 GrTextureParams::kNone_Fi
lterMode, |
278 kPosition_GrCoordSet))->u
nref(); | 299 kPosition_GrCoordSet))->u
nref(); |
279 | 300 |
280 target->drawSimpleRect(dstRect); | 301 target->drawSimpleRect(dstRect); |
281 } | 302 } |
OLD | NEW |