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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 *fmt = SkTextureCompressor::kR11_EAC_Format; | 78 *fmt = SkTextureCompressor::kR11_EAC_Format; |
79 return true; | 79 return true; |
80 } | 80 } |
81 | 81 |
82 return false; | 82 return false; |
83 } | 83 } |
84 #endif | 84 #endif |
85 | 85 |
86 } | 86 } |
87 | 87 |
88 GrSWMaskHelper::~GrSWMaskHelper() { | |
89 if (NULL != fCompressedBuffer) { | |
reed1
2014/08/06 20:56:03
1. can just call sk_free() w/o checking
2. don't n
krajcevski
2014/08/06 22:42:00
Done.
| |
90 sk_free(fCompressedBuffer); | |
91 fCompressedBuffer = NULL; | |
92 } | |
93 } | |
94 | |
88 /** | 95 /** |
89 * Draw a single rect element of the clip stack into the accumulation bitmap | 96 * Draw a single rect element of the clip stack into the accumulation bitmap |
90 */ | 97 */ |
91 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, | 98 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, |
92 bool antiAlias, uint8_t alpha) { | 99 bool antiAlias, uint8_t alpha) { |
93 SkPaint paint; | 100 SkPaint paint; |
94 | 101 |
95 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); | 102 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); |
96 | 103 |
97 paint.setXfermode(mode); | 104 paint.setXfermode(mode); |
(...skipping 20 matching lines...) Expand all Loading... | |
118 paint.setStyle(SkPaint::kFill_Style); | 125 paint.setStyle(SkPaint::kFill_Style); |
119 } else { | 126 } else { |
120 paint.setStyle(SkPaint::kStroke_Style); | 127 paint.setStyle(SkPaint::kStroke_Style); |
121 paint.setStrokeJoin(stroke.getJoin()); | 128 paint.setStrokeJoin(stroke.getJoin()); |
122 paint.setStrokeCap(stroke.getCap()); | 129 paint.setStrokeCap(stroke.getCap()); |
123 paint.setStrokeWidth(stroke.getWidth()); | 130 paint.setStrokeWidth(stroke.getWidth()); |
124 } | 131 } |
125 } | 132 } |
126 paint.setAntiAlias(antiAlias); | 133 paint.setAntiAlias(antiAlias); |
127 | 134 |
135 SkTBlitterAllocator allocator; | |
136 SkBlitter* blitter = NULL; | |
137 if (kBlitter_CompressionMode == fCompressionMode) { | |
138 blitter = SkTextureCompressor::CreateBlitterForFormat( | |
139 fBM.width(), fBM.height(), fCompressedBuffer, &allocator, fCompresse dFormat); | |
140 } | |
141 | |
128 if (SkRegion::kReplace_Op == op && 0xFF == alpha) { | 142 if (SkRegion::kReplace_Op == op && 0xFF == alpha) { |
129 SkASSERT(0xFF == paint.getAlpha()); | 143 SkASSERT(0xFF == paint.getAlpha()); |
130 fDraw.drawPathCoverage(path, paint); | 144 fDraw.drawPathCoverage(path, paint, blitter); |
131 } else { | 145 } else { |
132 paint.setXfermodeMode(op_to_mode(op)); | 146 paint.setXfermodeMode(op_to_mode(op)); |
133 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); | 147 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); |
134 fDraw.drawPath(path, paint); | 148 fDraw.drawPath(path, paint, blitter); |
135 } | 149 } |
136 } | 150 } |
137 | 151 |
138 bool GrSWMaskHelper::init(const SkIRect& resultBounds, | 152 bool GrSWMaskHelper::init(const SkIRect& resultBounds, |
139 const SkMatrix* matrix) { | 153 const SkMatrix* matrix) { |
140 if (NULL != matrix) { | 154 if (NULL != matrix) { |
141 fMatrix = *matrix; | 155 fMatrix = *matrix; |
142 } else { | 156 } else { |
143 fMatrix.setIdentity(); | 157 fMatrix.setIdentity(); |
144 } | 158 } |
145 | 159 |
146 // Now translate so the bound's UL corner is at the origin | 160 // Now translate so the bound's UL corner is at the origin |
147 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, | 161 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, |
148 -resultBounds.fTop * SK_Scalar1); | 162 -resultBounds.fTop * SK_Scalar1); |
149 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), | 163 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), |
150 resultBounds.height()); | 164 resultBounds.height()); |
151 | 165 |
152 #if GR_COMPRESS_ALPHA_MASK | 166 #if GR_COMPRESS_ALPHA_MASK |
153 fCompressMask = choose_compressed_fmt(fContext->getGpu()->caps(), &fCompress edFormat); | 167 if (choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat)) { |
154 #else | 168 fCompressionMode = kCompress_CompressionMode; |
155 fCompressMask = false; | 169 } |
156 #endif | 170 #endif |
157 | 171 |
158 // Make sure that the width is a multiple of 16 so that we can use | 172 // Make sure that the width is a multiple of 16 so that we can use |
159 // specialized SIMD instructions that compress 4 blocks at a time. | 173 // specialized SIMD instructions that compress 4 blocks at a time. |
160 int cmpWidth, cmpHeight; | 174 int cmpWidth = bounds.fRight; |
161 if (fCompressMask) { | 175 int cmpHeight = bounds.fBottom; |
176 if (kCompress_CompressionMode == fCompressionMode) { | |
162 int dimX, dimY; | 177 int dimX, dimY; |
163 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; | 178 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; |
164 cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); | 179 cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX); |
165 cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); | 180 cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY); |
181 | |
182 // Can we create a blitter? | |
183 if (SkTextureCompressor::ExistsBlitterForFormat(fCompressedFormat)) { | |
184 int cmpSz = SkTextureCompressor::GetCompressedDataSize( | |
185 fCompressedFormat, cmpWidth, cmpHeight); | |
186 | |
187 SkASSERT(cmpSz > 0); | |
188 fCompressedBuffer = sk_malloc_throw(cmpSz); | |
189 fCompressionMode = kBlitter_CompressionMode; | |
190 } | |
191 } | |
192 | |
193 // If we don't have a custom blitter, then we need a bitmap | |
194 // to compress into. | |
195 const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight); | |
196 if (kBlitter_CompressionMode != fCompressionMode) { | |
197 if (!fBM.allocPixels(bmImageInfo)) { | |
198 return false; | |
199 } | |
200 | |
201 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | |
166 } else { | 202 } else { |
167 cmpWidth = bounds.fRight; | 203 // Otherwise, we just need to remember how big the buffer is... |
168 cmpHeight = bounds.fBottom; | 204 fBM.setInfo(bmImageInfo); |
169 } | 205 } |
170 | 206 |
171 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { | 207 sk_bzero(&fDraw, sizeof(fDraw)); |
172 return false; | |
173 } | |
174 | 208 |
175 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | |
176 | |
177 sk_bzero(&fDraw, sizeof(fDraw)); | |
178 fRasterClip.setRect(bounds); | 209 fRasterClip.setRect(bounds); |
179 fDraw.fRC = &fRasterClip; | 210 fDraw.fRC = &fRasterClip; |
180 fDraw.fClip = &fRasterClip.bwRgn(); | 211 fDraw.fClip = &fRasterClip.bwRgn(); |
181 fDraw.fMatrix = &fMatrix; | 212 fDraw.fMatrix = &fMatrix; |
182 fDraw.fBitmap = &fBM; | 213 fDraw.fBitmap = &fBM; |
183 return true; | 214 return true; |
184 } | 215 } |
185 | 216 |
186 /** | 217 /** |
187 * Get a texture (from the texture cache) of the correct size & format. | 218 * Get a texture (from the texture cache) of the correct size & format. |
188 * Return true on success; false on failure. | 219 * Return true on success; false on failure. |
189 */ | 220 */ |
190 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { | 221 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
191 GrTextureDesc desc; | 222 GrTextureDesc desc; |
192 desc.fWidth = fBM.width(); | 223 desc.fWidth = fBM.width(); |
193 desc.fHeight = fBM.height(); | 224 desc.fHeight = fBM.height(); |
194 desc.fConfig = kAlpha_8_GrPixelConfig; | 225 desc.fConfig = kAlpha_8_GrPixelConfig; |
195 | 226 |
196 if (fCompressMask) { | 227 if (kNone_CompressionMode != fCompressionMode) { |
197 | 228 |
198 #ifdef SK_DEBUG | 229 #ifdef SK_DEBUG |
199 int dimX, dimY; | 230 int dimX, dimY; |
200 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; | 231 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; |
201 SkASSERT((desc.fWidth % dimX) == 0); | 232 SkASSERT((desc.fWidth % dimX) == 0); |
202 SkASSERT((desc.fHeight % dimY) == 0); | 233 SkASSERT((desc.fHeight % dimY) == 0); |
203 #endif | 234 #endif |
204 | 235 |
205 desc.fConfig = fmt_to_config(fCompressedFormat); | 236 desc.fConfig = fmt_to_config(fCompressedFormat); |
206 | 237 SkASSERT(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig)); |
207 // If this config isn't supported then we should fall back to A8 | |
208 if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { | |
209 SkDEBUGFAIL("Determining compression should be set from choose_compr essed_fmt"); | |
210 desc.fConfig = kAlpha_8_GrPixelConfig; | |
211 } | |
212 } | 238 } |
213 | 239 |
214 texture->set(fContext, desc); | 240 texture->set(fContext, desc); |
215 return NULL != texture->texture(); | 241 return NULL != texture->texture(); |
216 } | 242 } |
217 | 243 |
218 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de sc, | 244 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de sc, |
219 const void *data, int rowbytes) { | 245 const void *data, int rowbytes) { |
220 // If we aren't reusing scratch textures we don't need to flush before | 246 // If we aren't reusing scratch textures we don't need to flush before |
221 // writing since no one else will be using 'texture' | 247 // writing since no one else will be using 'texture' |
(...skipping 24 matching lines...) Expand all Loading... | |
246 */ | 272 */ |
247 void GrSWMaskHelper::toTexture(GrTexture *texture) { | 273 void GrSWMaskHelper::toTexture(GrTexture *texture) { |
248 SkAutoLockPixels alp(fBM); | 274 SkAutoLockPixels alp(fBM); |
249 | 275 |
250 GrTextureDesc desc; | 276 GrTextureDesc desc; |
251 desc.fWidth = fBM.width(); | 277 desc.fWidth = fBM.width(); |
252 desc.fHeight = fBM.height(); | 278 desc.fHeight = fBM.height(); |
253 desc.fConfig = texture->config(); | 279 desc.fConfig = texture->config(); |
254 | 280 |
255 // First see if we should compress this texture before uploading. | 281 // First see if we should compress this texture before uploading. |
256 if (fCompressMask) { | 282 switch (fCompressionMode) { |
257 this->compressTextureData(texture, desc); | 283 case kNone_CompressionMode: |
258 } else { | 284 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes() ); |
259 // Looks like we have to send a full A8 texture. | 285 break; |
260 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); | 286 |
287 case kCompress_CompressionMode: | |
288 this->compressTextureData(texture, desc); | |
289 break; | |
290 | |
291 case kBlitter_CompressionMode: | |
292 SkASSERT(NULL != fCompressedBuffer); | |
293 this->sendTextureData(texture, desc, fCompressedBuffer, 0); | |
261 } | 294 } |
262 } | 295 } |
263 | 296 |
264 //////////////////////////////////////////////////////////////////////////////// | 297 //////////////////////////////////////////////////////////////////////////////// |
265 /** | 298 /** |
266 * Software rasterizes path to A8 mask (possibly using the context's matrix) | 299 * Software rasterizes path to A8 mask (possibly using the context's matrix) |
267 * and uploads the result to a scratch texture. Returns the resulting | 300 * and uploads the result to a scratch texture. Returns the resulting |
268 * texture on success; NULL on failure. | 301 * texture on success; NULL on failure. |
269 */ | 302 */ |
270 GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, | 303 GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 maskMatrix.preConcat(drawState->getViewMatrix()); | 350 maskMatrix.preConcat(drawState->getViewMatrix()); |
318 | 351 |
319 drawState->addCoverageEffect( | 352 drawState->addCoverageEffect( |
320 GrSimpleTextureEffect::Create(texture, | 353 GrSimpleTextureEffect::Create(texture, |
321 maskMatrix, | 354 maskMatrix, |
322 GrTextureParams::kNone_Fi lterMode, | 355 GrTextureParams::kNone_Fi lterMode, |
323 kPosition_GrCoordSet))->u nref(); | 356 kPosition_GrCoordSet))->u nref(); |
324 | 357 |
325 target->drawSimpleRect(dstRect); | 358 target->drawSimpleRect(dstRect); |
326 } | 359 } |
OLD | NEW |