Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / image / SkImage_Raster.cpp
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
8 #include "include/core/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColorSpace.h"
11 #include "include/core/SkData.h"
12 #include "include/core/SkPixelRef.h"
13 #include "include/core/SkSurface.h"
14 #include "include/private/SkImageInfoPriv.h"
15 #include "src/codec/SkColorTable.h"
16 #include "src/core/SkCompressedDataUtils.h"
17 #include "src/core/SkConvertPixels.h"
18 #include "src/core/SkImagePriv.h"
19 #include "src/core/SkTLazy.h"
20 #include "src/image/SkImage_Base.h"
21 #include "src/shaders/SkBitmapProcShader.h"
22
23 #if SK_SUPPORT_GPU
24 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
25 #include "src/gpu/ganesh/SkGr.h"
26 #include "src/gpu/ganesh/effects/GrBicubicEffect.h"
27 #include "src/gpu/ganesh/effects/GrTextureEffect.h"
28 #endif
29
30 #ifdef SK_GRAPHITE_ENABLED
31 #include "include/gpu/graphite/GraphiteTypes.h"
32 #include "include/gpu/graphite/Recorder.h"
33 #include "src/gpu/graphite/Buffer.h"
34 #include "src/gpu/graphite/Caps.h"
35 #include "src/gpu/graphite/CommandBuffer.h"
36 #include "src/gpu/graphite/RecorderPriv.h"
37 #include "src/gpu/graphite/TextureUtils.h"
38 #include "src/gpu/graphite/UploadTask.h"
39 #endif
40
41 // fixes https://bug.skia.org/5096
42 static bool is_not_subset(const SkBitmap& bm) {
43     SkASSERT(bm.pixelRef());
44     SkISize dim = SkISize::Make(bm.pixelRef()->width(), bm.pixelRef()->height());
45     SkASSERT(dim != bm.dimensions() || bm.pixelRefOrigin().isZero());
46     return dim == bm.dimensions();
47 }
48
49 class SkImage_Raster : public SkImage_Base {
50 public:
51     static bool ValidArgs(const SkImageInfo& info, size_t rowBytes, size_t* minSize) {
52         const int maxDimension = SK_MaxS32 >> 2;
53
54         // TODO(mtklein): eliminate anything here that setInfo() has already checked.
55         SkBitmap b;
56         if (!b.setInfo(info, rowBytes)) {
57             return false;
58         }
59
60         if (info.width() <= 0 || info.height() <= 0) {
61             return false;
62         }
63         if (info.width() > maxDimension || info.height() > maxDimension) {
64             return false;
65         }
66         if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
67             return false;
68         }
69         if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
70             return false;
71         }
72
73         if (kUnknown_SkColorType == info.colorType()) {
74             return false;
75         }
76         if (!info.validRowBytes(rowBytes)) {
77             return false;
78         }
79
80         size_t size = info.computeByteSize(rowBytes);
81         if (SkImageInfo::ByteSizeOverflowed(size)) {
82             return false;
83         }
84
85         if (minSize) {
86             *minSize = size;
87         }
88         return true;
89     }
90
91     SkImage_Raster(const SkImageInfo&, sk_sp<SkData>, size_t rb,
92                    uint32_t id = kNeedNewImageUniqueID);
93     ~SkImage_Raster() override;
94
95     bool onReadPixels(GrDirectContext*, const SkImageInfo&, void*, size_t, int srcX, int srcY,
96                       CachingHint) const override;
97     bool onPeekPixels(SkPixmap*) const override;
98     const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
99
100     bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override;
101     sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override;
102
103     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
104
105     bool onAsLegacyBitmap(GrDirectContext*, SkBitmap*) const override;
106
107     SkImage_Raster(const SkBitmap& bm, bool bitmapMayBeMutable = false)
108             : INHERITED(bm.info(),
109                         is_not_subset(bm) ? bm.getGenerationID() : (uint32_t)kNeedNewImageUniqueID)
110             , fBitmap(bm) {
111         SkASSERT(bitmapMayBeMutable || fBitmap.isImmutable());
112     }
113
114     sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>,
115                                                 GrDirectContext*) const override;
116
117     sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const override;
118
119     bool onIsValid(GrRecordingContext* context) const override { return true; }
120     void notifyAddedToRasterCache() const override {
121         // We explicitly DON'T want to call INHERITED::notifyAddedToRasterCache. That ties the
122         // lifetime of derived/cached resources to the image. In this case, we only want cached
123         // data (eg mips) tied to the lifetime of the underlying pixelRef.
124         SkASSERT(fBitmap.pixelRef());
125         fBitmap.pixelRef()->notifyAddedToCache();
126     }
127
128 #if SK_SUPPORT_GPU
129     bool onPinAsTexture(GrRecordingContext*) const override;
130     void onUnpinAsTexture(GrRecordingContext*) const override;
131     bool isPinnedOnContext(GrRecordingContext*) const override;
132 #endif
133
134     bool onHasMipmaps() const override { return SkToBool(fBitmap.fMips); }
135
136     SkMipmap* onPeekMips() const override { return fBitmap.fMips.get(); }
137
138     sk_sp<SkImage> onMakeWithMipmaps(sk_sp<SkMipmap> mips) const override {
139         // It's dangerous to have two SkBitmaps that share a SkPixelRef but have different SkMipmaps
140         // since various caches key on SkPixelRef's generation ID. Also, SkPixelRefs that back
141         // SkSurfaces are marked "temporarily immutable" and making an image that uses the same
142         // SkPixelRef can interact badly with SkSurface/SkImage copy-on-write. So we just always
143         // make a copy with a new ID.
144         static auto constexpr kCopyMode = SkCopyPixelsMode::kAlways_SkCopyPixelsMode;
145         sk_sp<SkImage> img = SkMakeImageFromRasterBitmap(fBitmap, kCopyMode);
146         auto imgRaster = static_cast<SkImage_Raster*>(img.get());
147         if (mips) {
148             imgRaster->fBitmap.fMips = std::move(mips);
149         } else {
150             imgRaster->fBitmap.fMips.reset(SkMipmap::Build(fBitmap.pixmap(), nullptr));
151         }
152         return img;
153     }
154
155 private:
156 #if SK_SUPPORT_GPU
157     std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
158                                                          GrMipmapped,
159                                                          GrImageTexGenPolicy) const override;
160
161     std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(GrRecordingContext*,
162                                                                SkSamplingOptions,
163                                                                const SkTileMode[2],
164                                                                const SkMatrix&,
165                                                                const SkRect*,
166                                                                const SkRect*) const override;
167 #endif
168 #ifdef SK_GRAPHITE_ENABLED
169     std::tuple<skgpu::graphite::TextureProxyView, SkColorType> onAsView(
170             skgpu::graphite::Recorder*, skgpu::graphite::Mipmapped) const override;
171 #endif
172
173     SkBitmap fBitmap;
174
175 #if SK_SUPPORT_GPU
176     mutable GrSurfaceProxyView fPinnedView;
177     mutable int32_t fPinnedCount = 0;
178     mutable uint32_t fPinnedUniqueID = SK_InvalidUniqueID;
179     mutable uint32_t fPinnedContextID = SK_InvalidUniqueID;
180     mutable GrColorType fPinnedColorType = GrColorType::kUnknown;
181 #endif
182
183     using INHERITED = SkImage_Base;
184 };
185
186 ///////////////////////////////////////////////////////////////////////////////
187
188 static void release_data(void* addr, void* context) {
189     SkData* data = static_cast<SkData*>(context);
190     data->unref();
191 }
192
193 SkImage_Raster::SkImage_Raster(const SkImageInfo& info, sk_sp<SkData> data, size_t rowBytes,
194                                uint32_t id)
195         : INHERITED(info, id) {
196     void* addr = const_cast<void*>(data->data());
197
198     fBitmap.installPixels(info, addr, rowBytes, release_data, data.release());
199     fBitmap.setImmutable();
200 }
201
202 SkImage_Raster::~SkImage_Raster() {
203 #if SK_SUPPORT_GPU
204     SkASSERT(!fPinnedView);  // want the caller to have manually unpinned
205 #endif
206 }
207
208 bool SkImage_Raster::onReadPixels(GrDirectContext*,
209                                   const SkImageInfo& dstInfo,
210                                   void* dstPixels,
211                                   size_t dstRowBytes,
212                                   int srcX,
213                                   int srcY,
214                                   CachingHint) const {
215     SkBitmap shallowCopy(fBitmap);
216     return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
217 }
218
219 bool SkImage_Raster::onPeekPixels(SkPixmap* pm) const {
220     return fBitmap.peekPixels(pm);
221 }
222
223 bool SkImage_Raster::getROPixels(GrDirectContext*, SkBitmap* dst, CachingHint) const {
224     *dst = fBitmap;
225     return true;
226 }
227
228 #if SK_SUPPORT_GPU
229 bool SkImage_Raster::onPinAsTexture(GrRecordingContext* rContext) const {
230     if (fPinnedView) {
231         SkASSERT(fPinnedCount > 0);
232         SkASSERT(fPinnedUniqueID != 0);
233         if (rContext->priv().contextID() != fPinnedContextID) {
234             return false;
235         }
236     } else {
237         SkASSERT(fPinnedCount == 0);
238         SkASSERT(fPinnedUniqueID == 0);
239         std::tie(fPinnedView, fPinnedColorType) = GrMakeCachedBitmapProxyView(rContext,
240                                                                               fBitmap,
241                                                                               GrMipmapped::kNo);
242         if (!fPinnedView) {
243             fPinnedColorType = GrColorType::kUnknown;
244             return false;
245         }
246         fPinnedUniqueID = fBitmap.getGenerationID();
247         fPinnedContextID = rContext->priv().contextID();
248     }
249     // Note: we only increment if the texture was successfully pinned
250     ++fPinnedCount;
251     return true;
252 }
253
254 void SkImage_Raster::onUnpinAsTexture(GrRecordingContext* rContext) const {
255     // Note: we always decrement, even if fPinnedTexture is null
256     SkASSERT(fPinnedCount > 0);
257     SkASSERT(fPinnedUniqueID != 0);
258 #if 0 // This would be better but Android currently calls with an already freed context ptr.
259     if (rContext->priv().contextID() != fPinnedContextID) {
260         return;
261     }
262 #endif
263
264     if (0 == --fPinnedCount) {
265         fPinnedView = GrSurfaceProxyView();
266         fPinnedUniqueID = SK_InvalidUniqueID;
267         fPinnedContextID = SK_InvalidUniqueID;
268         fPinnedColorType = GrColorType::kUnknown;
269     }
270 }
271
272 bool SkImage_Raster::isPinnedOnContext(GrRecordingContext* rContext) const {
273     return fPinnedContextID == rContext->priv().contextID();
274 }
275 #endif
276
277 sk_sp<SkImage> SkImage_Raster::onMakeSubset(const SkIRect& subset, GrDirectContext*) const {
278     SkImageInfo info = fBitmap.info().makeDimensions(subset.size());
279     SkBitmap bitmap;
280     if (!bitmap.tryAllocPixels(info)) {
281         return nullptr;
282     }
283
284     void* dst = bitmap.getPixels();
285     void* src = fBitmap.getAddr(subset.x(), subset.y());
286     if (!dst || !src) {
287         SkDEBUGFAIL("SkImage_Raster::onMakeSubset with nullptr src or dst");
288         return nullptr;
289     }
290
291     SkRectMemcpy(dst, bitmap.rowBytes(), src, fBitmap.rowBytes(), bitmap.rowBytes(),
292                  subset.height());
293
294     bitmap.setImmutable();
295     return bitmap.asImage();
296 }
297
298 ///////////////////////////////////////////////////////////////////////////////
299
300 sk_sp<SkImage> MakeRasterCopyPriv(const SkPixmap& pmap, uint32_t id) {
301     size_t size;
302     if (!SkImage_Raster::ValidArgs(pmap.info(), pmap.rowBytes(), &size) || !pmap.addr()) {
303         return nullptr;
304     }
305
306     // Here we actually make a copy of the caller's pixel data
307     sk_sp<SkData> data(SkData::MakeWithCopy(pmap.addr(), size));
308     return sk_make_sp<SkImage_Raster>(pmap.info(), std::move(data), pmap.rowBytes(), id);
309 }
310
311 sk_sp<SkImage> SkImage::MakeRasterCopy(const SkPixmap& pmap) {
312     return MakeRasterCopyPriv(pmap, kNeedNewImageUniqueID);
313 }
314
315 sk_sp<SkImage> SkImage::MakeRasterData(const SkImageInfo& info, sk_sp<SkData> data,
316                                        size_t rowBytes) {
317     size_t size;
318     if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !data) {
319         return nullptr;
320     }
321
322     // did they give us enough data?
323     if (data->size() < size) {
324         return nullptr;
325     }
326
327     return sk_make_sp<SkImage_Raster>(info, std::move(data), rowBytes);
328 }
329
330 // TODO: this could be improved to decode and make use of the mipmap
331 // levels potentially present in the compressed data. For now, any
332 // mipmap levels are discarded.
333 sk_sp<SkImage> SkImage::MakeRasterFromCompressed(sk_sp<SkData> data,
334                                                  int width, int height,
335                                                  CompressionType type) {
336     size_t expectedSize = SkCompressedFormatDataSize(type, { width, height }, false);
337     if (!data || data->size() < expectedSize) {
338         return nullptr;
339     }
340
341     SkAlphaType at = SkCompressionTypeIsOpaque(type) ? kOpaque_SkAlphaType
342                                                      : kPremul_SkAlphaType;
343
344     SkImageInfo ii = SkImageInfo::MakeN32(width, height, at);
345
346     if (!SkImage_Raster::ValidArgs(ii, ii.minRowBytes(), nullptr)) {
347         return nullptr;
348     }
349
350     SkBitmap bitmap;
351     if (!bitmap.tryAllocPixels(ii)) {
352         return nullptr;
353     }
354
355     if (!SkDecompress(std::move(data), { width, height }, type, &bitmap)) {
356         return nullptr;
357     }
358
359     bitmap.setImmutable();
360     return MakeFromBitmap(bitmap);
361 }
362
363 sk_sp<SkImage> SkImage::MakeFromRaster(const SkPixmap& pmap, RasterReleaseProc proc,
364                                        ReleaseContext ctx) {
365     size_t size;
366     if (!SkImage_Raster::ValidArgs(pmap.info(), pmap.rowBytes(), &size) || !pmap.addr()) {
367         return nullptr;
368     }
369
370     sk_sp<SkData> data(SkData::MakeWithProc(pmap.addr(), size, proc, ctx));
371     return sk_make_sp<SkImage_Raster>(pmap.info(), std::move(data), pmap.rowBytes());
372 }
373
374 sk_sp<SkImage> SkMakeImageFromRasterBitmapPriv(const SkBitmap& bm, SkCopyPixelsMode cpm,
375                                                uint32_t idForCopy) {
376     if (kAlways_SkCopyPixelsMode == cpm || (!bm.isImmutable() && kNever_SkCopyPixelsMode != cpm)) {
377         SkPixmap pmap;
378         if (bm.peekPixels(&pmap)) {
379             return MakeRasterCopyPriv(pmap, idForCopy);
380         } else {
381             return sk_sp<SkImage>();
382         }
383     }
384
385     return sk_make_sp<SkImage_Raster>(bm, kNever_SkCopyPixelsMode == cpm);
386 }
387
388 sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap& bm, SkCopyPixelsMode cpm) {
389     if (!SkImageInfoIsValid(bm.info()) || bm.rowBytes() < bm.info().minRowBytes()) {
390         return nullptr;
391     }
392
393     return SkMakeImageFromRasterBitmapPriv(bm, cpm, kNeedNewImageUniqueID);
394 }
395
396 const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) {
397     return ((const SkImage_Raster*)image)->getPixelRef();
398 }
399
400 bool SkImage_Raster::onAsLegacyBitmap(GrDirectContext*, SkBitmap* bitmap) const {
401     // When we're a snapshot from a surface, our bitmap may not be marked immutable
402     // even though logically always we are, but in that case we can't physically share our
403     // pixelref since the caller might call setImmutable() themselves
404     // (thus changing our state).
405     if (fBitmap.isImmutable()) {
406         SkIPoint origin = fBitmap.pixelRefOrigin();
407         bitmap->setInfo(fBitmap.info(), fBitmap.rowBytes());
408         bitmap->setPixelRef(sk_ref_sp(fBitmap.pixelRef()), origin.x(), origin.y());
409         return true;
410     }
411     return this->INHERITED::onAsLegacyBitmap(nullptr, bitmap);
412 }
413
414 ///////////////////////////////////////////////////////////////////////////////
415
416 sk_sp<SkImage> SkImage_Raster::onMakeColorTypeAndColorSpace(SkColorType targetCT,
417                                                             sk_sp<SkColorSpace> targetCS,
418                                                             GrDirectContext*) const {
419     SkPixmap src;
420     SkAssertResult(fBitmap.peekPixels(&src));
421
422     SkBitmap dst;
423     if (!dst.tryAllocPixels(fBitmap.info().makeColorType(targetCT).makeColorSpace(targetCS))) {
424         return nullptr;
425     }
426
427     SkAssertResult(dst.writePixels(src));
428     dst.setImmutable();
429     return dst.asImage();
430 }
431
432 sk_sp<SkImage> SkImage_Raster::onReinterpretColorSpace(sk_sp<SkColorSpace> newCS) const {
433     // TODO: If our bitmap is immutable, then we could theoretically create another image sharing
434     // our pixelRef. That doesn't work (without more invasive logic), because the image gets its
435     // gen ID from the bitmap, which gets it from the pixelRef.
436     SkPixmap pixmap = fBitmap.pixmap();
437     pixmap.setColorSpace(std::move(newCS));
438     return SkImage::MakeRasterCopy(pixmap);
439 }
440
441 #if SK_SUPPORT_GPU
442 std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Raster::onAsView(
443         GrRecordingContext* rContext,
444         GrMipmapped mipmapped,
445         GrImageTexGenPolicy policy) const {
446     if (fPinnedView) {
447         // We ignore the mipmap request here. If the pinned view isn't mipmapped then we will
448         // fallback to bilinear. The pin API is used by Android Framework which does not expose
449         // mipmapping . Moreover, we're moving towards requiring that images be made with mip levels
450         // if mipmapping is desired (skbug.com/10411)
451         mipmapped = GrMipmapped::kNo;
452         if (policy != GrImageTexGenPolicy::kDraw) {
453             return {CopyView(rContext, fPinnedView, mipmapped, policy), fPinnedColorType};
454         }
455         return {fPinnedView, fPinnedColorType};
456     }
457     if (policy == GrImageTexGenPolicy::kDraw) {
458         // If the draw doesn't require mipmaps but this SkImage has them go ahead and make a
459         // mipmapped texture. There are three reasons for this:
460         // 1) Avoiding another texture creation if a later draw requires mipmaps.
461         // 2) Ensuring we upload the bitmap's levels instead of generating on the GPU from the base.
462         if (this->hasMipmaps()) {
463             mipmapped = GrMipmapped::kYes;
464         }
465         return GrMakeCachedBitmapProxyView(rContext, fBitmap, mipmapped);
466     }
467     auto budgeted = (policy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted)
468             ? SkBudgeted::kNo
469             : SkBudgeted::kYes;
470     return GrMakeUncachedBitmapProxyView(rContext,
471                                          fBitmap,
472                                          mipmapped,
473                                          SkBackingFit::kExact,
474                                          budgeted);
475 }
476
477 std::unique_ptr<GrFragmentProcessor> SkImage_Raster::onAsFragmentProcessor(
478         GrRecordingContext* rContext,
479         SkSamplingOptions sampling,
480         const SkTileMode tileModes[2],
481         const SkMatrix& m,
482         const SkRect* subset,
483         const SkRect* domain) const {
484     auto mm = sampling.mipmap == SkMipmapMode::kNone ? GrMipmapped::kNo : GrMipmapped::kYes;
485     return MakeFragmentProcessorFromView(rContext,
486                                          std::get<0>(this->asView(rContext, mm)),
487                                          this->alphaType(),
488                                          sampling,
489                                          tileModes,
490                                          m,
491                                          subset,
492                                          domain);
493 }
494 #endif
495
496 #ifdef SK_GRAPHITE_ENABLED
497 std::tuple<skgpu::graphite::TextureProxyView, SkColorType> SkImage_Raster::onAsView(
498         skgpu::graphite::Recorder* recorder,
499         skgpu::graphite::Mipmapped mipmapped) const {
500     return MakeBitmapProxyView(recorder, fBitmap, mipmapped, SkBudgeted::kNo);
501 }
502
503 #endif