ec9b4aab87
https://clang.llvm.org/extra/clang-tidy/checks/readability-const-return-type.html `const` on a non-pointer/reference return type typically doesn't add value and can have negative side effects. (i.e., returning a `const std::string` isn't meaningfully different from returning a `std::string`, but can sometimes inhibit move-related optimizations.) In Skia's case, the priv() functions are a notable exception where const return types are intentional and valuable. These calls have been marked with NOLINT to exclude them from the check. This check does not affect pointer and reference returns, where constness is important. Change-Id: I86cab92332f164e5ab710b4127182eec99831d7d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308564 Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
210 lines
7.5 KiB
C++
210 lines
7.5 KiB
C++
/*
|
|
* 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 SkVertices_DEFINED
|
|
#define SkVertices_DEFINED
|
|
|
|
#include "include/core/SkColor.h"
|
|
#include "include/core/SkRect.h"
|
|
#include "include/core/SkRefCnt.h"
|
|
|
|
class SkData;
|
|
struct SkPoint;
|
|
class SkVerticesPriv;
|
|
|
|
/**
|
|
* An immutable set of vertex data that can be used with SkCanvas::drawVertices.
|
|
*/
|
|
class SK_API SkVertices : public SkNVRefCnt<SkVertices> {
|
|
struct Desc;
|
|
struct Sizes;
|
|
public:
|
|
enum VertexMode {
|
|
kTriangles_VertexMode,
|
|
kTriangleStrip_VertexMode,
|
|
kTriangleFan_VertexMode,
|
|
|
|
kLast_VertexMode = kTriangleFan_VertexMode,
|
|
};
|
|
|
|
/**
|
|
* Create a vertices by copying the specified arrays. texs, colors may be nullptr,
|
|
* and indices is ignored if indexCount == 0.
|
|
*/
|
|
static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
|
|
const SkPoint positions[],
|
|
const SkPoint texs[],
|
|
const SkColor colors[],
|
|
int indexCount,
|
|
const uint16_t indices[]);
|
|
|
|
static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
|
|
const SkPoint positions[],
|
|
const SkPoint texs[],
|
|
const SkColor colors[]) {
|
|
return MakeCopy(mode,
|
|
vertexCount,
|
|
positions,
|
|
texs,
|
|
colors,
|
|
0,
|
|
nullptr);
|
|
}
|
|
|
|
static constexpr int kMaxCustomAttributes = 8;
|
|
|
|
/**
|
|
* EXPERIMENTAL - An SkVertices object can be constructed with a custom collection of vertex
|
|
* attributes. Each attribute is described by a single Attribute struct. Type defines the CPU
|
|
* type of the data. Usage determines what transformation (if any) is applied to that data in
|
|
* the vertex shader. For positions or vectors, markerName identifies what matrix is used in
|
|
* the vertex shader to transform the data. Those names should match a named transform on the
|
|
* CTM stack, created by calling SkCanvas::markCTM().
|
|
*
|
|
* For attributes with a usage of kVector, kNormalVector, or kPosition, a null markerName
|
|
* will transform the attribute by the canvas CTM matrix.
|
|
*/
|
|
struct Attribute {
|
|
enum class Type : uint8_t {
|
|
kFloat,
|
|
kFloat2,
|
|
kFloat3,
|
|
kFloat4,
|
|
kByte4_unorm,
|
|
};
|
|
|
|
enum class Usage : uint8_t {
|
|
// Raw values passed directly to effect
|
|
kRaw,
|
|
|
|
// sRGB unpremul colors, transformed to destination color space (3 or 4 channels)
|
|
// Colors are always assumed to be in RGBA order, and are automatically premultiplied.
|
|
kColor,
|
|
|
|
// Local vector, transformed via marker (2 or 3 channels)
|
|
kVector,
|
|
|
|
// Normal vector (or any other bivector), transformed via marker (2 or 3 channels)
|
|
kNormalVector,
|
|
|
|
// Local position, transformed via marker (2 or 3 channels)
|
|
kPosition,
|
|
};
|
|
|
|
/**
|
|
* markerName is not copied by the Attribute, so it must outlive this struct.
|
|
* It is copied when this Attribute is passed to the Builder constructor.
|
|
*/
|
|
Attribute(Type t = Type::kFloat, Usage u = Usage::kRaw, const char* markerName = nullptr);
|
|
|
|
bool operator==(const Attribute& that) const {
|
|
return fType == that.fType && fUsage == that.fUsage && fMarkerID == that.fMarkerID;
|
|
}
|
|
bool operator!=(const Attribute& that) const { return !(*this == that); }
|
|
|
|
// Number of channels that will be produced for the SkRuntimeEffect to consume.
|
|
// May not match the number of channels in fType. For example, kVector Attributes always
|
|
// produce three channels, even if the input is kFloat2.
|
|
int channelCount() const;
|
|
size_t bytesPerVertex() const;
|
|
bool isValid() const;
|
|
|
|
Type fType;
|
|
Usage fUsage;
|
|
uint32_t fMarkerID;
|
|
const char* fMarkerName; // Preserved for serialization and debugging
|
|
};
|
|
|
|
enum BuilderFlags {
|
|
kHasTexCoords_BuilderFlag = 1 << 0,
|
|
kHasColors_BuilderFlag = 1 << 1,
|
|
};
|
|
class Builder {
|
|
public:
|
|
Builder(VertexMode mode, int vertexCount, int indexCount, uint32_t flags);
|
|
|
|
// EXPERIMENTAL -- do not call if you care what happens
|
|
Builder(VertexMode mode,
|
|
int vertexCount,
|
|
int indexCount,
|
|
const Attribute* attrs,
|
|
int attrCount);
|
|
|
|
bool isValid() const { return fVertices != nullptr; }
|
|
|
|
SkPoint* positions();
|
|
uint16_t* indices(); // returns null if there are no indices
|
|
|
|
// if we have texCoords or colors, this will always be null
|
|
void* customData(); // returns null if there are no custom attributes
|
|
|
|
// If we have custom attributes, these will always be null
|
|
SkPoint* texCoords(); // returns null if there are no texCoords
|
|
SkColor* colors(); // returns null if there are no colors
|
|
|
|
// Detach the built vertices object. After the first call, this will always return null.
|
|
sk_sp<SkVertices> detach();
|
|
|
|
private:
|
|
Builder(const Desc&);
|
|
|
|
void init(const Desc&);
|
|
|
|
// holds a partially complete object. only completed in detach()
|
|
sk_sp<SkVertices> fVertices;
|
|
// Extra storage for intermediate vertices in the case where the client specifies indexed
|
|
// triangle fans. These get converted to indexed triangles when the Builder is finalized.
|
|
std::unique_ptr<uint8_t[]> fIntermediateFanIndices;
|
|
|
|
friend class SkVertices;
|
|
friend class SkVerticesPriv;
|
|
};
|
|
|
|
uint32_t uniqueID() const { return fUniqueID; }
|
|
const SkRect& bounds() const { return fBounds; }
|
|
|
|
// returns approximate byte size of the vertices object
|
|
size_t approximateSize() const;
|
|
|
|
// Provides access to functions that aren't part of the public API.
|
|
SkVerticesPriv priv();
|
|
const SkVerticesPriv priv() const; // NOLINT(readability-const-return-type)
|
|
|
|
private:
|
|
SkVertices() {}
|
|
|
|
friend class SkVerticesPriv;
|
|
|
|
// these are needed since we've manually sized our allocation (see Builder::init)
|
|
friend class SkNVRefCnt<SkVertices>;
|
|
void operator delete(void* p);
|
|
|
|
Sizes getSizes() const;
|
|
|
|
// we store this first, to pair with the refcnt in our base-class, so we don't have an
|
|
// unnecessary pad between it and the (possibly 8-byte aligned) ptrs.
|
|
uint32_t fUniqueID;
|
|
|
|
// these point inside our allocation, so none of these can be "freed"
|
|
Attribute* fAttributes; // [attributeCount] or null
|
|
SkPoint* fPositions; // [vertexCount]
|
|
uint16_t* fIndices; // [indexCount] or null
|
|
void* fCustomData; // [customDataSize * vertexCount] or null
|
|
SkPoint* fTexs; // [vertexCount] or null
|
|
SkColor* fColors; // [vertexCount] or null
|
|
|
|
SkRect fBounds; // computed to be the union of the fPositions[]
|
|
int fVertexCount;
|
|
int fIndexCount;
|
|
int fAttributeCount;
|
|
|
|
VertexMode fMode;
|
|
// below here is where the actual array data is stored.
|
|
};
|
|
|
|
#endif
|