| /* | |
| * 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<ManagedBackendTexture> { | |
| 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 <typename... Args> | |
| static sk_sp<ManagedBackendTexture> 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 <typename... Args> | |
| static sk_sp<ManagedBackendTexture> MakeWithoutData(GrDirectContext*, Args&&...); | |
| static sk_sp<ManagedBackendTexture> MakeFromInfo(GrDirectContext* dContext, | |
| const SkImageInfo&, | |
| skgpu::Mipmapped = skgpu::Mipmapped::kNo, | |
| skgpu::Renderable = skgpu::Renderable::kNo, | |
| skgpu::Protected = skgpu::Protected::kNo); | |
| static sk_sp<ManagedBackendTexture> MakeFromBitmap(GrDirectContext*, | |
| const SkBitmap&, | |
| skgpu::Mipmapped, | |
| skgpu::Renderable, | |
| skgpu::Protected = skgpu::Protected::kNo); | |
| static sk_sp<ManagedBackendTexture> 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<skgpu::RefCntedCallback> 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<ManagedBackendTexture>[SkYUVAInfo::kMaxPlanes]); | |
| const GrBackendTexture& texture() { return fTexture; } | |
| private: | |
| ManagedBackendTexture() = default; | |
| ManagedBackendTexture(const ManagedBackendTexture&) = delete; | |
| ManagedBackendTexture(ManagedBackendTexture&&) = delete; | |
| sk_sp<GrDirectContext> fDContext; | |
| GrBackendTexture fTexture; | |
| }; | |
| template <typename... Args> | |
| inline sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeWithData(GrDirectContext* dContext, | |
| Args&&... args) { | |
| sk_sp<ManagedBackendTexture> mbet(new ManagedBackendTexture); | |
| mbet->fDContext = sk_ref_sp(dContext); | |
| mbet->fTexture = dContext->createBackendTexture(std::forward<Args>(args)..., | |
| ReleaseProc, | |
| mbet->releaseContext()); | |
| if (!mbet->fTexture.isValid()) { | |
| return nullptr; | |
| } | |
| return mbet; | |
| } | |
| template <typename... Args> | |
| inline sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeWithoutData( | |
| GrDirectContext* dContext, | |
| Args&&... args) { | |
| GrBackendTexture texture = | |
| dContext->createBackendTexture(std::forward<Args>(args)...); | |
| if (!texture.isValid()) { | |
| return nullptr; | |
| } | |
| sk_sp<ManagedBackendTexture> 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<ManagedGraphiteTexture> { | |
| public: | |
| static sk_sp<ManagedGraphiteTexture> MakeUnInit(Recorder*, | |
| const SkImageInfo&, | |
| skgpu::Mipmapped, | |
| skgpu::Renderable, | |
| skgpu::Protected = skgpu::Protected::kNo); | |
| static sk_sp<ManagedGraphiteTexture> MakeFromPixmap(Recorder*, | |
| const SkPixmap&, | |
| skgpu::Mipmapped, | |
| skgpu::Renderable, | |
| skgpu::Protected = skgpu::Protected::kNo); | |
| static sk_sp<ManagedGraphiteTexture> MakeMipmappedFromPixmaps( | |
| Recorder*, | |
| SkSpan<const SkPixmap> levels, | |
| skgpu::Renderable, | |
| skgpu::Protected = skgpu::Protected::kNo); | |
| static sk_sp<ManagedGraphiteTexture> MakeFromCompressedData( | |
| Recorder*, | |
| SkISize dimmensions, | |
| SkTextureCompressionType, | |
| sk_sp<SkData>, | |
| 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<skgpu::RefCntedCallback> 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<ManagedGraphiteTexture>[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 |