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" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 kASTC_12x12_GrPixelConfig // kASTC_12x12_Format, | 43 kASTC_12x12_GrPixelConfig // kASTC_12x12_Format, |
44 }; | 44 }; |
45 GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); | 45 GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); |
46 GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); | 46 GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); |
47 GR_STATIC_ASSERT(2 == SkTextureCompressor::kASTC_12x12_Format); | 47 GR_STATIC_ASSERT(2 == SkTextureCompressor::kASTC_12x12_Format); |
48 GR_STATIC_ASSERT(SK_ARRAY_COUNT(configMap) == SkTextureCompressor::kFormatCn t); | 48 GR_STATIC_ASSERT(SK_ARRAY_COUNT(configMap) == SkTextureCompressor::kFormatCn t); |
49 | 49 |
50 return configMap[fmt]; | 50 return configMap[fmt]; |
51 } | 51 } |
52 | 52 |
53 #if GR_COMPRESS_ALPHA_MASK | |
robertphillips
2014/07/30 12:15:49
I would reverse the order of the arguments.
Would
krajcevski
2014/07/30 15:10:19
Done.
| |
54 static bool choose_compressed_fmt(SkTextureCompressor::Format *fmt, GrContext *c tx) { | |
55 if (NULL == fmt) { | |
56 return false; | |
57 } | |
58 | |
59 // Figure out what our preferred texture type is. If ASTC is available, that always | |
60 // gives the biggest win. Otherwise, in terms of compression speed and accur acy, | |
61 // LATC has a slight edge over R11 EAC. | |
62 bool result = false; | |
63 if (ctx->getGpu()->caps()->isConfigTexturable(kASTC_12x12_GrPixelConfig)) { | |
64 *fmt = SkTextureCompressor::kASTC_12x12_Format; | |
65 result = true; | |
66 } else if (ctx->getGpu()->caps()->isConfigTexturable(kLATC_GrPixelConfig)) { | |
67 *fmt = SkTextureCompressor::kLATC_Format; | |
68 result = true; | |
69 } else if (ctx->getGpu()->caps()->isConfigTexturable(kR11_EAC_GrPixelConfig) ) { | |
70 *fmt = SkTextureCompressor::kR11_EAC_Format; | |
71 result = true; | |
robertphillips
2014/07/30 12:15:49
We usually only use #error in preprocessor-ish cod
krajcevski
2014/07/30 15:10:19
Done.
| |
72 #error "FIXME: Is there a way to find out if we're on desktop or not?" | |
73 } | |
74 | |
75 return result; | |
76 } | |
77 #endif | |
78 | |
53 } | 79 } |
54 | 80 |
55 /** | 81 /** |
56 * Draw a single rect element of the clip stack into the accumulation bitmap | 82 * Draw a single rect element of the clip stack into the accumulation bitmap |
57 */ | 83 */ |
58 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, | 84 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, |
59 bool antiAlias, uint8_t alpha) { | 85 bool antiAlias, uint8_t alpha) { |
60 SkPaint paint; | 86 SkPaint paint; |
61 | 87 |
62 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); | 88 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 fMatrix.setIdentity(); | 136 fMatrix.setIdentity(); |
111 } | 137 } |
112 | 138 |
113 // Now translate so the bound's UL corner is at the origin | 139 // Now translate so the bound's UL corner is at the origin |
114 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, | 140 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, |
115 -resultBounds.fTop * SK_Scalar1); | 141 -resultBounds.fTop * SK_Scalar1); |
116 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), | 142 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), |
117 resultBounds.height()); | 143 resultBounds.height()); |
118 | 144 |
119 #if GR_COMPRESS_ALPHA_MASK | 145 #if GR_COMPRESS_ALPHA_MASK |
120 fCompressedFormat = SkTextureCompressor::kR11_EAC_Format; | 146 fCompressMask = choose_compressed_fmt(&fCompressedFormat, fContext); |
147 #else | |
148 fCompressMask = false; | |
149 #endif | |
121 | 150 |
122 // Make sure that the width is a multiple of 16 so that we can use | 151 // Make sure that the width is a multiple of 16 so that we can use |
123 // specialized SIMD instructions that compress 4 blocks at a time. | 152 // specialized SIMD instructions that compress 4 blocks at a time. |
124 int dimX, dimY; | 153 int cmpWidth, cmpHeight; |
125 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); | 154 if (fCompressMask) { |
126 const int cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); | 155 int dimX, dimY; |
127 const int cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); | 156 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; |
128 #else | 157 cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); |
129 const int cmpWidth = bounds.fRight; | 158 cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); |
130 const int cmpHeight = bounds.fBottom; | 159 } else { |
131 #endif | 160 cmpWidth = bounds.fRight; |
161 cmpHeight = bounds.fBottom; | |
162 } | |
132 | 163 |
133 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { | 164 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { |
134 return false; | 165 return false; |
135 } | 166 } |
136 | 167 |
137 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | 168 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); |
138 | 169 |
139 sk_bzero(&fDraw, sizeof(fDraw)); | 170 sk_bzero(&fDraw, sizeof(fDraw)); |
140 fRasterClip.setRect(bounds); | 171 fRasterClip.setRect(bounds); |
141 fDraw.fRC = &fRasterClip; | 172 fDraw.fRC = &fRasterClip; |
142 fDraw.fClip = &fRasterClip.bwRgn(); | 173 fDraw.fClip = &fRasterClip.bwRgn(); |
143 fDraw.fMatrix = &fMatrix; | 174 fDraw.fMatrix = &fMatrix; |
144 fDraw.fBitmap = &fBM; | 175 fDraw.fBitmap = &fBM; |
145 return true; | 176 return true; |
146 } | 177 } |
147 | 178 |
148 /** | 179 /** |
149 * Get a texture (from the texture cache) of the correct size & format. | 180 * Get a texture (from the texture cache) of the correct size & format. |
150 * Return true on success; false on failure. | 181 * Return true on success; false on failure. |
151 */ | 182 */ |
152 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { | 183 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
153 GrTextureDesc desc; | 184 GrTextureDesc desc; |
154 desc.fWidth = fBM.width(); | 185 desc.fWidth = fBM.width(); |
155 desc.fHeight = fBM.height(); | 186 desc.fHeight = fBM.height(); |
187 desc.fConfig = kAlpha_8_GrPixelConfig; | |
156 | 188 |
157 #if GR_COMPRESS_ALPHA_MASK | 189 if (fCompressMask) { |
158 | 190 |
159 #ifdef SK_DEBUG | 191 #ifdef SK_DEBUG |
160 int dimX, dimY; | 192 int dimX, dimY; |
161 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); | 193 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; |
162 SkASSERT((desc.fWidth % dimX) == 0); | 194 SkASSERT((desc.fWidth % dimX) == 0); |
163 SkASSERT((desc.fHeight % dimY) == 0); | 195 SkASSERT((desc.fHeight % dimY) == 0); |
164 #endif | 196 #endif |
165 | 197 |
166 desc.fConfig = fmt_to_config(fCompressedFormat); | 198 desc.fConfig = fmt_to_config(fCompressedFormat); |
167 | 199 |
168 // If this config isn't supported then we should fall back to A8 | 200 // If this config isn't supported then we should fall back to A8 |
169 if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { | 201 if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { |
170 desc.fConfig = kAlpha_8_GrPixelConfig; | 202 desc.fConfig = kAlpha_8_GrPixelConfig; |
203 } | |
171 } | 204 } |
172 #else | |
173 desc.fConfig = kAlpha_8_GrPixelConfig; | |
174 #endif | |
175 | 205 |
176 texture->set(fContext, desc); | 206 texture->set(fContext, desc); |
177 return NULL != texture->texture(); | 207 return NULL != texture->texture(); |
178 } | 208 } |
179 | 209 |
180 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de sc, | 210 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de sc, |
181 const void *data, int rowbytes) { | 211 const void *data, int rowbytes) { |
182 // If we aren't reusing scratch textures we don't need to flush before | 212 // If we aren't reusing scratch textures we don't need to flush before |
183 // writing since no one else will be using 'texture' | 213 // writing since no one else will be using 'texture' |
184 bool reuseScratch = fContext->getGpu()->caps()->reuseScratchTextures(); | 214 bool reuseScratch = fContext->getGpu()->caps()->reuseScratchTextures(); |
185 | 215 |
186 // Since we're uploading to it, and it's compressed, 'texture' shouldn't | 216 // Since we're uploading to it, and it's compressed, 'texture' shouldn't |
187 // have a render target. | 217 // have a render target. |
188 SkASSERT(NULL == texture->asRenderTarget()); | 218 SkASSERT(NULL == texture->asRenderTarget()); |
189 | 219 |
190 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, | 220 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, |
191 desc.fConfig, data, rowbytes, | 221 desc.fConfig, data, rowbytes, |
192 reuseScratch ? 0 : GrContext::kDontFlush_PixelOpsFlag); | 222 reuseScratch ? 0 : GrContext::kDontFlush_PixelOpsFlag); |
193 } | 223 } |
194 | 224 |
195 void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrTextureDesc & desc) { | 225 void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrTextureDesc & desc) { |
196 | 226 |
197 SkASSERT(GrPixelConfigIsCompressed(desc.fConfig)); | 227 SkASSERT(GrPixelConfigIsCompressed(desc.fConfig)); |
228 SkASSERT(fmt_to_config(fCompressedFormat) == desc.fConfig); | |
198 | 229 |
199 SkTextureCompressor::Format format = SkTextureCompressor::kLATC_Format; | 230 SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fBM, fCo mpressedFormat)); |
200 | |
201 // Choose the format required by the texture descriptor. | |
202 switch(desc.fConfig) { | |
203 case kLATC_GrPixelConfig: | |
204 format = SkTextureCompressor::kLATC_Format; | |
205 break; | |
206 case kR11_EAC_GrPixelConfig: | |
207 format = SkTextureCompressor::kR11_EAC_Format; | |
208 break; | |
209 default: | |
210 SkFAIL("Unrecognized texture compression format."); | |
211 break; | |
212 } | |
213 | |
214 SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fBM, for mat)); | |
215 SkASSERT(NULL != cmpData); | 231 SkASSERT(NULL != cmpData); |
216 | 232 |
217 this->sendTextureData(texture, desc, cmpData->data(), 0); | 233 this->sendTextureData(texture, desc, cmpData->data(), 0); |
218 } | 234 } |
219 | 235 |
220 /** | 236 /** |
221 * Move the result of the software mask generation back to the gpu | 237 * Move the result of the software mask generation back to the gpu |
222 */ | 238 */ |
223 void GrSWMaskHelper::toTexture(GrTexture *texture) { | 239 void GrSWMaskHelper::toTexture(GrTexture *texture) { |
224 SkAutoLockPixels alp(fBM); | 240 SkAutoLockPixels alp(fBM); |
225 | 241 |
226 GrTextureDesc desc; | 242 GrTextureDesc desc; |
227 desc.fWidth = fBM.width(); | 243 desc.fWidth = fBM.width(); |
228 desc.fHeight = fBM.height(); | 244 desc.fHeight = fBM.height(); |
229 desc.fConfig = texture->config(); | 245 desc.fConfig = texture->config(); |
230 | 246 |
231 // First see if we should compress this texture before uploading. | 247 // First see if we should compress this texture before uploading. |
232 if (GrPixelConfigIsCompressed(texture->config())) { | 248 if (fCompressMask) { |
233 this->compressTextureData(texture, desc); | 249 this->compressTextureData(texture, desc); |
234 } else { | 250 } else { |
235 // Looks like we have to send a full A8 texture. | 251 // Looks like we have to send a full A8 texture. |
236 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); | 252 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); |
237 } | 253 } |
238 } | 254 } |
239 | 255 |
240 //////////////////////////////////////////////////////////////////////////////// | 256 //////////////////////////////////////////////////////////////////////////////// |
241 /** | 257 /** |
242 * Software rasterizes path to A8 mask (possibly using the context's matrix) | 258 * Software rasterizes path to A8 mask (possibly using the context's matrix) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 maskMatrix.preConcat(drawState->getViewMatrix()); | 309 maskMatrix.preConcat(drawState->getViewMatrix()); |
294 | 310 |
295 drawState->addCoverageEffect( | 311 drawState->addCoverageEffect( |
296 GrSimpleTextureEffect::Create(texture, | 312 GrSimpleTextureEffect::Create(texture, |
297 maskMatrix, | 313 maskMatrix, |
298 GrTextureParams::kNone_Fi lterMode, | 314 GrTextureParams::kNone_Fi lterMode, |
299 kPosition_GrCoordSet))->u nref(); | 315 kPosition_GrCoordSet))->u nref(); |
300 | 316 |
301 target->drawSimpleRect(dstRect); | 317 target->drawSimpleRect(dstRect); |
302 } | 318 } |
OLD | NEW |