/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkGr_DEFINED #define SkGr_DEFINED #include "include/core/SkBlendMode.h" #include "include/core/SkColor.h" #include "include/core/SkColorPriv.h" #include "include/core/SkRefCnt.h" #include "include/core/SkSamplingOptions.h" #include "include/core/SkTileMode.h" #include "include/core/SkTypes.h" #include "include/gpu/GpuTypes.h" #include "include/private/SkColorData.h" #include "src/gpu/Blend.h" #include "src/gpu/SkBackingFit.h" #include "src/gpu/ganesh/GrColor.h" #include "src/gpu/ganesh/GrSamplerState.h" #include #include #include #include class GrColorInfo; class GrFragmentProcessor; class GrPaint; class GrRecordingContext; class GrSurfaceProxy; class GrSurfaceProxyView; class SkBitmap; class SkBlender; class SkIDChangeListener; class SkMatrix; class SkPaint; class SkSurfaceProps; enum class GrColorType; enum GrSurfaceOrigin : int; struct SkIRect; namespace skgpu { class UniqueKey; } //////////////////////////////////////////////////////////////////////////////// // Color type conversions static inline GrColor SkColorToPremulGrColor(SkColor c) { SkPMColor pm = SkPreMultiplyColor(c); unsigned r = SkGetPackedR32(pm); unsigned g = SkGetPackedG32(pm); unsigned b = SkGetPackedB32(pm); unsigned a = SkGetPackedA32(pm); return GrColorPackRGBA(r, g, b, a); } static inline GrColor SkColorToUnpremulGrColor(SkColor c) { unsigned r = SkColorGetR(c); unsigned g = SkColorGetG(c); unsigned b = SkColorGetB(c); unsigned a = SkColorGetA(c); return GrColorPackRGBA(r, g, b, a); } /** Similar, but using SkPMColor4f. */ SkPMColor4f SkColorToPMColor4f(SkColor, const GrColorInfo&); /** Converts an SkColor4f to the destination color space. */ SkColor4f SkColor4fPrepForDst(SkColor4f, const GrColorInfo&); //////////////////////////////////////////////////////////////////////////////// // SkTileMode conversion static constexpr GrSamplerState::WrapMode SkTileModeToWrapMode(SkTileMode tileMode) { switch (tileMode) { case SkTileMode::kClamp: return GrSamplerState::WrapMode::kClamp; case SkTileMode::kDecal: return GrSamplerState::WrapMode::kClampToBorder; case SkTileMode::kMirror: return GrSamplerState::WrapMode::kMirrorRepeat; case SkTileMode::kRepeat: return GrSamplerState::WrapMode::kRepeat; } SkUNREACHABLE; } //////////////////////////////////////////////////////////////////////////////// // Paint conversion /** Converts an SkPaint to a GrPaint for a given GrRecordingContext. The matrix is required in order to convert the SkShader (if any) on the SkPaint. The primitive itself has no color. */ bool SkPaintToGrPaint(GrRecordingContext*, const GrColorInfo& dstColorInfo, const SkPaint& skPaint, const SkMatrix& ctm, const SkSurfaceProps& surfaceProps, GrPaint* grPaint); /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor, if not null. If null then it is assumed that the geometry processor is implementing a shader replacement. The processor should expect an unpremul input color and produce a premultiplied output color. */ bool SkPaintToGrPaintReplaceShader(GrRecordingContext*, const GrColorInfo& dstColorInfo, const SkPaint& skPaint, const SkMatrix& ctm, std::unique_ptr shaderFP, const SkSurfaceProps& surfaceProps, GrPaint* grPaint); /** Blends the SkPaint's shader (or color if no shader) with the color which specified via a GrOp's GrPrimitiveProcesssor. */ bool SkPaintToGrPaintWithBlend(GrRecordingContext* context, const GrColorInfo& dstColorInfo, const SkPaint& skPaint, const SkMatrix& ctm, SkBlender* primColorBlender, const SkSurfaceProps& surfaceProps, GrPaint* grPaint); //////////////////////////////////////////////////////////////////////////////// // Misc Sk to Gr type conversions static_assert((int)skgpu::BlendCoeff::kZero == (int)SkBlendModeCoeff::kZero); static_assert((int)skgpu::BlendCoeff::kOne == (int)SkBlendModeCoeff::kOne); static_assert((int)skgpu::BlendCoeff::kSC == (int)SkBlendModeCoeff::kSC); static_assert((int)skgpu::BlendCoeff::kISC == (int)SkBlendModeCoeff::kISC); static_assert((int)skgpu::BlendCoeff::kDC == (int)SkBlendModeCoeff::kDC); static_assert((int)skgpu::BlendCoeff::kIDC == (int)SkBlendModeCoeff::kIDC); static_assert((int)skgpu::BlendCoeff::kSA == (int)SkBlendModeCoeff::kSA); static_assert((int)skgpu::BlendCoeff::kISA == (int)SkBlendModeCoeff::kISA); static_assert((int)skgpu::BlendCoeff::kDA == (int)SkBlendModeCoeff::kDA); static_assert((int)skgpu::BlendCoeff::kIDA == (int)SkBlendModeCoeff::kIDA); static_assert((int)SkBlendModeCoeff::kCoeffCount == 10); //////////////////////////////////////////////////////////////////////////////// // Texture management /** * Policies for how to create textures for SkImages (and SkBitmaps). */ enum class GrImageTexGenPolicy : int { // Choose the cheapest way to generate the texture. Use GrResourceCache if appropriate. kDraw, // Always make a new texture that is uncached and unbudgeted. kNew_Uncached_Unbudgeted, // Always make a new texture that is uncached and budgeted. kNew_Uncached_Budgeted }; /** * Creates a new texture with mipmap levels and copies the baseProxy into the base layer. */ sk_sp GrCopyBaseMipMapToTextureProxy(GrRecordingContext*, sk_sp baseProxy, GrSurfaceOrigin origin, std::string_view label, skgpu::Budgeted = skgpu::Budgeted::kYes); /** * Same as GrCopyBaseMipMapToTextureProxy but takes the src as a view and returns a view with same * origin and swizzle as the src view. */ GrSurfaceProxyView GrCopyBaseMipMapToView(GrRecordingContext*, GrSurfaceProxyView, skgpu::Budgeted = skgpu::Budgeted::kYes); /* * Create a texture proxy from the provided bitmap and add it to the texture cache using the key * also extracted from the bitmap. If skgpu::Mipmapped is kYes a non-mipmapped result may be * returned if mipmapping isn't supported or for a 1x1 bitmap. If skgpu::Mipmapped is kNo it * indicates mipmaps aren't required but a previously created mipmapped texture may still be * returned. A color type is returned as color type conversion may be performed if there isn't a * texture format equivalent of the bitmap's color type. */ std::tuple GrMakeCachedBitmapProxyView( GrRecordingContext*, const SkBitmap&, std::string_view label, skgpu::Mipmapped = skgpu::Mipmapped::kNo); /** * Like above but always uploads the bitmap and never inserts into the cache. Unlike above, the * texture may be approx or scratch and budgeted or not. */ std::tuple GrMakeUncachedBitmapProxyView( GrRecordingContext*, const SkBitmap&, skgpu::Mipmapped = skgpu::Mipmapped::kNo, SkBackingFit = SkBackingFit::kExact, skgpu::Budgeted = skgpu::Budgeted::kYes); /** * Our key includes the offset, width, and height so that bitmaps created by extractSubset() * are unique. * * The imageID is in the shared namespace (see SkNextID::ImageID()) * - SkBitmap/SkPixelRef * - SkImage * - SkImageGenerator */ void GrMakeKeyFromImageID(skgpu::UniqueKey* key, uint32_t imageID, const SkIRect& imageBounds); /** * Makes a SkIDChangeListener from a skgpu::UniqueKey. The key will be invalidated in the resource * cache if the ID becomes invalid. This also modifies the key so that it will cause the listener * to be deregistered if the key is destroyed (to prevent unbounded listener growth when resources * are purged before listeners trigger). */ sk_sp GrMakeUniqueKeyInvalidationListener(skgpu::UniqueKey*, uint32_t contextID); static inline bool GrValidCubicResampler(SkCubicResampler cubic) { return cubic.B >= 0 && cubic.C >= 0; } #endif