blob: 90f67caee8fad5af3b094ee243bf383e15eb6182 [file] [log] [blame]
/*
* Copyright 2022 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_PaintParams_DEFINED
#define skgpu_graphite_PaintParams_DEFINED
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "src/base/SkEnumBitMask.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/Renderer.h"
#include "src/gpu/graphite/geom/NonMSAAClip.h"
class SkColorInfo;
class SkShader;
namespace skgpu::graphite {
class DrawContext;
class KeyContext;
class FloatStorageManager;
class PaintParamsKeyBuilder;
class PipelineDataGatherer;
class Recorder;
class TextureProxy;
class UniquePaintParamsID;
// NOTE: Only represents the shading state of an SkPaint. Style and complex effects (mask filters,
// image filters, path effects) must be handled higher up. AA is not tracked since everything is
// assumed to be anti-aliased.
//
// The full shading of a draw is a combination of the PaintParams extracted from an SkPaint, any
// analytic NonMSAA clipping, analytic coverage from a RenderStep, and the target TextureFormat
// being rendered into. These additional parameters are aggregated together in ShadingParams.
//
// Both PaintParams and ShadingParams are meant to be short-lived objects used for processing a
// draw's effects into a UniquePaintID and extracted uniforms and textures. As such, they do not
// keep high-level Skia objects alive since these Params types should go out of scope by the end of
// the draw call.
class PaintParams {
public:
// Converts an SkPaint to PaintParams, possibly adding a primitive blender (e.g. for
// drawVertices or text rendering).
explicit PaintParams(const SkPaint&,
const SkBlender* primitiveBlender = nullptr,
bool skipColorXform = false,
bool ignoreShader = false);
// Creates a constant color PaintParams with the specific blend mode.
PaintParams(const SkColor4f& color, SkBlendMode finalBlendMode);
const SkColor4f& color() const { return fColor; }
const SkShader* shader() const { return fShader; }
const SkColorFilter* colorFilter() const { return fColorFilter; }
const SkBlender* primitiveBlender() const { return fPrimitiveBlender; }
bool skipPrimitiveColorXform() const { return fSkipColorXform; }
const SkBlender* finalBlender() const { return fFinalBlend.first; }
// Must also check finalBlender() to see if that overrides finalBlendMode() behavior.
SkBlendMode finalBlendMode() const { SkASSERT(!fFinalBlend.first); return fFinalBlend.second; }
bool dither() const { return fDither; }
/** Converts an SkColor4f to the destination color space. */
static SkColor4f Color4fPrepForDst(SkColor4f srgb, const SkColorInfo& dstColorInfo);
private:
SkColor4f fColor;
// Either a non-null SkBlender for runtime blending, or the SkBlendMode to use instead. If
// the blender is non-null, the blend mode is set to kSrc to match the HW blend config used for
// shader-based blending.
std::pair<const SkBlender*, SkBlendMode> fFinalBlend;
const SkShader* fShader;
const SkColorFilter* fColorFilter;
// A nullptr fPrimitiveBlender means there's no primitive color blending and it is skipped.
// In the case where there is primitive blending, the primitive color is the source color and
// the dest is the paint's color (or the paint's shader's computed color).
const SkBlender* fPrimitiveBlender;
bool fSkipColorXform;
bool fDither;
};
// ShadingParams wraps a PaintParams with the additional per-pixel state to handle clipping and
// anti-aliasing, as well as making the final determinations for how blending will be implemented
// given the current hardware.
class ShadingParams {
public:
// NOTE: Does not copy `paint`, `nonMSAAClip` or `clipShader`; these must outlive ShadingParams.
ShadingParams(const Caps* caps,
const PaintParams& paint,
const NonMSAAClip& nonMSAAClip,
const SkShader* clipShader,
Coverage coverage,
TextureFormat targetFormat);
Coverage rendererCoverage() const { return fRendererCoverage; }
bool dstReadRequired() const { return SkToBool(fDstUsage & DstUsage::kDstReadRequired); }
using Result = std::tuple<UniquePaintParamsID, SkEnumBitMask<DstUsage>>;
std::optional<Result> toKey(const KeyContext&) const;
private:
bool addPaintColorToKey(const KeyContext&) const;
bool handlePrimitiveColor(const KeyContext&) const;
bool handlePaintAlpha(const KeyContext&) const;
bool handleColorFilter(const KeyContext&) const;
bool handleDithering(const KeyContext&) const;
bool handleDstRead(const KeyContext&) const;
void handleClipping(const KeyContext&) const;
const PaintParams& fPaint;
const NonMSAAClip& fNonMSAAClip;
const SkShader* fClipShader;
Coverage fRendererCoverage;
TextureFormat fTargetFormat;
SkEnumBitMask<DstUsage> fDstUsage;
};
} // namespace skgpu::graphite
#endif // skgpu_PaintParams_DEFINED