SkBitmapDevice.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. /*
  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. #include "include/core/SkImageFilter.h"
  8. #include "include/core/SkMatrix.h"
  9. #include "include/core/SkPaint.h"
  10. #include "include/core/SkPath.h"
  11. #include "include/core/SkPixmap.h"
  12. #include "include/core/SkRasterHandleAllocator.h"
  13. #include "include/core/SkShader.h"
  14. #include "include/core/SkSurface.h"
  15. #include "include/core/SkVertices.h"
  16. #include "src/core/SkBitmapDevice.h"
  17. #include "src/core/SkDraw.h"
  18. #include "src/core/SkGlyphRun.h"
  19. #include "src/core/SkImageFilterCache.h"
  20. #include "src/core/SkMakeUnique.h"
  21. #include "src/core/SkRasterClip.h"
  22. #include "src/core/SkSpecialImage.h"
  23. #include "src/core/SkStrikeCache.h"
  24. #include "src/core/SkTLazy.h"
  25. struct Bounder {
  26. SkRect fBounds;
  27. bool fHasBounds;
  28. Bounder(const SkRect& r, const SkPaint& paint) {
  29. if ((fHasBounds = paint.canComputeFastBounds())) {
  30. fBounds = paint.computeFastBounds(r, &fBounds);
  31. }
  32. }
  33. bool hasBounds() const { return fHasBounds; }
  34. const SkRect* bounds() const { return fHasBounds ? &fBounds : nullptr; }
  35. operator const SkRect* () const { return this->bounds(); }
  36. };
  37. class SkDrawTiler {
  38. enum {
  39. // 8K is 1 too big, since 8K << supersample == 32768 which is too big for SkFixed
  40. kMaxDim = 8192 - 1
  41. };
  42. SkBitmapDevice* fDevice;
  43. SkPixmap fRootPixmap;
  44. SkIRect fSrcBounds;
  45. // Used for tiling and non-tiling
  46. SkDraw fDraw;
  47. // fCurr... are only used if fNeedTiling
  48. SkMatrix fTileMatrix;
  49. SkRasterClip fTileRC;
  50. SkIPoint fOrigin;
  51. bool fDone, fNeedsTiling;
  52. public:
  53. static bool NeedsTiling(SkBitmapDevice* dev) {
  54. return dev->width() > kMaxDim || dev->height() > kMaxDim;
  55. }
  56. SkDrawTiler(SkBitmapDevice* dev, const SkRect* bounds) : fDevice(dev) {
  57. fDone = false;
  58. // we need fDst to be set, and if we're actually drawing, to dirty the genID
  59. if (!dev->accessPixels(&fRootPixmap)) {
  60. // NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
  61. fRootPixmap.reset(dev->imageInfo(), nullptr, 0);
  62. }
  63. // do a quick check, so we don't even have to process "bounds" if there is no need
  64. const SkIRect clipR = dev->fRCStack.rc().getBounds();
  65. fNeedsTiling = clipR.right() > kMaxDim || clipR.bottom() > kMaxDim;
  66. if (fNeedsTiling) {
  67. if (bounds) {
  68. // Make sure we round first, and then intersect. We can't rely on promoting the
  69. // clipR to floats (and then intersecting with devBounds) since promoting
  70. // int --> float can make the float larger than the int.
  71. // rounding(out) first runs the risk of clamping if the float is larger an intmax
  72. // but our roundOut() is saturating, which is fine for this use case
  73. //
  74. // e.g. the older version of this code did this:
  75. // devBounds = mapRect(bounds);
  76. // if (devBounds.intersect(SkRect::Make(clipR))) {
  77. // fSrcBounds = devBounds.roundOut();
  78. // The problem being that the promotion of clipR to SkRect was unreliable
  79. //
  80. fSrcBounds = dev->ctm().mapRect(*bounds).roundOut();
  81. if (fSrcBounds.intersect(clipR)) {
  82. // Check again, now that we have computed srcbounds.
  83. fNeedsTiling = fSrcBounds.right() > kMaxDim || fSrcBounds.bottom() > kMaxDim;
  84. } else {
  85. fNeedsTiling = false;
  86. fDone = true;
  87. }
  88. } else {
  89. fSrcBounds = clipR;
  90. }
  91. }
  92. if (fNeedsTiling) {
  93. // fDraw.fDst is reset each time in setupTileDraw()
  94. fDraw.fMatrix = &fTileMatrix;
  95. fDraw.fRC = &fTileRC;
  96. // we'll step/increase it before using it
  97. fOrigin.set(fSrcBounds.fLeft - kMaxDim, fSrcBounds.fTop);
  98. } else {
  99. // don't reference fSrcBounds, as it may not have been set
  100. fDraw.fDst = fRootPixmap;
  101. fDraw.fMatrix = &dev->ctm();
  102. fDraw.fRC = &dev->fRCStack.rc();
  103. fOrigin.set(0, 0);
  104. fDraw.fCoverage = dev->accessCoverage();
  105. }
  106. }
  107. bool needsTiling() const { return fNeedsTiling; }
  108. const SkDraw* next() {
  109. if (fDone) {
  110. return nullptr;
  111. }
  112. if (fNeedsTiling) {
  113. do {
  114. this->stepAndSetupTileDraw(); // might set the clip to empty and fDone to true
  115. } while (!fDone && fTileRC.isEmpty());
  116. // if we exit the loop and we're still empty, we're (past) done
  117. if (fTileRC.isEmpty()) {
  118. SkASSERT(fDone);
  119. return nullptr;
  120. }
  121. SkASSERT(!fTileRC.isEmpty());
  122. } else {
  123. fDone = true; // only draw untiled once
  124. }
  125. return &fDraw;
  126. }
  127. private:
  128. void stepAndSetupTileDraw() {
  129. SkASSERT(!fDone);
  130. SkASSERT(fNeedsTiling);
  131. // We do fRootPixmap.width() - kMaxDim instead of fOrigin.fX + kMaxDim to avoid overflow.
  132. if (fOrigin.fX >= fSrcBounds.fRight - kMaxDim) { // too far
  133. fOrigin.fX = fSrcBounds.fLeft;
  134. fOrigin.fY += kMaxDim;
  135. } else {
  136. fOrigin.fX += kMaxDim;
  137. }
  138. // fDone = next origin will be invalid.
  139. fDone = fOrigin.fX >= fSrcBounds.fRight - kMaxDim &&
  140. fOrigin.fY >= fSrcBounds.fBottom - kMaxDim;
  141. SkIRect bounds = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), kMaxDim, kMaxDim);
  142. SkASSERT(!bounds.isEmpty());
  143. bool success = fRootPixmap.extractSubset(&fDraw.fDst, bounds);
  144. SkASSERT_RELEASE(success);
  145. // now don't use bounds, since fDst has the clipped dimensions.
  146. fTileMatrix = fDevice->ctm();
  147. fTileMatrix.postTranslate(SkIntToScalar(-fOrigin.x()), SkIntToScalar(-fOrigin.y()));
  148. fDevice->fRCStack.rc().translate(-fOrigin.x(), -fOrigin.y(), &fTileRC);
  149. fTileRC.op(SkIRect::MakeWH(fDraw.fDst.width(), fDraw.fDst.height()),
  150. SkRegion::kIntersect_Op);
  151. }
  152. };
  153. // Passing a bounds allows the tiler to only visit the dst-tiles that might intersect the
  154. // drawing. If null is passed, the tiler has to visit everywhere. The bounds is expected to be
  155. // in local coordinates, as the tiler itself will transform that into device coordinates.
  156. //
  157. #define LOOP_TILER(code, boundsPtr) \
  158. SkDrawTiler priv_tiler(this, boundsPtr); \
  159. while (const SkDraw* priv_draw = priv_tiler.next()) { \
  160. priv_draw->code; \
  161. }
  162. // Helper to create an SkDraw from a device
  163. class SkBitmapDevice::BDDraw : public SkDraw {
  164. public:
  165. BDDraw(SkBitmapDevice* dev) {
  166. // we need fDst to be set, and if we're actually drawing, to dirty the genID
  167. if (!dev->accessPixels(&fDst)) {
  168. // NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
  169. fDst.reset(dev->imageInfo(), nullptr, 0);
  170. }
  171. fMatrix = &dev->ctm();
  172. fRC = &dev->fRCStack.rc();
  173. fCoverage = dev->accessCoverage();
  174. }
  175. };
  176. static bool valid_for_bitmap_device(const SkImageInfo& info,
  177. SkAlphaType* newAlphaType) {
  178. if (info.width() < 0 || info.height() < 0 || kUnknown_SkColorType == info.colorType()) {
  179. return false;
  180. }
  181. if (newAlphaType) {
  182. *newAlphaType = SkColorTypeIsAlwaysOpaque(info.colorType()) ? kOpaque_SkAlphaType
  183. : info.alphaType();
  184. }
  185. return true;
  186. }
  187. SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
  188. : INHERITED(bitmap.info(), SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType))
  189. , fBitmap(bitmap)
  190. , fRCStack(bitmap.width(), bitmap.height())
  191. , fGlyphPainter(this->surfaceProps(),
  192. bitmap.colorType(),
  193. bitmap.colorSpace(),
  194. SkStrikeCache::GlobalStrikeCache()) {
  195. SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
  196. }
  197. SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) {
  198. return Create(info, SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
  199. }
  200. SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps,
  201. SkRasterHandleAllocator::Handle hndl, const SkBitmap* coverage)
  202. : INHERITED(bitmap.info(), surfaceProps)
  203. , fBitmap(bitmap)
  204. , fRasterHandle(hndl)
  205. , fRCStack(bitmap.width(), bitmap.height())
  206. , fGlyphPainter(this->surfaceProps(),
  207. bitmap.colorType(),
  208. bitmap.colorSpace(),
  209. SkStrikeCache::GlobalStrikeCache()) {
  210. SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
  211. if (coverage) {
  212. SkASSERT(coverage->width() == bitmap.width());
  213. SkASSERT(coverage->height() == bitmap.height());
  214. fCoverage = skstd::make_unique<SkBitmap>(*coverage);
  215. }
  216. }
  217. SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
  218. const SkSurfaceProps& surfaceProps,
  219. bool trackCoverage,
  220. SkRasterHandleAllocator* allocator) {
  221. SkAlphaType newAT = origInfo.alphaType();
  222. if (!valid_for_bitmap_device(origInfo, &newAT)) {
  223. return nullptr;
  224. }
  225. SkRasterHandleAllocator::Handle hndl = nullptr;
  226. const SkImageInfo info = origInfo.makeAlphaType(newAT);
  227. SkBitmap bitmap;
  228. if (kUnknown_SkColorType == info.colorType()) {
  229. if (!bitmap.setInfo(info)) {
  230. return nullptr;
  231. }
  232. } else if (allocator) {
  233. hndl = allocator->allocBitmap(info, &bitmap);
  234. if (!hndl) {
  235. return nullptr;
  236. }
  237. } else if (info.isOpaque()) {
  238. // If this bitmap is opaque, we don't have any sensible default color,
  239. // so we just return uninitialized pixels.
  240. if (!bitmap.tryAllocPixels(info)) {
  241. return nullptr;
  242. }
  243. } else {
  244. // This bitmap has transparency, so we'll zero the pixels (to transparent).
  245. // We use the flag as a faster alloc-then-eraseColor(SK_ColorTRANSPARENT).
  246. if (!bitmap.tryAllocPixelsFlags(info, SkBitmap::kZeroPixels_AllocFlag)) {
  247. return nullptr;
  248. }
  249. }
  250. SkBitmap coverage;
  251. if (trackCoverage) {
  252. SkImageInfo ci = SkImageInfo::Make(info.width(), info.height(), kAlpha_8_SkColorType,
  253. kPremul_SkAlphaType);
  254. if (!coverage.tryAllocPixelsFlags(ci, SkBitmap::kZeroPixels_AllocFlag)) {
  255. return nullptr;
  256. }
  257. }
  258. return new SkBitmapDevice(bitmap, surfaceProps, hndl, trackCoverage ? &coverage : nullptr);
  259. }
  260. void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
  261. SkASSERT(bm.width() == fBitmap.width());
  262. SkASSERT(bm.height() == fBitmap.height());
  263. fBitmap = bm; // intent is to use bm's pixelRef (and rowbytes/config)
  264. this->privateResize(fBitmap.info().width(), fBitmap.info().height());
  265. }
  266. SkBaseDevice* SkBitmapDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
  267. const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
  268. return SkBitmapDevice::Create(cinfo.fInfo, surfaceProps, cinfo.fTrackCoverage,
  269. cinfo.fAllocator);
  270. }
  271. bool SkBitmapDevice::onAccessPixels(SkPixmap* pmap) {
  272. if (this->onPeekPixels(pmap)) {
  273. fBitmap.notifyPixelsChanged();
  274. return true;
  275. }
  276. return false;
  277. }
  278. bool SkBitmapDevice::onPeekPixels(SkPixmap* pmap) {
  279. const SkImageInfo info = fBitmap.info();
  280. if (fBitmap.getPixels() && (kUnknown_SkColorType != info.colorType())) {
  281. pmap->reset(fBitmap.info(), fBitmap.getPixels(), fBitmap.rowBytes());
  282. return true;
  283. }
  284. return false;
  285. }
  286. bool SkBitmapDevice::onWritePixels(const SkPixmap& pm, int x, int y) {
  287. // since we don't stop creating un-pixeled devices yet, check for no pixels here
  288. if (nullptr == fBitmap.getPixels()) {
  289. return false;
  290. }
  291. if (fBitmap.writePixels(pm, x, y)) {
  292. fBitmap.notifyPixelsChanged();
  293. return true;
  294. }
  295. return false;
  296. }
  297. bool SkBitmapDevice::onReadPixels(const SkPixmap& pm, int x, int y) {
  298. return fBitmap.readPixels(pm, x, y);
  299. }
  300. ///////////////////////////////////////////////////////////////////////////////
  301. void SkBitmapDevice::drawPaint(const SkPaint& paint) {
  302. BDDraw(this).drawPaint(paint);
  303. }
  304. void SkBitmapDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
  305. const SkPoint pts[], const SkPaint& paint) {
  306. LOOP_TILER( drawPoints(mode, count, pts, paint, nullptr), nullptr)
  307. }
  308. void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) {
  309. LOOP_TILER( drawRect(r, paint), Bounder(r, paint))
  310. }
  311. void SkBitmapDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
  312. SkPath path;
  313. path.addOval(oval);
  314. // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
  315. // required to override drawOval.
  316. this->drawPath(path, paint, true);
  317. }
  318. void SkBitmapDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
  319. #ifdef SK_IGNORE_BLURRED_RRECT_OPT
  320. SkPath path;
  321. path.addRRect(rrect);
  322. // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
  323. // required to override drawRRect.
  324. this->drawPath(path, paint, true);
  325. #else
  326. LOOP_TILER( drawRRect(rrect, paint), Bounder(rrect.getBounds(), paint))
  327. #endif
  328. }
  329. void SkBitmapDevice::drawPath(const SkPath& path,
  330. const SkPaint& paint,
  331. bool pathIsMutable) {
  332. const SkRect* bounds = nullptr;
  333. if (SkDrawTiler::NeedsTiling(this) && !path.isInverseFillType()) {
  334. bounds = &path.getBounds();
  335. }
  336. SkDrawTiler tiler(this, bounds ? Bounder(*bounds, paint).bounds() : nullptr);
  337. if (tiler.needsTiling()) {
  338. pathIsMutable = false;
  339. }
  340. while (const SkDraw* draw = tiler.next()) {
  341. draw->drawPath(path, paint, nullptr, pathIsMutable);
  342. }
  343. }
  344. void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
  345. const SkRect* dstOrNull, const SkPaint& paint) {
  346. const SkRect* bounds = dstOrNull;
  347. SkRect storage;
  348. if (!bounds && SkDrawTiler::NeedsTiling(this)) {
  349. matrix.mapRect(&storage, SkRect::MakeIWH(bitmap.width(), bitmap.height()));
  350. Bounder b(storage, paint);
  351. if (b.hasBounds()) {
  352. storage = *b.bounds();
  353. bounds = &storage;
  354. }
  355. }
  356. LOOP_TILER(drawBitmap(bitmap, matrix, dstOrNull, paint), bounds)
  357. }
  358. static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
  359. if (!paint.getMaskFilter()) {
  360. return true;
  361. }
  362. // Some mask filters parameters (sigma) depend on the CTM/scale.
  363. return m.getType() <= SkMatrix::kTranslate_Mask;
  364. }
  365. void SkBitmapDevice::drawBitmapRect(const SkBitmap& bitmap,
  366. const SkRect* src, const SkRect& dst,
  367. const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
  368. SkASSERT(dst.isFinite());
  369. SkASSERT(dst.isSorted());
  370. SkMatrix matrix;
  371. SkRect bitmapBounds, tmpSrc, tmpDst;
  372. SkBitmap tmpBitmap;
  373. bitmapBounds.isetWH(bitmap.width(), bitmap.height());
  374. // Compute matrix from the two rectangles
  375. if (src) {
  376. tmpSrc = *src;
  377. } else {
  378. tmpSrc = bitmapBounds;
  379. }
  380. matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
  381. LogDrawScaleFactor(this->ctm(), matrix, paint.getFilterQuality());
  382. const SkRect* dstPtr = &dst;
  383. const SkBitmap* bitmapPtr = &bitmap;
  384. // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
  385. // needed (if the src was clipped). No check needed if src==null.
  386. if (src) {
  387. if (!bitmapBounds.contains(*src)) {
  388. if (!tmpSrc.intersect(bitmapBounds)) {
  389. return; // nothing to draw
  390. }
  391. // recompute dst, based on the smaller tmpSrc
  392. matrix.mapRect(&tmpDst, tmpSrc);
  393. if (!tmpDst.isFinite()) {
  394. return;
  395. }
  396. dstPtr = &tmpDst;
  397. }
  398. }
  399. if (src && !src->contains(bitmapBounds) &&
  400. SkCanvas::kFast_SrcRectConstraint == constraint &&
  401. paint.getFilterQuality() != kNone_SkFilterQuality) {
  402. // src is smaller than the bounds of the bitmap, and we are filtering, so we don't know
  403. // how much more of the bitmap we need, so we can't use extractSubset or drawBitmap,
  404. // but we must use a shader w/ dst bounds (which can access all of the bitmap needed).
  405. goto USE_SHADER;
  406. }
  407. if (src) {
  408. // since we may need to clamp to the borders of the src rect within
  409. // the bitmap, we extract a subset.
  410. const SkIRect srcIR = tmpSrc.roundOut();
  411. if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
  412. return;
  413. }
  414. bitmapPtr = &tmpBitmap;
  415. // Since we did an extract, we need to adjust the matrix accordingly
  416. SkScalar dx = 0, dy = 0;
  417. if (srcIR.fLeft > 0) {
  418. dx = SkIntToScalar(srcIR.fLeft);
  419. }
  420. if (srcIR.fTop > 0) {
  421. dy = SkIntToScalar(srcIR.fTop);
  422. }
  423. if (dx || dy) {
  424. matrix.preTranslate(dx, dy);
  425. }
  426. #ifdef SK_DRAWBITMAPRECT_FAST_OFFSET
  427. SkRect extractedBitmapBounds = SkRect::MakeXYWH(dx, dy,
  428. SkIntToScalar(bitmapPtr->width()),
  429. SkIntToScalar(bitmapPtr->height()));
  430. #else
  431. SkRect extractedBitmapBounds;
  432. extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
  433. #endif
  434. if (extractedBitmapBounds == tmpSrc) {
  435. // no fractional part in src, we can just call drawBitmap
  436. goto USE_DRAWBITMAP;
  437. }
  438. } else {
  439. USE_DRAWBITMAP:
  440. // We can go faster by just calling drawBitmap, which will concat the
  441. // matrix with the CTM, and try to call drawSprite if it can. If not,
  442. // it will make a shader and call drawRect, as we do below.
  443. if (CanApplyDstMatrixAsCTM(matrix, paint)) {
  444. this->drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
  445. return;
  446. }
  447. }
  448. USE_SHADER:
  449. // TODO(herb): Move this over to SkArenaAlloc when arena alloc has a facility to return sk_sps.
  450. // Since the shader need only live for our stack-frame, pass in a custom allocator. This
  451. // can save malloc calls, and signals to SkMakeBitmapShader to not try to copy the bitmap
  452. // if its mutable, since that precaution is not needed (give the short lifetime of the shader).
  453. // construct a shader, so we can call drawRect with the dst
  454. auto s = SkMakeBitmapShaderForPaint(paint, *bitmapPtr, SkTileMode::kClamp,
  455. SkTileMode::kClamp, &matrix, kNever_SkCopyPixelsMode);
  456. if (!s) {
  457. return;
  458. }
  459. SkPaint paintWithShader(paint);
  460. paintWithShader.setStyle(SkPaint::kFill_Style);
  461. paintWithShader.setShader(std::move(s));
  462. // Call ourself, in case the subclass wanted to share this setup code
  463. // but handle the drawRect code themselves.
  464. this->drawRect(*dstPtr, paintWithShader);
  465. }
  466. void SkBitmapDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) {
  467. BDDraw(this).drawSprite(bitmap, x, y, paint);
  468. }
  469. void SkBitmapDevice::drawGlyphRunList(const SkGlyphRunList& glyphRunList) {
  470. LOOP_TILER( drawGlyphRunList(glyphRunList, &fGlyphPainter), nullptr )
  471. }
  472. void SkBitmapDevice::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
  473. int boneCount, SkBlendMode bmode, const SkPaint& paint) {
  474. BDDraw(this).drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
  475. vertices->texCoords(), vertices->colors(), vertices->boneIndices(),
  476. vertices->boneWeights(), bmode, vertices->indices(),
  477. vertices->indexCount(), paint, bones, boneCount);
  478. }
  479. void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& origPaint) {
  480. SkASSERT(!origPaint.getImageFilter());
  481. // todo: can we unify with similar adjustment in SkGpuDevice?
  482. SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
  483. if (paint->getMaskFilter()) {
  484. paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithMatrix(this->ctm()));
  485. }
  486. // hack to test coverage
  487. SkBitmapDevice* src = static_cast<SkBitmapDevice*>(device);
  488. if (src->fCoverage) {
  489. SkDraw draw;
  490. draw.fDst = fBitmap.pixmap();
  491. draw.fMatrix = &SkMatrix::I();
  492. draw.fRC = &fRCStack.rc();
  493. SkPaint paint(origPaint);
  494. paint.setShader(src->fBitmap.makeShader());
  495. draw.drawBitmap(*src->fCoverage.get(),
  496. SkMatrix::MakeTrans(SkIntToScalar(x),SkIntToScalar(y)), nullptr, paint);
  497. } else {
  498. this->drawSprite(src->fBitmap, x, y, *paint);
  499. }
  500. }
  501. ///////////////////////////////////////////////////////////////////////////////
  502. namespace {
  503. class SkAutoDeviceClipRestore {
  504. public:
  505. SkAutoDeviceClipRestore(SkBaseDevice* device, const SkIRect& clip)
  506. : fDevice(device)
  507. , fPrevCTM(device->ctm()) {
  508. fDevice->save();
  509. fDevice->setCTM(SkMatrix::I());
  510. fDevice->clipRect(SkRect::Make(clip), SkClipOp::kIntersect, false);
  511. fDevice->setCTM(fPrevCTM);
  512. }
  513. ~SkAutoDeviceClipRestore() {
  514. fDevice->restore(fPrevCTM);
  515. }
  516. private:
  517. SkBaseDevice* fDevice;
  518. const SkMatrix fPrevCTM;
  519. };
  520. } // anonymous ns
  521. void SkBitmapDevice::drawSpecial(SkSpecialImage* src, int x, int y, const SkPaint& origPaint,
  522. SkImage* clipImage, const SkMatrix& clipMatrix) {
  523. SkASSERT(!src->isTextureBacked());
  524. sk_sp<SkSpecialImage> filteredImage;
  525. SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
  526. if (SkImageFilter* filter = paint->getImageFilter()) {
  527. SkIPoint offset = SkIPoint::Make(0, 0);
  528. const SkMatrix matrix = SkMatrix::Concat(
  529. SkMatrix::MakeTrans(SkIntToScalar(-x), SkIntToScalar(-y)), this->ctm());
  530. const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
  531. sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
  532. SkImageFilter::OutputProperties outputProperties(fBitmap.colorType(), fBitmap.colorSpace());
  533. SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
  534. filteredImage = filter->filterImage(src, ctx, &offset);
  535. if (!filteredImage) {
  536. return;
  537. }
  538. src = filteredImage.get();
  539. paint.writable()->setImageFilter(nullptr);
  540. x += offset.x();
  541. y += offset.y();
  542. }
  543. if (paint->getMaskFilter()) {
  544. paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithMatrix(this->ctm()));
  545. }
  546. if (!clipImage) {
  547. SkBitmap resultBM;
  548. if (src->getROPixels(&resultBM)) {
  549. this->drawSprite(resultBM, x, y, *paint);
  550. }
  551. return;
  552. }
  553. // Clip image case.
  554. sk_sp<SkImage> srcImage(src->asImage());
  555. if (!srcImage) {
  556. return;
  557. }
  558. const SkMatrix totalMatrix = SkMatrix::Concat(this->ctm(), clipMatrix);
  559. SkRect clipBounds;
  560. totalMatrix.mapRect(&clipBounds, SkRect::Make(clipImage->bounds()));
  561. const SkIRect srcBounds = srcImage->bounds().makeOffset(x, y);
  562. SkIRect maskBounds = fRCStack.rc().getBounds();
  563. if (!maskBounds.intersect(clipBounds.roundOut()) || !maskBounds.intersect(srcBounds)) {
  564. return;
  565. }
  566. sk_sp<SkImage> mask;
  567. SkMatrix maskMatrix, shaderMatrix;
  568. SkTLazy<SkAutoDeviceClipRestore> autoClipRestore;
  569. SkMatrix totalInverse;
  570. if (clipImage->isAlphaOnly() && totalMatrix.invert(&totalInverse)) {
  571. // If the mask is already in A8 format, we can draw it directly
  572. // (while compensating in the shader matrix).
  573. mask = sk_ref_sp(clipImage);
  574. maskMatrix = totalMatrix;
  575. shaderMatrix = SkMatrix::Concat(totalInverse, SkMatrix::MakeTrans(x, y));
  576. // If the mask is not fully contained within the src layer, we must clip.
  577. if (!srcBounds.contains(clipBounds)) {
  578. autoClipRestore.init(this, srcBounds);
  579. }
  580. maskBounds.offsetTo(0, 0);
  581. } else {
  582. // Otherwise, we convert the mask to A8 explicitly.
  583. sk_sp<SkSurface> surf = SkSurface::MakeRaster(SkImageInfo::MakeA8(maskBounds.width(),
  584. maskBounds.height()));
  585. SkCanvas* canvas = surf->getCanvas();
  586. canvas->translate(-maskBounds.x(), -maskBounds.y());
  587. canvas->concat(totalMatrix);
  588. canvas->drawImage(clipImage, 0, 0);
  589. mask = surf->makeImageSnapshot();
  590. maskMatrix = SkMatrix::I();
  591. shaderMatrix = SkMatrix::MakeTrans(x - maskBounds.x(), y - maskBounds.y());
  592. }
  593. SkAutoDeviceCTMRestore adctmr(this, maskMatrix);
  594. paint.writable()->setShader(srcImage->makeShader(&shaderMatrix));
  595. this->drawImageRect(mask.get(), nullptr,
  596. SkRect::MakeXYWH(maskBounds.x(), maskBounds.y(),
  597. mask->width(), mask->height()),
  598. *paint, SkCanvas::kFast_SrcRectConstraint);
  599. }
  600. sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {
  601. return SkSpecialImage::MakeFromRaster(bitmap.bounds(), bitmap);
  602. }
  603. sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkImage* image) {
  604. return SkSpecialImage::MakeFromImage(nullptr, SkIRect::MakeWH(image->width(), image->height()),
  605. image->makeNonTextureImage());
  606. }
  607. sk_sp<SkSpecialImage> SkBitmapDevice::snapSpecial() {
  608. return this->makeSpecial(fBitmap);
  609. }
  610. sk_sp<SkSpecialImage> SkBitmapDevice::snapBackImage(const SkIRect& bounds) {
  611. return SkSpecialImage::CopyFromRaster(bounds, fBitmap, &this->surfaceProps());
  612. }
  613. ///////////////////////////////////////////////////////////////////////////////
  614. sk_sp<SkSurface> SkBitmapDevice::makeSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
  615. return SkSurface::MakeRaster(info, &props);
  616. }
  617. SkImageFilterCache* SkBitmapDevice::getImageFilterCache() {
  618. SkImageFilterCache* cache = SkImageFilterCache::Get();
  619. cache->ref();
  620. return cache;
  621. }
  622. ///////////////////////////////////////////////////////////////////////////////////////////////////
  623. void SkBitmapDevice::onSave() {
  624. fRCStack.save();
  625. }
  626. void SkBitmapDevice::onRestore() {
  627. fRCStack.restore();
  628. }
  629. void SkBitmapDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
  630. fRCStack.clipRect(this->ctm(), rect, op, aa);
  631. }
  632. void SkBitmapDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
  633. fRCStack.clipRRect(this->ctm(), rrect, op, aa);
  634. }
  635. void SkBitmapDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
  636. fRCStack.clipPath(this->ctm(), path, op, aa);
  637. }
  638. void SkBitmapDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) {
  639. SkIPoint origin = this->getOrigin();
  640. SkRegion tmp;
  641. const SkRegion* ptr = &rgn;
  642. if (origin.fX | origin.fY) {
  643. // translate from "global/canvas" coordinates to relative to this device
  644. rgn.translate(-origin.fX, -origin.fY, &tmp);
  645. ptr = &tmp;
  646. }
  647. fRCStack.clipRegion(*ptr, op);
  648. }
  649. void SkBitmapDevice::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {
  650. fRCStack.setDeviceClipRestriction(mutableClipRestriction);
  651. if (!mutableClipRestriction->isEmpty()) {
  652. SkRegion rgn(*mutableClipRestriction);
  653. fRCStack.clipRegion(rgn, SkClipOp::kIntersect);
  654. }
  655. }
  656. bool SkBitmapDevice::onClipIsAA() const {
  657. const SkRasterClip& rc = fRCStack.rc();
  658. return !rc.isEmpty() && rc.isAA();
  659. }
  660. void SkBitmapDevice::onAsRgnClip(SkRegion* rgn) const {
  661. const SkRasterClip& rc = fRCStack.rc();
  662. if (rc.isAA()) {
  663. rgn->setRect(rc.getBounds());
  664. } else {
  665. *rgn = rc.bwRgn();
  666. }
  667. }
  668. void SkBitmapDevice::validateDevBounds(const SkIRect& drawClipBounds) {
  669. #ifdef SK_DEBUG
  670. const SkIRect& stackBounds = fRCStack.rc().getBounds();
  671. SkASSERT(drawClipBounds == stackBounds);
  672. #endif
  673. }
  674. SkBaseDevice::ClipType SkBitmapDevice::onGetClipType() const {
  675. const SkRasterClip& rc = fRCStack.rc();
  676. if (rc.isEmpty()) {
  677. return kEmpty_ClipType;
  678. } else if (rc.isRect()) {
  679. return kRect_ClipType;
  680. } else {
  681. return kComplex_ClipType;
  682. }
  683. }