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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 fMatrix = *matrix; | 95 fMatrix = *matrix; |
96 } else { | 96 } else { |
97 fMatrix.setIdentity(); | 97 fMatrix.setIdentity(); |
98 } | 98 } |
99 | 99 |
100 // Now translate so the bound's UL corner is at the origin | 100 // Now translate so the bound's UL corner is at the origin |
101 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, | 101 fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, |
102 -resultBounds.fTop * SK_Scalar1); | 102 -resultBounds.fTop * SK_Scalar1); |
103 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), | 103 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), |
104 resultBounds.height()); | 104 resultBounds.height()); |
| 105 #if GR_COMPRESS_ALPHA_MASK |
| 106 // Make sure that the width is a multiple of 16 so that we can use |
| 107 // specialized SIMD instructions that compress 4 blocks at a time. |
| 108 const int cmpWidth = (bounds.fRight + 15) & ~15; |
| 109 const int cmpHeight = (bounds.fBottom + 3) & ~3; |
| 110 #else |
| 111 const int cmpWidth = bounds.fRight; |
| 112 const int cmpHeight = bounds.fBottom; |
| 113 #endif |
105 | 114 |
106 if (!fBM.allocPixels(SkImageInfo::MakeA8(bounds.fRight, bounds.fBottom))) { | 115 if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { |
107 return false; | 116 return false; |
108 } | 117 } |
| 118 |
109 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); | 119 sk_bzero(fBM.getPixels(), fBM.getSafeSize()); |
110 | 120 |
111 sk_bzero(&fDraw, sizeof(fDraw)); | 121 sk_bzero(&fDraw, sizeof(fDraw)); |
112 fRasterClip.setRect(bounds); | 122 fRasterClip.setRect(bounds); |
113 fDraw.fRC = &fRasterClip; | 123 fDraw.fRC = &fRasterClip; |
114 fDraw.fClip = &fRasterClip.bwRgn(); | 124 fDraw.fClip = &fRasterClip.bwRgn(); |
115 fDraw.fMatrix = &fMatrix; | 125 fDraw.fMatrix = &fMatrix; |
116 fDraw.fBitmap = &fBM; | 126 fDraw.fBitmap = &fBM; |
117 return true; | 127 return true; |
118 } | 128 } |
119 | 129 |
120 /** | 130 /** |
121 * Get a texture (from the texture cache) of the correct size & format. | 131 * Get a texture (from the texture cache) of the correct size & format. |
122 * Return true on success; false on failure. | 132 * Return true on success; false on failure. |
123 */ | 133 */ |
124 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { | 134 bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
125 GrTextureDesc desc; | 135 GrTextureDesc desc; |
126 desc.fWidth = fBM.width(); | 136 desc.fWidth = fBM.width(); |
127 desc.fHeight = fBM.height(); | 137 desc.fHeight = fBM.height(); |
| 138 desc.fConfig = kAlpha_8_GrPixelConfig; |
128 | 139 |
129 #if GR_COMPRESS_ALPHA_MASK | 140 #if GR_COMPRESS_ALPHA_MASK |
130 static const int kLATCBlockSize = 4; | 141 static const int kCompressedBlockSize = 4; |
131 if (desc.fWidth % kLATCBlockSize == 0 && desc.fHeight % kLATCBlockSize == 0)
{ | 142 static const GrPixelConfig kCompressedConfig = kR11_EAC_GrPixelConfig; |
132 desc.fConfig = kLATC_GrPixelConfig; | 143 |
133 } else { | 144 if (desc.fWidth % kCompressedBlockSize == 0 && |
134 #endif | 145 desc.fHeight % kCompressedBlockSize == 0) { |
| 146 desc.fConfig = kCompressedConfig; |
| 147 } |
| 148 |
| 149 // If this config isn't supported then we should fall back to A8 |
| 150 if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { |
135 desc.fConfig = kAlpha_8_GrPixelConfig; | 151 desc.fConfig = kAlpha_8_GrPixelConfig; |
136 #if GR_COMPRESS_ALPHA_MASK | |
137 } | 152 } |
138 #endif | 153 #endif |
139 | 154 |
140 texture->set(fContext, desc); | 155 texture->set(fContext, desc); |
141 return NULL != texture->texture(); | 156 return NULL != texture->texture(); |
142 } | 157 } |
143 | 158 |
144 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de
sc, | 159 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de
sc, |
145 const void *data, int rowbytes) { | 160 const void *data, int rowbytes) { |
146 // If we aren't reusing scratch textures we don't need to flush before | 161 // If we aren't reusing scratch textures we don't need to flush before |
147 // writing since no one else will be using 'texture' | 162 // writing since no one else will be using 'texture' |
148 bool reuseScratch = fContext->getGpu()->caps()->reuseScratchTextures(); | 163 bool reuseScratch = fContext->getGpu()->caps()->reuseScratchTextures(); |
149 | 164 |
150 // Since we're uploading to it, and it's compressed, 'texture' shouldn't | 165 // Since we're uploading to it, and it's compressed, 'texture' shouldn't |
151 // have a render target. | 166 // have a render target. |
152 SkASSERT(NULL == texture->asRenderTarget()); | 167 SkASSERT(NULL == texture->asRenderTarget()); |
153 | 168 |
154 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, | 169 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, |
155 desc.fConfig, data, rowbytes, | 170 desc.fConfig, data, rowbytes, |
156 reuseScratch ? 0 : GrContext::kDontFlush_PixelOpsFlag); | 171 reuseScratch ? 0 : GrContext::kDontFlush_PixelOpsFlag); |
157 } | 172 } |
158 | 173 |
| 174 void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrTextureDesc
& desc) { |
| 175 |
| 176 SkASSERT(GrPixelConfigIsCompressed(desc.fConfig)); |
| 177 |
| 178 SkTextureCompressor::Format format = SkTextureCompressor::kLATC_Format; |
| 179 |
| 180 // Choose the format required by the texture descriptor. |
| 181 switch(desc.fConfig) { |
| 182 case kLATC_GrPixelConfig: |
| 183 format = SkTextureCompressor::kLATC_Format; |
| 184 break; |
| 185 case kR11_EAC_GrPixelConfig: |
| 186 format = SkTextureCompressor::kR11_EAC_Format; |
| 187 break; |
| 188 default: |
| 189 SkFAIL("Unrecognized texture compression format."); |
| 190 break; |
| 191 } |
| 192 |
| 193 SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fBM, for
mat)); |
| 194 SkASSERT(NULL != cmpData); |
| 195 |
| 196 this->sendTextureData(texture, desc, cmpData->data(), 0); |
| 197 } |
| 198 |
159 /** | 199 /** |
160 * Move the result of the software mask generation back to the gpu | 200 * Move the result of the software mask generation back to the gpu |
161 */ | 201 */ |
162 void GrSWMaskHelper::toTexture(GrTexture *texture) { | 202 void GrSWMaskHelper::toTexture(GrTexture *texture) { |
163 SkAutoLockPixels alp(fBM); | 203 SkAutoLockPixels alp(fBM); |
164 | 204 |
165 GrTextureDesc desc; | 205 GrTextureDesc desc; |
166 desc.fWidth = fBM.width(); | 206 desc.fWidth = fBM.width(); |
167 desc.fHeight = fBM.height(); | 207 desc.fHeight = fBM.height(); |
168 desc.fConfig = texture->config(); | 208 desc.fConfig = texture->config(); |
169 | 209 |
170 // First see if we should compress this texture before uploading. | 210 // First see if we should compress this texture before uploading. |
171 if (texture->config() == kLATC_GrPixelConfig) { | 211 if (GrPixelConfigIsCompressed(texture->config())) { |
172 SkTextureCompressor::Format format = SkTextureCompressor::kLATC_Format; | 212 this->compressTextureData(texture, desc); |
173 SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(fBM
, format)); | |
174 SkASSERT(NULL != latcData); | |
175 | |
176 this->sendTextureData(texture, desc, latcData->data(), 0); | |
177 } else { | 213 } else { |
178 // Looks like we have to send a full A8 texture. | 214 // Looks like we have to send a full A8 texture. |
179 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); | 215 this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); |
180 } | 216 } |
181 } | 217 } |
182 | 218 |
183 //////////////////////////////////////////////////////////////////////////////// | 219 //////////////////////////////////////////////////////////////////////////////// |
184 /** | 220 /** |
185 * Software rasterizes path to A8 mask (possibly using the context's matrix) | 221 * Software rasterizes path to A8 mask (possibly using the context's matrix) |
186 * and uploads the result to a scratch texture. Returns the resulting | 222 * and uploads the result to a scratch texture. Returns the resulting |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 maskMatrix.preConcat(drawState->getViewMatrix()); | 272 maskMatrix.preConcat(drawState->getViewMatrix()); |
237 | 273 |
238 drawState->addCoverageEffect( | 274 drawState->addCoverageEffect( |
239 GrSimpleTextureEffect::Create(texture, | 275 GrSimpleTextureEffect::Create(texture, |
240 maskMatrix, | 276 maskMatrix, |
241 GrTextureParams::kNone_Fi
lterMode, | 277 GrTextureParams::kNone_Fi
lterMode, |
242 kPosition_GrCoordSet))->u
nref(); | 278 kPosition_GrCoordSet))->u
nref(); |
243 | 279 |
244 target->drawSimpleRect(dstRect); | 280 target->drawSimpleRect(dstRect); |
245 } | 281 } |
OLD | NEW |