chromium/third_party/skia/include/core/SkMesh.h

/*
 * 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> {};

/**
 * 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 {};

struct SkMesh::Result {};

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