• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
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 "src/gpu/graphite/Surface_Graphite.h"
9 
10 #include "include/core/SkCapabilities.h"
11 #include "include/gpu/graphite/BackendTexture.h"
12 #include "include/gpu/graphite/Recorder.h"
13 #include "src/gpu/graphite/Caps.h"
14 #include "src/gpu/graphite/Device.h"
15 #include "src/gpu/graphite/Image_Graphite.h"
16 #include "src/gpu/graphite/RecorderPriv.h"
17 #include "src/gpu/graphite/ResourceProvider.h"
18 #include "src/gpu/graphite/Texture.h"
19 
20 namespace skgpu::graphite {
21 
Surface(sk_sp<Device> device)22 Surface::Surface(sk_sp<Device> device)
23         : SkSurface_Base(device->width(), device->height(), &device->surfaceProps())
24         , fDevice(std::move(device)) {
25 }
26 
~Surface()27 Surface::~Surface() {}
28 
imageInfo() const29 SkImageInfo Surface::imageInfo() const {
30     return fDevice->imageInfo();
31 }
32 
onGetRecorder()33 Recorder* Surface::onGetRecorder() {
34     return fDevice->recorder();
35 }
36 
readSurfaceView() const37 TextureProxyView Surface::readSurfaceView() const {
38     return fDevice->readSurfaceView();
39 }
40 
onNewCanvas()41 SkCanvas* Surface::onNewCanvas() { return new SkCanvas(fDevice); }
42 
onNewSurface(const SkImageInfo & ii)43 sk_sp<SkSurface> Surface::onNewSurface(const SkImageInfo& ii) {
44     return SkSurface::MakeGraphite(fDevice->recorder(), ii, Mipmapped::kNo, &this->props());
45 }
46 
onNewImageSnapshot(const SkIRect * subset)47 sk_sp<SkImage> Surface::onNewImageSnapshot(const SkIRect* subset) {
48     TextureProxyView srcView = fDevice->readSurfaceView();
49     if (!srcView) {
50         return nullptr;
51     }
52 
53     return this->onMakeImageCopy(subset, srcView.mipmapped());
54 }
55 
onAsImage()56 sk_sp<SkImage> Surface::onAsImage() {
57     TextureProxyView srcView = fDevice->readSurfaceView();
58     if (!srcView) {
59         return nullptr;
60     }
61 
62     return sk_sp<Image>(new Image(std::move(srcView), this->imageInfo().colorInfo()));
63 }
64 
onMakeImageCopy(const SkIRect * subset,Mipmapped mipmapped)65 sk_sp<SkImage> Surface::onMakeImageCopy(const SkIRect* subset, Mipmapped mipmapped) {
66     TextureProxyView srcView = fDevice->createCopy(subset, mipmapped);
67     if (!srcView) {
68         return nullptr;
69     }
70 
71     return sk_sp<Image>(new Image(std::move(srcView), this->imageInfo().colorInfo()));
72 }
73 
onWritePixels(const SkPixmap & pixmap,int x,int y)74 void Surface::onWritePixels(const SkPixmap& pixmap, int x, int y) {
75     fDevice->writePixels(pixmap, x, y);
76 }
77 
onCopyOnWrite(ContentChangeMode)78 bool Surface::onCopyOnWrite(ContentChangeMode) { return true; }
79 
onAsyncRescaleAndReadPixels(const SkImageInfo & info,SkIRect srcRect,RescaleGamma rescaleGamma,RescaleMode rescaleMode,ReadPixelsCallback callback,ReadPixelsContext context)80 void Surface::onAsyncRescaleAndReadPixels(const SkImageInfo& info,
81                                           SkIRect srcRect,
82                                           RescaleGamma rescaleGamma,
83                                           RescaleMode rescaleMode,
84                                           ReadPixelsCallback callback,
85                                           ReadPixelsContext context) {
86     fDevice->asyncRescaleAndReadPixels(info,
87                                        srcRect,
88                                        rescaleGamma,
89                                        rescaleMode,
90                                        callback,
91                                        context);
92 }
93 
onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,sk_sp<SkColorSpace> dstColorSpace,SkIRect srcRect,SkISize dstSize,RescaleGamma rescaleGamma,RescaleMode rescaleMode,ReadPixelsCallback callback,ReadPixelsContext context)94 void Surface::onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
95                                                 sk_sp<SkColorSpace> dstColorSpace,
96                                                 SkIRect srcRect,
97                                                 SkISize dstSize,
98                                                 RescaleGamma rescaleGamma,
99                                                 RescaleMode rescaleMode,
100                                                 ReadPixelsCallback callback,
101                                                 ReadPixelsContext context) {
102     fDevice->asyncRescaleAndReadPixelsYUV420(yuvColorSpace,
103                                              dstColorSpace,
104                                              srcRect,
105                                              dstSize,
106                                              rescaleGamma,
107                                              rescaleMode,
108                                              callback,
109                                              context);
110 }
111 
onCapabilities()112 sk_sp<const SkCapabilities> Surface::onCapabilities() {
113     return fDevice->recorder()->priv().caps()->capabilities();
114 }
115 
116 #if GRAPHITE_TEST_UTILS && defined(SK_GANESH)
onFlush(BackendSurfaceAccess,const GrFlushInfo &,const skgpu::MutableTextureState *)117 GrSemaphoresSubmitted Surface::onFlush(BackendSurfaceAccess,
118                                        const GrFlushInfo&,
119                                        const skgpu::MutableTextureState*) {
120     fDevice->flushPendingWorkToRecorder();
121     return GrSemaphoresSubmitted::kNo;
122 }
123 #endif
124 
backingTextureProxy()125 TextureProxy* Surface::backingTextureProxy() { return fDevice->target(); }
126 
MakeGraphite(Recorder * recorder,const SkImageInfo & info,skgpu::Budgeted budgeted,Mipmapped mipmapped,const SkSurfaceProps * props)127 sk_sp<SkSurface> Surface::MakeGraphite(Recorder* recorder,
128                                        const SkImageInfo& info,
129                                        skgpu::Budgeted budgeted,
130                                        Mipmapped mipmapped,
131                                        const SkSurfaceProps* props) {
132     sk_sp<Device> device = Device::Make(recorder, info, budgeted, mipmapped,
133                                         SkSurfacePropsCopyOrDefault(props),
134                                         /* addInitialClear= */ true);
135     if (!device) {
136         return nullptr;
137     }
138 
139     if (!device->target()->instantiate(recorder->priv().resourceProvider())) {
140         return nullptr;
141     }
142     return sk_make_sp<Surface>(std::move(device));
143 }
144 
145 } // namespace skgpu::graphite
146 
147 using namespace skgpu::graphite;
148 
149 namespace {
150 
validate_backend_texture(const Caps * caps,const BackendTexture & texture,const SkColorInfo & info)151 bool validate_backend_texture(const Caps* caps,
152                               const BackendTexture& texture,
153                               const SkColorInfo& info) {
154     if (!texture.isValid() ||
155         texture.dimensions().width() <= 0 ||
156         texture.dimensions().height() <= 0) {
157         return false;
158     }
159 
160     if (!SkColorInfoIsValid(info)) {
161         return false;
162     }
163 
164     if (!caps->isRenderable(texture.info())) {
165         return false;
166     }
167 
168     return caps->areColorTypeAndTextureInfoCompatible(info.colorType(), texture.info());
169 }
170 
171 } // anonymous namespace
172 
MakeGraphite(Recorder * recorder,const SkImageInfo & info,skgpu::Mipmapped mipmapped,const SkSurfaceProps * props)173 sk_sp<SkSurface> SkSurface::MakeGraphite(Recorder* recorder,
174                                          const SkImageInfo& info,
175                                          skgpu::Mipmapped mipmapped,
176                                          const SkSurfaceProps* props) {
177     // The client is getting the ref on this surface so it must be unbudgeted.
178     return skgpu::graphite::Surface::MakeGraphite(
179             recorder, info, skgpu::Budgeted::kNo, mipmapped, props);
180 }
181 
MakeGraphiteFromBackendTexture(Recorder * recorder,const BackendTexture & backendTex,SkColorType ct,sk_sp<SkColorSpace> cs,const SkSurfaceProps * props)182 sk_sp<SkSurface> SkSurface::MakeGraphiteFromBackendTexture(Recorder* recorder,
183                                                            const BackendTexture& backendTex,
184                                                            SkColorType ct,
185                                                            sk_sp<SkColorSpace> cs,
186                                                            const SkSurfaceProps* props) {
187 
188     if (!recorder) {
189         return nullptr;
190     }
191 
192     const Caps* caps = recorder->priv().caps();
193 
194     SkColorInfo info(ct, kPremul_SkAlphaType, std::move(cs));
195 
196     if (!validate_backend_texture(caps, backendTex, info)) {
197         return nullptr;
198     }
199 
200     sk_sp<Texture> texture = recorder->priv().resourceProvider()->createWrappedTexture(backendTex);
201     if (!texture) {
202         return nullptr;
203     }
204 
205     sk_sp<TextureProxy> proxy(new TextureProxy(std::move(texture)));
206 
207     sk_sp<Device> device = Device::Make(recorder,
208                                         std::move(proxy),
209                                         info,
210                                         SkSurfacePropsCopyOrDefault(props),
211                                         /* addInitialClear= */ false);
212     if (!device) {
213         return nullptr;
214     }
215 
216     return sk_make_sp<Surface>(std::move(device));
217 }
218