Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: src/gpu/GrSWMaskHelper.cpp

Issue 446103002: Pass compressed blitters to our mask drawing algorithm (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698