SkSurface_Raster.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright 2012 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/SkCanvas.h"
  8. #include "include/core/SkMallocPixelRef.h"
  9. #include "include/private/SkImageInfoPriv.h"
  10. #include "src/core/SkDevice.h"
  11. #include "src/core/SkImagePriv.h"
  12. #include "src/image/SkSurface_Base.h"
  13. class SkSurface_Raster : public SkSurface_Base {
  14. public:
  15. SkSurface_Raster(const SkImageInfo&, void*, size_t rb,
  16. void (*releaseProc)(void* pixels, void* context), void* context,
  17. const SkSurfaceProps*);
  18. SkSurface_Raster(const SkImageInfo& info, sk_sp<SkPixelRef>, const SkSurfaceProps*);
  19. SkCanvas* onNewCanvas() override;
  20. sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override;
  21. sk_sp<SkImage> onNewImageSnapshot(const SkIRect* subset) override;
  22. void onWritePixels(const SkPixmap&, int x, int y) override;
  23. void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override;
  24. void onCopyOnWrite(ContentChangeMode) override;
  25. void onRestoreBackingMutability() override;
  26. private:
  27. SkBitmap fBitmap;
  28. size_t fRowBytes;
  29. bool fWeOwnThePixels;
  30. typedef SkSurface_Base INHERITED;
  31. };
  32. ///////////////////////////////////////////////////////////////////////////////
  33. bool SkSurfaceValidateRasterInfo(const SkImageInfo& info, size_t rowBytes) {
  34. if (!SkImageInfoIsValid(info)) {
  35. return false;
  36. }
  37. if (kIgnoreRowBytesValue == rowBytes) {
  38. return true;
  39. }
  40. int shift = info.shiftPerPixel();
  41. uint64_t minRB = (uint64_t)info.width() << shift;
  42. if (minRB > rowBytes) {
  43. return false;
  44. }
  45. size_t alignedRowBytes = rowBytes >> shift << shift;
  46. if (alignedRowBytes != rowBytes) {
  47. return false;
  48. }
  49. uint64_t size = sk_64_mul(info.height(), rowBytes);
  50. static const size_t kMaxTotalSize = SK_MaxS32;
  51. if (size > kMaxTotalSize) {
  52. return false;
  53. }
  54. return true;
  55. }
  56. SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb,
  57. void (*releaseProc)(void* pixels, void* context), void* context,
  58. const SkSurfaceProps* props)
  59. : INHERITED(info, props)
  60. {
  61. fBitmap.installPixels(info, pixels, rb, releaseProc, context);
  62. fRowBytes = 0; // don't need to track the rowbytes
  63. fWeOwnThePixels = false; // We are "Direct"
  64. }
  65. SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, sk_sp<SkPixelRef> pr,
  66. const SkSurfaceProps* props)
  67. : INHERITED(pr->width(), pr->height(), props)
  68. {
  69. fBitmap.setInfo(info, pr->rowBytes());
  70. fRowBytes = pr->rowBytes(); // we track this, so that subsequent re-allocs will match
  71. fBitmap.setPixelRef(std::move(pr), 0, 0);
  72. fWeOwnThePixels = true;
  73. }
  74. SkCanvas* SkSurface_Raster::onNewCanvas() { return new SkCanvas(fBitmap, this->props()); }
  75. sk_sp<SkSurface> SkSurface_Raster::onNewSurface(const SkImageInfo& info) {
  76. return SkSurface::MakeRaster(info, &this->props());
  77. }
  78. void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
  79. const SkPaint* paint) {
  80. canvas->drawBitmap(fBitmap, x, y, paint);
  81. }
  82. sk_sp<SkImage> SkSurface_Raster::onNewImageSnapshot(const SkIRect* subset) {
  83. if (subset) {
  84. SkASSERT(SkIRect::MakeWH(fBitmap.width(), fBitmap.height()).contains(*subset));
  85. SkBitmap dst;
  86. dst.allocPixels(fBitmap.info().makeWH(subset->width(), subset->height()));
  87. SkAssertResult(fBitmap.readPixels(dst.pixmap(), subset->left(), subset->top()));
  88. dst.setImmutable(); // key, so MakeFromBitmap doesn't make a copy of the buffer
  89. return SkImage::MakeFromBitmap(dst);
  90. }
  91. SkCopyPixelsMode cpm = kIfMutable_SkCopyPixelsMode;
  92. if (fWeOwnThePixels) {
  93. // SkImage_raster requires these pixels are immutable for its full lifetime.
  94. // We'll undo this via onRestoreBackingMutability() if we can avoid the COW.
  95. if (SkPixelRef* pr = fBitmap.pixelRef()) {
  96. pr->setTemporarilyImmutable();
  97. }
  98. } else {
  99. cpm = kAlways_SkCopyPixelsMode;
  100. }
  101. // Our pixels are in memory, so read access on the snapshot SkImage could be cheap.
  102. // Lock the shared pixel ref to ensure peekPixels() is usable.
  103. return SkMakeImageFromRasterBitmap(fBitmap, cpm);
  104. }
  105. void SkSurface_Raster::onWritePixels(const SkPixmap& src, int x, int y) {
  106. fBitmap.writePixels(src, x, y);
  107. }
  108. void SkSurface_Raster::onRestoreBackingMutability() {
  109. SkASSERT(!this->hasCachedImage()); // Shouldn't be any snapshots out there.
  110. if (SkPixelRef* pr = fBitmap.pixelRef()) {
  111. pr->restoreMutability();
  112. }
  113. }
  114. void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
  115. // are we sharing pixelrefs with the image?
  116. sk_sp<SkImage> cached(this->refCachedImage());
  117. SkASSERT(cached);
  118. if (SkBitmapImageGetPixelRef(cached.get()) == fBitmap.pixelRef()) {
  119. SkASSERT(fWeOwnThePixels);
  120. if (kDiscard_ContentChangeMode == mode) {
  121. fBitmap.allocPixels();
  122. } else {
  123. SkBitmap prev(fBitmap);
  124. fBitmap.allocPixels();
  125. SkASSERT(prev.info() == fBitmap.info());
  126. SkASSERT(prev.rowBytes() == fBitmap.rowBytes());
  127. memcpy(fBitmap.getPixels(), prev.getPixels(), fBitmap.computeByteSize());
  128. }
  129. SkASSERT(fBitmap.rowBytes() == fRowBytes); // be sure we always use the same value
  130. // Now fBitmap is a deep copy of itself (and therefore different from
  131. // what is being used by the image. Next we update the canvas to use
  132. // this as its backend, so we can't modify the image's pixels anymore.
  133. SkASSERT(this->getCachedCanvas());
  134. this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap);
  135. }
  136. }
  137. ///////////////////////////////////////////////////////////////////////////////
  138. sk_sp<SkSurface> SkSurface::MakeRasterDirectReleaseProc(const SkImageInfo& info, void* pixels,
  139. size_t rb, void (*releaseProc)(void* pixels, void* context), void* context,
  140. const SkSurfaceProps* props) {
  141. if (nullptr == releaseProc) {
  142. context = nullptr;
  143. }
  144. if (!SkSurfaceValidateRasterInfo(info, rb)) {
  145. return nullptr;
  146. }
  147. if (nullptr == pixels) {
  148. return nullptr;
  149. }
  150. return sk_make_sp<SkSurface_Raster>(info, pixels, rb, releaseProc, context, props);
  151. }
  152. sk_sp<SkSurface> SkSurface::MakeRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes,
  153. const SkSurfaceProps* props) {
  154. return MakeRasterDirectReleaseProc(info, pixels, rowBytes, nullptr, nullptr, props);
  155. }
  156. sk_sp<SkSurface> SkSurface::MakeRaster(const SkImageInfo& info, size_t rowBytes,
  157. const SkSurfaceProps* props) {
  158. if (!SkSurfaceValidateRasterInfo(info)) {
  159. return nullptr;
  160. }
  161. sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeAllocate(info, rowBytes);
  162. if (!pr) {
  163. return nullptr;
  164. }
  165. if (rowBytes) {
  166. SkASSERT(pr->rowBytes() == rowBytes);
  167. }
  168. return sk_make_sp<SkSurface_Raster>(info, std::move(pr), props);
  169. }
  170. sk_sp<SkSurface> SkSurface::MakeRasterN32Premul(int width, int height,
  171. const SkSurfaceProps* surfaceProps) {
  172. return MakeRaster(SkImageInfo::MakeN32Premul(width, height), surfaceProps);
  173. }