/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef skgpu_graphite_Surface_Graphite_DEFINED #define skgpu_graphite_Surface_Graphite_DEFINED #include "src/image/SkSurface_Base.h" #include "include/gpu/GpuTypes.h" #include "src/gpu/SkBackingFit.h" #include "src/gpu/graphite/ResourceTypes.h" #include "src/gpu/graphite/TextureProxyView.h" namespace skgpu::graphite { class Context; class Device; class Image; class Recorder; class TextureProxy; class Surface final : public SkSurface_Base { public: // Convenience factory to create a Device, instantiate its target proxy and return as a Surface. static sk_sp Make(Recorder* recorder, const SkImageInfo& info, std::string_view label, Budgeted budgeted, Mipmapped mipmapped = Mipmapped::kNo, SkBackingFit backingFit = SkBackingFit::kExact, const SkSurfaceProps* props = nullptr) { return Make(recorder, info, std::move(label), budgeted, mipmapped, backingFit, props, LoadOp::kClear, /*registerWithRecorder=*/true); } // Make a surface that is not registered with the provided recorder. This surface should be // short-lived and it must be flushed manually for its draw commands to be recorded. Most // scratch surfaces will be budgeted, but if the underlying texture is being returned as a // client-owned image, that may not be the case. static sk_sp MakeScratch(Recorder* recorder, const SkImageInfo& info, std::string_view label, Budgeted budgeted = Budgeted::kYes, Mipmapped mipmapped = Mipmapped::kNo, SkBackingFit backingFit = SkBackingFit::kApprox) { return Make(recorder, info, std::move(label), budgeted, mipmapped, backingFit, /*props=*/nullptr, LoadOp::kDiscard, /*registerWithRecorder=*/false); } Surface(sk_sp); ~Surface() override; // From SkSurface.h SkImageInfo imageInfo() const override; // From SkSurface_Base.h SkSurface_Base::Type type() const override { return SkSurface_Base::Type::kGraphite; } Recorder* onGetRecorder() const override; SkCanvas* onNewCanvas() override; sk_sp onNewSurface(const SkImageInfo&) override; sk_sp onNewImageSnapshot(const SkIRect* subset) override; void onWritePixels(const SkPixmap&, int x, int y) override; void onAsyncRescaleAndReadPixels(const SkImageInfo& info, SkIRect srcRect, RescaleGamma rescaleGamma, RescaleMode rescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) override; void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, bool readAlpha, sk_sp dstColorSpace, SkIRect srcRect, SkISize dstSize, RescaleGamma rescaleGamma, RescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) override; bool onCopyOnWrite(ContentChangeMode) override; sk_sp onCapabilities() override; TextureProxyView readSurfaceView() const; sk_sp asImage() const; sk_sp makeImageCopy(const SkIRect* subset, Mipmapped) const; TextureProxy* backingTextureProxy() const; private: // Regular and scratch surfaces differ by initial clear and if they are registered or not, // otherwise are constructed the same. static sk_sp Make(Recorder* recorder, const SkImageInfo&, std::string_view label, Budgeted, Mipmapped, SkBackingFit, const SkSurfaceProps* props, LoadOp initialLoadOp, bool registerWithRecorder); sk_sp fDevice; sk_sp fImageView; // the image object returned by asImage() friend void Flush(SkSurface*); }; // TODO: The long-term for the public API around surfaces and flushing/submitting will likely // be replaced with explicit control over Recorders and submitting Recordings to the Context // directly. For now, internal tools often rely on surface/canvas flushing to control what's // being timed (nanobench or viewer's stats layer), so we flush any pending draws to a DrawPass. // While this won't measure actual conversion of the task list to backend command buffers, that // should be fairly negligible since most of the work is handled in DrawPass::Make(). // Additionally flushing pending work here ensures we don't batch across or clear prior recorded // work when looping in a benchmark, as the controlling code expects. void Flush(sk_sp surface); void Flush(SkSurface* surface); } // namespace skgpu::graphite #endif // skgpu_graphite_Surface_Graphite_DEFINED