const SkPath&,
const GrStyle& style);
+ enum class ColorArrayType {
+ kPremulGrColor,
+ kSkColor,
+ };
/**
* Draws vertices with a paint.
*
* are drawn non-indexed.
* @param indexCount if indices is non-null then this is the
* number of indices.
+ * @param ColorArrayType Determines how the color array should be interpreted.
*/
void drawVertices(const GrClip&,
GrPaint&& paint,
int vertexCount,
const SkPoint positions[],
const SkPoint texs[],
- const GrColor colors[],
+ const uint32_t colors[],
const uint16_t indices[],
- int indexCount);
+ int indexCount,
+ ColorArrayType = ColorArrayType::kPremulGrColor);
/**
* Draws textured sprites from an atlas with a paint. This currently does not support AA for the
*/
enum GPFlag {
- kColor_GPFlag = 0x1,
- kLocalCoord_GPFlag = 0x2,
- kCoverage_GPFlag= 0x4,
+ kColorAttribute_GPFlag = 0x1,
+ kColorAttributeIsSkColor_GPFlag = 0x2,
+ kLocalCoordAttribute_GPFlag = 0x4,
+ kCoverageAttribute_GPFlag = 0x8,
};
class DefaultGeoProc : public GrGeometryProcessor {
public:
static sk_sp<GrGeometryProcessor> Make(uint32_t gpTypeFlags,
- GrColor color,
- const SkMatrix& viewMatrix,
- const SkMatrix& localMatrix,
- bool localCoordsWillBeRead,
- uint8_t coverage) {
+ GrColor color,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ bool localCoordsWillBeRead,
+ uint8_t coverage) {
return sk_sp<GrGeometryProcessor>(new DefaultGeoProc(
gpTypeFlags, color, viewMatrix, localMatrix, coverage, localCoordsWillBeRead));
}
// Setup pass through color
if (gp.hasVertexColor()) {
- varyingHandler->addPassThroughAttribute(gp.inColor(), args.fOutputColor);
+ GrGLSLVertToFrag varying(kVec4f_GrSLType);
+ varyingHandler->addVarying("color", &varying);
+ if (gp.fFlags & kColorAttributeIsSkColor_GPFlag) {
+ // Do a red/blue swap and premul the color.
+ vertBuilder->codeAppendf("%s = vec4(%s.a*%s.bgr, %s.a);", varying.vsOut(),
+ gp.inColor()->fName, gp.inColor()->fName,
+ gp.inColor()->fName);
+ } else {
+ vertBuilder->codeAppendf("%s = %s;\n", varying.vsOut(), gp.inColor()->fName);
+ }
+ fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
} else {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
GrProcessorKeyBuilder* b) {
const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
uint32_t key = def.fFlags;
- key |= def.hasVertexColor() << 8;
- key |= def.hasVertexCoverage() << 9;
- key |= (def.coverage() == 0xff) ? (0x1 << 10) : 0;
- key |= (def.localCoordsWillBeRead() && def.localMatrix().hasPerspective()) ? (0x1 << 24)
- : 0x0;
- key |= ComputePosKey(def.viewMatrix()) << 25;
+ key |= (def.coverage() == 0xff) ? 0x10 : 0;
+ key |= (def.localCoordsWillBeRead() && def.localMatrix().hasPerspective()) ? 0x20 : 0x0;
+ key |= ComputePosKey(def.viewMatrix()) << 20;
b->add32(key);
}
const SkMatrix& localMatrix,
uint8_t coverage,
bool localCoordsWillBeRead)
- : fInPosition(nullptr)
- , fInColor(nullptr)
- , fInLocalCoords(nullptr)
- , fInCoverage(nullptr)
- , fColor(color)
+ : fColor(color)
, fViewMatrix(viewMatrix)
, fLocalMatrix(localMatrix)
, fCoverage(coverage)
, fFlags(gpTypeFlags)
, fLocalCoordsWillBeRead(localCoordsWillBeRead) {
this->initClassID<DefaultGeoProc>();
- bool hasColor = SkToBool(gpTypeFlags & kColor_GPFlag);
- bool hasExplicitLocalCoords = SkToBool(gpTypeFlags & kLocalCoord_GPFlag);
- bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPFlag);
fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
kHigh_GrSLPrecision);
- if (hasColor) {
+ if (fFlags & kColorAttribute_GPFlag) {
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
}
- if (hasExplicitLocalCoords) {
+ if (fFlags & kLocalCoordAttribute_GPFlag) {
fInLocalCoords = &this->addVertexAttrib("inLocalCoord", kVec2f_GrVertexAttribType,
kHigh_GrSLPrecision);
this->setHasExplicitLocalCoords();
}
- if (hasCoverage) {
+ if (fFlags & kCoverageAttribute_GPFlag) {
fInCoverage = &this->addVertexAttrib("inCoverage", kFloat_GrVertexAttribType);
}
}
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInLocalCoords;
- const Attribute* fInCoverage;
+ const Attribute* fInPosition = nullptr;
+ const Attribute* fInColor = nullptr;
+ const Attribute* fInLocalCoords = nullptr;
+ const Attribute* fInCoverage = nullptr;
GrColor fColor;
SkMatrix fViewMatrix;
SkMatrix fLocalMatrix;
sk_sp<GrGeometryProcessor> DefaultGeoProc::TestCreate(GrProcessorTestData* d) {
uint32_t flags = 0;
if (d->fRandom->nextBool()) {
- flags |= kColor_GPFlag;
+ flags |= kColorAttribute_GPFlag;
}
if (d->fRandom->nextBool()) {
- flags |= kCoverage_GPFlag;
+ flags |= kColorAttributeIsSkColor_GPFlag;
}
if (d->fRandom->nextBool()) {
- flags |= kLocalCoord_GPFlag;
+ flags |= kCoverageAttribute_GPFlag;
+ }
+ if (d->fRandom->nextBool()) {
+ flags |= kLocalCoordAttribute_GPFlag;
}
return DefaultGeoProc::Make(flags,
GrRandomColor(d->fRandom),
GrTest::TestMatrix(d->fRandom),
GrTest::TestMatrix(d->fRandom),
+
d->fRandom->nextBool(),
GrRandomCoverage(d->fRandom));
}
const LocalCoords& localCoords,
const SkMatrix& viewMatrix) {
uint32_t flags = 0;
- flags |= color.fType == Color::kAttribute_Type ? kColor_GPFlag : 0;
- flags |= coverage.fType == Coverage::kAttribute_Type ? kCoverage_GPFlag : 0;
- flags |= localCoords.fType == LocalCoords::kHasExplicit_Type ? kLocalCoord_GPFlag : 0;
+ if (Color::kPremulGrColorAttribute_Type == color.fType) {
+ flags |= kColorAttribute_GPFlag;
+ } else if (Color::kUnpremulSkColorAttribute_Type == color.fType) {
+ flags |= kColorAttribute_GPFlag | kColorAttributeIsSkColor_GPFlag;
+ }
+ flags |= coverage.fType == Coverage::kAttribute_Type ? kCoverageAttribute_GPFlag : 0;
+ flags |= localCoords.fType == LocalCoords::kHasExplicit_Type ? kLocalCoordAttribute_GPFlag : 0;
uint8_t inCoverage = coverage.fCoverage;
bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type;
struct Color {
enum Type {
- kNone_Type,
- kUniform_Type,
- kAttribute_Type,
+ kPremulGrColorUniform_Type,
+ kPremulGrColorAttribute_Type,
+ kUnpremulSkColorAttribute_Type,
};
- explicit Color(GrColor color) : fType(kUniform_Type), fColor(color) {}
+ explicit Color(GrColor color) : fType(kPremulGrColorUniform_Type), fColor(color) {}
Color(Type type) : fType(type), fColor(GrColor_ILLEGAL) {
- SkASSERT(type != kUniform_Type);
-
- // TODO This is temporary
- if (kAttribute_Type == type) {
- fColor = GrColor_WHITE;
- }
+ SkASSERT(type != kPremulGrColorUniform_Type);
}
Type fType;
int vertexCount,
const SkPoint positions[],
const SkPoint texCoords[],
- const GrColor colors[],
+ const uint32_t colors[],
const uint16_t indices[],
- int indexCount) {
+ int indexCount,
+ ColorArrayType colorArrayType) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
viewMatrix.mapRect(&bounds);
- std::unique_ptr<GrDrawOp> op =
- GrDrawVerticesOp::Make(paint.getColor(), primitiveType, viewMatrix, positions,
- vertexCount, indices, indexCount, colors, texCoords, bounds);
+ std::unique_ptr<GrDrawOp> op = GrDrawVerticesOp::Make(
+ paint.getColor(), primitiveType, viewMatrix, positions, vertexCount, indices,
+ indexCount, colors, texCoords, bounds, colorArrayType);
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
GrPrimitiveType primType = gVertexMode2PrimitiveType[vmode];
- SkAutoSTMalloc<128, GrColor> convertedColors(0);
- if (colors) {
- // need to convert byte order and from non-PM to PM. TODO: Keep unpremul until after
- // interpolation.
- convertedColors.reset(vertexCount);
- for (int i = 0; i < vertexCount; ++i) {
- convertedColors[i] = SkColorToPremulGrColor(colors[i]);
- }
- colors = convertedColors.get();
- }
GrPaint grPaint;
if (texs && paint.getShader()) {
if (colors) {
texs,
colors,
indices,
- indexCount);
+ indexCount,
+ GrRenderTargetContext::ColorArrayType::kSkColor);
}
///////////////////////////////////////////////////////////////////////////////
}
LocalCoords::Type localCoordsType =
usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type;
- return MakeForDeviceSpace(Color::kAttribute_Type, coverageType, localCoordsType, viewMatrix);
+ return MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, coverageType, localCoordsType,
+ viewMatrix);
}
class AAConvexPathOp final : public GrMeshDrawOp {
void onPrepareDraws(Target* target) const override {
using namespace GrDefaultGeoProcFactory;
- Color color(Color::kAttribute_Type);
+ Color color(Color::kPremulGrColorAttribute_Type);
Coverage::Type coverageType;
if (fCanTweakAlphaForCoverage) {
coverageType = Coverage::kSolid_Type;
}
LocalCoords::Type localCoordsType =
usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type;
- return MakeForDeviceSpace(Color::kAttribute_Type, coverageType, localCoordsType, viewMatrix);
+ return MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, coverageType, localCoordsType,
+ viewMatrix);
}
class AAFlatteningConvexPathOp final : public GrMeshDrawOp {
}
LocalCoords::Type localCoordsType =
usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type;
- return MakeForDeviceSpace(Color::kAttribute_Type, coverageType, localCoordsType, viewMatrix);
+ return MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, coverageType, localCoordsType,
+ viewMatrix);
}
class AAStrokeRectOp final : public GrMeshDrawOp {
using namespace GrDefaultGeoProcFactory;
Color gpColor(color);
if (hasColors) {
- gpColor.fType = Color::kAttribute_Type;
+ gpColor.fType = Color::kPremulGrColorAttribute_Type;
}
return GrDefaultGeoProcFactory::Make(gpColor, Coverage::kSolid_Type,
#include "GrInvariantOutput.h"
#include "GrOpFlushState.h"
-static sk_sp<GrGeometryProcessor> set_vertex_attributes(bool hasLocalCoords,
- int* colorOffset,
- int* texOffset,
- const SkMatrix& viewMatrix) {
+static sk_sp<GrGeometryProcessor> set_vertex_attributes(
+ bool hasLocalCoords,
+ int* colorOffset,
+ GrRenderTargetContext::ColorArrayType colorArrayType,
+ int* texOffset,
+ const SkMatrix& viewMatrix) {
using namespace GrDefaultGeoProcFactory;
*texOffset = -1;
*colorOffset = -1;
hasLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUsePosition_Type;
*colorOffset = sizeof(SkPoint);
if (hasLocalCoords) {
- *texOffset = sizeof(SkPoint) + sizeof(GrColor);
+ *texOffset = sizeof(SkPoint) + sizeof(uint32_t);
}
- return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type,
- localCoordsType, viewMatrix);
+ Color::Type colorType =
+ (colorArrayType == GrRenderTargetContext::ColorArrayType::kPremulGrColor)
+ ? Color::kPremulGrColorAttribute_Type
+ : Color::kUnpremulSkColorAttribute_Type;
+ return GrDefaultGeoProcFactory::Make(colorType, Coverage::kSolid_Type, localCoordsType,
+ viewMatrix);
}
GrDrawVerticesOp::GrDrawVerticesOp(GrColor color, GrPrimitiveType primitiveType,
const SkMatrix& viewMatrix, const SkPoint* positions,
int vertexCount, const uint16_t* indices, int indexCount,
- const GrColor* colors, const SkPoint* localCoords,
- const SkRect& bounds)
+ const uint32_t* colors, const SkPoint* localCoords,
+ const SkRect& bounds,
+ GrRenderTargetContext::ColorArrayType colorArrayType)
: INHERITED(ClassID()) {
SkASSERT(positions);
if (colors) {
fVariableColor = true;
mesh.fColors.append(vertexCount, colors);
+ fColorArrayType = colorArrayType;
} else {
fVariableColor = false;
+ // When we tessellate we will fill a color array with the GrColor value passed above as
+ // 'color'.
+ fColorArrayType = GrRenderTargetContext::ColorArrayType::kPremulGrColor;
}
if (localCoords) {
fMeshes[0].fColor = overrideColor;
fMeshes[0].fColors.reset();
fVariableColor = false;
+ fColorArrayType = GrRenderTargetContext::ColorArrayType::kPremulGrColor;
}
if (!optimizations.readsLocalCoords()) {
fMeshes[0].fLocalCoords.reset();
void GrDrawVerticesOp::onPrepareDraws(Target* target) const {
bool hasLocalCoords = !fMeshes[0].fLocalCoords.isEmpty();
int colorOffset = -1, texOffset = -1;
- sk_sp<GrGeometryProcessor> gp(
- set_vertex_attributes(hasLocalCoords, &colorOffset, &texOffset, fViewMatrix));
+ sk_sp<GrGeometryProcessor> gp(set_vertex_attributes(hasLocalCoords, &colorOffset,
+ fColorArrayType, &texOffset, fViewMatrix));
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride ==
- sizeof(SkPoint) + (hasLocalCoords ? sizeof(SkPoint) : 0) + sizeof(GrColor));
+ sizeof(SkPoint) + (hasLocalCoords ? sizeof(SkPoint) : 0) + sizeof(uint32_t));
int instanceCount = fMeshes.count();
for (int j = 0; j < mesh.fPositions.count(); ++j) {
*((SkPoint*)verts) = mesh.fPositions[j];
if (mesh.fColors.isEmpty()) {
- *(GrColor*)((intptr_t)verts + colorOffset) = mesh.fColor;
+ *(uint32_t*)((intptr_t)verts + colorOffset) = mesh.fColor;
} else {
- *(GrColor*)((intptr_t)verts + colorOffset) = mesh.fColors[j];
+ *(uint32_t*)((intptr_t)verts + colorOffset) = mesh.fColors[j];
}
if (hasLocalCoords) {
*(SkPoint*)((intptr_t)verts + texOffset) = mesh.fLocalCoords[j];
return false;
}
+ if (fColorArrayType != that->fColorArrayType) {
+ return false;
+ }
+
if (!fVariableColor) {
if (that->fVariableColor || that->fMeshes[0].fColor != fMeshes[0].fColor) {
fVariableColor = true;
static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max,
SkRandom* random, SkTArray<SkPoint>* positions,
SkTArray<SkPoint>* texCoords, bool hasTexCoords,
- SkTArray<GrColor>* colors, bool hasColors, SkTArray<uint16_t>* indices,
- bool hasIndices) {
+ SkTArray<uint32_t>* colors, bool hasColors,
+ SkTArray<uint16_t>* indices, bool hasIndices) {
for (uint32_t v = 0; v < count; v++) {
positions->push_back(random_point(random, min, max));
if (hasTexCoords) {
// TODO make 'sensible' indexbuffers
SkTArray<SkPoint> positions;
SkTArray<SkPoint> texCoords;
- SkTArray<GrColor> colors;
+ SkTArray<uint32_t> colors;
SkTArray<uint16_t> indices;
bool hasTexCoords = random->nextBool();
hasIndices);
}
+ GrRenderTargetContext::ColorArrayType colorArrayType =
+ random->nextBool() ? GrRenderTargetContext::ColorArrayType::kPremulGrColor
+ : GrRenderTargetContext::ColorArrayType::kSkColor;
SkMatrix viewMatrix = GrTest::TestMatrix(random);
SkRect bounds;
SkDEBUGCODE(bool result =) bounds.setBoundsCheck(positions.begin(), vertexCount);
GrColor color = GrRandomColor(random);
return GrDrawVerticesOp::Make(color, type, viewMatrix, positions.begin(), vertexCount,
indices.begin(), hasIndices ? vertexCount : 0, colors.begin(),
- texCoords.begin(), bounds);
+ texCoords.begin(), bounds, colorArrayType);
}
#endif
#include "GrColor.h"
#include "GrMeshDrawOp.h"
+#include "GrRenderTargetContext.h"
#include "GrTypes.h"
#include "SkMatrix.h"
#include "SkRect.h"
static std::unique_ptr<GrDrawOp> Make(GrColor color, GrPrimitiveType primitiveType,
const SkMatrix& viewMatrix, const SkPoint* positions,
int vertexCount, const uint16_t* indices, int indexCount,
- const GrColor* colors, const SkPoint* localCoords,
- const SkRect& bounds) {
- return std::unique_ptr<GrDrawOp>(
- new GrDrawVerticesOp(color, primitiveType, viewMatrix, positions, vertexCount,
- indices, indexCount, colors, localCoords, bounds));
+ const uint32_t* colors, const SkPoint* localCoords,
+ const SkRect& bounds,
+ GrRenderTargetContext::ColorArrayType colorArrayType) {
+ return std::unique_ptr<GrDrawOp>(new GrDrawVerticesOp(
+ color, primitiveType, viewMatrix, positions, vertexCount, indices, indexCount,
+ colors, localCoords, bounds, colorArrayType));
}
const char* name() const override { return "DrawVerticesOp"; }
private:
GrDrawVerticesOp(GrColor color, GrPrimitiveType primitiveType, const SkMatrix& viewMatrix,
const SkPoint* positions, int vertexCount, const uint16_t* indices,
- int indexCount, const GrColor* colors, const SkPoint* localCoords,
- const SkRect& bounds);
+ int indexCount, const uint32_t* colors, const SkPoint* localCoords,
+ const SkRect& bounds, GrRenderTargetContext::ColorArrayType colorArrayType);
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override;
void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
GrColor fColor; // Only used if there are no per-vertex colors
SkTDArray<SkPoint> fPositions;
SkTDArray<uint16_t> fIndices;
- SkTDArray<GrColor> fColors;
+ SkTDArray<uint32_t> fColors;
SkTDArray<SkPoint> fLocalCoords;
};
bool fVariableColor;
int fVertexCount;
int fIndexCount;
+ GrRenderTargetContext::ColorArrayType fColorArrayType;
SkSTArray<1, Mesh, true> fMeshes;
static sk_sp<GrGeometryProcessor> create_gp() {
using namespace GrDefaultGeoProcFactory;
- return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type,
+ return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
LocalCoords::kHasExplicit_Type, SkMatrix::I());
}
sk_sp<GrGeometryProcessor> lineGP;
{
using namespace GrDefaultGeoProcFactory;
- lineGP = GrDefaultGeoProcFactory::Make(Color(Color::kAttribute_Type),
+ lineGP = GrDefaultGeoProcFactory::Make(Color(Color::kPremulGrColorAttribute_Type),
Coverage::kSolid_Type,
LocalCoords(LocalCoords::kUnused_Type),
fViewMatrix);
*/
static sk_sp<GrGeometryProcessor> make_gp() {
using namespace GrDefaultGeoProcFactory;
- return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type,
+ return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
LocalCoords::kHasExplicit_Type, SkMatrix::I());
}
LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
: LocalCoords::kUsePosition_Type,
localMatrix);
- return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type,
- localCoords, viewMatrix);
+ return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
+ Coverage::kSolid_Type, localCoords, viewMatrix);
} else if (hasExplicitLocalCoords) {
LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
- return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type,
- localCoords, SkMatrix::I());
+ return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
+ Coverage::kSolid_Type, localCoords, SkMatrix::I());
} else {
LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
- return GrDefaultGeoProcFactory::MakeForDeviceSpace(
- Color::kAttribute_Type, Coverage::kSolid_Type, localCoords, viewMatrix);
+ return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type,
+ Coverage::kSolid_Type, localCoords,
+ viewMatrix);
}
}
static sk_sp<GrGeometryProcessor> make_gp(const SkMatrix& viewMatrix) {
using namespace GrDefaultGeoProcFactory;
- return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type,
+ return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
LocalCoords::kUsePosition_Type, viewMatrix);
}
: LocalCoords::kUnused_Type;
Coverage::Type coverageType;
if (fAntiAlias) {
- color = Color(Color::kAttribute_Type);
+ color = Color(Color::kPremulGrColorAttribute_Type);
if (fCanTweakAlphaForCoverage) {
coverageType = Coverage::kSolid_Type;
} else {