/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef ManagedBackendTexture_DEFINED #define ManagedBackendTexture_DEFINED #include "include/core/SkRefCnt.h" #include "include/core/SkYUVAInfo.h" #ifdef SK_GANESH #include "include/gpu/ganesh/GrBackendSurface.h" #include "include/gpu/ganesh/GrDirectContext.h" #endif #ifdef SK_GRAPHITE #include "include/gpu/graphite/BackendTexture.h" #include "include/gpu/graphite/Context.h" #include "src/gpu/graphite/RecorderPriv.h" #endif namespace skgpu { class RefCntedCallback; } namespace skgpu::graphite { class Recorder; } class SkBitmap; struct SkImageInfo; #ifdef SK_GRAPHITE using Recorder = skgpu::graphite::Recorder; #endif namespace sk_gpu_test { #ifdef SK_GANESH class ManagedBackendTexture : public SkNVRefCnt { public: /** * Make a managed backend texture with initial pixmap/color data. The 'Args' are any valid set * of arguments to GrDirectContext::createBackendTexture that takes data but with the release * proc/context omitted as the ManagedBackendTexture will provide them. */ template static sk_sp MakeWithData(GrDirectContext*, Args&&...); /** * Make a managed backend texture without initial data. The 'Args' are any valid set of * arguments to GrDirectContext::createBackendTexture that does not take data. Because our * createBackendTexture methods that *do* take data also use default args for the proc/context * this can be used to make a texture with data but then the MBET won't be able to ensure that * the upload has completed before the texture is deleted. Use the WithData variant instead to * avoid this issue. */ template static sk_sp MakeWithoutData(GrDirectContext*, Args&&...); static sk_sp MakeFromInfo(GrDirectContext* dContext, const SkImageInfo&, skgpu::Mipmapped = skgpu::Mipmapped::kNo, skgpu::Renderable = skgpu::Renderable::kNo, skgpu::Protected = skgpu::Protected::kNo); static sk_sp MakeFromBitmap(GrDirectContext*, const SkBitmap&, skgpu::Mipmapped, skgpu::Renderable, skgpu::Protected = skgpu::Protected::kNo); static sk_sp MakeFromPixmap(GrDirectContext*, const SkPixmap&, skgpu::Mipmapped, skgpu::Renderable, skgpu::Protected = skgpu::Protected::kNo); /** GrGpuFinishedProc or image/surface release proc. */ static void ReleaseProc(void* context); ~ManagedBackendTexture(); /** * The context to use with ReleaseProc. This adds a ref so it *must* be balanced by a call to * ReleaseProc. If a wrappedProc is provided then it will be called by ReleaseProc. */ void* releaseContext(GrGpuFinishedProc wrappedProc = nullptr, GrGpuFinishedContext wrappedContext = nullptr) const; sk_sp refCountedCallback() const; /** * Call if the underlying GrBackendTexture was adopted by a GrContext. This clears this out the * MBET without deleting the texture. */ void wasAdopted(); /** * SkImages::TextureFromYUVATextures takes a single release proc that is called once for all the * textures. This makes a single release context for the group of textures. It's used with the * standard ReleaseProc. Like releaseContext(), it must be balanced by a ReleaseProc call for * proper ref counting. */ static void* MakeYUVAReleaseContext(const sk_sp[SkYUVAInfo::kMaxPlanes]); const GrBackendTexture& texture() { return fTexture; } private: ManagedBackendTexture() = default; ManagedBackendTexture(const ManagedBackendTexture&) = delete; ManagedBackendTexture(ManagedBackendTexture&&) = delete; sk_sp fDContext; GrBackendTexture fTexture; }; template inline sk_sp ManagedBackendTexture::MakeWithData(GrDirectContext* dContext, Args&&... args) { sk_sp mbet(new ManagedBackendTexture); mbet->fDContext = sk_ref_sp(dContext); mbet->fTexture = dContext->createBackendTexture(std::forward(args)..., ReleaseProc, mbet->releaseContext()); if (!mbet->fTexture.isValid()) { return nullptr; } return mbet; } template inline sk_sp ManagedBackendTexture::MakeWithoutData( GrDirectContext* dContext, Args&&... args) { GrBackendTexture texture = dContext->createBackendTexture(std::forward(args)...); if (!texture.isValid()) { return nullptr; } sk_sp mbet(new ManagedBackendTexture); mbet->fDContext = sk_ref_sp(dContext); mbet->fTexture = std::move(texture); return mbet; } #endif // SK_GANESH #ifdef SK_GRAPHITE /* * Graphite version of ManagedBackendTexture */ class ManagedGraphiteTexture : public SkNVRefCnt { public: static sk_sp MakeUnInit(Recorder*, const SkImageInfo&, skgpu::Mipmapped, skgpu::Renderable, skgpu::Protected = skgpu::Protected::kNo); static sk_sp MakeFromPixmap(Recorder*, const SkPixmap&, skgpu::Mipmapped, skgpu::Renderable, skgpu::Protected = skgpu::Protected::kNo); static sk_sp MakeMipmappedFromPixmaps( Recorder*, SkSpan levels, skgpu::Renderable, skgpu::Protected = skgpu::Protected::kNo); static sk_sp MakeFromCompressedData( Recorder*, SkISize dimmensions, SkTextureCompressionType, sk_sp, skgpu::Mipmapped, skgpu::Protected = skgpu::Protected::kNo); /** finished and image/surface release procs */ static void FinishedProc(void* context, skgpu::CallbackResult); static void ReleaseProc(void* context); static void ImageReleaseProc(void* context); ~ManagedGraphiteTexture(); /** * The context to use with the ReleaseProcs. This adds a ref so it *must* be balanced by a call * to TextureReleaseProc or ImageReleaseProc. */ void* releaseContext() const; sk_sp refCountedCallback() const; /** * SkImage::MakeGraphiteFromYUVABackendTextures takes a single release proc that is called once * for all the textures. This makes a single release context for the group of textures. It's * used with the standard ReleaseProc. Like releaseContext(), it must be balanced by a * ReleaseProc call for proper ref counting. */ static void* MakeYUVAReleaseContext(const sk_sp[SkYUVAInfo::kMaxPlanes]); const skgpu::graphite::BackendTexture& texture() { return fTexture; } private: ManagedGraphiteTexture() = default; ManagedGraphiteTexture(const ManagedGraphiteTexture&) = delete; ManagedGraphiteTexture(ManagedGraphiteTexture&&) = delete; skgpu::graphite::Context* fContext; skgpu::graphite::BackendTexture fTexture; }; #endif // SK_GRAPHITE } // namespace sk_gpu_test #endif // ManagedBackendTexture_DEFINED