• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/SkSurface.h"
9 
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkCapabilities.h" // IWYU pragma: keep
13 #include "include/core/SkColorSpace.h"
14 #include "include/core/SkImage.h"
15 #include "include/core/SkImageInfo.h"
16 #include "include/core/SkPixmap.h"
17 #include "include/core/SkRect.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkScalar.h"
20 #include "include/core/SkSize.h"
21 #include "include/core/SkSurfaceProps.h"
22 #include "include/private/base/SkTemplates.h"
23 #include "src/core/SkImageInfoPriv.h"
24 #include "src/core/SkSurfacePriv.h"
25 #include "src/image/SkSurface_Base.h"
26 
27 #include <cstddef>
28 #include <cstdint>
29 #include <utility>
30 
31 class GrBackendSemaphore;
32 class GrRecordingContext;  // IWYU pragma: keep
33 class SkPaint;
34 class GrSurfaceCharacterization;
35 namespace skgpu { namespace graphite { class Recorder; } }
36 
SkSurfaceProps()37 SkSurfaceProps::SkSurfaceProps()
38     : fFlags(0)
39     , fPixelGeometry(kUnknown_SkPixelGeometry)
40     , fTextContrast(SK_GAMMA_CONTRAST)
41     , fTextGamma(SK_GAMMA_EXPONENT) {}
42 
SkSurfaceProps(uint32_t flags,SkPixelGeometry pg)43 SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
44     : fFlags(flags)
45     , fPixelGeometry(pg)
46     , fTextContrast(SK_GAMMA_CONTRAST)
47     , fTextGamma(SK_GAMMA_EXPONENT) {}
48 
SkSurfaceProps(uint32_t flags,SkPixelGeometry pg,SkScalar textContrast,SkScalar textGamma)49 SkSurfaceProps::SkSurfaceProps(uint32_t flags,
50                                SkPixelGeometry pg,
51                                SkScalar textContrast,
52                                SkScalar textGamma)
53     : fFlags(flags), fPixelGeometry(pg), fTextContrast(textContrast), fTextGamma(textGamma) {}
54 
SkSurface(int width,int height,const SkSurfaceProps * props)55 SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
56     : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
57 {
58     SkASSERT(fWidth > 0);
59     SkASSERT(fHeight > 0);
60     fGenerationID = 0;
61 }
62 
SkSurface(const SkImageInfo & info,const SkSurfaceProps * props)63 SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
64     : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
65 {
66     SkASSERT(fWidth > 0);
67     SkASSERT(fHeight > 0);
68     fGenerationID = 0;
69 }
70 
generationID()71 uint32_t SkSurface::generationID() {
72     if (0 == fGenerationID) {
73         fGenerationID = asSB(this)->newGenerationID();
74     }
75     return fGenerationID;
76 }
77 
notifyContentWillChange(ContentChangeMode mode)78 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
79     sk_ignore_unused_variable(asSB(this)->aboutToDraw(mode));
80 }
81 
getCanvas()82 SkCanvas* SkSurface::getCanvas() {
83     return asSB(this)->getCachedCanvas();
84 }
85 
capabilities()86 sk_sp<const SkCapabilities> SkSurface::capabilities() {
87     return asSB(this)->onCapabilities();
88 }
89 
makeImageSnapshot()90 sk_sp<SkImage> SkSurface::makeImageSnapshot() {
91     return asSB(this)->refCachedImage();
92 }
93 
makeImageSnapshot(const SkIRect & srcBounds)94 sk_sp<SkImage> SkSurface::makeImageSnapshot(const SkIRect& srcBounds) {
95     const SkIRect surfBounds = { 0, 0, fWidth, fHeight };
96     SkIRect bounds = srcBounds;
97     if (!bounds.intersect(surfBounds)) {
98         return nullptr;
99     }
100     SkASSERT(!bounds.isEmpty());
101     if (bounds == surfBounds) {
102         return this->makeImageSnapshot();
103     } else {
104         return asSB(this)->onNewImageSnapshot(&bounds);
105     }
106 }
107 
makeTemporaryImage()108 sk_sp<SkImage> SkSurface::makeTemporaryImage() {
109     return asSB(this)->onMakeTemporaryImage();
110 }
111 
makeSurface(const SkImageInfo & info)112 sk_sp<SkSurface> SkSurface::makeSurface(const SkImageInfo& info) {
113     return asSB(this)->onNewSurface(info);
114 }
115 
makeSurface(int width,int height)116 sk_sp<SkSurface> SkSurface::makeSurface(int width, int height) {
117     return this->makeSurface(this->imageInfo().makeWH(width, height));
118 }
119 
draw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkSamplingOptions & sampling,const SkPaint * paint)120 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkSamplingOptions& sampling,
121                      const SkPaint* paint) {
122     asSB(this)->onDraw(canvas, x, y, sampling, paint);
123 }
124 
peekPixels(SkPixmap * pmap)125 bool SkSurface::peekPixels(SkPixmap* pmap) {
126     return this->getCanvas()->peekPixels(pmap);
127 }
128 
readPixels(const SkPixmap & pm,int srcX,int srcY)129 bool SkSurface::readPixels(const SkPixmap& pm, int srcX, int srcY) {
130     return this->getCanvas()->readPixels(pm, srcX, srcY);
131 }
132 
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY)133 bool SkSurface::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
134                            int srcX, int srcY) {
135     return this->readPixels({dstInfo, dstPixels, dstRowBytes}, srcX, srcY);
136 }
137 
readPixels(const SkBitmap & bitmap,int srcX,int srcY)138 bool SkSurface::readPixels(const SkBitmap& bitmap, int srcX, int srcY) {
139     SkPixmap pm;
140     return bitmap.peekPixels(&pm) && this->readPixels(pm, srcX, srcY);
141 }
142 
asyncRescaleAndReadPixels(const SkImageInfo & info,const SkIRect & srcRect,RescaleGamma rescaleGamma,RescaleMode rescaleMode,ReadPixelsCallback callback,ReadPixelsContext context)143 void SkSurface::asyncRescaleAndReadPixels(const SkImageInfo& info,
144                                           const SkIRect& srcRect,
145                                           RescaleGamma rescaleGamma,
146                                           RescaleMode rescaleMode,
147                                           ReadPixelsCallback callback,
148                                           ReadPixelsContext context) {
149     if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) ||
150         !SkImageInfoIsValid(info)) {
151         callback(context, nullptr);
152         return;
153     }
154     asSB(this)->onAsyncRescaleAndReadPixels(
155             info, srcRect, rescaleGamma, rescaleMode, callback, context);
156 }
157 
asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,sk_sp<SkColorSpace> dstColorSpace,const SkIRect & srcRect,const SkISize & dstSize,RescaleGamma rescaleGamma,RescaleMode rescaleMode,ReadPixelsCallback callback,ReadPixelsContext context)158 void SkSurface::asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
159                                                 sk_sp<SkColorSpace> dstColorSpace,
160                                                 const SkIRect& srcRect,
161                                                 const SkISize& dstSize,
162                                                 RescaleGamma rescaleGamma,
163                                                 RescaleMode rescaleMode,
164                                                 ReadPixelsCallback callback,
165                                                 ReadPixelsContext context) {
166     if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) || dstSize.isZero() ||
167         (dstSize.width() & 0b1) || (dstSize.height() & 0b1)) {
168         callback(context, nullptr);
169         return;
170     }
171     asSB(this)->onAsyncRescaleAndReadPixelsYUV420(yuvColorSpace,
172                                                   /*readAlpha=*/false,
173                                                   std::move(dstColorSpace),
174                                                   srcRect,
175                                                   dstSize,
176                                                   rescaleGamma,
177                                                   rescaleMode,
178                                                   callback,
179                                                   context);
180 }
181 
asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace,sk_sp<SkColorSpace> dstColorSpace,const SkIRect & srcRect,const SkISize & dstSize,RescaleGamma rescaleGamma,RescaleMode rescaleMode,ReadPixelsCallback callback,ReadPixelsContext context)182 void SkSurface::asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace,
183                                                  sk_sp<SkColorSpace> dstColorSpace,
184                                                  const SkIRect& srcRect,
185                                                  const SkISize& dstSize,
186                                                  RescaleGamma rescaleGamma,
187                                                  RescaleMode rescaleMode,
188                                                  ReadPixelsCallback callback,
189                                                  ReadPixelsContext context) {
190     if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) || dstSize.isZero() ||
191         (dstSize.width() & 0b1) || (dstSize.height() & 0b1)) {
192         callback(context, nullptr);
193         return;
194     }
195     asSB(this)->onAsyncRescaleAndReadPixelsYUV420(yuvColorSpace,
196                                                   /*readAlpha=*/true,
197                                                   std::move(dstColorSpace),
198                                                   srcRect,
199                                                   dstSize,
200                                                   rescaleGamma,
201                                                   rescaleMode,
202                                                   callback,
203                                                   context);
204 }
205 
writePixels(const SkPixmap & pmap,int x,int y)206 void SkSurface::writePixels(const SkPixmap& pmap, int x, int y) {
207     if (pmap.addr() == nullptr || pmap.width() <= 0 || pmap.height() <= 0) {
208         return;
209     }
210 
211     const SkIRect srcR = SkIRect::MakeXYWH(x, y, pmap.width(), pmap.height());
212     const SkIRect dstR = SkIRect::MakeWH(this->width(), this->height());
213     if (SkIRect::Intersects(srcR, dstR)) {
214         ContentChangeMode mode = kRetain_ContentChangeMode;
215         if (srcR.contains(dstR)) {
216             mode = kDiscard_ContentChangeMode;
217         }
218         if (!asSB(this)->aboutToDraw(mode)) {
219             return;
220         }
221         asSB(this)->onWritePixels(pmap, x, y);
222     }
223 }
224 
writePixels(const SkBitmap & src,int x,int y)225 void SkSurface::writePixels(const SkBitmap& src, int x, int y) {
226     SkPixmap pm;
227     if (src.peekPixels(&pm)) {
228         this->writePixels(pm, x, y);
229     }
230 }
231 
recordingContext() const232 GrRecordingContext* SkSurface::recordingContext() const {
233     return asConstSB(this)->onGetRecordingContext();
234 }
235 
recorder() const236 skgpu::graphite::Recorder* SkSurface::recorder() const { return asConstSB(this)->onGetRecorder(); }
237 
wait(int numSemaphores,const GrBackendSemaphore * waitSemaphores,bool deleteSemaphoresAfterWait)238 bool SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores,
239                      bool deleteSemaphoresAfterWait) {
240     return asSB(this)->onWait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait);
241 }
242 
characterize(GrSurfaceCharacterization * characterization) const243 bool SkSurface::characterize(GrSurfaceCharacterization* characterization) const {
244     return asConstSB(this)->onCharacterize(characterization);
245 }
246 
isCompatible(const GrSurfaceCharacterization & characterization) const247 bool SkSurface::isCompatible(const GrSurfaceCharacterization& characterization) const {
248     return asConstSB(this)->onIsCompatible(characterization);
249 }
250