Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / image / SkSurface.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 <atomic>
9 #include <cmath>
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkCapabilities.h"
12 #include "src/core/SkAutoPixmapStorage.h"
13 #include "src/core/SkImagePriv.h"
14 #include "src/core/SkPaintPriv.h"
15 #include "src/image/SkImage_Base.h"
16 #include "src/image/SkRescaleAndReadPixels.h"
17 #include "src/image/SkSurface_Base.h"
18
19 #if SK_SUPPORT_GPU
20 #include "include/gpu/GrBackendSurface.h"
21 #endif
22
23 SkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {}
24
25 SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
26     : fFlags(flags), fPixelGeometry(pg)
27 {}
28
29 SkSurfaceProps::SkSurfaceProps(const SkSurfaceProps&) = default;
30 SkSurfaceProps& SkSurfaceProps::operator=(const SkSurfaceProps&) = default;
31
32 ///////////////////////////////////////////////////////////////////////////////
33
34 SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
35     : INHERITED(width, height, props) {
36 }
37
38 SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
39     : INHERITED(info, props) {
40 }
41
42 SkSurface_Base::~SkSurface_Base() {
43     // in case the canvas outsurvives us, we null the callback
44     if (fCachedCanvas) {
45         fCachedCanvas->setSurfaceBase(nullptr);
46     }
47 #if SK_SUPPORT_GPU
48     if (fCachedImage) {
49         as_IB(fCachedImage.get())->generatingSurfaceIsDeleted();
50     }
51 #endif
52 }
53
54 GrRecordingContext* SkSurface_Base::onGetRecordingContext() {
55     return nullptr;
56 }
57
58 skgpu::graphite::Recorder* SkSurface_Base::onGetRecorder() {
59     return nullptr;
60 }
61
62 #if SK_SUPPORT_GPU
63 GrBackendTexture SkSurface_Base::onGetBackendTexture(BackendHandleAccess) {
64     return GrBackendTexture(); // invalid
65 }
66
67 GrBackendRenderTarget SkSurface_Base::onGetBackendRenderTarget(BackendHandleAccess) {
68     return GrBackendRenderTarget(); // invalid
69 }
70
71 bool SkSurface_Base::onReplaceBackendTexture(const GrBackendTexture&,
72                                              GrSurfaceOrigin, ContentChangeMode,
73                                              TextureReleaseProc,
74                                              ReleaseContext) {
75     return false;
76 }
77 #endif
78
79 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
80                             const SkSamplingOptions& sampling, const SkPaint* paint) {
81     auto image = this->makeImageSnapshot();
82     if (image) {
83         canvas->drawImage(image.get(), x, y, sampling, paint);
84     }
85 }
86
87 void SkSurface_Base::onAsyncRescaleAndReadPixels(const SkImageInfo& info,
88                                                  const SkIRect& origSrcRect,
89                                                  SkSurface::RescaleGamma rescaleGamma,
90                                                  RescaleMode rescaleMode,
91                                                  SkSurface::ReadPixelsCallback callback,
92                                                  SkSurface::ReadPixelsContext context) {
93     SkBitmap src;
94     SkPixmap peek;
95     SkIRect srcRect;
96     if (this->peekPixels(&peek)) {
97         src.installPixels(peek);
98         srcRect = origSrcRect;
99     } else {
100         src.setInfo(this->imageInfo().makeDimensions(origSrcRect.size()));
101         src.allocPixels();
102         if (!this->readPixels(src, origSrcRect.x(), origSrcRect.y())) {
103             callback(context, nullptr);
104             return;
105         }
106         srcRect = SkIRect::MakeSize(src.dimensions());
107     }
108     return SkRescaleAndReadPixels(src, info, srcRect, rescaleGamma, rescaleMode, callback,
109                                   context);
110 }
111
112 void SkSurface_Base::onAsyncRescaleAndReadPixelsYUV420(
113         SkYUVColorSpace yuvColorSpace, sk_sp<SkColorSpace> dstColorSpace, const SkIRect& srcRect,
114         const SkISize& dstSize, RescaleGamma rescaleGamma, RescaleMode,
115         ReadPixelsCallback callback, ReadPixelsContext context) {
116     // TODO: Call non-YUV asyncRescaleAndReadPixels and then make our callback convert to YUV and
117     // call client's callback.
118     callback(context, nullptr);
119 }
120
121 bool SkSurface_Base::outstandingImageSnapshot() const {
122     return fCachedImage && !fCachedImage->unique();
123 }
124
125 bool SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
126     this->dirtyGenerationID();
127
128     SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
129
130     if (fCachedImage) {
131         // the surface may need to fork its backend, if its sharing it with
132         // the cached image. Note: we only call if there is an outstanding owner
133         // on the image (besides us).
134         bool unique = fCachedImage->unique();
135         if (!unique) {
136             if (!this->onCopyOnWrite(mode)) {
137                 return false;
138             }
139         }
140
141         // regardless of copy-on-write, we must drop our cached image now, so
142         // that the next request will get our new contents.
143         fCachedImage.reset();
144
145         if (unique) {
146             // Our content isn't held by any image now, so we can consider that content mutable.
147             // Raster surfaces need to be told it's safe to consider its pixels mutable again.
148             // We make this call after the ->unref() so the subclass can assert there are no images.
149             this->onRestoreBackingMutability();
150         }
151     } else if (kDiscard_ContentChangeMode == mode) {
152         this->onDiscard();
153     }
154     return true;
155 }
156
157 uint32_t SkSurface_Base::newGenerationID() {
158     SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
159     static std::atomic<uint32_t> nextID{1};
160     return nextID.fetch_add(1, std::memory_order_relaxed);
161 }
162
163 sk_sp<const SkCapabilities> SkSurface_Base::onCapabilities() {
164     return SkCapabilities::RasterBackend();
165 }
166
167 static SkSurface_Base* asSB(SkSurface* surface) {
168     return static_cast<SkSurface_Base*>(surface);
169 }
170
171 static const SkSurface_Base* asConstSB(const SkSurface* surface) {
172     return static_cast<const SkSurface_Base*>(surface);
173 }
174
175 ///////////////////////////////////////////////////////////////////////////////
176
177 SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
178     : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
179 {
180     SkASSERT(fWidth > 0);
181     SkASSERT(fHeight > 0);
182     fGenerationID = 0;
183 }
184
185 SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
186     : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
187 {
188     SkASSERT(fWidth > 0);
189     SkASSERT(fHeight > 0);
190     fGenerationID = 0;
191 }
192
193 SkImageInfo SkSurface::imageInfo() {
194     // TODO: do we need to go through canvas for this?
195     return this->getCanvas()->imageInfo();
196 }
197
198 uint32_t SkSurface::generationID() {
199     if (0 == fGenerationID) {
200         fGenerationID = asSB(this)->newGenerationID();
201     }
202     return fGenerationID;
203 }
204
205 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
206     sk_ignore_unused_variable(asSB(this)->aboutToDraw(mode));
207 }
208
209 SkCanvas* SkSurface::getCanvas() {
210     return asSB(this)->getCachedCanvas();
211 }
212
213 sk_sp<const SkCapabilities> SkSurface::capabilities() {
214     return asSB(this)->onCapabilities();
215 }
216
217 sk_sp<SkImage> SkSurface::makeImageSnapshot() {
218     return asSB(this)->refCachedImage();
219 }
220
221 sk_sp<SkImage> SkSurface::makeImageSnapshot(const SkIRect& srcBounds) {
222     const SkIRect surfBounds = { 0, 0, fWidth, fHeight };
223     SkIRect bounds = srcBounds;
224     if (!bounds.intersect(surfBounds)) {
225         return nullptr;
226     }
227     SkASSERT(!bounds.isEmpty());
228     if (bounds == surfBounds) {
229         return this->makeImageSnapshot();
230     } else {
231         return asSB(this)->onNewImageSnapshot(&bounds);
232     }
233 }
234
235 sk_sp<SkSurface> SkSurface::makeSurface(const SkImageInfo& info) {
236     return asSB(this)->onNewSurface(info);
237 }
238
239 sk_sp<SkSurface> SkSurface::makeSurface(int width, int height) {
240     return this->makeSurface(this->imageInfo().makeWH(width, height));
241 }
242
243 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkSamplingOptions& sampling,
244                      const SkPaint* paint) {
245     asSB(this)->onDraw(canvas, x, y, sampling, paint);
246 }
247
248 bool SkSurface::peekPixels(SkPixmap* pmap) {
249     return this->getCanvas()->peekPixels(pmap);
250 }
251
252 bool SkSurface::readPixels(const SkPixmap& pm, int srcX, int srcY) {
253     return this->getCanvas()->readPixels(pm, srcX, srcY);
254 }
255
256 bool SkSurface::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
257                            int srcX, int srcY) {
258     return this->readPixels({dstInfo, dstPixels, dstRowBytes}, srcX, srcY);
259 }
260
261 bool SkSurface::readPixels(const SkBitmap& bitmap, int srcX, int srcY) {
262     SkPixmap pm;
263     return bitmap.peekPixels(&pm) && this->readPixels(pm, srcX, srcY);
264 }
265
266 void SkSurface::asyncRescaleAndReadPixels(const SkImageInfo& info,
267                                           const SkIRect& srcRect,
268                                           RescaleGamma rescaleGamma,
269                                           RescaleMode rescaleMode,
270                                           ReadPixelsCallback callback,
271                                           ReadPixelsContext context) {
272     if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) ||
273         !SkImageInfoIsValid(info)) {
274         callback(context, nullptr);
275         return;
276     }
277     asSB(this)->onAsyncRescaleAndReadPixels(
278             info, srcRect, rescaleGamma, rescaleMode, callback, context);
279 }
280
281 void SkSurface::asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
282                                                 sk_sp<SkColorSpace> dstColorSpace,
283                                                 const SkIRect& srcRect,
284                                                 const SkISize& dstSize,
285                                                 RescaleGamma rescaleGamma,
286                                                 RescaleMode rescaleMode,
287                                                 ReadPixelsCallback callback,
288                                                 ReadPixelsContext context) {
289     if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) || dstSize.isZero() ||
290         (dstSize.width() & 0b1) || (dstSize.height() & 0b1)) {
291         callback(context, nullptr);
292         return;
293     }
294     asSB(this)->onAsyncRescaleAndReadPixelsYUV420(yuvColorSpace,
295                                                   std::move(dstColorSpace),
296                                                   srcRect,
297                                                   dstSize,
298                                                   rescaleGamma,
299                                                   rescaleMode,
300                                                   callback,
301                                                   context);
302 }
303
304 void SkSurface::writePixels(const SkPixmap& pmap, int x, int y) {
305     if (pmap.addr() == nullptr || pmap.width() <= 0 || pmap.height() <= 0) {
306         return;
307     }
308
309     const SkIRect srcR = SkIRect::MakeXYWH(x, y, pmap.width(), pmap.height());
310     const SkIRect dstR = SkIRect::MakeWH(this->width(), this->height());
311     if (SkIRect::Intersects(srcR, dstR)) {
312         ContentChangeMode mode = kRetain_ContentChangeMode;
313         if (srcR.contains(dstR)) {
314             mode = kDiscard_ContentChangeMode;
315         }
316         if (!asSB(this)->aboutToDraw(mode)) {
317             return;
318         }
319         asSB(this)->onWritePixels(pmap, x, y);
320     }
321 }
322
323 void SkSurface::writePixels(const SkBitmap& src, int x, int y) {
324     SkPixmap pm;
325     if (src.peekPixels(&pm)) {
326         this->writePixels(pm, x, y);
327     }
328 }
329
330 GrRecordingContext* SkSurface::recordingContext() {
331     return asSB(this)->onGetRecordingContext();
332 }
333
334 skgpu::graphite::Recorder* SkSurface::recorder() {
335     return asSB(this)->onGetRecorder();
336 }
337
338 bool SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores,
339                      bool deleteSemaphoresAfterWait) {
340     return asSB(this)->onWait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait);
341 }
342
343 bool SkSurface::characterize(SkSurfaceCharacterization* characterization) const {
344     return asConstSB(this)->onCharacterize(characterization);
345 }
346
347 bool SkSurface::isCompatible(const SkSurfaceCharacterization& characterization) const {
348     return asConstSB(this)->onIsCompatible(characterization);
349 }
350
351 bool SkSurface::draw(sk_sp<const SkDeferredDisplayList> ddl, int xOffset, int yOffset) {
352     if (xOffset != 0 || yOffset != 0) {
353         return false; // the offsets currently aren't supported
354     }
355
356     return asSB(this)->onDraw(std::move(ddl), { xOffset, yOffset });
357 }
358
359 #if SK_SUPPORT_GPU
360 GrBackendTexture SkSurface::getBackendTexture(BackendHandleAccess access) {
361     return asSB(this)->onGetBackendTexture(access);
362 }
363
364 GrBackendRenderTarget SkSurface::getBackendRenderTarget(BackendHandleAccess access) {
365     return asSB(this)->onGetBackendRenderTarget(access);
366 }
367
368 bool SkSurface::replaceBackendTexture(const GrBackendTexture& backendTexture,
369                                       GrSurfaceOrigin origin, ContentChangeMode mode,
370                                       TextureReleaseProc textureReleaseProc,
371                                       ReleaseContext releaseContext) {
372     return asSB(this)->onReplaceBackendTexture(backendTexture, origin, mode, textureReleaseProc,
373                                                releaseContext);
374 }
375
376 void SkSurface::resolveMSAA() {
377     asSB(this)->onResolveMSAA();
378 }
379
380 GrSemaphoresSubmitted SkSurface::flush(BackendSurfaceAccess access, const GrFlushInfo& flushInfo) {
381     return asSB(this)->onFlush(access, flushInfo, nullptr);
382 }
383
384 GrSemaphoresSubmitted SkSurface::flush(const GrFlushInfo& info,
385                                        const GrBackendSurfaceMutableState* newState) {
386     return asSB(this)->onFlush(BackendSurfaceAccess::kNoAccess, info, newState);
387 }
388
389 void SkSurface::flush() {
390     this->flush({});
391 }
392 #else
393 void SkSurface::flush() {} // Flush is a no-op for CPU surfaces
394
395 void SkSurface::flushAndSubmit(bool syncCpu) {}
396
397 // TODO(kjlubick, scroggo) Remove this once Android is updated.
398 sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrRecordingContext*, SkBudgeted, const SkImageInfo&,
399                                              int, GrSurfaceOrigin, const SkSurfaceProps*, bool) {
400     return nullptr;
401 }
402 #endif
403
404 //////////////////////////////////////////////////////////////////////////////////////
405 #include "include/utils/SkNoDrawCanvas.h"
406
407 class SkNullSurface : public SkSurface_Base {
408 public:
409     SkNullSurface(int width, int height) : SkSurface_Base(width, height, nullptr) {}
410
411 protected:
412     SkCanvas* onNewCanvas() override {
413         return new SkNoDrawCanvas(this->width(), this->height());
414     }
415     sk_sp<SkSurface> onNewSurface(const SkImageInfo& info) override {
416         return MakeNull(info.width(), info.height());
417     }
418     sk_sp<SkImage> onNewImageSnapshot(const SkIRect* subsetOrNull) override { return nullptr; }
419     void onWritePixels(const SkPixmap&, int x, int y) override {}
420     void onDraw(SkCanvas*, SkScalar, SkScalar, const SkSamplingOptions&, const SkPaint*) override {}
421     bool onCopyOnWrite(ContentChangeMode) override { return true; }
422     sk_sp<const SkCapabilities> onCapabilities() override {
423         // Not really, but we have to return *something*
424         return SkCapabilities::RasterBackend();
425     }
426 };
427
428 sk_sp<SkSurface> SkSurface::MakeNull(int width, int height) {
429     if (width < 1 || height < 1) {
430         return nullptr;
431     }
432     return sk_sp<SkSurface>(new SkNullSurface(width, height));
433 }
434
435 //////////////////////////////////////////////////////////////////////////////////////
436
437
438