blob: 4b25e21e862b138e237392c91fc1e78809b2e1ba [file] [log] [blame]
robertphillips@google.com53238bc2013-08-30 13:12:10 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkBitmapDevice.h"
9#include "SkConfig8888.h"
10#include "SkDraw.h"
reede51c3562016-07-19 14:33:20 -070011#include "SkImageFilter.h"
senorblanco900c3672016-04-27 11:31:23 -070012#include "SkImageFilterCache.h"
mtkleincd495412015-11-05 09:46:23 -080013#include "SkMallocPixelRef.h"
bungemand3ebb482015-08-05 13:57:49 -070014#include "SkMatrix.h"
15#include "SkPaint.h"
16#include "SkPath.h"
reed884e97c2015-05-26 11:31:54 -070017#include "SkPixelRef.h"
bungemand3ebb482015-08-05 13:57:49 -070018#include "SkPixmap.h"
reede51c3562016-07-19 14:33:20 -070019#include "SkRasterClip.h"
robertphillips@google.com53238bc2013-08-30 13:12:10 +000020#include "SkShader.h"
reede51c3562016-07-19 14:33:20 -070021#include "SkSpecialImage.h"
reed@google.com76f10a32014-02-05 15:32:21 +000022#include "SkSurface.h"
bungemand3ebb482015-08-05 13:57:49 -070023#include "SkXfermode.h"
24
25class SkColorTable;
robertphillips@google.com53238bc2013-08-30 13:12:10 +000026
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000027static bool valid_for_bitmap_device(const SkImageInfo& info,
28 SkAlphaType* newAlphaType) {
29 if (info.width() < 0 || info.height() < 0) {
30 return false;
31 }
32
33 // TODO: can we stop supporting kUnknown in SkBitmkapDevice?
34 if (kUnknown_SkColorType == info.colorType()) {
35 if (newAlphaType) {
reed44977482015-02-27 10:23:00 -080036 *newAlphaType = kUnknown_SkAlphaType;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000037 }
38 return true;
39 }
skia.committer@gmail.com969588f2014-02-16 03:01:56 +000040
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000041 switch (info.alphaType()) {
42 case kPremul_SkAlphaType:
43 case kOpaque_SkAlphaType:
44 break;
45 default:
46 return false;
47 }
48
49 SkAlphaType canonicalAlphaType = info.alphaType();
50
51 switch (info.colorType()) {
52 case kAlpha_8_SkColorType:
53 break;
54 case kRGB_565_SkColorType:
55 canonicalAlphaType = kOpaque_SkAlphaType;
56 break;
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000057 case kN32_SkColorType:
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000058 break;
reeda34be682016-02-15 07:48:35 -080059 case kRGBA_F16_SkColorType:
60 break;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000061 default:
62 return false;
63 }
64
65 if (newAlphaType) {
66 *newAlphaType = canonicalAlphaType;
67 }
68 return true;
69}
70
robertphillips9a53fd72015-06-22 09:46:59 -070071SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
72 : INHERITED(SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType))
reed2c9e2002016-07-25 08:05:22 -070073 , fBitmap(bitmap)
74{
halcanary96fcdcc2015-08-27 07:41:13 -070075 SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
reed2c9e2002016-07-25 08:05:22 -070076 fBitmap.lockPixels();
robertphillips@google.com53238bc2013-08-30 13:12:10 +000077}
78
robertphillips9a53fd72015-06-22 09:46:59 -070079SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) {
80 return Create(info, SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
81}
82
robertphillipsfcf78292015-06-19 11:49:52 -070083SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps)
robertphillips9a53fd72015-06-22 09:46:59 -070084 : INHERITED(surfaceProps)
reed2c9e2002016-07-25 08:05:22 -070085 , fBitmap(bitmap)
86{
halcanary96fcdcc2015-08-27 07:41:13 -070087 SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
reed2c9e2002016-07-25 08:05:22 -070088 fBitmap.lockPixels();
robertphillips@google.com53238bc2013-08-30 13:12:10 +000089}
90
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000091SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
robertphillips9a53fd72015-06-22 09:46:59 -070092 const SkSurfaceProps& surfaceProps) {
reede5ea5002014-09-03 11:54:58 -070093 SkAlphaType newAT = origInfo.alphaType();
94 if (!valid_for_bitmap_device(origInfo, &newAT)) {
halcanary96fcdcc2015-08-27 07:41:13 -070095 return nullptr;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000096 }
robertphillips@google.com53238bc2013-08-30 13:12:10 +000097
reede5ea5002014-09-03 11:54:58 -070098 const SkImageInfo info = origInfo.makeAlphaType(newAT);
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000099 SkBitmap bitmap;
100
101 if (kUnknown_SkColorType == info.colorType()) {
commit-bot@chromium.orga3264e52014-05-30 13:26:10 +0000102 if (!bitmap.setInfo(info)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700103 return nullptr;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +0000104 }
lsalzman04d975a2016-01-08 11:20:14 -0800105 } else if (info.isOpaque()) {
mtkleincd495412015-11-05 09:46:23 -0800106 // If this bitmap is opaque, we don't have any sensible default color,
107 // so we just return uninitialized pixels.
reed84825042014-09-02 12:50:45 -0700108 if (!bitmap.tryAllocPixels(info)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700109 return nullptr;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +0000110 }
mtkleincd495412015-11-05 09:46:23 -0800111 } else {
112 // This bitmap has transparency, so we'll zero the pixels (to transparent).
113 // We use a ZeroedPRFactory as a faster alloc-then-eraseColor(SK_ColorTRANSPARENT).
114 SkMallocPixelRef::ZeroedPRFactory factory;
115 if (!bitmap.tryAllocPixels(info, &factory, nullptr/*color table*/)) {
116 return nullptr;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +0000117 }
118 }
119
halcanary385fe4d2015-08-26 13:07:48 -0700120 return new SkBitmapDevice(bitmap, surfaceProps);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000121}
122
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000123SkImageInfo SkBitmapDevice::imageInfo() const {
124 return fBitmap.info();
125}
126
mtkleinfeaadee2015-04-08 11:25:48 -0700127void SkBitmapDevice::setNewSize(const SkISize& size) {
128 SkASSERT(!fBitmap.pixelRef());
129 fBitmap.setInfo(fBitmap.info().makeWH(size.fWidth, size.fHeight));
130}
131
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000132void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
133 SkASSERT(bm.width() == fBitmap.width());
134 SkASSERT(bm.height() == fBitmap.height());
135 fBitmap = bm; // intent is to use bm's pixelRef (and rowbytes/config)
136 fBitmap.lockPixels();
137}
138
reed76033be2015-03-14 10:54:31 -0700139SkBaseDevice* SkBitmapDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
robertphillips9a53fd72015-06-22 09:46:59 -0700140 const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
141 return SkBitmapDevice::Create(cinfo.fInfo, surfaceProps);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000142}
143
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000144const SkBitmap& SkBitmapDevice::onAccessBitmap() {
145 return fBitmap;
146}
147
reed884e97c2015-05-26 11:31:54 -0700148bool SkBitmapDevice::onAccessPixels(SkPixmap* pmap) {
reedb560b5c2016-07-24 12:30:34 -0700149 if (this->onPeekPixels(pmap)) {
reed6e764852015-06-05 14:11:32 -0700150 fBitmap.notifyPixelsChanged();
151 return true;
152 }
153 return false;
reed9572a102015-05-26 19:22:17 -0700154}
155
156bool SkBitmapDevice::onPeekPixels(SkPixmap* pmap) {
reed884e97c2015-05-26 11:31:54 -0700157 const SkImageInfo info = fBitmap.info();
158 if (fBitmap.getPixels() && (kUnknown_SkColorType != info.colorType())) {
halcanary96fcdcc2015-08-27 07:41:13 -0700159 SkColorTable* ctable = nullptr;
reed884e97c2015-05-26 11:31:54 -0700160 pmap->reset(fBitmap.info(), fBitmap.getPixels(), fBitmap.rowBytes(), ctable);
161 return true;
reed@google.com9c135db2014-03-12 18:28:35 +0000162 }
reed884e97c2015-05-26 11:31:54 -0700163 return false;
reed@google.com9c135db2014-03-12 18:28:35 +0000164}
165
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000166bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels,
167 size_t srcRowBytes, int x, int y) {
reed@google.com0d30c512014-03-14 14:02:58 +0000168 // since we don't stop creating un-pixeled devices yet, check for no pixels here
halcanary96fcdcc2015-08-27 07:41:13 -0700169 if (nullptr == fBitmap.getPixels()) {
reed@google.com0d30c512014-03-14 14:02:58 +0000170 return false;
171 }
172
reede5ea5002014-09-03 11:54:58 -0700173 const SkImageInfo dstInfo = fBitmap.info().makeWH(srcInfo.width(), srcInfo.height());
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000174
175 void* dstPixels = fBitmap.getAddr(x, y);
176 size_t dstRowBytes = fBitmap.rowBytes();
177
reedb184f7f2014-07-13 04:32:32 -0700178 if (SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) {
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000179 fBitmap.notifyPixelsChanged();
180 return true;
181 }
182 return false;
183}
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000184
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000185bool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
186 int x, int y) {
reedb184f7f2014-07-13 04:32:32 -0700187 return fBitmap.readPixels(dstInfo, dstPixels, dstRowBytes, x, y);
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000188}
189
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000190///////////////////////////////////////////////////////////////////////////////
191
192void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
193 draw.drawPaint(paint);
194}
195
196void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
197 const SkPoint pts[], const SkPaint& paint) {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000198 draw.drawPoints(mode, count, pts, paint);
199}
200
201void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000202 draw.drawRect(r, paint);
203}
204
205void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000206 SkPath path;
207 path.addOval(oval);
208 // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
209 // required to override drawOval.
halcanary96fcdcc2015-08-27 07:41:13 -0700210 this->drawPath(draw, path, paint, nullptr, true);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000211}
212
213void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
robertphillips@google.com50a76002013-11-12 01:16:56 +0000214#ifdef SK_IGNORE_BLURRED_RRECT_OPT
215 SkPath path;
216
217 path.addRRect(rrect);
218 // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
219 // required to override drawRRect.
halcanary96fcdcc2015-08-27 07:41:13 -0700220 this->drawPath(draw, path, paint, nullptr, true);
robertphillips@google.com50a76002013-11-12 01:16:56 +0000221#else
scroggo@google.coma8e33a92013-11-08 18:02:53 +0000222 draw.drawRRect(rrect, paint);
robertphillips@google.com50a76002013-11-12 01:16:56 +0000223#endif
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000224}
225
226void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
227 const SkPaint& paint, const SkMatrix* prePathMatrix,
228 bool pathIsMutable) {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000229 draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
230}
231
232void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
233 const SkMatrix& matrix, const SkPaint& paint) {
ericrk983294f2016-04-18 09:14:00 -0700234 LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
halcanary96fcdcc2015-08-27 07:41:13 -0700235 draw.drawBitmap(bitmap, matrix, nullptr, paint);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000236}
237
238void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
239 const SkRect* src, const SkRect& dst,
reed562fe472015-07-28 07:35:14 -0700240 const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000241 SkMatrix matrix;
242 SkRect bitmapBounds, tmpSrc, tmpDst;
243 SkBitmap tmpBitmap;
244
245 bitmapBounds.isetWH(bitmap.width(), bitmap.height());
246
247 // Compute matrix from the two rectangles
248 if (src) {
249 tmpSrc = *src;
250 } else {
251 tmpSrc = bitmapBounds;
252 }
253 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
254
ericrk983294f2016-04-18 09:14:00 -0700255 LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
256
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000257 const SkRect* dstPtr = &dst;
258 const SkBitmap* bitmapPtr = &bitmap;
259
260 // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
261 // needed (if the src was clipped). No check needed if src==null.
262 if (src) {
263 if (!bitmapBounds.contains(*src)) {
264 if (!tmpSrc.intersect(bitmapBounds)) {
265 return; // nothing to draw
266 }
267 // recompute dst, based on the smaller tmpSrc
268 matrix.mapRect(&tmpDst, tmpSrc);
269 dstPtr = &tmpDst;
270 }
271
272 // since we may need to clamp to the borders of the src rect within
273 // the bitmap, we extract a subset.
reedb07a94f2014-11-19 05:03:18 -0800274 const SkIRect srcIR = tmpSrc.roundOut();
piotaixr0e977052014-09-17 16:24:04 -0700275 if(bitmap.pixelRef()->getTexture()) {
276 // Accelerated source canvas, don't use extractSubset but readPixels to get the subset.
277 // This way, the pixels are copied in CPU memory instead of GPU memory.
bsalomon9d22fd62016-01-11 11:14:17 -0800278 bitmap.pixelRef()->readPixels(&tmpBitmap, kN32_SkColorType, &srcIR);
piotaixr0e977052014-09-17 16:24:04 -0700279 } else {
280 if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
281 return;
282 }
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000283 }
284 bitmapPtr = &tmpBitmap;
285
286 // Since we did an extract, we need to adjust the matrix accordingly
287 SkScalar dx = 0, dy = 0;
288 if (srcIR.fLeft > 0) {
289 dx = SkIntToScalar(srcIR.fLeft);
290 }
291 if (srcIR.fTop > 0) {
292 dy = SkIntToScalar(srcIR.fTop);
293 }
294 if (dx || dy) {
295 matrix.preTranslate(dx, dy);
296 }
297
298 SkRect extractedBitmapBounds;
299 extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
300 if (extractedBitmapBounds == tmpSrc) {
301 // no fractional part in src, we can just call drawBitmap
302 goto USE_DRAWBITMAP;
303 }
304 } else {
305 USE_DRAWBITMAP:
306 // We can go faster by just calling drawBitmap, which will concat the
307 // matrix with the CTM, and try to call drawSprite if it can. If not,
308 // it will make a shader and call drawRect, as we do below.
reed03939122014-12-15 13:42:51 -0800309 draw.drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000310 return;
311 }
312
313 // construct a shader, so we can call drawRect with the dst
reed8a21c9f2016-03-08 18:50:00 -0800314 auto s = SkShader::MakeBitmapShader(*bitmapPtr, SkShader::kClamp_TileMode,
315 SkShader::kClamp_TileMode, &matrix);
316 if (!s) {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000317 return;
318 }
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000319
320 SkPaint paintWithShader(paint);
321 paintWithShader.setStyle(SkPaint::kFill_Style);
reed8a21c9f2016-03-08 18:50:00 -0800322 paintWithShader.setShader(std::move(s));
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000323
324 // Call ourself, in case the subclass wanted to share this setup code
325 // but handle the drawRect code themselves.
326 this->drawRect(draw, *dstPtr, paintWithShader);
327}
328
329void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
330 int x, int y, const SkPaint& paint) {
331 draw.drawSprite(bitmap, x, y, paint);
332}
333
334void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
335 SkScalar x, SkScalar y, const SkPaint& paint) {
336 draw.drawText((const char*)text, len, x, y, paint);
337}
338
339void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
fmalita05c4a432014-09-29 06:29:53 -0700340 const SkScalar xpos[], int scalarsPerPos,
341 const SkPoint& offset, const SkPaint& paint) {
342 draw.drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000343}
344
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000345void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
346 int vertexCount,
347 const SkPoint verts[], const SkPoint textures[],
348 const SkColor colors[], SkXfermode* xmode,
349 const uint16_t indices[], int indexCount,
350 const SkPaint& paint) {
351 draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
352 indices, indexCount, paint);
353}
354
355void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
356 int x, int y, const SkPaint& paint) {
reedcf5c8462016-07-20 12:28:40 -0700357 SkASSERT(!paint.getImageFilter());
reed9572a102015-05-26 19:22:17 -0700358 draw.drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000359}
360
reede51c3562016-07-19 14:33:20 -0700361///////////////////////////////////////////////////////////////////////////////
362
363void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
364 const SkPaint& paint) {
365 SkASSERT(!srcImg->isTextureBacked());
366
367 SkBitmap resultBM;
368
369 SkImageFilter* filter = paint.getImageFilter();
370 if (filter) {
371 SkIPoint offset = SkIPoint::Make(0, 0);
372 SkMatrix matrix = *draw.fMatrix;
373 matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
374 const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y);
375 SkAutoTUnref<SkImageFilterCache> cache(this->getImageFilterCache());
376 SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
377
378 sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
379 if (resultImg) {
380 SkPaint tmpUnfiltered(paint);
381 tmpUnfiltered.setImageFilter(nullptr);
382 if (resultImg->getROPixels(&resultBM)) {
383 this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
384 }
385 }
386 } else {
387 if (srcImg->getROPixels(&resultBM)) {
388 this->drawSprite(draw, resultBM, x, y, paint);
389 }
390 }
391}
392
393sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {
394 return SkSpecialImage::MakeFromRaster(bitmap.bounds(), bitmap);
395}
396
397sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkImage* image) {
398 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image->height()),
399 image->makeNonTextureImage());
400}
401
402sk_sp<SkSpecialImage> SkBitmapDevice::snapSpecial() {
403 return this->makeSpecial(fBitmap);
404}
405
406///////////////////////////////////////////////////////////////////////////////
407
reede8f30622016-03-23 18:59:25 -0700408sk_sp<SkSurface> SkBitmapDevice::makeSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
409 return SkSurface::MakeRaster(info, &props);
reed@google.com76f10a32014-02-05 15:32:21 +0000410}
411
senorblanco900c3672016-04-27 11:31:23 -0700412SkImageFilterCache* SkBitmapDevice::getImageFilterCache() {
413 SkImageFilterCache* cache = SkImageFilterCache::Get();
senorblanco55b6d8b2014-07-30 11:26:46 -0700414 cache->ref();
415 return cache;
416}
417
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000418///////////////////////////////////////////////////////////////////////////////
419
reedb2db8982014-11-13 12:41:02 -0800420bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
commit-bot@chromium.orgcba73782014-05-29 15:57:47 +0000421 if (kN32_SkColorType != fBitmap.colorType() ||
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000422 paint.getRasterizer() ||
423 paint.getPathEffect() ||
424 paint.isFakeBoldText() ||
425 paint.getStyle() != SkPaint::kFill_Style ||
reedb2db8982014-11-13 12:41:02 -0800426 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode))
427 {
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000428 return true;
429 }
robertphillips@google.com53238bc2013-08-30 13:12:10 +0000430 return false;
431}