SkImage_Raster.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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/SkBitmap.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkData.h"
  10. #include "include/core/SkPixelRef.h"
  11. #include "include/core/SkSurface.h"
  12. #include "include/private/SkImageInfoPriv.h"
  13. #include "src/codec/SkColorTable.h"
  14. #include "src/core/SkConvertPixels.h"
  15. #include "src/core/SkImagePriv.h"
  16. #include "src/core/SkTLazy.h"
  17. #include "src/image/SkImage_Base.h"
  18. #include "src/shaders/SkBitmapProcShader.h"
  19. #if SK_SUPPORT_GPU
  20. #include "include/gpu/GrContext.h"
  21. #include "src/gpu/GrTextureAdjuster.h"
  22. #include "src/gpu/SkGr.h"
  23. #endif
  24. // fixes https://bug.skia.org/5096
  25. static bool is_not_subset(const SkBitmap& bm) {
  26. SkASSERT(bm.pixelRef());
  27. SkISize dim = SkISize::Make(bm.pixelRef()->width(), bm.pixelRef()->height());
  28. SkASSERT(dim != bm.dimensions() || bm.pixelRefOrigin().isZero());
  29. return dim == bm.dimensions();
  30. }
  31. class SkImage_Raster : public SkImage_Base {
  32. public:
  33. static bool ValidArgs(const SkImageInfo& info, size_t rowBytes, size_t* minSize) {
  34. const int maxDimension = SK_MaxS32 >> 2;
  35. if (info.width() <= 0 || info.height() <= 0) {
  36. return false;
  37. }
  38. if (info.width() > maxDimension || info.height() > maxDimension) {
  39. return false;
  40. }
  41. if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
  42. return false;
  43. }
  44. if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
  45. return false;
  46. }
  47. if (kUnknown_SkColorType == info.colorType()) {
  48. return false;
  49. }
  50. if (!info.validRowBytes(rowBytes)) {
  51. return false;
  52. }
  53. size_t size = info.computeByteSize(rowBytes);
  54. if (SkImageInfo::ByteSizeOverflowed(size)) {
  55. return false;
  56. }
  57. if (minSize) {
  58. *minSize = size;
  59. }
  60. return true;
  61. }
  62. SkImage_Raster(const SkImageInfo&, sk_sp<SkData>, size_t rb,
  63. uint32_t id = kNeedNewImageUniqueID);
  64. ~SkImage_Raster() override;
  65. bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
  66. bool onPeekPixels(SkPixmap*) const override;
  67. const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
  68. #if SK_SUPPORT_GPU
  69. sk_sp<GrTextureProxy> asTextureProxyRef(GrRecordingContext*, const GrSamplerState&,
  70. SkScalar scaleAdjust[2]) const override;
  71. #endif
  72. bool getROPixels(SkBitmap*, CachingHint) const override;
  73. sk_sp<SkImage> onMakeSubset(GrRecordingContext*, const SkIRect&) const override;
  74. SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
  75. bool onAsLegacyBitmap(SkBitmap*) const override;
  76. SkImage_Raster(const SkBitmap& bm, bool bitmapMayBeMutable = false)
  77. : INHERITED(bm.info(),
  78. is_not_subset(bm) ? bm.getGenerationID() : (uint32_t)kNeedNewImageUniqueID)
  79. , fBitmap(bm) {
  80. SkASSERT(bitmapMayBeMutable || fBitmap.isImmutable());
  81. }
  82. sk_sp<SkImage> onMakeColorTypeAndColorSpace(GrRecordingContext*,
  83. SkColorType, sk_sp<SkColorSpace>) const override;
  84. bool onIsValid(GrContext* context) const override { return true; }
  85. void notifyAddedToRasterCache() const override {
  86. // We explicitly DON'T want to call INHERITED::notifyAddedToRasterCache. That ties the
  87. // lifetime of derived/cached resources to the image. In this case, we only want cached
  88. // data (eg mips) tied to the lifetime of the underlying pixelRef.
  89. SkASSERT(fBitmap.pixelRef());
  90. fBitmap.pixelRef()->notifyAddedToCache();
  91. }
  92. #if SK_SUPPORT_GPU
  93. sk_sp<GrTextureProxy> refPinnedTextureProxy(GrRecordingContext*,
  94. uint32_t* uniqueID) const override;
  95. bool onPinAsTexture(GrContext*) const override;
  96. void onUnpinAsTexture(GrContext*) const override;
  97. #endif
  98. private:
  99. SkBitmap fBitmap;
  100. #if SK_SUPPORT_GPU
  101. mutable sk_sp<GrTextureProxy> fPinnedProxy;
  102. mutable int32_t fPinnedCount = 0;
  103. mutable uint32_t fPinnedUniqueID = 0;
  104. #endif
  105. typedef SkImage_Base INHERITED;
  106. };
  107. ///////////////////////////////////////////////////////////////////////////////
  108. static void release_data(void* addr, void* context) {
  109. SkData* data = static_cast<SkData*>(context);
  110. data->unref();
  111. }
  112. SkImage_Raster::SkImage_Raster(const SkImageInfo& info, sk_sp<SkData> data, size_t rowBytes,
  113. uint32_t id)
  114. : INHERITED(info, id) {
  115. void* addr = const_cast<void*>(data->data());
  116. fBitmap.installPixels(info, addr, rowBytes, release_data, data.release());
  117. fBitmap.setImmutable();
  118. }
  119. SkImage_Raster::~SkImage_Raster() {
  120. #if SK_SUPPORT_GPU
  121. SkASSERT(nullptr == fPinnedProxy.get()); // want the caller to have manually unpinned
  122. #endif
  123. }
  124. bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
  125. int srcX, int srcY, CachingHint) const {
  126. SkBitmap shallowCopy(fBitmap);
  127. return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
  128. }
  129. bool SkImage_Raster::onPeekPixels(SkPixmap* pm) const {
  130. return fBitmap.peekPixels(pm);
  131. }
  132. bool SkImage_Raster::getROPixels(SkBitmap* dst, CachingHint) const {
  133. *dst = fBitmap;
  134. return true;
  135. }
  136. #if SK_SUPPORT_GPU
  137. sk_sp<GrTextureProxy> SkImage_Raster::asTextureProxyRef(GrRecordingContext* context,
  138. const GrSamplerState& params,
  139. SkScalar scaleAdjust[2]) const {
  140. if (!context) {
  141. return nullptr;
  142. }
  143. uint32_t uniqueID;
  144. sk_sp<GrTextureProxy> tex = this->refPinnedTextureProxy(context, &uniqueID);
  145. if (tex) {
  146. GrTextureAdjuster adjuster(context, fPinnedProxy,
  147. SkColorTypeToGrColorType(fBitmap.colorType()),
  148. fBitmap.alphaType(), fPinnedUniqueID, fBitmap.colorSpace());
  149. return adjuster.refTextureProxyForParams(params, scaleAdjust);
  150. }
  151. return GrRefCachedBitmapTextureProxy(context, fBitmap, params, scaleAdjust);
  152. }
  153. #endif
  154. #if SK_SUPPORT_GPU
  155. sk_sp<GrTextureProxy> SkImage_Raster::refPinnedTextureProxy(GrRecordingContext*,
  156. uint32_t* uniqueID) const {
  157. if (fPinnedProxy) {
  158. SkASSERT(fPinnedCount > 0);
  159. SkASSERT(fPinnedUniqueID != 0);
  160. *uniqueID = fPinnedUniqueID;
  161. return fPinnedProxy;
  162. }
  163. return nullptr;
  164. }
  165. bool SkImage_Raster::onPinAsTexture(GrContext* ctx) const {
  166. if (fPinnedProxy) {
  167. SkASSERT(fPinnedCount > 0);
  168. SkASSERT(fPinnedUniqueID != 0);
  169. } else {
  170. SkASSERT(fPinnedCount == 0);
  171. SkASSERT(fPinnedUniqueID == 0);
  172. fPinnedProxy = GrRefCachedBitmapTextureProxy(ctx, fBitmap, GrSamplerState::ClampNearest(),
  173. nullptr);
  174. if (!fPinnedProxy) {
  175. return false;
  176. }
  177. fPinnedUniqueID = fBitmap.getGenerationID();
  178. }
  179. // Note: we only increment if the texture was successfully pinned
  180. ++fPinnedCount;
  181. return true;
  182. }
  183. void SkImage_Raster::onUnpinAsTexture(GrContext* ctx) const {
  184. // Note: we always decrement, even if fPinnedTexture is null
  185. SkASSERT(fPinnedCount > 0);
  186. SkASSERT(fPinnedUniqueID != 0);
  187. if (0 == --fPinnedCount) {
  188. fPinnedProxy.reset(nullptr);
  189. fPinnedUniqueID = 0;
  190. }
  191. }
  192. #endif
  193. sk_sp<SkImage> SkImage_Raster::onMakeSubset(GrRecordingContext*, const SkIRect& subset) const {
  194. SkImageInfo info = fBitmap.info().makeWH(subset.width(), subset.height());
  195. SkBitmap bitmap;
  196. if (!bitmap.tryAllocPixels(info)) {
  197. return nullptr;
  198. }
  199. void* dst = bitmap.getPixels();
  200. void* src = fBitmap.getAddr(subset.x(), subset.y());
  201. if (!dst || !src) {
  202. SkDEBUGFAIL("SkImage_Raster::onMakeSubset with nullptr src or dst");
  203. return nullptr;
  204. }
  205. SkRectMemcpy(dst, bitmap.rowBytes(), src, fBitmap.rowBytes(), bitmap.rowBytes(),
  206. subset.height());
  207. bitmap.setImmutable();
  208. return MakeFromBitmap(bitmap);
  209. }
  210. ///////////////////////////////////////////////////////////////////////////////
  211. sk_sp<SkImage> MakeRasterCopyPriv(const SkPixmap& pmap, uint32_t id) {
  212. size_t size;
  213. if (!SkImage_Raster::ValidArgs(pmap.info(), pmap.rowBytes(), &size) || !pmap.addr()) {
  214. return nullptr;
  215. }
  216. // Here we actually make a copy of the caller's pixel data
  217. sk_sp<SkData> data(SkData::MakeWithCopy(pmap.addr(), size));
  218. return sk_make_sp<SkImage_Raster>(pmap.info(), std::move(data), pmap.rowBytes(), id);
  219. }
  220. sk_sp<SkImage> SkImage::MakeRasterCopy(const SkPixmap& pmap) {
  221. return MakeRasterCopyPriv(pmap, kNeedNewImageUniqueID);
  222. }
  223. sk_sp<SkImage> SkImage::MakeRasterData(const SkImageInfo& info, sk_sp<SkData> data,
  224. size_t rowBytes) {
  225. size_t size;
  226. if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !data) {
  227. return nullptr;
  228. }
  229. // did they give us enough data?
  230. if (data->size() < size) {
  231. return nullptr;
  232. }
  233. return sk_make_sp<SkImage_Raster>(info, std::move(data), rowBytes);
  234. }
  235. sk_sp<SkImage> SkImage::MakeFromRaster(const SkPixmap& pmap, RasterReleaseProc proc,
  236. ReleaseContext ctx) {
  237. size_t size;
  238. if (!SkImage_Raster::ValidArgs(pmap.info(), pmap.rowBytes(), &size) || !pmap.addr()) {
  239. return nullptr;
  240. }
  241. sk_sp<SkData> data(SkData::MakeWithProc(pmap.addr(), size, proc, ctx));
  242. return sk_make_sp<SkImage_Raster>(pmap.info(), std::move(data), pmap.rowBytes());
  243. }
  244. sk_sp<SkImage> SkMakeImageFromRasterBitmapPriv(const SkBitmap& bm, SkCopyPixelsMode cpm,
  245. uint32_t idForCopy) {
  246. if (kAlways_SkCopyPixelsMode == cpm || (!bm.isImmutable() && kNever_SkCopyPixelsMode != cpm)) {
  247. SkPixmap pmap;
  248. if (bm.peekPixels(&pmap)) {
  249. return MakeRasterCopyPriv(pmap, idForCopy);
  250. } else {
  251. return sk_sp<SkImage>();
  252. }
  253. }
  254. return sk_make_sp<SkImage_Raster>(bm, kNever_SkCopyPixelsMode == cpm);
  255. }
  256. sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap& bm, SkCopyPixelsMode cpm) {
  257. if (!SkImageInfoIsValid(bm.info()) || bm.rowBytes() < bm.info().minRowBytes()) {
  258. return nullptr;
  259. }
  260. return SkMakeImageFromRasterBitmapPriv(bm, cpm, kNeedNewImageUniqueID);
  261. }
  262. const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) {
  263. return ((const SkImage_Raster*)image)->getPixelRef();
  264. }
  265. bool SkImage_Raster::onAsLegacyBitmap(SkBitmap* bitmap) const {
  266. // When we're a snapshot from a surface, our bitmap may not be marked immutable
  267. // even though logically always we are, but in that case we can't physically share our
  268. // pixelref since the caller might call setImmutable() themselves
  269. // (thus changing our state).
  270. if (fBitmap.isImmutable()) {
  271. SkIPoint origin = fBitmap.pixelRefOrigin();
  272. bitmap->setInfo(fBitmap.info(), fBitmap.rowBytes());
  273. bitmap->setPixelRef(sk_ref_sp(fBitmap.pixelRef()), origin.x(), origin.y());
  274. return true;
  275. }
  276. return this->INHERITED::onAsLegacyBitmap(bitmap);
  277. }
  278. ///////////////////////////////////////////////////////////////////////////////
  279. sk_sp<SkImage> SkImage_Raster::onMakeColorTypeAndColorSpace(GrRecordingContext*,
  280. SkColorType targetCT,
  281. sk_sp<SkColorSpace> targetCS) const {
  282. SkPixmap src;
  283. SkAssertResult(fBitmap.peekPixels(&src));
  284. SkBitmap dst;
  285. dst.allocPixels(fBitmap.info().makeColorType(targetCT).makeColorSpace(targetCS));
  286. SkAssertResult(dst.writePixels(src));
  287. dst.setImmutable();
  288. return SkImage::MakeFromBitmap(dst);
  289. }