/* * Copyright 2017 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrBackendSurface_DEFINED #define GrBackendSurface_DEFINED #include "include/core/SkRefCnt.h" #include "include/core/SkSize.h" #include "include/gpu/GpuTypes.h" #include "include/gpu/ganesh/GrTypes.h" #include "include/private/base/SkAPI.h" #include "include/private/base/SkAnySubclass.h" #include "include/private/base/SkDebug.h" #include "include/private/gpu/ganesh/GrTypesPriv.h" class GrBackendFormatData; class GrBackendTextureData; class GrBackendRenderTargetData; namespace skgpu { class MutableTextureState; } #if defined(SK_DEBUG) || defined(GPU_TEST_UTILS) class SkString; #endif #include #include #include #include class SK_API GrBackendFormat { public: // Creates an invalid backend format. GrBackendFormat(); GrBackendFormat(const GrBackendFormat&); GrBackendFormat& operator=(const GrBackendFormat&); ~GrBackendFormat(); bool operator==(const GrBackendFormat& that) const; bool operator!=(const GrBackendFormat& that) const { return !(*this == that); } GrBackendApi backend() const { return fBackend; } GrTextureType textureType() const { return fTextureType; } /** * Gets the channels present in the format as a bitfield of SkColorChannelFlag values. * Luminance channels are reported as kGray_SkColorChannelFlag. */ uint32_t channelMask() const; GrColorFormatDesc desc() const; // If possible, copies the GrBackendFormat and forces the texture type to be Texture2D. If the // GrBackendFormat was for Vulkan and it originally had a skgpu::VulkanYcbcrConversionInfo, // we will remove the conversion and set the format to be VK_FORMAT_R8G8B8A8_UNORM. GrBackendFormat makeTexture2D() const; // Returns true if the backend format has been initialized. bool isValid() const { return fValid; } #if defined(SK_DEBUG) || defined(GPU_TEST_UTILS) SkString toStr() const; #endif private: // Size determined by looking at the GrBackendFormatData subclasses, then guessing-and-checking. // Compiler will complain if this is too small - in that case, just increase the number. inline constexpr static size_t kMaxSubclassSize = 80; using AnyFormatData = SkAnySubclass; friend class GrBackendSurfacePriv; friend class GrBackendFormatData; // Used by internal factories. Should not be used externally. Use factories like // GrBackendFormats::MakeGL instead. template GrBackendFormat(GrTextureType textureType, GrBackendApi api, const FormatData& formatData) : fBackend(api), fTextureType(textureType), fValid(true) { fFormatData.emplace(formatData); } AnyFormatData fFormatData; GrBackendApi fBackend = GrBackendApi::kUnsupported; GrTextureType fTextureType = GrTextureType::kNone; bool fValid = false; }; class SK_API GrBackendTexture { public: // Creates an invalid backend texture. GrBackendTexture(); GrBackendTexture(const GrBackendTexture& that); ~GrBackendTexture(); GrBackendTexture& operator=(const GrBackendTexture& that); SkISize dimensions() const { return {fWidth, fHeight}; } int width() const { return fWidth; } int height() const { return fHeight; } std::string_view getLabel() const { return fLabel; } skgpu::Mipmapped mipmapped() const { return fMipmapped; } bool hasMipmaps() const { return fMipmapped == skgpu::Mipmapped::kYes; } GrBackendApi backend() const {return fBackend; } GrTextureType textureType() const { return fTextureType; } // Get the GrBackendFormat for this texture (or an invalid format if this is not valid). GrBackendFormat getBackendFormat() const; // If the client changes any of the mutable backend of the GrBackendTexture they should call // this function to inform Skia that those values have changed. The backend API specific state // that can be set from this function are: // // Vulkan: VkImageLayout and QueueFamilyIndex void setMutableState(const skgpu::MutableTextureState&); // Returns true if we are working with protected content. bool isProtected() const; // Returns true if the backend texture has been initialized. bool isValid() const { return fIsValid; } // Returns true if both textures are valid and refer to the same API texture. bool isSameTexture(const GrBackendTexture&); #if defined(GPU_TEST_UTILS) static bool TestingOnly_Equals(const GrBackendTexture&, const GrBackendTexture&); #endif private: // Size determined by looking at the GrBackendTextureData subclasses, then guessing-and-checking. // Compiler will complain if this is too small - in that case, just increase the number. inline constexpr static size_t kMaxSubclassSize = 176; using AnyTextureData = SkAnySubclass; friend class GrBackendSurfacePriv; friend class GrBackendTextureData; // Used by internal factories. Should not be used externally. Use factories like // GrBackendTextures::MakeGL instead. template GrBackendTexture(int width, int height, std::string_view label, skgpu::Mipmapped mipped, GrBackendApi backend, GrTextureType texture, const TextureData& textureData) : fIsValid(true) , fWidth(width) , fHeight(height) , fLabel(label) , fMipmapped(mipped) , fBackend(backend) , fTextureType(texture) { fTextureData.emplace(textureData); } friend class GrVkGpu; // for getMutableState sk_sp getMutableState() const; bool fIsValid; int fWidth; //; friend class GrBackendSurfacePriv; friend class GrBackendRenderTargetData; // Used by internal factories. Should not be used externally. Use factories like // GrBackendRenderTargets::MakeGL instead. template GrBackendRenderTarget(int width, int height, int sampleCnt, int stencilBits, GrBackendApi backend, bool framebufferOnly, const RenderTargetData& rtData) : fIsValid(true) , fFramebufferOnly(framebufferOnly) , fWidth(width) , fHeight(height) , fSampleCnt(sampleCnt) , fStencilBits(stencilBits) , fBackend(backend) { fRTData.emplace(rtData); } friend class GrVkGpu; // for getMutableState sk_sp getMutableState() const; bool fIsValid; bool fFramebufferOnly = false; int fWidth; //