Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Unified Diff: src/gpu/instanced/InstancedRenderingTypes.h

Issue 2120163002: Enable blend optimizations with instanced draws (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_ingorecov
Patch Set: fixes for perf regressions Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/instanced/InstancedRendering.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/instanced/InstancedRenderingTypes.h
diff --git a/src/gpu/instanced/InstancedRenderingTypes.h b/src/gpu/instanced/InstancedRenderingTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..97f8946d033309c6357f37074373dc0071c329ad
--- /dev/null
+++ b/src/gpu/instanced/InstancedRenderingTypes.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef gr_instanced_InstancedRenderingTypes_DEFINED
+#define gr_instanced_InstancedRenderingTypes_DEFINED
+
+#include "GrTypes.h"
+#include "SkRRect.h"
+
+namespace gr_instanced {
+
+/**
+ * Per-vertex data. These values get fed into normal vertex attribs.
+ */
+struct ShapeVertex {
+ float fX, fY; //!< Shape coordinates.
+ int32_t fAttrs; //!< Shape-specific vertex attributes, if needed.
+};
+
+/**
+ * Per-instance data. These values get fed into instanced vertex attribs.
+ */
+struct Instance {
+ uint32_t fInfo; //!< Packed info about the instance. See InfoBits.
+ float fShapeMatrix2x3[6]; //!< Maps canonical shape coords -> device space coords.
+ uint32_t fColor; //!< Color to be written out by the primitive processor.
+ float fLocalRect[4]; //!< Local coords rect that spans [-1, +1] in shape coords.
+};
+
+enum class Attrib : uint8_t {
+ kShapeCoords,
+ kVertexAttrs,
+ kInstanceInfo,
+ kShapeMatrixX,
+ kShapeMatrixY,
+ kColor,
+ kLocalRect
+};
+constexpr int kNumAttribs = 1 + (int)Attrib::kLocalRect;
+
+enum class AntialiasMode : uint8_t {
+ kNone,
+ kCoverage,
+ kMSAA,
+ kMixedSamples
+};
+constexpr int kNumAntialiasModes = 1 + (int)AntialiasMode::kMixedSamples;
+
+enum class ShapeType : uint8_t {
+ kRect,
+ kOval,
+ kSimpleRRect,
+ kNinePatch,
+ kComplexRRect
+};
+constexpr int kNumShapeTypes = 1 + (int)ShapeType::kComplexRRect;
+
+inline static ShapeType GetRRectShapeType(const SkRRect& rrect) {
+ SkASSERT(rrect.getType() >= SkRRect::kRect_Type &&
+ rrect.getType() <= SkRRect::kComplex_Type);
+ return static_cast<ShapeType>(rrect.getType() - 1);
+
+ GR_STATIC_ASSERT((int)ShapeType::kRect == SkRRect::kRect_Type - 1);
+ GR_STATIC_ASSERT((int)ShapeType::kOval == SkRRect::kOval_Type - 1);
+ GR_STATIC_ASSERT((int)ShapeType::kSimpleRRect == SkRRect::kSimple_Type - 1);
+ GR_STATIC_ASSERT((int)ShapeType::kNinePatch == SkRRect::kNinePatch_Type - 1);
+ GR_STATIC_ASSERT((int)ShapeType::kComplexRRect == SkRRect::kComplex_Type - 1);
+ GR_STATIC_ASSERT(kNumShapeTypes == SkRRect::kComplex_Type);
+}
+
+enum ShapeFlag {
+ kRect_ShapeFlag = (1 << (int)ShapeType::kRect),
+ kOval_ShapeFlag = (1 << (int)ShapeType::kOval),
+ kSimpleRRect_ShapeFlag = (1 << (int)ShapeType::kSimpleRRect),
+ kNinePatch_ShapeFlag = (1 << (int)ShapeType::kNinePatch),
+ kComplexRRect_ShapeFlag = (1 << (int)ShapeType::kComplexRRect),
+
+ kRRect_ShapesMask = kSimpleRRect_ShapeFlag | kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag
+};
+
+constexpr uint8_t GetShapeFlag(ShapeType type) { return 1 << (int)type; }
+
+/**
+ * Defines what data is stored at which bits in the fInfo field of the instanced data.
+ */
+enum InfoBits {
+ kShapeType_InfoBit = 29,
+ kInnerShapeType_InfoBit = 27,
+ kPerspective_InfoBit = 26,
+ kLocalMatrix_InfoBit = 25,
+ kParamsIdx_InfoBit = 0
+};
+
+enum InfoMasks {
+ kShapeType_InfoMask = 0u - (1 << kShapeType_InfoBit),
+ kInnerShapeType_InfoMask = (1 << kShapeType_InfoBit) - (1 << kInnerShapeType_InfoBit),
+ kPerspective_InfoFlag = (1 << kPerspective_InfoBit),
+ kLocalMatrix_InfoFlag = (1 << kLocalMatrix_InfoBit),
+ kParamsIdx_InfoMask = (1 << kLocalMatrix_InfoBit) - 1
+};
+
+GR_STATIC_ASSERT((kNumShapeTypes - 1) <= (uint32_t)kShapeType_InfoMask >> kShapeType_InfoBit);
+GR_STATIC_ASSERT((int)ShapeType::kSimpleRRect <=
+ kInnerShapeType_InfoMask >> kInnerShapeType_InfoBit);
+
+/**
+ * Additional parameters required by some instances (e.g. round rect radii, perspective column,
+ * local matrix). These are accessed via texel buffer.
+ */
+struct ParamsTexel {
+ float fX, fY, fZ, fW;
+};
+
+GR_STATIC_ASSERT(0 == offsetof(ParamsTexel, fX));
+GR_STATIC_ASSERT(4 * 4 == sizeof(ParamsTexel));
+
+/**
+ * Tracks all information needed in order to draw a batch of instances. This struct also serves
+ * as an all-in-one shader key for the batch.
+ */
+struct BatchInfo {
+ BatchInfo() : fData(0) {}
+ explicit BatchInfo(uint32_t data) : fData(data) {}
+
+ static bool CanCombine(const BatchInfo& a, const BatchInfo& b);
+
+ bool isSimpleRects() const {
+ return !((fShapeTypes & ~kRect_ShapeFlag) | fInnerShapeTypes);
+ }
+
+ union {
+ struct {
+ AntialiasMode fAntialiasMode;
+ uint8_t fShapeTypes;
+ uint8_t fInnerShapeTypes;
+ bool fHasPerspective : 1;
+ bool fHasLocalMatrix : 1;
+ bool fHasParams : 1;
+ bool fNonSquare : 1;
+ bool fUsesLocalCoords : 1;
+ bool fCannotTweakAlphaForCoverage : 1;
+ bool fCannotDiscard : 1;
+ };
+ uint32_t fData;
+ };
+};
+
+inline bool BatchInfo::CanCombine(const BatchInfo& a, const BatchInfo& b) {
+ if (a.fAntialiasMode != b.fAntialiasMode) {
+ return false;
+ }
+ if (SkToBool(a.fInnerShapeTypes) != SkToBool(b.fInnerShapeTypes)) {
+ // GrInstanceProcessor can't currently combine draws with and without inner shapes.
+ return false;
+ }
+ if (a.fCannotDiscard != b.fCannotDiscard) {
+ // For stencil draws, the use of discard can be a requirement.
+ return false;
+ }
+ return true;
+}
+
+inline BatchInfo operator|(const BatchInfo& a, const BatchInfo& b) {
+ SkASSERT(BatchInfo::CanCombine(a, b));
+ return BatchInfo(a.fData | b.fData);
+}
+
+// This is required since all the data must fit into 32 bits of a shader key.
+GR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(BatchInfo));
+GR_STATIC_ASSERT(kNumShapeTypes <= 8);
+
+struct IndexRange {
+ bool operator ==(const IndexRange& that) const {
+ SkASSERT(fStart != that.fStart || fCount == that.fCount);
+ return fStart == that.fStart;
+ }
+ bool operator !=(const IndexRange& that) const { return !(*this == that); }
+
+ bool isEmpty() const { return fCount <= 0; }
+ int end() { return fStart + fCount; }
+
+ int16_t fStart;
+ int16_t fCount;
+};
+
+}
+
+#endif
« no previous file with comments | « src/gpu/instanced/InstancedRendering.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698