Quelle SkMesh.h
Sprache: C
/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD - style license that can be
* found in the LICENSE file .
*/
#ifndef SkMesh_DEFINED
#define SkMesh_DEFINED
#include "include/core/SkData.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "include/core/SkString.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/base/SkAPI.h"
#include "include/private/base/SkTArray.h"
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string_view>
#include <tuple>
#include <vector>
class GrDirectContext;
class SkColorSpace;
enum SkAlphaType : int ;
namespace SkSL { struct Program; }
/**
* A specification for custom meshes . Specifies the vertex buffer attributes and stride , the
* vertex program that produces a user - defined set of varyings , and a fragment program that ingests
* the interpolated varyings and produces local coordinates for shading and optionally a color .
*
* The varyings must include a float2 named " position " . If the passed varyings does not
* contain such a varying then one is implicitly added to the final specification and the SkSL
* Varyings struct described below . It is an error to have a varying named " position " that has a
* type other than float2 .
*
* The provided attributes and varyings are used to create Attributes and Varyings structs in SkSL
* that are used by the shaders . Each attribute from the Attribute span becomes a member of the
* SkSL Attributes struct and likewise for the varyings .
*
* The signature of the vertex program must be :
* Varyings main ( const Attributes ) .
*
* The signature of the fragment program must be either :
* float2 main ( const Varyings )
* or
* float2 main ( const Varyings , out ( half4 | float4 ) color )
*
* where the return value is the local coordinates that will be used to access SkShader . If the
* color variant is used , the returned color will be blended with SkPaint ' s SkShader ( or SkPaint
* color in absence of a SkShader ) using the SkBlender passed to SkCanvas drawMesh ( ) . To use
* interpolated local space positions as the shader coordinates , equivalent to how SkPaths are
* shaded , return the position field from the Varying struct as the coordinates .
*
* The vertex and fragment programs may both contain uniforms . Uniforms with the same name are
* assumed to be shared between stages . It is an error to specify uniforms in the vertex and
* fragment program with the same name but different types , dimensionality , or layouts .
*/
class SK_API SkMeshSpecification : public SkNVRefCnt<SkMeshSpecification> {
public:
/** These values are enforced when creating a specification. */
static constexpr size_t kMaxStride = 1024 ;
static constexpr size_t kMaxAttributes = 8 ;
static constexpr size_t kStrideAlignment = 4 ;
static constexpr size_t kOffsetAlignment = 4 ;
static constexpr size_t kMaxVaryings = 6 ;
struct Attribute {
enum class Type : uint32_t { // CPU representation Shader Type
kFloat, // float float
kFloat2, // two floats float2
kFloat3, // three floats float3
kFloat4, // four floats float4
kUByte4_unorm, // four bytes half4
kLast = kUByte4_unorm
};
Type type;
size_t offset;
SkString name;
};
struct Varying {
enum class Type : uint32_t {
kFloat, // "float"
kFloat2, // "float2"
kFloat3, // "float3"
kFloat4, // "float4"
kHalf, // "half"
kHalf2, // "half2"
kHalf3, // "half3"
kHalf4, // "half4"
kLast = kHalf4
};
Type type;
SkString name;
};
using Uniform = SkRuntimeEffect::Uniform;
using Child = SkRuntimeEffect::Child;
~SkMeshSpecification();
struct Result {
sk_sp<SkMeshSpecification> specification;
SkString error;
};
/**
* If successful the return is a specification and an empty error string . Otherwise , it is a
* null specification a non - empty error string .
*
* @ param attributes The vertex attributes that will be consumed by ' vs ' . Attributes need
* not be tightly packed but attribute offsets must be aligned to
* kOffsetAlignment and offset + size may not be greater than
* ' vertexStride ' . At least one attribute is required .
* @ param vertexStride The offset between successive attribute values . This must be aligned to
* kStrideAlignment .
* @ param varyings The varyings that will be written by ' vs ' and read by ' fs ' . This may
* be empty .
* @ param vs The vertex shader code that computes a vertex position and the varyings
* from the attributes .
* @ param fs The fragment code that computes a local coordinate and optionally a
* color from the varyings . The local coordinate is used to sample
* SkShader .
* @ param cs The colorspace of the color produced by ' fs ' . Ignored if ' fs ' s main ( )
* function does not have a color out param .
* @ param at The alpha type of the color produced by ' fs ' . Ignored if ' fs ' s main ( )
* function does not have a color out param . Cannot be kUnknown .
*/
static Result Make(SkSpan<const Attribute> attributes,
size_t vertexStride,
SkSpan<const Varying> varyings,
const SkString& vs,
const SkString& fs);
static Result Make(SkSpan<const Attribute> attributes,
size_t vertexStride,
SkSpan<const Varying> varyings,
const SkString& vs,
const SkString& fs,
sk_sp<SkColorSpace> cs);
static Result Make(SkSpan<const Attribute> attributes,
size_t vertexStride,
SkSpan<const Varying> varyings,
const SkString& vs,
const SkString& fs,
sk_sp<SkColorSpace> cs,
SkAlphaType at);
SkSpan<const Attribute> attributes() const { return SkSpan(fAttributes); }
/**
* Combined size of all ' uniform ' variables . When creating a SkMesh with this specification
* provide an SkData of this size , containing values for all of those variables . Use uniforms ( )
* to get the offset of each uniform within the SkData .
*/
size_t uniformSize() const ;
/**
* Provides info about individual uniforms including the offset into an SkData where each
* uniform value should be placed .
*/
SkSpan<const Uniform> uniforms() const { return SkSpan(fUniforms); }
/** Provides basic info about individual children: names, indices and runtime effect type. */
SkSpan<const Child> children() const { return SkSpan(fChildren); }
/** Returns a pointer to the named child's description, or nullptr if not found. */
const Child* findChild(std::string_view name) const ;
/** Returns a pointer to the named uniform variable's description, or nullptr if not found. */
const Uniform* findUniform(std::string_view name) const ;
/** Returns a pointer to the named attribute, or nullptr if not found. */
const Attribute* findAttribute(std::string_view name) const ;
/** Returns a pointer to the named varying, or nullptr if not found. */
const Varying* findVarying(std::string_view name) const ;
size_t stride() const { return fStride; }
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
private :
friend struct SkMeshSpecificationPriv;
enum class ColorType {
kNone,
kHalf4,
kFloat4,
};
static Result MakeFromSourceWithStructs(SkSpan<const Attribute> attributes,
size_t stride,
SkSpan<const Varying> varyings,
const SkString& vs,
const SkString& fs,
sk_sp<SkColorSpace> cs,
SkAlphaType at);
SkMeshSpecification(SkSpan<const Attribute>,
size_t,
SkSpan<const Varying>,
int passthroughLocalCoordsVaryingIndex,
uint32_t deadVaryingMask,
std::vector<Uniform> uniforms,
std::vector<Child> children,
std::unique_ptr<const SkSL::Program>,
std::unique_ptr<const SkSL::Program>,
ColorType,
sk_sp<SkColorSpace>,
SkAlphaType);
SkMeshSpecification(const SkMeshSpecification&) = delete ;
SkMeshSpecification(SkMeshSpecification&&) = delete ;
SkMeshSpecification& operator =(const SkMeshSpecification&) = delete ;
SkMeshSpecification& operator =(SkMeshSpecification&&) = delete ;
const std::vector<Attribute> fAttributes;
const std::vector<Varying> fVaryings;
const std::vector<Uniform> fUniforms;
const std::vector<Child> fChildren;
const std::unique_ptr<const SkSL::Program> fVS;
const std::unique_ptr<const SkSL::Program> fFS;
const size_t fStride;
uint32_t fHash;
const int fPassthroughLocalCoordsVaryingIndex;
const uint32_t fDeadVaryingMask;
const ColorType fColorType;
const sk_sp<SkColorSpace> fColorSpace;
const SkAlphaType fAlphaType;
};
/**
* A vertex buffer , a topology , optionally an index buffer , and a compatible SkMeshSpecification .
*
* The data in the vertex buffer is expected to contain the attributes described by the spec
* for vertexCount vertices , beginning at vertexOffset . vertexOffset must be aligned to the
* SkMeshSpecification ' s vertex stride . The size of the buffer must be at least vertexOffset +
* spec - > stride ( ) * vertexCount ( even if vertex attributes contains pad at the end of the stride ) . If
* the specified bounds do not contain all the points output by the spec ' s vertex program when
* applied to the vertices in the custom mesh , then the result is undefined .
*
* MakeIndexed may be used to create an indexed mesh . indexCount indices are read from the index
* buffer at the specified offset , which must be aligned to 2 . The indices are always unsigned
* 16 - bit integers . The index count must be at least 3 .
*
* If Make ( ) is used , the implicit index sequence is 0 , 1 , 2 , 3 , . . . and vertexCount must be at
* least 3 .
*
* Both Make ( ) and MakeIndexed ( ) take a SkData with the uniform values . See
* SkMeshSpecification : : uniformSize ( ) and SkMeshSpecification : : uniforms ( ) for sizing and packing
* uniforms into the SkData .
*/
class SK_API SkMesh {
public:
class IndexBuffer : public SkRefCnt {
public:
virtual size_t size() const = 0 ;
/**
* Modifies the data in the IndexBuffer by copying size bytes from data into the buffer
* at offset . Fails if offset + size > this - > size ( ) or if either offset or size is not
* aligned to 4 bytes . The GrDirectContext * must match that used to create the buffer . We
* take it as a parameter to emphasize that the context must be used to update the data and
* thus the context must be valid for the current thread .
*/
bool update(GrDirectContext*, const void * data, size_t offset, size_t size);
private :
virtual bool onUpdate(GrDirectContext*, const void * data, size_t offset, size_t size) = 0 ;
};
class VertexBuffer : public SkRefCnt {
public:
virtual size_t size() const = 0 ;
/**
* Modifies the data in the IndexBuffer by copying size bytes from data into the buffer
* at offset . Fails if offset + size > this - > size ( ) or if either offset or size is not
* aligned to 4 bytes . The GrDirectContext * must match that used to create the buffer . We
* take it as a parameter to emphasize that the context must be used to update the data and
* thus the context must be valid for the current thread .
*/
bool update(GrDirectContext*, const void * data, size_t offset, size_t size);
private :
virtual bool onUpdate(GrDirectContext*, const void * data, size_t offset, size_t size) = 0 ;
};
SkMesh();
~SkMesh();
SkMesh(const SkMesh&);
SkMesh(SkMesh&&);
SkMesh& operator =(const SkMesh&);
SkMesh& operator =(SkMesh&&);
enum class Mode { kTriangles, kTriangleStrip };
struct Result;
using ChildPtr = SkRuntimeEffect::ChildPtr;
/**
* Creates a non - indexed SkMesh . The returned SkMesh can be tested for validity using
* SkMesh : : isValid ( ) . An invalid mesh simply fails to draws if passed to SkCanvas : : drawMesh ( ) .
* If the mesh is invalid the returned string give contain the reason for the failure ( e . g . the
* vertex buffer was null or uniform data too small ) .
*/
static Result Make(sk_sp<SkMeshSpecification>,
Mode,
sk_sp<VertexBuffer>,
size_t vertexCount,
size_t vertexOffset,
sk_sp<const SkData> uniforms,
SkSpan<ChildPtr> children,
const SkRect& bounds);
/**
* Creates an indexed SkMesh . The returned SkMesh can be tested for validity using
* SkMesh : : isValid ( ) . A invalid mesh simply fails to draw if passed to SkCanvas : : drawMesh ( ) .
* If the mesh is invalid the returned string give contain the reason for the failure ( e . g . the
* index buffer was null or uniform data too small ) .
*/
static Result MakeIndexed(sk_sp<SkMeshSpecification>,
Mode,
sk_sp<VertexBuffer>,
size_t vertexCount,
size_t vertexOffset,
sk_sp<IndexBuffer>,
size_t indexCount,
size_t indexOffset,
sk_sp<const SkData> uniforms,
SkSpan<ChildPtr> children,
const SkRect& bounds);
sk_sp<SkMeshSpecification> refSpec() const { return fSpec; }
SkMeshSpecification* spec() const { return fSpec.get(); }
Mode mode() const { return fMode; }
sk_sp<VertexBuffer> refVertexBuffer() const { return fVB; }
VertexBuffer* vertexBuffer() const { return fVB.get(); }
size_t vertexOffset() const { return fVOffset; }
size_t vertexCount() const { return fVCount; }
sk_sp<IndexBuffer> refIndexBuffer() const { return fIB; }
IndexBuffer* indexBuffer() const { return fIB.get(); }
size_t indexOffset() const { return fIOffset; }
size_t indexCount() const { return fICount; }
sk_sp<const SkData> refUniforms() const { return fUniforms; }
const SkData* uniforms() const { return fUniforms.get(); }
SkSpan<const ChildPtr> children() const { return SkSpan(fChildren); }
SkRect bounds() const { return fBounds; }
bool isValid() const ;
private :
std::tuple<bool , SkString> validate() const ;
sk_sp<SkMeshSpecification> fSpec;
sk_sp<VertexBuffer> fVB;
sk_sp<IndexBuffer> fIB;
sk_sp<const SkData> fUniforms;
skia_private::STArray<2 , ChildPtr> fChildren;
size_t fVOffset = 0 ; // Must be a multiple of spec->stride()
size_t fVCount = 0 ;
size_t fIOffset = 0 ; // Must be a multiple of sizeof(uint16_t)
size_t fICount = 0 ;
Mode fMode = Mode::kTriangles;
SkRect fBounds = SkRect::MakeEmpty();
};
struct SkMesh::Result { SkMesh mesh; SkString error; };
namespace SkMeshes {
/**
* Makes a CPU - backed index buffer to be used with SkMeshes .
*
* @ param data The data used to populate the buffer , or nullptr to create a zero -
* initialized buffer .
* @ param size Both the size of the data in ' data ' and the size of the resulting
* buffer , in bytes .
*/
SK_API sk_sp<SkMesh::IndexBuffer> MakeIndexBuffer(const void * data, size_t size);
/**
* Makes a copy of an index buffer . The copy will be CPU - backed .
*/
SK_API sk_sp<SkMesh::IndexBuffer> CopyIndexBuffer(const sk_sp<SkMesh::IndexBuffer>&);
/**
* Makes a CPU - backed vertex buffer to be used with SkMeshes .
*
* @ param data The data used to populate the buffer , or nullptr to create a zero -
* initialized buffer .
* @ param size Both the size of the data in ' data ' and the size of the resulting
* buffer , in bytes .
*/
SK_API sk_sp<SkMesh::VertexBuffer> MakeVertexBuffer(const void *, size_t size);
/**
* Makes a copy of a vertex buffer . The copy will be CPU - backed .
*/
SK_API sk_sp<SkMesh::VertexBuffer> CopyVertexBuffer(const sk_sp<SkMesh::VertexBuffer>&);
} // namespace SkMeshes
#endif
Messung V0.5 in Prozent C=90 H=97 G=93
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-08-26)
¤
*© Formatika GbR, Deutschland
2026-08-25
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=277311
#Domains=655579