blob: 77269a860c0d32d78c23c92efebe2aa983ddce70 [file] [log] [blame]
reed@google.comc9062042012-07-30 18:06:00 +00001/*
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
Brian Salomonab32f652019-05-10 14:24:50 -04008#include <atomic>
Brian Salomon201700f2019-05-17 12:05:44 -04009#include <cmath>
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkCanvas.h"
11#include "include/core/SkFontLCDConfig.h"
12#include "include/gpu/GrBackendSurface.h"
Brian Salomonab32f652019-05-10 14:24:50 -040013#include "src/core/SkAutoPixmapStorage.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/core/SkImagePriv.h"
15#include "src/image/SkSurface_Base.h"
Robert Phillips8caf85f2018-04-05 09:30:38 -040016
reed4a8126e2014-09-22 07:29:03 -070017static SkPixelGeometry compute_default_geometry() {
18 SkFontLCDConfig::LCDOrder order = SkFontLCDConfig::GetSubpixelOrder();
19 if (SkFontLCDConfig::kNONE_LCDOrder == order) {
20 return kUnknown_SkPixelGeometry;
21 } else {
22 // Bit0 is RGB(0), BGR(1)
23 // Bit1 is H(0), V(1)
24 const SkPixelGeometry gGeo[] = {
25 kRGB_H_SkPixelGeometry,
26 kBGR_H_SkPixelGeometry,
27 kRGB_V_SkPixelGeometry,
28 kBGR_V_SkPixelGeometry,
29 };
30 int index = 0;
31 if (SkFontLCDConfig::kBGR_LCDOrder == order) {
32 index |= 1;
33 }
34 if (SkFontLCDConfig::kVertical_LCDOrientation == SkFontLCDConfig::GetSubpixelOrientation()){
35 index |= 2;
36 }
37 return gGeo[index];
38 }
39}
40
41SkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {}
42
43SkSurfaceProps::SkSurfaceProps(InitType) : fFlags(0), fPixelGeometry(compute_default_geometry()) {}
44
45SkSurfaceProps::SkSurfaceProps(uint32_t flags, InitType)
46 : fFlags(flags)
47 , fPixelGeometry(compute_default_geometry())
48{}
49
50SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
51 : fFlags(flags), fPixelGeometry(pg)
52{}
53
Ben Wagner833313b2020-03-23 17:22:24 -040054SkSurfaceProps::SkSurfaceProps(const SkSurfaceProps&) = default;
55SkSurfaceProps& SkSurfaceProps::operator=(const SkSurfaceProps&) = default;
reed4af267b2014-11-21 08:46:37 -080056
reed@google.com889b09e2012-07-27 21:10:42 +000057///////////////////////////////////////////////////////////////////////////////
58
reed4a8126e2014-09-22 07:29:03 -070059SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
Robert Phillipsa54ccb22017-01-31 07:40:33 -050060 : INHERITED(width, height, props) {
reed@google.com9ea5a3b2012-07-30 21:03:46 +000061}
reed@google.com889b09e2012-07-27 21:10:42 +000062
reed4a8126e2014-09-22 07:29:03 -070063SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
Robert Phillipsa54ccb22017-01-31 07:40:33 -050064 : INHERITED(info, props) {
reed@google.com1360c522014-01-08 21:25:26 +000065}
66
reed@google.com9ea5a3b2012-07-30 21:03:46 +000067SkSurface_Base::~SkSurface_Base() {
reed@google.com97af1a62012-08-28 12:19:02 +000068 // in case the canvas outsurvives us, we null the callback
69 if (fCachedCanvas) {
halcanary96fcdcc2015-08-27 07:41:13 -070070 fCachedCanvas->setSurfaceBase(nullptr);
reed@google.com97af1a62012-08-28 12:19:02 +000071 }
reed@google.com9ea5a3b2012-07-30 21:03:46 +000072}
reed@google.com889b09e2012-07-27 21:10:42 +000073
Greg Daniel5ab94e12020-05-13 14:11:40 -040074GrContext* SkSurface_Base::onGetContext() {
75 return nullptr;
76}
77
Robert Phillips8caf85f2018-04-05 09:30:38 -040078GrBackendTexture SkSurface_Base::onGetBackendTexture(BackendHandleAccess) {
79 return GrBackendTexture(); // invalid
80}
81
82GrBackendRenderTarget SkSurface_Base::onGetBackendRenderTarget(BackendHandleAccess) {
83 return GrBackendRenderTarget(); // invalid
84}
85
Brian Salomonaad83152019-05-24 10:16:35 -040086bool SkSurface_Base::onReplaceBackendTexture(const GrBackendTexture&,
Yi Xu55bca412020-02-14 18:10:40 -050087 GrSurfaceOrigin, ContentChangeMode,
Brian Salomonaad83152019-05-24 10:16:35 -040088 TextureReleaseProc,
89 ReleaseContext) {
90 return false;
91}
92
reed4a8126e2014-09-22 07:29:03 -070093void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
Robert Phillipsac6b1fa2017-03-20 08:38:50 -040094 auto image = this->makeImageSnapshot();
reed@google.com889b09e2012-07-27 21:10:42 +000095 if (image) {
piotaixrb5fae932014-09-24 13:03:30 -070096 canvas->drawImage(image, x, y, paint);
reed@google.com889b09e2012-07-27 21:10:42 +000097 }
98}
99
Brian Salomon031b0ba2019-05-23 11:05:26 -0400100void SkSurface_Base::onAsyncRescaleAndReadPixels(const SkImageInfo& info, const SkIRect& srcRect,
101 SkSurface::RescaleGamma rescaleGamma,
102 SkFilterQuality rescaleQuality,
103 SkSurface::ReadPixelsCallback callback,
104 SkSurface::ReadPixelsContext context) {
105 int srcW = srcRect.width();
106 int srcH = srcRect.height();
107 float sx = (float)info.width() / srcW;
108 float sy = (float)info.height() / srcH;
109 // How many bilerp/bicubic steps to do in X and Y. + means upscaling, - means downscaling.
110 int stepsX;
111 int stepsY;
112 if (rescaleQuality > kNone_SkFilterQuality) {
113 stepsX = static_cast<int>((sx > 1.f) ? std::ceil(std::log2f(sx))
114 : std::floor(std::log2f(sx)));
115 stepsY = static_cast<int>((sy > 1.f) ? std::ceil(std::log2f(sy))
116 : std::floor(std::log2f(sy)));
117 } else {
118 stepsX = sx != 1.f;
119 stepsY = sy != 1.f;
120 }
121
122 SkPaint paint;
123 paint.setBlendMode(SkBlendMode::kSrc);
124 if (stepsX < 0 || stepsY < 0) {
125 // Don't trigger MIP generation. We don't currently have a way to trigger bicubic for
126 // downscaling draws.
127 rescaleQuality = std::min(rescaleQuality, kLow_SkFilterQuality);
128 }
129 paint.setFilterQuality(rescaleQuality);
130 sk_sp<SkSurface> src(SkRef(this));
131 int srcX = srcRect.fLeft;
132 int srcY = srcRect.fTop;
133 SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
134 // Assume we should ignore the rescale linear request if the surface has no color space since
135 // it's unclear how we'd linearize from an unknown color space.
136 if (rescaleGamma == SkSurface::RescaleGamma::kLinear &&
137 this->getCanvas()->imageInfo().colorSpace() &&
138 !this->getCanvas()->imageInfo().colorSpace()->gammaIsLinear()) {
139 auto cs = this->getCanvas()->imageInfo().colorSpace()->makeLinearGamma();
140 // Promote to F16 color type to preserve precision.
141 auto ii = SkImageInfo::Make(srcW, srcH, kRGBA_F16_SkColorType,
142 this->getCanvas()->imageInfo().alphaType(), std::move(cs));
143 auto linearSurf = this->makeSurface(ii);
144 if (!linearSurf) {
145 // Maybe F16 isn't supported? Try again with original color type.
146 ii = ii.makeColorType(this->getCanvas()->imageInfo().colorType());
147 linearSurf = this->makeSurface(ii);
148 if (!linearSurf) {
Brian Salomon9241a6d2019-10-03 13:26:54 -0400149 callback(context, nullptr);
Brian Salomon031b0ba2019-05-23 11:05:26 -0400150 return;
151 }
152 }
153 this->draw(linearSurf->getCanvas(), -srcX, -srcY, &paint);
154 src = std::move(linearSurf);
155 srcX = 0;
156 srcY = 0;
157 constraint = SkCanvas::kFast_SrcRectConstraint;
158 }
159 while (stepsX || stepsY) {
160 int nextW = info.width();
161 int nextH = info.height();
162 if (stepsX < 0) {
163 nextW = info.width() << (-stepsX - 1);
164 stepsX++;
165 } else if (stepsX != 0) {
166 if (stepsX > 1) {
167 nextW = srcW * 2;
168 }
169 --stepsX;
170 }
171 if (stepsY < 0) {
172 nextH = info.height() << (-stepsY - 1);
173 stepsY++;
174 } else if (stepsY != 0) {
175 if (stepsY > 1) {
176 nextH = srcH * 2;
177 }
178 --stepsY;
179 }
180 auto ii = src->getCanvas()->imageInfo().makeWH(nextW, nextH);
181 if (!stepsX && !stepsY) {
182 // Might as well fold conversion to final info in the last step.
183 ii = info;
184 }
185 auto next = this->makeSurface(ii);
186 if (!next) {
Brian Salomon9241a6d2019-10-03 13:26:54 -0400187 callback(context, nullptr);
Brian Salomon031b0ba2019-05-23 11:05:26 -0400188 return;
189 }
190 next->getCanvas()->drawImageRect(
191 src->makeImageSnapshot(), SkIRect::MakeXYWH(srcX, srcY, srcW, srcH),
192 SkRect::MakeWH((float)nextW, (float)nextH), &paint, constraint);
193 src = std::move(next);
194 srcX = srcY = 0;
195 srcW = nextW;
196 srcH = nextH;
197 constraint = SkCanvas::kFast_SrcRectConstraint;
198 }
199
Brian Salomon9241a6d2019-10-03 13:26:54 -0400200 size_t rowBytes = info.minRowBytes();
201 std::unique_ptr<char[]> data(new char[info.height() * rowBytes]);
202 SkPixmap pm(info, data.get(), rowBytes);
Brian Salomon031b0ba2019-05-23 11:05:26 -0400203 if (src->readPixels(pm, srcX, srcY)) {
Brian Salomon9241a6d2019-10-03 13:26:54 -0400204 class Result : public AsyncReadResult {
205 public:
206 Result(std::unique_ptr<const char[]> data, size_t rowBytes)
207 : fData(std::move(data)), fRowBytes(rowBytes) {}
208 int count() const override { return 1; }
209 const void* data(int i) const override { return fData.get(); }
210 size_t rowBytes(int i) const override { return fRowBytes; }
211
212 private:
213 std::unique_ptr<const char[]> fData;
214 size_t fRowBytes;
215 };
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500216 callback(context, std::make_unique<Result>(std::move(data), rowBytes));
Brian Salomonab32f652019-05-10 14:24:50 -0400217 } else {
Brian Salomon9241a6d2019-10-03 13:26:54 -0400218 callback(context, nullptr);
Brian Salomonab32f652019-05-10 14:24:50 -0400219 }
220}
221
Brian Salomon024bd002019-06-11 11:38:16 -0400222void SkSurface_Base::onAsyncRescaleAndReadPixelsYUV420(
223 SkYUVColorSpace yuvColorSpace, sk_sp<SkColorSpace> dstColorSpace, const SkIRect& srcRect,
Brian Salomon9241a6d2019-10-03 13:26:54 -0400224 const SkISize& dstSize, RescaleGamma rescaleGamma, SkFilterQuality rescaleQuality,
225 ReadPixelsCallback callback, ReadPixelsContext context) {
Brian Salomon024bd002019-06-11 11:38:16 -0400226 // TODO: Call non-YUV asyncRescaleAndReadPixels and then make our callback convert to YUV and
227 // call client's callback.
Brian Salomon9241a6d2019-10-03 13:26:54 -0400228 callback(context, nullptr);
Brian Salomon024bd002019-06-11 11:38:16 -0400229}
230
reedc83a2972015-07-16 07:40:45 -0700231bool SkSurface_Base::outstandingImageSnapshot() const {
232 return fCachedImage && !fCachedImage->unique();
233}
234
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +0000235void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
reed@google.com97af1a62012-08-28 12:19:02 +0000236 this->dirtyGenerationID();
237
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000238 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
reed@google.com97af1a62012-08-28 12:19:02 +0000239
bsalomon49f085d2014-09-05 13:34:00 -0700240 if (fCachedImage) {
reed@google.com97af1a62012-08-28 12:19:02 +0000241 // the surface may need to fork its backend, if its sharing it with
242 // the cached image. Note: we only call if there is an outstanding owner
243 // on the image (besides us).
reed26e0e582015-07-29 11:44:52 -0700244 bool unique = fCachedImage->unique();
245 if (!unique) {
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +0000246 this->onCopyOnWrite(mode);
reed@google.com97af1a62012-08-28 12:19:02 +0000247 }
248
249 // regardless of copy-on-write, we must drop our cached image now, so
250 // that the next request will get our new contents.
Robert Phillipsa54ccb22017-01-31 07:40:33 -0500251 fCachedImage.reset();
reed26e0e582015-07-29 11:44:52 -0700252
253 if (unique) {
254 // Our content isn't held by any image now, so we can consider that content mutable.
255 // Raster surfaces need to be told it's safe to consider its pixels mutable again.
256 // We make this call after the ->unref() so the subclass can assert there are no images.
257 this->onRestoreBackingMutability();
258 }
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000259 } else if (kDiscard_ContentChangeMode == mode) {
260 this->onDiscard();
reed@google.com97af1a62012-08-28 12:19:02 +0000261 }
262}
263
264uint32_t SkSurface_Base::newGenerationID() {
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000265 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
Mike Klein0ec1c572018-12-04 11:52:51 -0500266 static std::atomic<uint32_t> nextID{1};
267 return nextID++;
reed@google.com97af1a62012-08-28 12:19:02 +0000268}
269
reed@google.com889b09e2012-07-27 21:10:42 +0000270static SkSurface_Base* asSB(SkSurface* surface) {
271 return static_cast<SkSurface_Base*>(surface);
272}
273
Robert Phillips9907e6e2019-06-25 14:47:04 -0400274static const SkSurface_Base* asConstSB(const SkSurface* surface) {
275 return static_cast<const SkSurface_Base*>(surface);
276}
277
reed@google.com889b09e2012-07-27 21:10:42 +0000278///////////////////////////////////////////////////////////////////////////////
279
reed4a8126e2014-09-22 07:29:03 -0700280SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
281 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
282{
reedb2497c22014-12-31 12:31:43 -0800283 SkASSERT(fWidth > 0);
284 SkASSERT(fHeight > 0);
reed@google.com1360c522014-01-08 21:25:26 +0000285 fGenerationID = 0;
286}
287
reed4a8126e2014-09-22 07:29:03 -0700288SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
289 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
290{
reedb2497c22014-12-31 12:31:43 -0800291 SkASSERT(fWidth > 0);
292 SkASSERT(fHeight > 0);
reed@google.com889b09e2012-07-27 21:10:42 +0000293 fGenerationID = 0;
294}
295
Mike Reed4b203ad2019-06-17 17:45:01 -0400296SkImageInfo SkSurface::imageInfo() {
297 // TODO: do we need to go through canvas for this?
298 return this->getCanvas()->imageInfo();
299}
300
reed@google.com97af1a62012-08-28 12:19:02 +0000301uint32_t SkSurface::generationID() {
302 if (0 == fGenerationID) {
303 fGenerationID = asSB(this)->newGenerationID();
304 }
305 return fGenerationID;
306}
307
commit-bot@chromium.orgc4c98702013-04-22 14:28:01 +0000308void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
309 asSB(this)->aboutToDraw(mode);
reed@google.com97af1a62012-08-28 12:19:02 +0000310}
311
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000312SkCanvas* SkSurface::getCanvas() {
313 return asSB(this)->getCachedCanvas();
reed@google.com889b09e2012-07-27 21:10:42 +0000314}
315
Robert Phillipsac6b1fa2017-03-20 08:38:50 -0400316sk_sp<SkImage> SkSurface::makeImageSnapshot() {
317 return asSB(this)->refCachedImage();
reed@google.com889b09e2012-07-27 21:10:42 +0000318}
319
Mike Reed114bde82018-11-21 09:12:09 -0500320sk_sp<SkImage> SkSurface::makeImageSnapshot(const SkIRect& srcBounds) {
321 const SkIRect surfBounds = { 0, 0, fWidth, fHeight };
322 SkIRect bounds = srcBounds;
323 if (!bounds.intersect(surfBounds)) {
324 return nullptr;
325 }
326 SkASSERT(!bounds.isEmpty());
327 if (bounds == surfBounds) {
328 return this->makeImageSnapshot();
329 } else {
330 return asSB(this)->onNewImageSnapshot(&bounds);
331 }
332}
333
reede8f30622016-03-23 18:59:25 -0700334sk_sp<SkSurface> SkSurface::makeSurface(const SkImageInfo& info) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000335 return asSB(this)->onNewSurface(info);
reed@google.com889b09e2012-07-27 21:10:42 +0000336}
337
Mike Reed4b203ad2019-06-17 17:45:01 -0400338sk_sp<SkSurface> SkSurface::makeSurface(int width, int height) {
339 return this->makeSurface(this->imageInfo().makeWH(width, height));
340}
341
reed@google.com889b09e2012-07-27 21:10:42 +0000342void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
343 const SkPaint* paint) {
344 return asSB(this)->onDraw(canvas, x, y, paint);
345}
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000346
reed6ceeebd2016-03-09 14:26:26 -0800347bool SkSurface::peekPixels(SkPixmap* pmap) {
348 return this->getCanvas()->peekPixels(pmap);
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000349}
reed4a8126e2014-09-22 07:29:03 -0700350
Mike Reed353196f2017-07-21 11:01:18 -0400351bool SkSurface::readPixels(const SkPixmap& pm, int srcX, int srcY) {
352 return this->getCanvas()->readPixels(pm, srcX, srcY);
353}
354
reed7543aa22014-12-09 14:39:44 -0800355bool SkSurface::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
356 int srcX, int srcY) {
Mike Reed353196f2017-07-21 11:01:18 -0400357 return this->readPixels({dstInfo, dstPixels, dstRowBytes}, srcX, srcY);
358}
359
360bool SkSurface::readPixels(const SkBitmap& bitmap, int srcX, int srcY) {
361 SkPixmap pm;
362 return bitmap.peekPixels(&pm) && this->readPixels(pm, srcX, srcY);
reed7543aa22014-12-09 14:39:44 -0800363}
364
Brian Salomon9241a6d2019-10-03 13:26:54 -0400365void SkSurface::asyncRescaleAndReadPixels(const SkImageInfo& info,
366 const SkIRect& srcRect,
367 RescaleGamma rescaleGamma,
368 SkFilterQuality rescaleQuality,
369 ReadPixelsCallback callback,
370 ReadPixelsContext context) {
371 if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) ||
372 !SkImageInfoIsValid(info)) {
373 callback(context, nullptr);
374 return;
375 }
376 asSB(this)->onAsyncRescaleAndReadPixels(
377 info, srcRect, rescaleGamma, rescaleQuality, callback, context);
378}
379
380void SkSurface::asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
381 sk_sp<SkColorSpace> dstColorSpace,
382 const SkIRect& srcRect,
Brian Salomon9241a6d2019-10-03 13:26:54 -0400383 const SkISize& dstSize,
384 RescaleGamma rescaleGamma,
385 SkFilterQuality rescaleQuality,
386 ReadPixelsCallback callback,
387 ReadPixelsContext context) {
388 if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) || dstSize.isZero() ||
389 (dstSize.width() & 0b1) || (dstSize.height() & 0b1)) {
390 callback(context, nullptr);
391 return;
392 }
393 asSB(this)->onAsyncRescaleAndReadPixelsYUV420(yuvColorSpace,
394 std::move(dstColorSpace),
395 srcRect,
396 dstSize,
397 rescaleGamma,
398 rescaleQuality,
399 callback,
400 context);
Brian Salomon024bd002019-06-11 11:38:16 -0400401}
402
Mike Reed4c790bd2018-02-08 14:10:40 -0500403void SkSurface::writePixels(const SkPixmap& pmap, int x, int y) {
404 if (pmap.addr() == nullptr || pmap.width() <= 0 || pmap.height() <= 0) {
405 return;
406 }
407
408 const SkIRect srcR = SkIRect::MakeXYWH(x, y, pmap.width(), pmap.height());
409 const SkIRect dstR = SkIRect::MakeWH(this->width(), this->height());
410 if (SkIRect::Intersects(srcR, dstR)) {
411 ContentChangeMode mode = kRetain_ContentChangeMode;
412 if (srcR.contains(dstR)) {
413 mode = kDiscard_ContentChangeMode;
414 }
415 asSB(this)->aboutToDraw(mode);
416 asSB(this)->onWritePixels(pmap, x, y);
417 }
418}
419
420void SkSurface::writePixels(const SkBitmap& src, int x, int y) {
421 SkPixmap pm;
422 if (src.peekPixels(&pm)) {
423 this->writePixels(pm, x, y);
424 }
425}
426
Greg Daniel5ab94e12020-05-13 14:11:40 -0400427GrContext* SkSurface::getContext() {
428 return asSB(this)->onGetContext();
429}
430
Robert Phillips8caf85f2018-04-05 09:30:38 -0400431GrBackendTexture SkSurface::getBackendTexture(BackendHandleAccess access) {
432 return asSB(this)->onGetBackendTexture(access);
433}
434
435GrBackendRenderTarget SkSurface::getBackendRenderTarget(BackendHandleAccess access) {
436 return asSB(this)->onGetBackendRenderTarget(access);
437}
Robert Phillips8caf85f2018-04-05 09:30:38 -0400438
Brian Salomonaad83152019-05-24 10:16:35 -0400439bool SkSurface::replaceBackendTexture(const GrBackendTexture& backendTexture,
Yi Xu55bca412020-02-14 18:10:40 -0500440 GrSurfaceOrigin origin, ContentChangeMode mode,
Brian Salomonaad83152019-05-24 10:16:35 -0400441 TextureReleaseProc textureReleaseProc,
442 ReleaseContext releaseContext) {
Yi Xu55bca412020-02-14 18:10:40 -0500443 return asSB(this)->onReplaceBackendTexture(backendTexture, origin, mode, textureReleaseProc,
Brian Salomonaad83152019-05-24 10:16:35 -0400444 releaseContext);
445}
446
Greg Daniel9ee15d72020-05-19 20:55:18 +0000447void SkSurface::flushAndSubmit() {
448 this->flush(BackendSurfaceAccess::kNoAccess, GrFlushInfo());
449}
450
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400451GrSemaphoresSubmitted SkSurface::flush(BackendSurfaceAccess access, const GrFlushInfo& flushInfo) {
452 return asSB(this)->onFlush(access, flushInfo);
Greg Daniela5cb7812017-06-16 09:45:32 -0400453}
454
Greg Danielc64ee462017-06-15 16:59:49 -0400455bool SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
456 return asSB(this)->onWait(numSemaphores, waitSemaphores);
ericrkf7b8b8a2016-02-24 14:49:51 -0800457}
458
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400459bool SkSurface::characterize(SkSurfaceCharacterization* characterization) const {
Robert Phillips9907e6e2019-06-25 14:47:04 -0400460 return asConstSB(this)->onCharacterize(characterization);
461}
462
463bool SkSurface::isCompatible(const SkSurfaceCharacterization& characterization) const {
464 return asConstSB(this)->onIsCompatible(characterization);
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400465}
466
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500467bool SkSurface::draw(SkDeferredDisplayList* ddl) {
Robert Phillipsad8a43f2017-08-30 12:06:35 -0400468 return asSB(this)->onDraw(ddl);
469}
470
reed4a8126e2014-09-22 07:29:03 -0700471//////////////////////////////////////////////////////////////////////////////////////
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500472#include "include/utils/SkNoDrawCanvas.h"
Mike Reed44d04bd2017-06-28 19:57:21 -0400473
474class SkNullSurface : public SkSurface_Base {
475public:
476 SkNullSurface(int width, int height) : SkSurface_Base(width, height, nullptr) {}
477
478protected:
479 SkCanvas* onNewCanvas() override {
480 return new SkNoDrawCanvas(this->width(), this->height());
481 }
482 sk_sp<SkSurface> onNewSurface(const SkImageInfo& info) override {
483 return MakeNull(info.width(), info.height());
484 }
Mike Reed114bde82018-11-21 09:12:09 -0500485 sk_sp<SkImage> onNewImageSnapshot(const SkIRect* subsetOrNull) override { return nullptr; }
Mike Reed4c790bd2018-02-08 14:10:40 -0500486 void onWritePixels(const SkPixmap&, int x, int y) override {}
Mike Reed44d04bd2017-06-28 19:57:21 -0400487 void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override {}
488 void onCopyOnWrite(ContentChangeMode) override {}
489};
490
491sk_sp<SkSurface> SkSurface::MakeNull(int width, int height) {
492 if (width < 1 || height < 1) {
493 return nullptr;
494 }
495 return sk_sp<SkSurface>(new SkNullSurface(width, height));
496}
497
498//////////////////////////////////////////////////////////////////////////////////////
reed4a8126e2014-09-22 07:29:03 -0700499
500#if !SK_SUPPORT_GPU
501
Brian Salomonbdecacf2018-02-02 20:32:49 -0500502sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&, int,
503 GrSurfaceOrigin, const SkSurfaceProps*, bool) {
halcanary96fcdcc2015-08-27 07:41:13 -0700504 return nullptr;
reed4a8126e2014-09-22 07:29:03 -0700505}
506
Robert Phillips9338c602019-02-19 12:52:29 -0500507sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrRecordingContext*, const SkSurfaceCharacterization&,
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400508 SkBudgeted) {
509 return nullptr;
510}
511
Greg Daniel94403452017-04-18 15:52:36 -0400512sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext*, const GrBackendTexture&,
513 GrSurfaceOrigin origin, int sampleCnt,
Greg Danielfaa095e2017-12-19 13:15:02 -0500514 SkColorType, sk_sp<SkColorSpace>,
Greg Daniel8ce79912019-02-05 10:08:43 -0500515 const SkSurfaceProps*,
516 TextureReleaseProc, ReleaseContext) {
Greg Danielfaa095e2017-12-19 13:15:02 -0500517 return nullptr;
518}
519
reede8f30622016-03-23 18:59:25 -0700520sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext*,
Greg Daniel94403452017-04-18 15:52:36 -0400521 const GrBackendRenderTarget&,
522 GrSurfaceOrigin origin,
Greg Danielfaa095e2017-12-19 13:15:02 -0500523 SkColorType,
524 sk_sp<SkColorSpace>,
Greg Daniel8ce79912019-02-05 10:08:43 -0500525 const SkSurfaceProps*,
526 RenderTargetReleaseProc, ReleaseContext) {
Greg Danielfaa095e2017-12-19 13:15:02 -0500527 return nullptr;
528}
529
Greg Daniel94403452017-04-18 15:52:36 -0400530sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext*,
Greg Daniel94403452017-04-18 15:52:36 -0400531 const GrBackendTexture&,
532 GrSurfaceOrigin origin,
533 int sampleCnt,
Greg Danielfaa095e2017-12-19 13:15:02 -0500534 SkColorType,
535 sk_sp<SkColorSpace>,
536 const SkSurfaceProps*) {
537 return nullptr;
538}
539
reed4a8126e2014-09-22 07:29:03 -0700540#endif