OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
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 "SkImageFilter.h" | 8 #include "SkImageFilter.h" |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| 11 #include "SkDevice.h" |
11 #include "SkReadBuffer.h" | 12 #include "SkReadBuffer.h" |
12 #include "SkWriteBuffer.h" | 13 #include "SkWriteBuffer.h" |
13 #include "SkRect.h" | 14 #include "SkRect.h" |
14 #include "SkValidationUtils.h" | 15 #include "SkValidationUtils.h" |
15 #if SK_SUPPORT_GPU | 16 #if SK_SUPPORT_GPU |
16 #include "GrContext.h" | 17 #include "GrContext.h" |
17 #include "SkGrPixelRef.h" | 18 #include "SkGrPixelRef.h" |
18 #include "SkGr.h" | 19 #include "SkGr.h" |
19 #endif | 20 #endif |
20 | 21 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 #if SK_SUPPORT_GPU | 149 #if SK_SUPPORT_GPU |
149 SkBitmap input = src; | 150 SkBitmap input = src; |
150 SkASSERT(fInputCount == 1); | 151 SkASSERT(fInputCount == 1); |
151 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 152 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
152 if (this->getInput(0) && | 153 if (this->getInput(0) && |
153 !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffse
t)) { | 154 !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffse
t)) { |
154 return false; | 155 return false; |
155 } | 156 } |
156 GrTexture* srcTexture = input.getTexture(); | 157 GrTexture* srcTexture = input.getTexture(); |
157 SkIRect bounds; | 158 SkIRect bounds; |
158 src.getBounds(&bounds); | 159 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { |
159 bounds.offset(srcOffset); | |
160 if (!this->applyCropRect(&bounds, ctx.ctm())) { | |
161 return false; | 160 return false; |
162 } | 161 } |
163 SkRect srcRect = SkRect::Make(bounds); | 162 SkRect srcRect = SkRect::Make(bounds); |
164 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); | 163 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
165 GrContext* context = srcTexture->getContext(); | 164 GrContext* context = srcTexture->getContext(); |
166 | 165 |
167 GrTextureDesc desc; | 166 GrTextureDesc desc; |
168 desc.fFlags = kRenderTarget_GrTextureFlagBit, | 167 desc.fFlags = kRenderTarget_GrTextureFlagBit, |
169 desc.fWidth = bounds.width(); | 168 desc.fWidth = bounds.width(); |
170 desc.fHeight = bounds.height(); | 169 desc.fHeight = bounds.height(); |
(...skipping 18 matching lines...) Expand all Loading... |
189 context->drawRectToRect(paint, dstRect, srcRect); | 188 context->drawRectToRect(paint, dstRect, srcRect); |
190 | 189 |
191 SkAutoTUnref<GrTexture> resultTex(dst.detach()); | 190 SkAutoTUnref<GrTexture> resultTex(dst.detach()); |
192 WrapTexture(resultTex, bounds.width(), bounds.height(), result); | 191 WrapTexture(resultTex, bounds.width(), bounds.height(), result); |
193 return true; | 192 return true; |
194 #else | 193 #else |
195 return false; | 194 return false; |
196 #endif | 195 #endif |
197 } | 196 } |
198 | 197 |
199 bool SkImageFilter::applyCropRect(SkIRect* rect, const SkMatrix& matrix) const { | 198 bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src, |
| 199 const SkIPoint& srcOffset, SkIRect* bounds) co
nst { |
| 200 SkIRect srcBounds; |
| 201 src.getBounds(&srcBounds); |
| 202 srcBounds.offset(srcOffset); |
200 SkRect cropRect; | 203 SkRect cropRect; |
201 matrix.mapRect(&cropRect, fCropRect.rect()); | 204 ctx.ctm().mapRect(&cropRect, fCropRect.rect()); |
202 SkIRect cropRectI; | 205 SkIRect cropRectI; |
203 cropRect.roundOut(&cropRectI); | 206 cropRect.roundOut(&cropRectI); |
204 uint32_t flags = fCropRect.flags(); | 207 uint32_t flags = fCropRect.flags(); |
205 // If the original crop rect edges were unset, max out the new crop edges | 208 if (flags & CropRect::kHasLeft_CropEdge) srcBounds.fLeft = cropRectI.fLeft; |
206 if (!(flags & CropRect::kHasLeft_CropEdge)) cropRectI.fLeft = SK_MinS32; | 209 if (flags & CropRect::kHasTop_CropEdge) srcBounds.fTop = cropRectI.fTop; |
207 if (!(flags & CropRect::kHasTop_CropEdge)) cropRectI.fTop = SK_MinS32; | 210 if (flags & CropRect::kHasRight_CropEdge) srcBounds.fRight = cropRectI.fRigh
t; |
208 if (!(flags & CropRect::kHasRight_CropEdge)) cropRectI.fRight = SK_MaxS32; | 211 if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBo
ttom; |
209 if (!(flags & CropRect::kHasBottom_CropEdge)) cropRectI.fBottom = SK_MaxS32; | 212 if (!srcBounds.intersect(ctx.clipBounds())) { |
210 return rect->intersect(cropRectI); | 213 return false; |
| 214 } |
| 215 *bounds = srcBounds; |
| 216 return true; |
| 217 } |
| 218 |
| 219 bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
ap& src, |
| 220 SkIPoint* srcOffset, SkIRect* bounds, SkBitmap
* dst) const { |
| 221 SkIRect srcBounds; |
| 222 src.getBounds(&srcBounds); |
| 223 srcBounds.offset(*srcOffset); |
| 224 SkRect cropRect; |
| 225 ctx.ctm().mapRect(&cropRect, fCropRect.rect()); |
| 226 SkIRect cropRectI; |
| 227 cropRect.roundOut(&cropRectI); |
| 228 uint32_t flags = fCropRect.flags(); |
| 229 *bounds = srcBounds; |
| 230 if (flags & CropRect::kHasLeft_CropEdge) bounds->fLeft = cropRectI.fLeft; |
| 231 if (flags & CropRect::kHasTop_CropEdge) bounds->fTop = cropRectI.fTop; |
| 232 if (flags & CropRect::kHasRight_CropEdge) bounds->fRight = cropRectI.fRight; |
| 233 if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBott
om; |
| 234 if (!bounds->intersect(ctx.clipBounds())) { |
| 235 return false; |
| 236 } |
| 237 if (srcBounds.contains(*bounds)) { |
| 238 *dst = src; |
| 239 return true; |
| 240 } else { |
| 241 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), b
ounds->height())); |
| 242 if (!device) { |
| 243 return false; |
| 244 } |
| 245 SkCanvas canvas(device); |
| 246 canvas.clear(0x00000000); |
| 247 canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bo
unds->y()); |
| 248 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); |
| 249 *dst = device->accessBitmap(false); |
| 250 return true; |
| 251 } |
211 } | 252 } |
212 | 253 |
213 bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, | 254 bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
214 SkIRect* dst) const { | 255 SkIRect* dst) const { |
215 if (fInputCount < 1) { | 256 if (fInputCount < 1) { |
216 return false; | 257 return false; |
217 } | 258 } |
218 | 259 |
219 SkIRect bounds; | 260 SkIRect bounds; |
220 for (int i = 0; i < fInputCount; ++i) { | 261 for (int i = 0; i < fInputCount; ++i) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); | 314 result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); |
274 GrUnlockAndUnrefCachedBitmapTexture(resultTex); | 315 GrUnlockAndUnrefCachedBitmapTexture(resultTex); |
275 } | 316 } |
276 return true; | 317 return true; |
277 } else { | 318 } else { |
278 return false; | 319 return false; |
279 } | 320 } |
280 } | 321 } |
281 } | 322 } |
282 #endif | 323 #endif |
OLD | NEW |