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

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

Issue 1974943002: Simplify GrSWMaskHelper (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix indent Created 4 years, 7 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
« no previous file with comments | « src/gpu/GrSWMaskHelper.h ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "GrCaps.h" 10 #include "GrCaps.h"
11 #include "GrDrawTarget.h" 11 #include "GrDrawTarget.h"
12 #include "GrGpu.h" 12 #include "GrGpu.h"
13 #include "GrPipelineBuilder.h" 13 #include "GrPipelineBuilder.h"
14 #include "GrStyle.h" 14 #include "GrStyle.h"
15 15
16 #include "SkData.h" 16 #include "SkData.h"
17 #include "SkDistanceFieldGen.h" 17 #include "SkDistanceFieldGen.h"
18 #include "SkStrokeRec.h" 18 #include "SkStrokeRec.h"
19 19
20 #include "batches/GrRectBatchFactory.h" 20 #include "batches/GrRectBatchFactory.h"
21 21
22 namespace {
23
24 /* 22 /*
25 * Convert a boolean operation into a transfer mode code 23 * Convert a boolean operation into a transfer mode code
26 */ 24 */
27 SkXfermode::Mode op_to_mode(SkRegion::Op op) { 25 static SkXfermode::Mode op_to_mode(SkRegion::Op op) {
28 26
29 static const SkXfermode::Mode modeMap[] = { 27 static const SkXfermode::Mode modeMap[] = {
30 SkXfermode::kDstOut_Mode, // kDifference_Op 28 SkXfermode::kDstOut_Mode, // kDifference_Op
31 SkXfermode::kModulate_Mode, // kIntersect_Op 29 SkXfermode::kModulate_Mode, // kIntersect_Op
32 SkXfermode::kSrcOver_Mode, // kUnion_Op 30 SkXfermode::kSrcOver_Mode, // kUnion_Op
33 SkXfermode::kXor_Mode, // kXOR_Op 31 SkXfermode::kXor_Mode, // kXOR_Op
34 SkXfermode::kClear_Mode, // kReverseDifference_Op 32 SkXfermode::kClear_Mode, // kReverseDifference_Op
35 SkXfermode::kSrc_Mode, // kReplace_Op 33 SkXfermode::kSrc_Mode, // kReplace_Op
36 }; 34 };
37 35
38 return modeMap[op]; 36 return modeMap[op];
39 } 37 }
40 38
41 static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) {
42
43 GrPixelConfig config;
44 switch (fmt) {
45 case SkTextureCompressor::kLATC_Format:
46 config = kLATC_GrPixelConfig;
47 break;
48
49 case SkTextureCompressor::kR11_EAC_Format:
50 config = kR11_EAC_GrPixelConfig;
51 break;
52
53 case SkTextureCompressor::kASTC_12x12_Format:
54 config = kASTC_12x12_GrPixelConfig;
55 break;
56
57 case SkTextureCompressor::kETC1_Format:
58 config = kETC1_GrPixelConfig;
59 break;
60
61 default:
62 SkDEBUGFAIL("No GrPixelConfig for compression format!");
63 // Best guess
64 config = kAlpha_8_GrPixelConfig;
65 break;
66 }
67
68 return config;
69 }
70
71 static bool choose_compressed_fmt(const GrCaps* caps,
72 SkTextureCompressor::Format *fmt) {
73 if (nullptr == fmt) {
74 return false;
75 }
76
77 // We can't use scratch textures without the ability to update
78 // compressed textures...
79 if (!(caps->compressedTexSubImageSupport())) {
80 return false;
81 }
82
83 // Figure out what our preferred texture type is. If ASTC is available, that always
84 // gives the biggest win. Otherwise, in terms of compression speed and accur acy,
85 // LATC has a slight edge over R11 EAC.
86 if (caps->isConfigTexturable(kASTC_12x12_GrPixelConfig)) {
87 *fmt = SkTextureCompressor::kASTC_12x12_Format;
88 return true;
89 } else if (caps->isConfigTexturable(kLATC_GrPixelConfig)) {
90 *fmt = SkTextureCompressor::kLATC_Format;
91 return true;
92 } else if (caps->isConfigTexturable(kR11_EAC_GrPixelConfig)) {
93 *fmt = SkTextureCompressor::kR11_EAC_Format;
94 return true;
95 }
96
97 return false;
98 }
99
100 }
101
102 /** 39 /**
103 * Draw a single rect element of the clip stack into the accumulation bitmap 40 * Draw a single rect element of the clip stack into the accumulation bitmap
104 */ 41 */
105 void GrSWMaskHelper::draw(const SkRect& rect, SkRegion::Op op, 42 void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op,
106 bool antiAlias, uint8_t alpha) { 43 bool antiAlias, uint8_t alpha) {
107 SkPaint paint; 44 SkPaint paint;
108 45
109 SkASSERT(kNone_CompressionMode == fCompressionMode);
110
111 paint.setXfermode(SkXfermode::Make(op_to_mode(op))); 46 paint.setXfermode(SkXfermode::Make(op_to_mode(op)));
112 paint.setAntiAlias(antiAlias); 47 paint.setAntiAlias(antiAlias);
113 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); 48 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
114 49
115 fDraw.drawRect(rect, paint); 50 fDraw.drawRect(rect, paint);
116 } 51 }
117 52
118 /** 53 /**
119 * Draw a single path element of the clip stack into the accumulation bitmap 54 * Draw a single path element of the clip stack into the accumulation bitmap
120 */ 55 */
121 void GrSWMaskHelper::draw(const SkPath& path, const GrStyle& style, SkRegion::Op op, 56 void GrSWMaskHelper::drawPath(const SkPath& path, const GrStyle& style, SkRegion ::Op op,
122 bool antiAlias, uint8_t alpha) { 57 bool antiAlias, uint8_t alpha) {
123 SkPaint paint; 58 SkPaint paint;
124 paint.setPathEffect(sk_ref_sp(style.pathEffect())); 59 paint.setPathEffect(sk_ref_sp(style.pathEffect()));
125 style.strokeRec().applyToPaint(&paint); 60 style.strokeRec().applyToPaint(&paint);
126 paint.setAntiAlias(antiAlias); 61 paint.setAntiAlias(antiAlias);
127 62
128 SkTBlitterAllocator allocator;
129 SkBlitter* blitter = nullptr;
130 if (kBlitter_CompressionMode == fCompressionMode) {
131 SkASSERT(fCompressedBuffer.get());
132 blitter = SkTextureCompressor::CreateBlitterForFormat(
133 fPixels.width(), fPixels.height(), fCompressedBuffer.get(), &allocat or,
134 fCompressedFormat) ;
135 }
136
137 if (SkRegion::kReplace_Op == op && 0xFF == alpha) { 63 if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
138 SkASSERT(0xFF == paint.getAlpha()); 64 SkASSERT(0xFF == paint.getAlpha());
139 fDraw.drawPathCoverage(path, paint, blitter); 65 fDraw.drawPathCoverage(path, paint);
140 } else { 66 } else {
141 paint.setXfermodeMode(op_to_mode(op)); 67 paint.setXfermodeMode(op_to_mode(op));
142 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); 68 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
143 fDraw.drawPath(path, paint, blitter); 69 fDraw.drawPath(path, paint);
144 } 70 }
145 } 71 }
146 72
147 bool GrSWMaskHelper::init(const SkIRect& resultBounds, 73 bool GrSWMaskHelper::init(const SkIRect& resultBounds, const SkMatrix* matrix) {
148 const SkMatrix* matrix,
149 bool allowCompression) {
150 if (matrix) { 74 if (matrix) {
151 fMatrix = *matrix; 75 fMatrix = *matrix;
152 } else { 76 } else {
153 fMatrix.setIdentity(); 77 fMatrix.setIdentity();
154 } 78 }
155 79
156 // Now translate so the bound's UL corner is at the origin 80 // Now translate so the bound's UL corner is at the origin
157 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, 81 fMatrix.postTranslate(-SkIntToScalar(resultBounds.fLeft), -SkIntToScalar(res ultBounds.fTop));
158 -resultBounds.fTop * SK_Scalar1); 82 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height() );
159 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(),
160 resultBounds.height());
161 83
162 if (allowCompression && 84 const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(bounds.width(), bounds.h eight());
163 fContext->caps()->drawPathMasksToCompressedTexturesSupport() && 85 if (!fPixels.tryAlloc(bmImageInfo)) {
164 choose_compressed_fmt(fContext->caps(), &fCompressedFormat)) { 86 return false;
165 fCompressionMode = kCompress_CompressionMode;
166 } 87 }
167 88 fPixels.erase(0);
168 // Make sure that the width is a multiple of the desired block dimensions
169 // to allow for specialized SIMD instructions that compress multiple blocks at a time.
170 int cmpWidth = bounds.fRight;
171 int cmpHeight = bounds.fBottom;
172 if (kCompress_CompressionMode == fCompressionMode) {
173 int dimX, dimY;
174 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ;
175 cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX);
176 cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY);
177
178 // Can we create a blitter?
179 if (SkTextureCompressor::ExistsBlitterForFormat(fCompressedFormat)) {
180 int cmpSz = SkTextureCompressor::GetCompressedDataSize(
181 fCompressedFormat, cmpWidth, cmpHeight);
182
183 SkASSERT(cmpSz > 0);
184 SkASSERT(nullptr == fCompressedBuffer.get());
185 fCompressedBuffer.reset(cmpSz);
186 fCompressionMode = kBlitter_CompressionMode;
187 }
188 }
189 89
190 sk_bzero(&fDraw, sizeof(fDraw)); 90 sk_bzero(&fDraw, sizeof(fDraw));
191
192 // If we don't have a custom blitter, then we either need a bitmap to compre ss
193 // from or a bitmap that we're going to use as a texture. In any case, we sh ould
194 // allocate the pixels for a bitmap
195 const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight);
196 if (kBlitter_CompressionMode != fCompressionMode) {
197 if (!fPixels.tryAlloc(bmImageInfo)) {
198 return false;
199 }
200 fPixels.erase(0);
201 } else {
202 // Otherwise, we just need to remember how big the buffer is...
203 fPixels.reset(bmImageInfo);
204 }
205 fDraw.fDst = fPixels; 91 fDraw.fDst = fPixels;
206 fRasterClip.setRect(bounds); 92 fRasterClip.setRect(bounds);
207 fDraw.fRC = &fRasterClip; 93 fDraw.fRC = &fRasterClip;
208 fDraw.fMatrix = &fMatrix; 94 fDraw.fMatrix = &fMatrix;
209 return true; 95 return true;
210 } 96 }
211 97
212 /** 98 /**
213 * Get a texture (from the texture cache) of the correct size & format. 99 * Get a texture (from the texture cache) of the correct size & format.
214 */ 100 */
215 GrTexture* GrSWMaskHelper::createTexture() { 101 GrTexture* GrSWMaskHelper::createTexture() {
216 GrSurfaceDesc desc; 102 GrSurfaceDesc desc;
217 desc.fWidth = fPixels.width(); 103 desc.fWidth = fPixels.width();
218 desc.fHeight = fPixels.height(); 104 desc.fHeight = fPixels.height();
219 desc.fConfig = kAlpha_8_GrPixelConfig; 105 desc.fConfig = kAlpha_8_GrPixelConfig;
220 106
221 if (kNone_CompressionMode != fCompressionMode) {
222
223 #ifdef SK_DEBUG
224 int dimX, dimY;
225 SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY) ;
226 SkASSERT((desc.fWidth % dimX) == 0);
227 SkASSERT((desc.fHeight % dimY) == 0);
228 #endif
229
230 desc.fConfig = fmt_to_config(fCompressedFormat);
231 SkASSERT(fContext->caps()->isConfigTexturable(desc.fConfig));
232 }
233
234 return fContext->textureProvider()->createApproxTexture(desc); 107 return fContext->textureProvider()->createApproxTexture(desc);
235 } 108 }
236 109
237 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrSurfaceDesc& de sc,
238 const void *data, size_t rowbytes) {
239 // Since we're uploading to it, and it's compressed, 'texture' shouldn't
240 // have a render target.
241 SkASSERT(nullptr == texture->asRenderTarget());
242
243 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, data, ro wbytes);
244 }
245
246 void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrSurfaceDesc & desc) {
247
248 SkASSERT(GrPixelConfigIsCompressed(desc.fConfig));
249 SkASSERT(fmt_to_config(fCompressedFormat) == desc.fConfig);
250
251 SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fPixels,
252 fCompres sedFormat));
253 SkASSERT(cmpData);
254
255 this->sendTextureData(texture, desc, cmpData->data(), 0);
256 }
257
258 /** 110 /**
259 * Move the result of the software mask generation back to the gpu 111 * Move the result of the software mask generation back to the gpu
260 */ 112 */
261 void GrSWMaskHelper::toTexture(GrTexture *texture) { 113 void GrSWMaskHelper::toTexture(GrTexture *texture) {
262 GrSurfaceDesc desc; 114 // Since we're uploading to it, and it's compressed, 'texture' shouldn't
263 desc.fWidth = fPixels.width(); 115 // have a render target.
264 desc.fHeight = fPixels.height(); 116 SkASSERT(!texture->asRenderTarget());
265 desc.fConfig = texture->config();
266 117
267 // First see if we should compress this texture before uploading. 118 texture->writePixels(0, 0, fPixels.width(), fPixels.height(), texture->confi g(),
268 switch (fCompressionMode) { 119 fPixels.addr(), fPixels.rowBytes());
269 case kNone_CompressionMode:
270 this->sendTextureData(texture, desc, fPixels.addr(), fPixels.rowByte s());
271 break;
272 120
273 case kCompress_CompressionMode:
274 this->compressTextureData(texture, desc);
275 break;
276
277 case kBlitter_CompressionMode:
278 SkASSERT(fCompressedBuffer.get());
279 this->sendTextureData(texture, desc, fCompressedBuffer.get(), 0);
280 break;
281 }
282 } 121 }
283 122
284 /** 123 /**
285 * Convert mask generation results to a signed distance field 124 * Convert mask generation results to a signed distance field
286 */ 125 */
287 void GrSWMaskHelper::toSDF(unsigned char* sdf) { 126 void GrSWMaskHelper::toSDF(unsigned char* sdf) {
288 SkGenerateDistanceFieldFromA8Image(sdf, (const unsigned char*)fPixels.addr() , 127 SkGenerateDistanceFieldFromA8Image(sdf, (const unsigned char*)fPixels.addr() ,
289 fPixels.width(), fPixels.height(), fPixel s.rowBytes()); 128 fPixels.width(), fPixels.height(), fPixel s.rowBytes());
290 } 129 }
291 130
292 //////////////////////////////////////////////////////////////////////////////// 131 ////////////////////////////////////////////////////////////////////////////////
293 /** 132 /**
294 * Software rasterizes path to A8 mask (possibly using the context's matrix) 133 * Software rasterizes path to A8 mask (possibly using the context's matrix)
295 * and uploads the result to a scratch texture. Returns the resulting 134 * and uploads the result to a scratch texture. Returns the resulting
296 * texture on success; nullptr on failure. 135 * texture on success; nullptr on failure.
297 */ 136 */
298 GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, 137 GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context,
299 const SkPath& path, 138 const SkPath& path,
300 const GrStyle& style, 139 const GrStyle& style,
301 const SkIRect& resultBounds, 140 const SkIRect& resultBounds,
302 bool antiAlias, 141 bool antiAlias,
303 const SkMatrix* matrix) { 142 const SkMatrix* matrix) {
304 GrSWMaskHelper helper(context); 143 GrSWMaskHelper helper(context);
305 144
306 if (!helper.init(resultBounds, matrix)) { 145 if (!helper.init(resultBounds, matrix)) {
307 return nullptr; 146 return nullptr;
308 } 147 }
309 148
310 helper.draw(path, style, SkRegion::kReplace_Op, antiAlias, 0xFF); 149 helper.drawPath(path, style, SkRegion::kReplace_Op, antiAlias, 0xFF);
311 150
312 GrTexture* texture(helper.createTexture()); 151 GrTexture* texture(helper.createTexture());
313 if (!texture) { 152 if (!texture) {
314 return nullptr; 153 return nullptr;
315 } 154 }
316 155
317 helper.toTexture(texture); 156 helper.toTexture(texture);
318 157
319 return texture; 158 return texture;
320 } 159 }
(...skipping 25 matching lines...) Expand all
346 pipelineBuilder->addCoverageFragmentProcessor( 185 pipelineBuilder->addCoverageFragmentProcessor(
347 GrSimpleTextureEffect::Create(texture, 186 GrSimpleTextureEffect::Create(texture,
348 maskMatrix, 187 maskMatrix,
349 GrTextureParams::kNone_Fi lterMode, 188 GrTextureParams::kNone_Fi lterMode,
350 kDevice_GrCoordSet))->unr ef(); 189 kDevice_GrCoordSet))->unr ef();
351 190
352 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, S kMatrix::I(), 191 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, S kMatrix::I(),
353 dstRect, nullptr, &invert)); 192 dstRect, nullptr, &invert));
354 target->drawBatch(*pipelineBuilder, batch); 193 target->drawBatch(*pipelineBuilder, batch);
355 } 194 }
OLDNEW
« no previous file with comments | « src/gpu/GrSWMaskHelper.h ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698