Chromium Code Reviews| 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 != fCompressedBlitter) { | |
| 90 delete fCompressedBlitter; | |
| 91 fCompressedBlitter = NULL; | |
| 92 } | |
| 93 | |
| 94 if (NULL != fCompressedBuffer) { | |
| 95 sk_free(fCompressedBuffer); | |
| 96 fCompressedBuffer = NULL; | |
| 97 } | |
| 98 } | |
| 99 | |
| 88 /** | 100 /** |
| 89 * Draw a single rect element of the clip stack into the accumulation bitmap | 101 * Draw a single rect element of the clip stack into the accumulation bitmap |
| 90 */ | 102 */ |
| 91 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, | 103 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, |
| 92 bool antiAlias, uint8_t alpha) { | 104 bool antiAlias, uint8_t alpha) { |
| 93 SkPaint paint; | 105 SkPaint paint; |
| 94 | 106 |
| 95 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); | 107 SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); |
| 96 | 108 |
| 97 paint.setXfermode(mode); | 109 paint.setXfermode(mode); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 118 paint.setStyle(SkPaint::kFill_Style); | 130 paint.setStyle(SkPaint::kFill_Style); |
| 119 } else { | 131 } else { |
| 120 paint.setStyle(SkPaint::kStroke_Style); | 132 paint.setStyle(SkPaint::kStroke_Style); |
| 121 paint.setStrokeJoin(stroke.getJoin()); | 133 paint.setStrokeJoin(stroke.getJoin()); |
| 122 paint.setStrokeCap(stroke.getCap()); | 134 paint.setStrokeCap(stroke.getCap()); |
| 123 paint.setStrokeWidth(stroke.getWidth()); | 135 paint.setStrokeWidth(stroke.getWidth()); |
| 124 } | 136 } |
| 125 } | 137 } |
| 126 paint.setAntiAlias(antiAlias); | 138 paint.setAntiAlias(antiAlias); |
| 127 | 139 |
| 140 SkBlitter* blitter = NULL; | |
| 141 if (kBlitter_CompressionMode == fCompressionMode) { | |
| 142 blitter = fCompressedBlitter; | |
| 143 } | |
| 144 | |
| 128 if (SkRegion::kReplace_Op == op && 0xFF == alpha) { | 145 if (SkRegion::kReplace_Op == op && 0xFF == alpha) { |
| 129 SkASSERT(0xFF == paint.getAlpha()); | 146 SkASSERT(0xFF == paint.getAlpha()); |
| 130 fDraw.drawPathCoverage(path, paint); | 147 fDraw.drawPathCoverage(path, paint, blitter); |
| 131 } else { | 148 } else { |
| 132 paint.setXfermodeMode(op_to_mode(op)); | 149 paint.setXfermodeMode(op_to_mode(op)); |
| 133 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); | 150 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); |
| 134 fDraw.drawPath(path, paint); | 151 fDraw.drawPath(path, paint, blitter); |
| 152 } | |
| 153 | |
|
robertphillips
2014/08/06 20:54:49
Get reset -> Get rid of ?
krajcevski
2014/08/06 22:41:59
Done.
| |
| 154 // Get reset the blitter, since we're done using it, and it might | |
| 155 // need to do some final cleanup for its cached scanlines | |
| 156 if (NULL != fCompressedBlitter) { | |
| 157 SkASSERT(kBlitter_CompressionMode == fCompressionMode); | |
| 158 SkASSERT(blitter == fCompressedBlitter); // we used the compressed blit ter | |
| 159 delete fCompressedBlitter; | |
| 160 fCompressedBlitter = NULL; | |
| 135 } | 161 } |
| 136 } | 162 } |
| 137 | 163 |
| 138 bool GrSWMaskHelper::init(const SkIRect& resultBounds, | 164 bool GrSWMaskHelper::init(const SkIRect& resultBounds, |
| 139 const SkMatrix* matrix) { | 165 const SkMatrix* matrix) { |
| 140 if (NULL != matrix) { | 166 if (NULL != matrix) { |
| 141 fMatrix = *matrix; | 167 fMatrix = *matrix; |
| 142 } else { | 168 } else { |
| 143 fMatrix.setIdentity(); | 169 fMatrix.setIdentity(); |
| 144 } | 170 } |
| 145 | 171 |
| 146 // Now translate so the bound's UL corner is at the origin | 172 // Now translate so the bound's UL corner is at the origin |
| 147 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, | 173 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, |
| 148 -resultBounds.fTop * SK_Scalar1); | 174 -resultBounds.fTop * SK_Scalar1); |
| 149 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), | 175 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), |
| 150 resultBounds.height()); | 176 resultBounds.height()); |
| 151 | 177 |
| 152 #if GR_COMPRESS_ALPHA_MASK | 178 #if GR_COMPRESS_ALPHA_MASK |
| 153 fCompressMask = choose_compressed_fmt(fContext->getGpu()->caps(), &fCompress edFormat); | 179 if (choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat)) { |
| 154 #else | 180 fCompressionMode = kCompress_CompressionMode; |
| 155 fCompressMask = false; | 181 } |
| 156 #endif | 182 #endif |
| 157 | 183 |
| 158 // Make sure that the width is a multiple of 16 so that we can use | 184 // 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. | 185 // specialized SIMD instructions that compress 4 blocks at a time. |
| 160 int cmpWidth, cmpHeight; | 186 int cmpWidth = bounds.fRight; |
| 161 if (fCompressMask) { | 187 int cmpHeight = bounds.fBottom; |
| 188 if (kCompress_CompressionMode == fCompressionMode) { | |
| 162 int dimX, dimY; | 189 int dimX, dimY; |
| 163 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; | 190 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; |
| 164 cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); | 191 cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX); |
| 165 cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); | 192 cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY); |
| 193 | |
| 194 // Can we create a blitter? | |
| 195 int cmpSz = SkTextureCompressor::GetCompressedDataSize( | |
| 196 fCompressedFormat, cmpWidth, cmpHeight); | |
| 197 | |
| 198 if (cmpSz > 0) { | |
| 199 fCompressedBuffer = sk_malloc_throw(cmpSz); | |
| 200 fCompressedBlitter = SkTextureCompressor::CreateBlitterForFormat( | |
| 201 cmpWidth, cmpHeight, fCompressedBuffer, fCompressedFormat); | |
| 202 | |
| 203 if (NULL != fCompressedBlitter) { | |
| 204 fCompressionMode = kBlitter_CompressionMode; | |
| 205 } else { | |
| 206 fCompressionMode = kCompress_CompressionMode; | |
| 207 sk_free(fCompressedBuffer); | |
| 208 } | |
| 209 } | |
| 210 } | |
| 211 | |
|
robertphillips
2014/08/06 20:54:48
If blitter creation failed in the above couldn't w
krajcevski
2014/08/06 22:41:59
Yes, but the munged ones only happen if we have a
| |
| 212 // If we don't have a custom blitter, then we need a bitmap | |
| 213 // to compress into. | |
| 214 const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight); | |
| 215 if (kBlitter_CompressionMode != fCompressionMode) { | |
| 216 if (!fBM.allocPixels(bmImageInfo)) { | |
| 217 return false; | |
| 218 } | |
| 219 | |
| 220 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | |
| 166 } else { | 221 } else { |
| 167 cmpWidth = bounds.fRight; | 222 // Otherwise, we just need to remember how big the buffer is... |
| 168 cmpHeight = bounds.fBottom; | 223 fBM.setInfo(bmImageInfo); |
| 169 } | 224 } |
| 170 | 225 |
| 171 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { | 226 sk_bzero(&fDraw, sizeof(fDraw)); |
| 172 return false; | |
| 173 } | |
| 174 | 227 |
| 175 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | |
| 176 | |
| 177 sk_bzero(&fDraw, sizeof(fDraw)); | |
| 178 fRasterClip.setRect(bounds); | 228 fRasterClip.setRect(bounds); |
| 179 fDraw.fRC = &fRasterClip; | 229 fDraw.fRC = &fRasterClip; |
| 180 fDraw.fClip = &fRasterClip.bwRgn(); | 230 fDraw.fClip = &fRasterClip.bwRgn(); |
| 181 fDraw.fMatrix = &fMatrix; | 231 fDraw.fMatrix = &fMatrix; |
| 182 fDraw.fBitmap = &fBM; | 232 fDraw.fBitmap = &fBM; |
| 183 return true; | 233 return true; |
| 184 } | 234 } |
| 185 | 235 |
| 186 /** | 236 /** |
| 187 * Get a texture (from the texture cache) of the correct size & format. | 237 * Get a texture (from the texture cache) of the correct size & format. |
| 188 * Return true on success; false on failure. | 238 * Return true on success; false on failure. |
| 189 */ | 239 */ |
| 190 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { | 240 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
| 191 GrTextureDesc desc; | 241 GrTextureDesc desc; |
| 192 desc.fWidth = fBM.width(); | 242 desc.fWidth = fBM.width(); |
| 193 desc.fHeight = fBM.height(); | 243 desc.fHeight = fBM.height(); |
| 194 desc.fConfig = kAlpha_8_GrPixelConfig; | 244 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 195 | 245 |
| 196 if (fCompressMask) { | 246 if (kNone_CompressionMode != fCompressionMode) { |
| 197 | 247 |
| 198 #ifdef SK_DEBUG | 248 #ifdef SK_DEBUG |
| 199 int dimX, dimY; | 249 int dimX, dimY; |
| 200 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; | 250 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ; |
| 201 SkASSERT((desc.fWidth % dimX) == 0); | 251 SkASSERT((desc.fWidth % dimX) == 0); |
| 202 SkASSERT((desc.fHeight % dimY) == 0); | 252 SkASSERT((desc.fHeight % dimY) == 0); |
| 203 #endif | 253 #endif |
| 204 | 254 |
| 205 desc.fConfig = fmt_to_config(fCompressedFormat); | 255 desc.fConfig = fmt_to_config(fCompressedFormat); |
| 206 | 256 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 } | 257 } |
| 213 | 258 |
| 214 texture->set(fContext, desc); | 259 texture->set(fContext, desc); |
| 215 return NULL != texture->texture(); | 260 return NULL != texture->texture(); |
| 216 } | 261 } |
| 217 | 262 |
| 218 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de sc, | 263 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de sc, |
| 219 const void *data, int rowbytes) { | 264 const void *data, int rowbytes) { |
| 220 // If we aren't reusing scratch textures we don't need to flush before | 265 // If we aren't reusing scratch textures we don't need to flush before |
| 221 // writing since no one else will be using 'texture' | 266 // writing since no one else will be using 'texture' |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 246 */ | 291 */ |
| 247 void GrSWMaskHelper::toTexture(GrTexture *texture) { | 292 void GrSWMaskHelper::toTexture(GrTexture *texture) { |
| 248 SkAutoLockPixels alp(fBM); | 293 SkAutoLockPixels alp(fBM); |
| 249 | 294 |
| 250 GrTextureDesc desc; | 295 GrTextureDesc desc; |
| 251 desc.fWidth = fBM.width(); | 296 desc.fWidth = fBM.width(); |
| 252 desc.fHeight = fBM.height(); | 297 desc.fHeight = fBM.height(); |
| 253 desc.fConfig = texture->config(); | 298 desc.fConfig = texture->config(); |
| 254 | 299 |
| 255 // First see if we should compress this texture before uploading. | 300 // First see if we should compress this texture before uploading. |
| 256 if (fCompressMask) { | 301 switch (fCompressionMode) { |
| 257 this->compressTextureData(texture, desc); | 302 case kNone_CompressionMode: |
| 258 } else { | 303 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes() ); |
| 259 // Looks like we have to send a full A8 texture. | 304 break; |
| 260 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); | 305 |
| 306 case kCompress_CompressionMode: | |
| 307 this->compressTextureData(texture, desc); | |
| 308 break; | |
| 309 | |
| 310 case kBlitter_CompressionMode: | |
| 311 SkASSERT(NULL != fCompressedBuffer); | |
| 312 this->sendTextureData(texture, desc, fCompressedBuffer, 0); | |
|
robertphillips
2014/08/06 20:54:48
break; ? for consistency.
krajcevski
2014/08/06 22:41:59
Done.
| |
| 261 } | 313 } |
| 262 } | 314 } |
| 263 | 315 |
| 264 //////////////////////////////////////////////////////////////////////////////// | 316 //////////////////////////////////////////////////////////////////////////////// |
| 265 /** | 317 /** |
| 266 * Software rasterizes path to A8 mask (possibly using the context's matrix) | 318 * Software rasterizes path to A8 mask (possibly using the context's matrix) |
| 267 * and uploads the result to a scratch texture. Returns the resulting | 319 * and uploads the result to a scratch texture. Returns the resulting |
| 268 * texture on success; NULL on failure. | 320 * texture on success; NULL on failure. |
| 269 */ | 321 */ |
| 270 GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, | 322 GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 maskMatrix.preConcat(drawState->getViewMatrix()); | 369 maskMatrix.preConcat(drawState->getViewMatrix()); |
| 318 | 370 |
| 319 drawState->addCoverageEffect( | 371 drawState->addCoverageEffect( |
| 320 GrSimpleTextureEffect::Create(texture, | 372 GrSimpleTextureEffect::Create(texture, |
| 321 maskMatrix, | 373 maskMatrix, |
| 322 GrTextureParams::kNone_Fi lterMode, | 374 GrTextureParams::kNone_Fi lterMode, |
| 323 kPosition_GrCoordSet))->u nref(); | 375 kPosition_GrCoordSet))->u nref(); |
| 324 | 376 |
| 325 target->drawSimpleRect(dstRect); | 377 target->drawSimpleRect(dstRect); |
| 326 } | 378 } |
| OLD | NEW |