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 #ifndef skgpu_graphite_Surface_Graphite_DEFINED 9 #define skgpu_graphite_Surface_Graphite_DEFINED 10 11 #include "src/image/SkSurface_Base.h" 12 13 #include "include/gpu/GpuTypes.h" 14 #include "src/gpu/SkBackingFit.h" 15 #include "src/gpu/graphite/ResourceTypes.h" 16 #include "src/gpu/graphite/TextureProxyView.h" 17 18 namespace skgpu::graphite { 19 20 class Context; 21 class Device; 22 class Image; 23 class Recorder; 24 class TextureProxy; 25 26 class Surface final : public SkSurface_Base { 27 public: 28 // Convenience factory to create a Device, instantiate its target proxy and return as a Surface. 29 static sk_sp<Surface> Make(Recorder* recorder, 30 const SkImageInfo& info, 31 std::string_view label, 32 Budgeted budgeted, 33 Mipmapped mipmapped = Mipmapped::kNo, 34 SkBackingFit backingFit = SkBackingFit::kExact, 35 const SkSurfaceProps* props = nullptr) { 36 return Make(recorder, info, std::move(label), budgeted, mipmapped, backingFit, props, 37 LoadOp::kClear, /*registerWithRecorder=*/true); 38 } 39 // Make a surface that is not registered with the provided recorder. This surface should be 40 // short-lived and it must be flushed manually for its draw commands to be recorded. Most 41 // scratch surfaces will be budgeted, but if the underlying texture is being returned as a 42 // client-owned image, that may not be the case. 43 static sk_sp<Surface> MakeScratch(Recorder* recorder, 44 const SkImageInfo& info, 45 std::string_view label, 46 Budgeted budgeted = Budgeted::kYes, 47 Mipmapped mipmapped = Mipmapped::kNo, 48 SkBackingFit backingFit = SkBackingFit::kApprox) { 49 return Make(recorder, info, std::move(label), budgeted, mipmapped, backingFit, 50 /*props=*/nullptr, LoadOp::kDiscard, /*registerWithRecorder=*/false); 51 } 52 53 Surface(sk_sp<Device>); 54 ~Surface() override; 55 56 // From SkSurface.h 57 SkImageInfo imageInfo() const override; 58 59 // From SkSurface_Base.h type()60 SkSurface_Base::Type type() const override { return SkSurface_Base::Type::kGraphite; } 61 62 Recorder* onGetRecorder() const override; 63 SkCanvas* onNewCanvas() override; 64 sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override; 65 sk_sp<SkImage> onNewImageSnapshot(const SkIRect* subset) override; 66 void onWritePixels(const SkPixmap&, int x, int y) override; 67 void onAsyncRescaleAndReadPixels(const SkImageInfo& info, 68 SkIRect srcRect, 69 RescaleGamma rescaleGamma, 70 RescaleMode rescaleMode, 71 ReadPixelsCallback callback, 72 ReadPixelsContext context) override; 73 void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, 74 bool readAlpha, 75 sk_sp<SkColorSpace> dstColorSpace, 76 SkIRect srcRect, 77 SkISize dstSize, 78 RescaleGamma rescaleGamma, 79 RescaleMode, 80 ReadPixelsCallback callback, 81 ReadPixelsContext context) override; 82 bool onCopyOnWrite(ContentChangeMode) override; 83 sk_sp<const SkCapabilities> onCapabilities() override; 84 85 TextureProxyView readSurfaceView() const; 86 sk_sp<Image> asImage() const; 87 sk_sp<Image> makeImageCopy(const SkIRect* subset, Mipmapped) const; 88 TextureProxy* backingTextureProxy() const; 89 90 private: 91 // Regular and scratch surfaces differ by initial clear and if they are registered or not, 92 // otherwise are constructed the same. 93 static sk_sp<Surface> Make(Recorder* recorder, 94 const SkImageInfo&, 95 std::string_view label, 96 Budgeted, 97 Mipmapped, 98 SkBackingFit, 99 const SkSurfaceProps* props, 100 LoadOp initialLoadOp, 101 bool registerWithRecorder); 102 103 sk_sp<Device> fDevice; 104 sk_sp<Image> fImageView; // the image object returned by asImage() 105 106 friend void Flush(SkSurface*); 107 }; 108 109 // TODO: The long-term for the public API around surfaces and flushing/submitting will likely 110 // be replaced with explicit control over Recorders and submitting Recordings to the Context 111 // directly. For now, internal tools often rely on surface/canvas flushing to control what's 112 // being timed (nanobench or viewer's stats layer), so we flush any pending draws to a DrawPass. 113 // While this won't measure actual conversion of the task list to backend command buffers, that 114 // should be fairly negligible since most of the work is handled in DrawPass::Make(). 115 // Additionally flushing pending work here ensures we don't batch across or clear prior recorded 116 // work when looping in a benchmark, as the controlling code expects. 117 void Flush(sk_sp<SkSurface> surface); 118 void Flush(SkSurface* surface); 119 120 } // namespace skgpu::graphite 121 122 #endif // skgpu_graphite_Surface_Graphite_DEFINED 123